一、MCP 是什么:从"胶水代码"困境说起
如果你用过大模型做过工具调用(Function Calling),大概率经历过这样的痛苦:每接入一个新的数据源——数据库、文件系统、Slack、GitHub——都要写一堆胶水代码,把该数据源的 API 翻译成大模型能理解的工具描述格式。更糟糕的是,换个模型(比如从 GPT-4 换到 Claude),这些胶水可能还得重写一遍。
MCP(Model Context Protocol) 就是为了解决这个问题而生的。它的定位可以类比为"AI 应用的 USB-C 接口":不管你的大模型是哪家的、工具是哪来的,只要双方都遵守 MCP 这套协议,就能即插即用。它由 Anthropic 在 2024 年底开源提出,目前已经逐渐成为业界连接 LLM 与外部工具的事实标准。
提示:MCP 解决的不是"模型能力"问题,而是"模型与外部世界之间的连接标准化"问题。它的本质是一个通信协议 + 接口约定,本身不涉及任何模型推理逻辑。
二、MCP 的核心架构:Host、Client、Server 三方角色
MCP 的架构里有三个关键角色,理解它们的分工是读懂协议的前提:
- Host:宿主应用,比如 Claude Desktop、IDE 插件、你自己的 Agent 程序。它是"最终用户"所在的地方。
- Client:嵌在 Host 内部的协议客户端,负责与某个具体的 MCP Server 建立一对一会话,管理连接生命周期。
- Server:协议服务端,暴露具体的能力(工具、资源、提示模板),每个 Server 通常对接一个数据源或服务。
这三者的关系可以简单理解为:Host 拿着用户的请求,通过 Client 去"问"某个 Server 能提供什么;Server 告诉 Client 自己有哪些工具和资源;最终 Host 把这些信息组合后交给大模型决策调用。值得注意的是,一个 Host 可以同时连接多个 Server,这就是 MCP 生态可扩展性的来源——你装一个新的 MCP Server,就像给系统插了一个新外设。
三、协议的三大能力:Tools、Resources、Prompts
MCP 定义了三类核心原语(Primitives),分别服务于不同场景:
- Tools(工具):由模型主动调用的可执行操作,比如"查询数据库""发送邮件"。这是最常用的能力,对应 Function Calling 的场景。
- Resources(资源):由应用程序按需读取的数据,比如文件内容、API 返回的 JSON。模型不直接"调用"资源,而是 Host 决定何时注入。
- Prompts(提示模板):预定义的提示词模板,用户在客户端中可以主动选择使用,比如一个"代码审查"模板。
很多初学者容易混淆 Tools 和 Resources。一个简单的判断标准是:这个操作会不会改变外部状态?如果会(写文件、发消息),就是 Tool;如果只是读取已有数据,通常用 Resource。不过实际开发中,绝大多数 Server 只实现了 Tools,因为它的交互模型最直观。
提示:MCP 还支持 Sampling(Server 反向请求 Host 调用 LLM)和 Roots(客户端告知 Server 工作目录)等高级能力,但初学阶段可以先聚焦 Tools 这一条主线。
四、一次完整的 MCP 交互流程
理解协议最好的方式是跟踪一次完整的调用。假设用户在 Host 中说"帮我查一下今天北京的天气",而你有一个 weather-server:
- 连接建立:Host 通过 Client 启动 Server(通常是
stdio子进程或SSE远程连接),双方进行initialize握手,交换协议版本和能力声明。 - 能力发现:Client 发送
tools/list请求,Server 返回它支持的工具列表(含名称、参数 JSON Schema)。 - 模型决策:Host 把工具描述注入 LLM 的 system prompt 或 tool 定义中,LLM 决定调用
get_weather(city="北京")。 - 工具执行:Client 发送
tools/call请求,Server 执行真实逻辑,返回结果(文本或结构化内容)。 - 结果回填:Host 把结果拼入对话上下文,LLM 生成最终回答。
整个流程中,MCP 只负责第 1、2、4 步的通信格式,模型的决策逻辑完全在 Host 端完成。这种"协议管传输、Host 管智能"的分层设计,是 MCP 能适配多种模型的原因。
五、动手写一个最小 MCP Server
官方的 Python SDK(mcp 包)把协议细节封装得很好,几行代码就能跑起来一个 Server。下面是一个最小可运行的示例:
# server.py — 一个极简 MCP Server
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("demo-server")
@mcp.tool()
def add(a: int, b: int) -> int:
"""将两个整数相加并返回结果。"""
return a + b
@mcp.tool()
def greet(name: str) -> str:
"""向指定的人打招呼。"""
return f"你好,{name}!欢迎使用 MCP。"
if __name__ == "__main__":
mcp.run() # 默认通过 stdio 传输
启动后,在 Host(比如 Claude Desktop)的配置文件中注册这个 Server 即可:
{
"mcpServers": {
"demo": {
"command": "python",
"args": ["server.py"]
}
}
}
配置完成后,你对 Claude 说"帮我算 3 加 5",它就会自动调用 add 工具。整个过程中你没有写任何 Function Calling 的胶水代码——SDK 自动生成了工具描述、序列化了请求响应、管理了连接生命周期,这正是 MCP 的价值所在。
提示:FastMCP是高层封装,适合快速原型;如果你需要精细控制协议细节(比如自定义resources、prompts),可以使用底层的mcp.server.Server类手动注册 handler。
六、MCP 的现实意义与当前局限
MCP 最大的现实意义在于生态复用。开发者写一个 MCP Server,就能被所有支持 MCP 的 Host 使用;反过来,一个 Host 支持 MCP,就能接入社区中成百上千的现成 Server。这种双向的网络效应,让 MCP 迅速从"一个协议"演变为"一个生态"。目前 VS Code、Cursor、Claude Desktop、甚至一些 Agent 框架(如 LangChain)都已支持 MCP。
但也要清醒地看到它目前的局限:
- 安全性:Server 拥有真实工具的执行权限,如何做细粒度的授权(比如某个工具只读不写)目前主要靠 Host 层控制,协议本身的安全模型还在完善中。
- 性能开销:每个 Server 一个进程(stdio 模式下),Server 数量多了资源消耗不可忽视。
- 状态管理:MCP 会话默认是无状态的,涉及复杂多轮交互的场景需要 Server 自己维护状态。
总的来说,MCP 是一次用协议统一 AI 工具生态的尝试,它的设计哲学和 HTTP 之于 Web、LSP 之于编辑器非常相似——不发明新轮子,只定义轮子之间的接口。对于想深入 AI 应用开发的同学,花一两个小时跑通一个 MCP Server,比读十篇解读文章更有收获。