FastMCP Rust
High-performance Model Context Protocol (MCP) framework for Rust
A Rust port of jlowin/fastmcp (Python), extended with asupersync for structured concurrency and cancel-correct async.
______________________________________________________________________
# Add to your project (crates.io)
cargo add fastmcp-rust
# Or use the git dependency for bleeding-edge changes
cargo add fastmcp-rust --git https://github.com/Dicklesworthstone/fastmcp_rust______________________________________________________________________
太长,读不下去了
问题
在Rust中构建MCP服务器是痛苦的:
- 没有一流的异步支持,也没有适当的取消
- 每个工具的手动JSON-RPC样板
- 无结构化并发——孤立任务和资源泄漏
- 请求超时是事后的想法,而不是保证
解决方案
FastMCP防锈 是一个包含电池的MCP框架,内置取消正确异步、属性宏和结构化并发:
use fastmcp_rust::prelude::*;
#[tool]
async fn greet(ctx: &McpContext, name: String) -> String {
ctx.checkpoint()?; // Cancellation point
format!("Hello, {name}!")
}
fn main() {
Server::new("my-server", "1.0.0")
.tool(greet)
.run_stdio();
}为什么FastMCP生锈?
| 功能 | FastMCP Rust | 手动实现 |
|---|---|---|
| 异步句柄 | #[tool] async fn | 手动未来拳击 |
| 取消 | ctx.checkpoint() | 希望最好 |
| 超时 | 基于预算,自动 | 自己动手 |
| 结构化并发 | 区域范围的任务 | 孤立任务泄漏 |
| 错误处理 | 4值结果 | 2值结果 |
| 样板文件 | 零(宏) | 每个工具100行以上 |
______________________________________________________________________
代理商.md
该项目包括 AGENTS.md AI编码代理指南文件。要点:
- 移植方法: 从旧版本中提取规范→ 根据规范实施→ 切勿逐行翻译
- 运行时间: 用途 作物 用于取消正确的异步(不直接tokio)
- 不安全代码: 禁止(
#![forbid(unsafe_code)]) - 工具链: Rust 2024版,每晚需要
______________________________________________________________________
快速示例
use fastmcp_rust::prelude::*;
// Define a tool with automatic JSON schema generation
#[tool(description = "Calculate the sum of two numbers")]
async fn add(ctx: &McpContext, a: i64, b: i64) -> i64 {
ctx.checkpoint()?; // Check for client disconnect
a + b
}
// Define a resource
#[resource(uri = "file://config.json", description = "Application config")]
async fn read_config(ctx: &McpContext) -> String {
ctx.checkpoint()?;
std::fs::read_to_string("config.json").unwrap_or_default()
}
// Define a prompt template
#[prompt(description = "Generate a greeting message")]
async fn greeting_prompt(ctx: &McpContext, name: String) -> Vec
{
ctx.checkpoint()?;
vec![PromptMessage::user(format!("Please greet {name} warmly."))]
}
fn main() {
Server::new("example-server", "1.0.0")
.tool(add)
.resource(read_config)
.prompt(greeting_prompt)
.request_timeout(30) // 30-second budget per request
.run_stdio();
}运行它:
cargo run --example server______________________________________________________________________
设计理念
1.为了方便而取消正确性
每个异步操作都必须可取消。无声的数据丢失。FastMCP使用检查点:
#[tool]
async fn process_items(ctx: &McpContext, items: Vec) -> Vec {
let mut results = vec![];
for item in items {
ctx.checkpoint()?; // Allow graceful cancellation between items
results.push(process(item).await);
}
results
}2.预算,而非超时
超时是“我们放弃了”。预算是“你有X个资源”。预算类型将截止日期、投票配额和成本配额作为产品半环进行跟踪:
// Server enforces 30-second budget per request
Server::new("server", "1.0.0")
.request_timeout(30)
.tool(my_tool)
.run_stdio();
// Handler can check remaining budget
#[tool]
async fn my_tool(ctx: &McpContext) -> String {
if ctx.budget().is_exhausted() {
return "Budget exhausted".to_string();
}
// ... work ...
}3.四个有价值的结果
Result 将“操作失败”与“操作被取消”和“操作恐慌”混为一谈。FastMCP使用 Outcome:
enum Outcome {
Ok(T), // Success
Err(E), // Expected failure
Cancelled(Why), // External interruption
Panicked(Msg), // Internal failure
}4.能力安全
没有环境权威。所有效果都通过显式 McpContext:
// BAD: Global state access
async fn bad_tool() {
let db = GLOBAL_DB.lock().await; // Hidden dependency
}
// GOOD: Explicit capability
async fn good_tool(ctx: &McpContext, db: &DbHandle) {
db.query(ctx.cx(), "SELECT ...").await; // Explicit
}5.结构化并发
所有生成的任务都属于区域。当一个区域关闭时,所有子区域都会完成或耗尽。无孤立任务:
#[tool]
async fn parallel_fetch(ctx: &McpContext, urls: Vec) -> Vec {
// All spawned tasks are scoped to this request's region
let handles: Vec = urls.iter()
.map(|url| ctx.spawn(fetch(url.clone())))
.collect();
// Region waits for all children before returning
join_all(handles).await
}______________________________________________________________________
比较与替代方案
| 功能 | FastMCP防锈 | rmcp | jsonrpc内核 |
|---|---|---|---|
| MCP本地 | 是 | 是 | 否(通用) |
| 异步句柄 | 本地 | 本地 | 本地 |
| 取消 | 检查点+掩码 | 手动 | 无 |
| 超时 | 基于预算 | 基于计时器 | 手动 |
| 宏 | #[tool], #[resource], #[prompt] | 手动执行 | 手动执行 |
| 运行时 | Asupersync(取消-正确) | 东京 | 东京 |
| 成果类型 | 4值 | 2值 | 2元 |
| 结构化并发 | 区域范围 | 手动 | 手动 |
| 不安全代码 | 禁止 | 允许 | 允许 |
______________________________________________________________________
安装
来自crates.io
[dependencies]
fastmcp-rust = "0.1"作为Git依赖
[dependencies]
fastmcp-rust = { git = "https://github.com/Dicklesworthstone/fastmcp_rust" }来源
git clone https://github.com/Dicklesworthstone/fastmcp_rust.git
cd fastmcp_rust
cargo build --releaseCLI(可选)
cargo install fastmcp-cli要求:
- Rust 1.85+(夜间)2024版功能
- 作物 作为兄弟目录(或在中调整路径
Cargo.toml)
______________________________________________________________________
快速开始
1.创建新项目
cargo new my-mcp-server
cd my-mcp-server2.添加FastMCP
# Cargo.toml
[dependencies]
fastmcp-rust = { git = "https://github.com/Dicklesworthstone/fastmcp_rust" }3.编写服务器
// src/main.rs
use fastmcp_rust::prelude::*;
#[tool(description = "Echo the input message")]
async fn echo(ctx: &McpContext, message: String) -> String {
ctx.checkpoint()?;
message
}
fn main() {
Server::new("echo-server", "1.0.0")
.tool(echo)
.instructions("A simple echo server for testing")
.run_stdio();
}4.跑步
cargo run5.使用MCP检查员进行测试
npx @anthropic-ai/mcp-inspector cargo run______________________________________________________________________
建筑
┌─────────────────────────────────────────────────────────────────┐
│ MCP Client │
└─────────────────────────────────────────────────────────────────┘
│
│ JSON-RPC over stdio
▼
┌─────────────────────────────────────────────────────────────────┐
│ StdioTransport │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Codec │───▶│ recv() │───▶│ send() │ │
│ │ (NDJSON) │ │ │ │ │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ Server │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Session │ │ Router │ │ Budget │ │
│ │ (state) │ │ (dispatch) │ │ (timeout) │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐│
│ │ McpContext ││
│ │ ┌─────┐ ┌──────────┐ ┌────────┐ ┌──────┐ ││
│ │ │ Cx │ │checkpoint│ │ budget │ │masked│ ││
│ │ └─────┘ └──────────┘ └────────┘ └──────┘ ││
│ └─────────────────────────────────────────────────────────────┘│
│ │ │
│ ▼ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ ToolHandler │ │ResourceHandler│ │PromptHandler │ │
│ │ call_async │ │ read_async │ │ get_async │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ asupersync │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Runtime │ │ Scope │ │ Budget │ │ Outcome │ │
│ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │
└─────────────────────────────────────────────────────────────────┘______________________________________________________________________
板条箱结构
FastMCP被组织成一个带有集中板条箱的工作区:
fastmcp_rust/
├── crates/
│ ├── fastmcp/ # Facade crate (published as fastmcp-rust)
│ ├── fastmcp-core/ # McpContext, errors, runtime helpers
│ ├── fastmcp-protocol/ # MCP types, JSON-RPC messages
│ ├── fastmcp-transport/ # Transport implementations (stdio, SSE, WebSocket)
│ ├── fastmcp-server/ # Server builder, router, handlers
│ ├── fastmcp-client/ # Client implementation
│ └── fastmcp-derive/ # #[tool], #[resource], #[prompt] macros| 板条箱 | 用途 |
|---|---|
fastmcp-rust | 方便再出口,简单 use fastmcp_rust::prelude::* |
fastmcp-core | McpContext 包装器、错误类型, block_on 助手 |
fastmcp-protocol | MCP消息类型、功能、JSON-RPC帧 |
fastmcp-transport | 传输特性,stdio/SSE/WebSocket实现 |
fastmcp-server | Server, ServerBuilder、路由、处理程序特征 |
fastmcp-client | Client 用于调用MCP服务器 |
fastmcp-derive | 用于生成处理程序的过程宏 |
______________________________________________________________________
处理程序特征
工具处理程序
pub trait ToolHandler: Send + Sync {
fn definition(&self) -> Tool;
fn call(&self, ctx: &McpContext, arguments: Value) -> McpResult>;
// Override for true async (default delegates to call())
fn call_async(&'a self, ctx: &'a McpContext, arguments: Value)
-> BoxFuture>>;
}资源处理程序
pub trait ResourceHandler: Send + Sync {
fn definition(&self) -> Resource;
fn read(&self, ctx: &McpContext) -> McpResult>;
// Override for true async
fn read_async(&'a self, ctx: &'a McpContext)
-> BoxFuture>>;
}提示处理程序
pub trait PromptHandler: Send + Sync {
fn definition(&self) -> Prompt;
fn get(&self, ctx: &McpContext, arguments: HashMap)
-> McpResult;
// Override for true async
fn get_async(&'a self, ctx: &'a McpContext, arguments: HashMap)
-> BoxFuture>;
}______________________________________________________________________
故障排除
| 问题 | 原因 | 修复 |
|---|---|---|
McpError::MethodNotFound("tool: my_tool") | 工具未注册 | 添加 .tool(my_tool) 到服务器构建器 |
| 请求在操作过程中取消 | 客户端断开连接或超时 | 使用 ctx.masked() 关键路段 |
| 预算用尽错误 | 超时时间太短 | 增加 .request_timeout(120) |
#[tool] 宏编译错误 | 缺少特性边界 | 确保处理程序返回 McpResult 或 Into> |
TransportError::Io 启动时 | stdin不可用 | 确保没有其他内容读取stdin |
关键部分示例
#[tool]
async fn critical_write(ctx: &McpContext, data: String) -> String {
// This section won't be interrupted
ctx.masked(|| {
fs::write("important.txt", &data).unwrap();
});
"Written".to_string()
}______________________________________________________________________
局限性
| 限制 | 详细信息 |
|---|---|
| 每晚需要 | 使用Rust 2024版本功能 |
| 网络传输 | SSE和WebSocket传输在传输层实现,但HTTP/WS服务器集成是外部的 |
| 无内置TLS | 传输加密必须由外部处理 |
| 单螺纹环路 | 主服务器循环是顺序的 |
| 兄弟姐妹依赖 | 需要在以下位置进行同步 ../asupersync |
| 早期发展 | API可能在1.0之前更改 |
______________________________________________________________________
常见问题解答
Q: 为什么不直接使用tokio?
A: Tokio不提供开箱即用的取消正确性。丢弃Future会自动丢弃工作。asupersync提供检查点、掩码和4值结果,使取消明确且安全。
Q: 我可以在Claude Desktop上使用这个吗?
A: 是的!FastMCP服务器通过stdio使用标准MCP协议。配置Claude Desktop以生成服务器二进制文件。
Q: 如何添加身份验证?
A: MCP没有在协议级别定义身份验证。对于Claude Desktop来说,该过程已经受到信任。对于网络传输,使用TLS封装连接,并在传输层实现身份验证。
Q: 检查点的性能开销是多少?
A: 检查点是一种简单的标志检查(原子加载)。开销可以忽略不计——每次调用通常\Built with asupersync for cancel-correct async
