MCP 简易指南(一):实践
目录
什么是 MCP
根据官方文档,mcp 是一种开放协议,用于标准化应用程序向 llm 提供上下文的方式。可以将 mcp 想象成 AI 应用程序的 usb-c 接口。正如 usb-c 提供了一种标准化的方式将设备连接到各种外设和配件,mcp 也提供了一种标准化的方式将 ai 模型连接到不同的数据源和工具。
总之来说,如果把 llm 比喻成大脑,各种各样的 tools 就是手和脚,mcp 就是让 llm 更方便的获取和切换这些手脚,就像冬兵的枕巾手臂一样,随时可插拔。
为什么我们需要 MCP
刚才提到,手和脚是工具。我们可以给一个 llm 编写很多工具给其调用,比如我们可以通过 openai 的 function calling 来赋予 llm 调用工具的能力(虽然本质上执行还是在我们这边,而不是 llm)。此外,我们有很多 llm 提供商,他们的 llm 使用工具的方式或许有所不同。极端情况下,假如我们有 M 个 llm,N 个工具,那么我们就要编写 M×N 个 connector 来让所有 llm 都可以使用这 N 个工具。
但是如果我们在中间加一层抽象,所有 llm 都通过这层抽象与工具进行交流,那么就只需编写 M+N 个 connector。尤其是对于我们比较终端的开发者来说,我们只需写 N 个,即只写工具即可,M 是在 mcp client 端实现的,我们无需关心如何调用不同的 llm(这就让我想到支持不同的 llm 提供商是多么的繁琐,不过现在已经有了很多库来解决这个事情了)。
结合下图,如果没有 mcp,即 2,那么每新增一个 llm,我们都需要重新编写 connector 来适配这 3 个工具。
所以 mcp 的最大作用,就是减少重复工作量。但是另一方面,如果全部 llm 都支持 openai 的 function calling 格式,那么确实我们无需 mcp,也没有重复工作。这就是标准之争了。
核心概念
- mcp host:host 就是用户与 mcp 的交互界面,任何支持调用 mcp server 的 app 都是 host。比如 github copilot for vscode、claude desktop。
- mcp client:client 是真正与 server 交互的部分,一般在 host 中实现。可能大多数情况并不自己实现。
- mcp server:这就是真正实现 mcp 逻辑的地方,在这里你会实现你需要的 tools,供 host 和 client 调用。
安装 mcp python sdk
官方文档推荐使用 uv
安装环境和依赖:
1 | # 1. 初始化项目,这会自动创建目录,并生成一些必要文件。 |
如果你对 uv
不熟,或者想要使用 conda/pip,那么你仍然可以使用 pip 安装:
1 | pip install "mcp[cli]" |
如何编写和使用 mcp server
这里以编写 mcp tools 为例,大部分情况我们写的都是 tools。
下面是一个简单的用于获取当前时间的 mcp server 例子:
1 | from datetime import datetime |
语法是不是看起来很熟悉,基本和 flask、fastapi 一致。整体流程就这么三步:
- 创建 mcp 对象:
mcp = FastMCP("Demo MCP Server")
; - 编写 tools 函数,用
@mcp.tool()
进行装饰; - 启动 server:
mcp.run(transport="streamable-http")
,这里的 transport 先不用关心,下面会再说,暂时你就认为这是一个 http 服务即可。
运行后,你的 mcp 地址就是 http://localhost:7011/mcp
,将这个地址添加到你的 host 中即可。下面我以 github copilot in vscode 为例,演示下如何添加 mcp server:
command + shift + p 调出命令中心,输入
mcp add
,选择添加服务器 → http:按照提示填入 url(就是刚才的地址,但是要记得在后面以斜杠结尾,详见下面的 gotcha)、name,然后就可以看到添加好的 json 配置,已经正常启动了,也已经发现了 1 个工具,就是刚才的获取当前时间的工具:
打开 gc,切换到 agent 模式,因为只有在
agent
模式下才能使用 mcp:你可以询问“现在几点了”等和时间有关的问题,gc 会提示可以运行 mcp tools 来获取时间,你选择“继续”即可:
另外点击扳手图标可以看到可用的工具,包含我们刚才添加的 mcp server:
调试
当你写好一个 server 和 tools 之后,你需要测试一下是否能正常跑通。mcp 官方提供了 mcp inspector 用于调试,此外也有很多其他的测试工具。我现在常用的是 postman,对,就是那个调试接口的 postman,它现在也支持 mcp 了,甚至还支持直接调用 llm 😂:
用起来比 inspector 方便点,inspector 还得启动一下浏览器里打开,而且界面有点乱的感觉:
ok,以上基本就是使用层面,如果你的目的是编写一个 mcp server 来提供 tools,那么基本已经够了。如果你还想了解更多一点,可以看下一期,为了保持文章简短集中,我就不放在这里了。
Gotchas
- 在 vscode 中添加 server 时,streamable http(
http
)类型的 server 的 URL 必须以斜杠/
结尾,否则会报错:Error sending message to http://localhost:7011/mcp: TypeError: fetch failed
,server 日志显示:INFO: ip:40226 - "POST /mcp HTTP/1.1" 307 Temporary Redirect
,通过curl -v -X POST http://your-server/mcp
可以看到,重定向到了斜杠结尾的路由。但是使用 inspector 或者 postman 时,仍然可以直接使用非斜杠结尾的 URL。
References
- The Model Context Protocol (MCP) by Anthropic: Origins, functionality, and impact | mcp – Weights & Biases
- Model Context Protocol (MCP), clearly explained (why it matters) - YouTube
- MCP 101: An Introduction to Model Context Protocol | DigitalOcean