MCP(Model Context Protocol) 协议很早就出来了,但是由于在早期支持 MCP协议 的客户端在国内就没几个,所以也没机会去搞 MCP server。早期 MCP 只有 Claude 自家的客户端支持得最好,但是你没点技术手段,还用不了Claude。
什么是 MCP?
大模型其实没有什么能力,本质上就是输入文本 => 输出文本。但是不妨碍用户在外部定义一些工具函数,让大模型在输出文本的时候,输出特写格式的数据(包括用哪个工具函数,参数是什么),然后再执行指定的工具函数。这就是 Function Call(Tool Call) 的功能。但是其实 Function Call 本质上还是内部函数,并没有什么外部的动态扩展能力。
MCP 本质上就是外部的“Function Call”,Agent 应用的插件。把函数调用做成了外部可拔插的标准化服务,客户端想用哪个服务直接注册即可。
这些能力能玩得转的前提是,大模型要有非常强的指令遵循能力。我主要使用 Qwen 模型,可以肯定的是,Qwen 模型在去年这个时间(2024 年 8 月)没有这个能力,甚至当时国内任何一家的大模型都没有这个能力,直到 DeepSeek V3/R1 的出现。
无论是函数调用还是 MCP,最简单的调用链路大致是这样的:
prompt -> 大模型理解 -> 返回输出
-> 判断需要调用工具(或者 mcp)->调用工具(或者 mcp)->合并结果再调用大模型理解 -> 返回输出
使用 Rust 实现一个 MCP 服务是比较简单的,因为 MCP 官方就直接 rust sdk。MCP 使用 json rpc 作为数据交换协议,而传输管道有两种:
- 标准输入输出 (stdio)
- 服务器发送事件 (SSE) |(以及后面的stream http)
前者适合本地,后者适合远程服务。
比如我觉得大模型应对 Rust 编程的时候效果太差了,很多时候根本是在胡说八道,无中生有。我希望大模型实现功能如果有使用到某些 crate 时,最好自己去查一下这个 crate 的最新文档,再好好给我干活。
依赖:
rmcp = {version = "0.5.0", features = ["transport-io","macros"]}
#[tool_router]
impl Docs {
fn new() -> Self {
Self {
tool_router: Self::tool_router(),
}
}
#[tool(name = "readme", description = "获取 rust crate 文档的信息")]
async fn readme(&self, params: Parameters<LibraryRequest>) -> Result<CallToolResult, McpError> {
let crate_name = params.0.name.as_str();
let version = params.0.version.as_deref().unwrap_or("latest");
let docs = reqwest::get(format!("https://docs.rs/{crate_name}/{version}")).await.unwrap().text().await.unwrap();
Ok(CallToolResult::success(vec![Content::text(docs)]))
}
}
#[tool_handler]
impl rmcp::ServerHandler for Docs {
fn get_info(&self) -> ServerInfo {
ServerInfo {
instructions: Some("crate 文档".into()),
capabilities: ServerCapabilities::builder().enable_tools().build(),
..Default::default()
}
}
}
这部分就是用户要实现的工具函数。
注册一个 stdin 作为传输层的 mcp server:
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
// Create and run the server with STDIO transport
let service = Docs::new().serve(stdio()).await.inspect_err(|e| {
println!("Error starting server: {e}");
})?;
service.waiting().await?;
Ok(())
}
如何使用?
据我所知, vscode 上的 ai code 插件现在基本都支持 mcp server。比如国内阿里的 lingma,腾讯的云代码助手,字节的 trae。我们只需要 cargo build 得到二进制包,在上面这些助手里配置 mcp server 即可。阿里的 lingma 配置是最方便的,不过它的插件整体质量一般。