深入理解 MCP:AI 连接外部世界的标准协议
一句话理解 MCP
MCP(Model Context Protocol)是 AI 界的 USB-C 接口------在它出现之前,每个 AI 应用要连接每个外部工具都需要专门对接;在它出现之后,只需一个标准协议,所有 AI 应用和所有工具即插即用。
2024 年 11 月,Anthropic 开源了 MCP(Model Context Protocol,模型上下文协议)。这个协议要解决的核心问题很明确:AI 模型如何以标准化的方式连接外部数据源和工具?
本文将从问题本质、架构设计、能力模型和通信流程四个维度,带你彻底理解 MCP。
一、问题:N × M 的对接噩梦
在 MCP 出现之前,AI 应用要使用外部工具(数据库、GitHub、文件系统等),每个应用都需要为每个工具编写专门的对接代码。
假设有 3 个 AI 应用和 3 个工具,就需要 3 × 3 = 9 套自定义集成代码。应用和工具一多,就变成了无法维护的意大利面条:
Before MCP:
AI App A ────┬──── GitHub (自定义代码)
AI App B ────┼──── Database (自定义代码)
AI App C ────┴──── Files (自定义代码)
→ 3 × 3 = 9 套集成代码
MCP 的解法是在中间插入一层标准协议:
After MCP:
AI App A ──┐ ┌── GitHub
AI App B ──┼── MCP Protocol ──┼── Database
AI App C ──┘ └── Files
→ 3 + 3 = 6 个标准实现,互不感知
从 N × M 降维到 N + M。 工具开发者只需写一个 MCP Server,就能被所有支持 MCP 的 AI 应用使用;AI 应用只需实现一个 MCP Client,就能连接所有 MCP Server。
这个模式并不新鲜------USB-C 统一了充电线接口,HTTP 统一了 Web 通信,JDBC 统一了数据库访问。MCP 做的也是同样的事,只不过标准化的对象是 AI 模型与外部世界之间的通信接口。
二、架构:清晰的客户端-服务器模型
MCP 的架构由四个角色组成:
| 角色 | 职责 | 举例 |
|---|---|---|
| Host(宿主) | AI 应用本体,内含 LLM 和一个或多个 Client | Claude Desktop、Cursor、Zed |
| Client(客户端) | 宿主内部的组件,与 Server 维持 1:1 连接 | 每个 Host 可有多个 Client 连不同 Server |
| Server(服务端) | 独立程序,向 Client 暴露能力,对接外部资源 | GitHub MCP Server、PostgreSQL MCP Server |
| Resources(资源) | Server 背后的真实数据源 | 数据库、文件系统、Web API |
架构示意:
┌──── Host (AI App) ────┐
│ │
│ ┌──── LLM ──────┐ │ ┌── MCP Server ──┐ ┌── Resources ──┐
│ └───────┬───────┘ │ │ tools │ │ Database │
│ │ │ JSON- │ resources │──────│ Files │
│ ┌─ MCP Client ─┐────┼───────→│ prompts │ │ APIs │
│ └──────────────┘ │ RPC └─────────────────┘ └───────────────┘
│ │
└────────────────────────┘
通信协议
Client 和 Server 之间使用 JSON-RPC 2.0 协议通信,支持两种传输方式:
- stdio(标准输入/输出):适用于本地运行的 Server,Server 作为 Host 的子进程,通过标准流通信。延迟极低,适合文件系统、本地数据库等场景。
- SSE / Streamable HTTP:适用于远程运行的 Server,通过网络通信。适合云端 API、远程数据库等场景。
关键设计:1:1 连接模型
注意,一个 Client 只与一个 Server 保持连接。如果 Host 需要同时连接 3 个 Server,就会创建 3 个 Client 实例。这种 1:1 模型简化了连接管理,每个连接可以独立维护状态、处理错误。
三、四种能力:精妙的控制权分配
MCP Server 可以向 AI 暴露四种能力。这四种能力最精妙的地方不在于"能做什么",而在于控制权归属不同:
1. Tools(工具)------ 模型控制
Tools 是 AI 可以调用的函数,类似于 OpenAI 的 Function Calling。
- 谁控制:AI 模型自主决定何时调用
- 用途:执行操作,如搜索代码、发送邮件、运行数据库查询
- 示例 :
search_code(query="auth")、send_email(to, subject, body)
json
{
"name": "search_code",
"description": "Search code in the repository",
"inputSchema": {
"type": "object",
"properties": {
"query": { "type": "string", "description": "Search query" }
},
"required": ["query"]
}
}
2. Resources(资源)------ 应用控制
Resources 是 AI 可以读取的静态或半静态数据。
- 谁控制:宿主应用决定把哪些资源暴露给 AI
- 用途:提供上下文数据,如文件内容、数据库记录、API 文档
- 示例 :
file:///project/README.md、database://users/schema
与 Tools 的关键区别:Resources 是"读取"而非"执行"。AI 不能通过 Resources 修改数据,只能读取。
3. Prompts(提示词模板)------ 用户控制
Prompts 是预定义的提示词模板,用户可以像使用"快捷指令"一样选择。
- 谁控制:用户从菜单中主动选择
- 用途:标准化常见任务,如代码审查、Bug 报告生成
- 示例 :
code_review模板会自动注入代码审查的上下文和指令
json
{
"name": "code_review",
"description": "Review code for best practices",
"arguments": [
{
"name": "code",
"description": "Code to review",
"required": true
}
]
}
4. Sampling(采样)------ 服务器发起
Sampling 是四种能力中最特别的------它打破了"AI → 工具"的单向调用,让 Server 反过来请求 Client 的 LLM 帮忙生成文本。
- 谁控制:Server 主动发起
- 用途:Server 需要借 AI 能力完成自己的任务
- 示例:一个检索 Server 找到大量文档后,请求 LLM 帮忙做摘要和分类
这个设计让 MCP 不只是"AI 调用工具的通道",而是一个完整的双向协作协议。Server 既是能力的提供者,也可以是 AI 能力的消费者。
控制权总结
| 能力 | 控制方 | 方向 | 类比 |
|---|---|---|---|
| Tools | AI 模型 | AI → Server | Function Calling |
| Resources | 宿主应用 | Server → AI | 文件读取 |
| Prompts | 用户 | Server → AI | 快捷指令 / Slash 命令 |
| Sampling | Server | Server → AI | 反向调用 LLM |
四、通信流程:四步生命周期
一次完整的 MCP 通信分为四个阶段:
① Initialize(初始化握手)
Client 与 Server 建立连接后,首先交换各自支持的协议版本和能力(capabilities)。
json
// Client → Server
{
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"capabilities": { "roots": { "listChanged": true } },
"clientInfo": { "name": "my-app", "version": "1.0.0" }
}
}
// Server → Client
{
"protocolVersion": "2024-11-05",
"capabilities": { "tools": { "listChanged": true } },
"serverInfo": { "name": "github-mcp", "version": "1.2.0" }
}
② Discover(能力发现)
Client 主动请求 Server 提供的能力清单:
json
// 列出所有工具
{ "method": "tools/list" }
// 列出所有资源
{ "method": "resources/list" }
// 列出所有提示词模板
{ "method": "prompts/list" }
Server 返回完整的能力清单后,Client 将这些信息注册到 LLM 的上下文中,LLM 就"知道"自己有哪些工具可用了。
③ Execute(执行调用)
当用户提出问题,LLM 根据上下文判断需要调用某个工具时,Client 发送执行请求:
json
// Client → Server
{
"method": "tools/call",
"params": {
"name": "search_code",
"arguments": { "query": "authentication" }
}
}
// Server → Client(执行结果)
{
"content": [
{ "type": "text", "text": "Found 3 matches..." }
]
}
Server 在后台执行实际操作(调用 GitHub API、查询数据库等),将结果返回给 Client。
④ Respond(响应生成)
Client 将工具执行结果交给 LLM,LLM 结合结果生成最终的自然语言回答,返回给用户。
用户: "项目里有哪些认证相关的代码?"
→ LLM: 决定调用 search_code 工具
→ Client → Server: tools/call { name: "search_code", arguments: { query: "auth" } }
→ Server: 调用 GitHub API 搜索代码
→ Server → Client: { content: "Found 3 files: auth.py, login.py, token.py..." }
→ LLM: 结合结果生成回答
→ 用户: "项目中有 3 个认证相关文件:auth.py 实现了核心认证逻辑..."
五、为什么 MCP 重要?
1. 生态效应
MCP 正在成为 AI 应用的"插件生态标准"。就像浏览器扩展之于 Chrome、App 之于 iOS------MCP Server 之于 AI 应用。
目前支持 MCP 的 AI 应用包括:Claude Desktop、Cursor、Zed、Windsurf 等。社区已有数百个开源 MCP Server,覆盖 GitHub、PostgreSQL、Slack、Google Drive、文件系统等常见工具。
2. 关注点分离
MCP 让三个角色各司其职:
- 工具开发者:只需写 MCP Server,不用关心哪个 AI 应用会用它
- AI 应用开发者:只需实现 MCP Client,不用关心有哪些 Server 可用
- 协议本身:负责中间的标准化通信
3. 安全性
MCP 的设计内置了安全考虑:
- 用户可以审查和控制哪些 Server 被连接
- Tools(模型控制)和 Resources(应用控制)的分离,让应用可以限制 AI 的操作范围
- Server 运行在本地(stdio 模式)时,用户对数据流向有完全的控制
4. 对比 Function Calling
很多人会问:MCP 和 OpenAI 的 Function Calling 有什么区别?
| 维度 | Function Calling | MCP |
|---|---|---|
| 本质 | LLM 的能力 | 通信协议 |
| 范围 | 单次调用 | 持久连接 + 生命周期 |
| 标准化 | 各厂商不同 | 开放标准,跨平台 |
| 能力类型 | 只有函数调用 | Tools + Resources + Prompts + Sampling |
| 生态 | 绑定特定 LLM | LLM 无关,任何应用都可以用 |
简言之:Function Calling 是 LLM 的一个功能,MCP 是连接 AI 和外部世界的一整套协议标准。MCP 可以在底层使用 Function Calling 机制,但它的视野远大于此。
六、实战:写一个最简 MCP Server
用 Python SDK 实现一个最简单的 MCP Server,暴露一个计算器工具:
python
from mcp.server import Server
from mcp.types import Tool, TextContent
import mcp.server.stdio
server = Server("calculator")
@server.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="add",
description="Add two numbers",
inputSchema={
"type": "object",
"properties": {
"a": { "type": "number" },
"b": { "type": "number" }
},
"required": ["a", "b"]
}
)
]
@server.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
if name == "add":
result = arguments["a"] + arguments["b"]
return [TextContent(type="text", text=f"Result: {result}")]
async def main():
async with mcp.server.stdio.stdio_server() as (read, write):
await server.run(read, write, server.create_initialization_options())
if __name__ == "__main__":
import asyncio
asyncio.run(main())
把这个文件配置到支持 MCP 的 AI 应用中(如 Claude Desktop 的 claude_desktop_config.json),AI 就能自动发现并使用 add 工具了。
总结
MCP 的本质可以用三层来理解:
- 协议层:标准化 AI 与外部世界的通信接口,将 N × M 的定制对接降维为 N + M 的标准连接
- 架构层:Host-Client-Server 三段式架构,JSON-RPC 2.0 通信,stdio / SSE 两种传输,1:1 连接模型
- 设计层:四种能力(Tools / Resources / Prompts / Sampling)配合四种控制权(模型 / 应用 / 用户 / 服务器),实现双向协作
MCP 解决的不是"AI 能不能调用工具"的问题(Function Calling 已经做了),而是"AI 如何以标准化的方式连接整个外部世界"的问题。它正在成为 AI 应用的基础设施协议,值得每个 AI 开发者关注。
参考资料:
- MCP 官方规范:https://spec.modelcontextprotocol.io/
- MCP 官方文档:https://modelcontextprotocol.io/
- Anthropic 发布博客:https://www.anthropic.com/news/model-context-protocol