llm-tool
Framework-agnostic Rust tool definitions for LLM agents.
Write plain Rust functions. Get typed LLM tools with JSON Schemas, automatic deserialization, and instant MCP server support.
Why llm-tool?
- Zero Boilerplate:
#[llm_tool]on a function → typed tool with JSON Schema. - Strongly Typed: Parameters are validated. Missing or extra arguments are caught instantly.
- Framework Agnostic: Use the
ToolRegistryto get JSON Schemas for any LLM SDK (OpenAI, Anthropic, Gemini, …). - MCP Ready: Spin up a fully compliant MCP server in 3 lines with
llm-tool-mcp. no_stdCompatible: Core types work in embedded and WASM targets.
⚡ Quick Start
[]
= "0.8"
= "0.8" # Optional: for MCP server support
Define a Tool
Doc comments become tool and parameter descriptions automatically.
use ;
/// Fetches the current weather for a given location.
async
// Register it! The macro generated a `GetWeather` struct for us.
let registry = new.with_tool;
// You can now extract the JSON schema for any LLM SDK...
let definitions = registry.definitions;
assert_eq!;
// ...or execute calls directly from JSON arguments!
# block_on;
🚀 MCP: Tools, Prompts, and Resources
Use llm-tool-mcp to expose everything over the Model Context Protocol.
# use ;
/// A Tool for the LLM to execute.
/// A Prompt template for the LLM to use.
/// A Resource for the LLM to read.
// Register tools in the ToolRegistry.
let registry = new.with_tool;
assert_eq!;
// Prompts and Resources are registered via llm-tool-mcp's builder:
// McpServer::builder("my-server", "1.0", registry)
// .with_prompt(CodeReview)
// .with_resource(GetConfig)
// .build();
🧠 Features
Return Types & Error Handling
Return Result<T, E> or just T. The ? operator works out of the box.
- Auto-Serialization: Return any
T: Serialize→ automatic JSON response. - Structured Metadata: Attach hidden metadata to
ToolOutputorToolError(logged but not sent to the LLM).
Context
Add ctx: &ToolContext to any tool function to access
shared state, conversation IDs, or typed extensions —
automatically hidden from the JSON Schema.
Custom Descriptions
Override doc comments with an inline string — no extra features needed:
# use ;
async
With the md-tmpl feature, you can also load
descriptions from .tmpl.md template files
(description_file = "..."), with compile-time variable
substitution and validation.
See the md-tmpl docs
for details.
Documentation
llm-tool— Return types, tool context, metadata, template descriptions.llm-tool-mcp— MCP transports, stdio/TCP, routing.md-tmpl— Template syntax, env variables, response templates.
License
Dual-licensed under Apache-2.0 OR MIT.