【免费下载链接】mcp-for-beginners
This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.
项目地址:
https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看 免费下载
Model Context Protocol(MCP)为 AI 应用提供了一套标准化的"上下文连接"方式,而 Rust 凭借其内存安全与高性能特性,成为实现 MCP 服务器的理想语言之一。本篇技术指南以 mcp-for-beginners 开源课程中的 Rust 示例 为骨架,结合仓库内的 完整源码 与 Cargo.toml,逐行剖析如何基于 rmcp SDK 构建一个通过标准输入输出(stdio)运行的 MCP 计算器服务器。读完本文,你将掌握 #[tool_router] / #[tool] 过程宏的用法、工具参数的结构化声明方式、ServerHandler 的服务器元信息配置,以及使用 MCP Inspector 对工具进行端到端调用验证的完整实战方案。
示例概览:一个四则运算的 MCP 服务器
仓库中的 Rust 示例 是一个麻雀虽小五脏俱全的 MCP 服务器:它注册了 add(加法)、subtract(减法)、multiply(乘法)、divide(除法)四个工具,全部通过 rmcp 框架的声明式宏暴露给任意 MCP 客户端调用。整个项目仅包含一个 src/main.rs(约 83 行),配合 Cargo.toml 中极简的依赖声明即可运行,非常适合作为学习 MCP 服务器开发的第一块跳板。
从协议层面看,这个示例演示了 MCP 服务器端三个关键组成部分:
- 工具(Tools):模型可调用的函数,本示例中的四个计算函数即为工具;
- 能力声明(Capabilities):服务器通过 ServerCapabilities::builder().enable_tools() 向客户端宣告自己支持工具调用;
- 传输层(Transport):通过 stdio() 在标准输入/输出上承载 MCP JSON-RPC 消息,这是本地 MCP 客户端与服务器通信的推荐标准,具备子进程隔离的天然安全优势。
项目结构与依赖声明
示例项目结构非常清晰:
03-GettingStarted/samples/rust/
├── Cargo.toml # 包元数据与依赖
├── Cargo.lock # 依赖锁定文件
├── README.md # 示例说明(英文原版)
└── src/
└── main.rs # 全部服务器实现
查看 Cargo.toml,可以看到这份依赖清单正是让 MCP 服务器运转的核心:
[package]
name = "calculator"
version = "1.0.0"
edition = "2024"
[dependencies]
rmcp = { version = "2.1.0", features = ["server", "transport-io"] }
serde = "1.0.219"
tokio = { version = "1.46.0", features = ["rt-multi-thread"] }
[dev-dependencies]
slab = "0.4.11"
三个依赖各司其职:
| rmcp | Rust 官方 MCP 协议 SDK(Rust Model Context Protocol) | server 特性开启服务器端能力,transport-io 提供 stdio 传输实现;版本锁定为 2.1.0 |
| serde | 工具参数的序列化/反序列化 | 与 schemars 配合,从 Rust 结构体自动生成工具入参的 JSON Schema |
| tokio | 异步运行时 | 启用 rt-multi-thread 多线程运行时,支撑 #[tokio::main] 入口与异步工具函数 |
edition = "2024" 表示项目使用 Rust 2024 edition,需要较新的 Rust 工具链支持。此外,rmcp 内部会用到 schemars(通过 #[tool_router] 宏隐式集成),用于把工具参数结构体编译为可供 LLM 与客户端理解的 JSON Schema。
核心实现逐段拆解
1. 引入 SDK 模块
src/main.rs 的第一段代码完成了所有必要的导入:
use rmcp::{
ServerHandler, ServiceExt,
handler::server::{router::tool::ToolRouter, tool::Parameters},
model::{ServerCapabilities, ServerInfo},
schemars, tool, tool_handler, tool_router,
transport::stdio,
};
use std::error::Error;
这里每个符号都有明确职责:
- ServerHandler:MCP 服务器主处理器 trait,实现它即可向客户端提供服务器信息与能力;
- ServiceExt:为服务器类型提供 serve() 与 waiting() 等生命周期方法;
- ToolRouter:工具路由器类型,负责聚合和分发注册的工具;
- Parameters:工具参数的包装类型,用于在函数签名中解构出结构化入参;
- ServerCapabilities / ServerInfo:服务器能力与元信息模型;
- schemars:JSON Schema 生成支持(经 tool_router 宏引入);
- tool、tool_handler、tool_router:三个核心过程宏;
- transport::stdio:标准输入输出传输构造器。
2. 声明工具参数结构体
#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
pub struct CalculatorRequest {
pub a: f64,
pub b: f64,
}
CalculatorRequest 定义了工具入参的结构:两个 f64 浮点数字 a 和 b。derive 的三个 trait 缺一不可:
- Debug:便于调试输出;
- serde::Deserialize:把客户端传来的 JSON 参数反序列化为 Rust 结构体;
- schemars::JsonSchema:自动生成参数的 JSON Schema,供客户端(尤其是 LLM)了解工具的输入约束——这是 MCP 工具可被模型"理解并正确调用"的关键机制。
3. 服务器结构与 #[tool_router] 宏
#[derive(Debug, Clone)]
pub struct Calculator {
tool_router: ToolRouter<Self>,
}
#[tool_router]
impl Calculator {
pub fn new() -> Self {
Self {
tool_router: Self::tool_router(),
}
}
#[tool(description = "Adds a and b")]
async fn add(
&self,
Parameters(CalculatorRequest { a, b }): Parameters<CalculatorRequest>,
) -> String {
(a + b).to_string()
}
// subtract / multiply / divide 结构相同……
}
从源码结构可以清晰看到 #[tool_router] 宏的工作方式:它扫描 impl Calculator 块内所有标注了 #[tool(description = "…")] 的方法,自动生成一个 Self::tool_router() 关联函数,把每个工具方法注册进 ToolRouter<Self>。new() 构造函数在初始化时即调用该生成函数完成工具注册,从而让"注册工具"这一动作完全声明化——开发者只需写普通方法,宏负责生成协议所需的注册与路由逻辑。
四个工具方法逐一解析:
| add | 返回 a + b | 无 |
| subtract | 返回 a – b | 无 |
| multiply | 返回 a * b | 无 |
| divide | 返回 a / b | 当 b == 0.0 时返回错误字符串 "Error: Division by zero",避免浮点除零异常 |
值得注意的细节:
- 每个工具方法都返回 String,这是 MCP 工具约定的一种文本结果格式,客户端可直接消费;
- 参数通过模式解构 Parameters(CalculatorRequest { a, b }) 一次性拆出两个字段,语法紧凑;
- description 元数据会被宏写入工具 schema,向客户端描述工具的用途,是 LLM 决定何时调用哪个工具的直接依据;
- 除零场景以返回值而非 panic 的方式处理,体现了工具实现中"错误应作为结果返回而非中断进程"的健壮性设计。
4. #[tool_handler] 与服务器元信息
#[tool_handler]
impl ServerHandler for Calculator {
fn get_info(&self) -> ServerInfo {
ServerInfo {
instructions: Some("A simple calculator tool".into()),
capabilities: ServerCapabilities::builder().enable_tools().build(),
..Default::default()
}
}
}
#[tool_handler] 宏把 Calculator 桥接到 MCP 服务器处理器。get_info() 返回的 ServerInfo 包含两个关键字段:
- instructions:面向客户端模型的服务器说明文本,此处为 "A simple calculator tool",帮助 LLM 理解服务器用途;
- capabilities:能力声明,enable_tools() 明确告诉客户端"本服务器支持工具调用";
- ..Default::default():其余字段(如协议版本)采用默认值。
5. 入口函数与 stdio 传输
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let service = Calculator::new().serve(stdio()).await?;
service.waiting().await?;
Ok(())
}
- #[tokio::main] 启动多线程异步运行时;
- Calculator::new() 创建服务器实例(同时完成工具注册);
- .serve(stdio()) 将服务器挂载到标准输入输出传输上:MCP 客户端通过向进程的 stdin 写入 JSON-RPC 消息、从 stdout 读取响应来与服务器通信;
- .waiting() 保持进程运行,直至收到终止信号。
至此,一个完整可用的 MCP 服务器便宣告完成。
编译与运行
按照示例文档给出的两步命令即可完成构建与启动:
# 编译项目(含依赖解析与类型检查)
cargo build
# 启动服务器(默认通过 stdio 等待客户端连接)
cargo run
cargo build 首次执行会拉取并编译 rmcp、serde、tokio 及其依赖(仓库中 Cargo.lock 已锁定全部依赖版本,保证可复现构建)。cargo run 启动后,由于采用 stdio 传输,进程本身不会打印交互界面,而是等待 MCP 客户端通过标准输入发起请求——这正是本地 MCP 服务器与客户端(如 Claude Desktop、VS Code 扩展等)协作的标准模式。
提示:若要快速验证服务器能否正常响应,推荐用下面的 MCP Inspector 进行交互式测试;直接运行 cargo run 后,也可以配合课程 02-client 中编写的客户端程序发起真实调用。
用 MCP Inspector 调试与验证工具
课程 01-first-server 为 Rust 服务器提供了专门的 Inspector 调试命令。MCP Inspector 是 MCP 官方的可视化调试工具,能自动发现服务器能力、实时执行工具并查看响应。对 Rust 示例,可以使用以下 CLI 方式调用 add 工具:
npx @modelcontextprotocol/inspector cargo run –cli –method tools/call –tool-name add –tool-arg a=1 b=2
命令参数拆解:
| npx @modelcontextprotocol/inspector | 启动 Inspector 工具(需已安装 Node.js/npx) |
| cargo run | 指定启动服务器进程的命令 |
| –cli | 以命令行非交互模式执行 |
| –method tools/call | 调用 MCP 协议中的 tools/call 方法 |
| –tool-name add | 指定要调用的工具名(即宏注册的 add) |
| –tool-arg a=1 b=2 | 传入工具参数 a = 1、b = 2 |
预期输出为 3(即 1 + 2 的结果)。同样的方法可以依次验证 subtract、multiply、divide,包括除零场景:调用 divide 并传入 b=0 时应得到 "Error: Division by zero" 字符串。这也验证了 #[tool_router] 生成的 schema 与工具分发逻辑确实按声明生效。
从零复现:跟随课程构建你自己的 Rust MCP 服务器
如果你希望亲手创建而非直接运行仓库示例,课程 01-first-server 给出了 Rust 路径的完整步骤:
# 1. 初始化 Cargo 项目
mkdir calculator-server
cd calculator-server
cargo init
# 2. 添加依赖(与示例 Cargo.toml 一致)
cargo add rmcp –features server,transport-io
cargo add serde
cargo add tokio –features rt-multi-thread
随后删除 cargo init 生成的默认 main.rs 内容,按上文拆解的顺序依次写入:模块导入 → CalculatorRequest 结构体 → Calculator 结构体与 #[tool_router] 实现 → #[tool_handler] 的 ServerHandler 实现 → main 入口。最后执行:
cargo fmt
cargo run
课程的 Assignment 进一步建议读者用自己擅长的语言实现一个自选工具并定义输入参数与返回值,再用 Inspector 验证——本示例正是完成该练习的 Rust 参考答案。
关键要点总结
- 声明式工具注册:#[tool_router] + #[tool(description = "…")] 宏让工具注册完全声明化,开发者只需编写普通异步方法,宏自动生成路由与 schema;
- 结构化参数与自动 Schema:CalculatorRequest 通过 serde::Deserialize 与 schemars::JsonSchema 同时解决参数反序列化和工具入参 schema 生成,这是 MCP 工具可被 LLM 正确调用的基础;
- 能力与元信息声明:ServerHandler::get_info() 返回的 instructions 与 capabilities 决定了客户端如何看待和使用这台服务器;
- stdio 传输:serve(stdio()) 使服务器通过标准输入输出通信,适合本地、进程隔离的安全场景;
- 可验证性:cargo build / cargo run 两命令即可构建运行,MCP Inspector 的 CLI 调用则提供了不依赖图形界面的工具级验证手段。
延伸阅读
- 本示例的英文原版说明:Rust 示例 README
- 完整实现源码:src/main.rs
- 依赖声明与版本:Cargo.toml
- 课程主教程(含 TypeScript / Python / .NET / Java / Rust 多语言对照与 Inspector 调试):01-first-server
- 更多语言的计算器示例与练习入口:03-GettingStarted 总览
赞
【免费下载链接】mcp-for-beginners
This open-source curriculum introduces the fundamentals of Model Context Protocol (MCP) through real-world, cross-language examples in .NET, Java, TypeScript, JavaScript, Rust and Python. Designed for developers, it focuses on practical techniques for building modular, scalable, and secure AI workflows from session setup to service orchestration.
项目地址:
https://gitcode.com/GitHub_Trending/mc/mcp-for-beginners
点击查看 免费下载
相关推荐
TensorRT 示例详解:sampleNamedDimensions —— 使用 ONNX 命名维度(Named Input Dimensions)构建动态推理引擎
如何快速上手WhatTheHack:新手团队协作学习的终极教程 🚀
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网硕互联帮助中心



评论前必须登录!
注册