1 unstable release
new 0.1.0 | Apr 17, 2025 |
---|
#740 in Procedural macros
Used in kuri
16KB
284 lines
kuri (栗 or くり)
kuri
is a framework to build Model Context Protocol (MCP) servers, focused on developer ergonomics and clarity.
Design philosophy
- Ergonomic developer experience. Tools and prompts are just plain Rust functions.
- Minimal use of macros: only for attaching tool metadata (description and param descriptions)
- Minimal boilerplate
- Take advantage of the
tower
ecosystem of middleware, services and utilities. Get timeouts, tracing, panic-handling, and more for free. Re-use the same logic you use foraxum
,tonic
andhyper
.
We're inspired by axum
and actix
.
Usage
#[tool(
description = "Perform basic arithmetic operations",
params(
x = "First number in the calculation",
y = "Second number in the calculation",
operation = "The operation to perform (add, subtract, multiply, divide)"
)
)]
async fn calculator(x: i32, y: i32, operation: String) -> Result<i32, ToolError> {
match operation.as_str() {
"add" => Ok(x + y),
"subtract" => Ok(x - y),
"multiply" => Ok(x * y),
"divide" => {
if y == 0 {
Err(ToolError::ExecutionError("Division by zero".into()))
} else {
Ok(x / y)
}
}
_ => Err(ToolError::InvalidParameters(format!(
"Unknown operation: {}",
operation
))),
}
}
#[prompt(
description = "Generates a prompt for summarising text",
params(
text = "The text to summarise",
format = "Optional format for the summary (eg: 'bullet points' or 'Shakespeare')"
)
)]
async fn summarise_text(text: String, format: Option<String>) -> String {
let format_instruction = match format {
Some(f) => format!(" in the format of {}", f),
None => String::new(),
};
format!(
"Please summarize the following text{}:\n\n{}",
format_instruction, text
)
}
#[tokio::main]
async fn main() -> Result<()> {
let service = MCPServiceBuilder::new(
"kuri's test server".to_string(),
"This server provides a `calculator` tool that can perform basic arithmetic operations, and a prompt to summarise text.".to_string()
)
.with_tool(Calculator)
.with_prompt(SummariseText)
.build();
// Create and run the server over the stdio transport
let server = Server::new(service);
let transport = ByteTransport::new(stdin(), stdout());
Ok(server.run(transport).await?)
}
More in the examples
Features
- Tools: Feature complete with tests
- Prompts: Mostly complete with tests
- Resources
- Transports
- stdin/stdout
- Streaming HTTP (
2025-03-26
protocol)
- Extra (optional) features
Our priorities are HTTP transport support, stabilising the API, and ensuring full support of the core specification.
Contributing
The goal of this project is to build a pleasant, ergonomic, idiomatic Rust library for building MCP Servers. It's in an early phase, so the structure can still change. If you enjoy any of Rust, MCP, building crates, or network protocols (maybe you're into protohackers!), we'd love to have you! Get involved in the repo, or reach out by email if you want to chat!
Dependencies
~0.6–1MB
~21K SLoC