
MCP 协议全景:为什么它是 AI 连接工具的「USB-C」
🔥 写在前面 :2024 年底 Anthropic 放出 MCP(Model Context Protocol),2025 年它几乎成了 AI 工具链的「通用接口」。但很多人只知道「MCP 很火」,却说不清它到底解决了什么、和自己手写一个 HTTP 接口有什么区别。这篇文章把协议栈、握手流程、核心原语一次性讲透,并给你一套可以自己复现的验收标准。
💡 我是做一线 Java + AI 工程落地的,信创和 MCP 都是真刀真枪踩过坑的。本专栏会持续更新 MCP / Spring AI / 信创实战,关注我,新篇第一时间看,少走弯路。
一、先说结论
- MCP 不是又一个 RPC 框架 ,它解决的是「AI 应用 ↔ 工具/数据」之间的标准化接入问题------以前每个工具都要写一套私有对接代码,现在统一成一套协议。
- 类比 USB-C:以前 AI 连数据库要写「Type-A 线」、连 Git 要写「Type-B 线」,MCP 就是那条 universal 的 USB-C 线,插上就能用。
- 对开发者最大的价值:一次实现 Server,所有支持 MCP 的 Client(Claude Desktop、Cursor、Cline、Trae...)直接复用,不用为每个客户端重写一遍。
- 但它不是银弹:MCP 解决「接得上」,不解决「接得安全、接得稳」,后两件事仍要你自己做(见第六、七节)。
二、为什么会出现 MCP(它解决了什么痛点)
在 MCP 之前,你的 AI 应用要调用一个工具,典型做法是:
text
应用代码 → 手写 HTTP 请求 → 你的后端 API → 返回 JSON
痛点在于:每接一个工具,就要写一套私有对接代码 。数据库、Git、浏览器、文件系统、飞书、内部系统......每个都是各自为政。更糟的是,这套代码和具体客户端(Claude / Cursor / Cline)强绑定,换一个客户端基本重写。
MCP 把这一层抽象成标准协议:
text
AI Client(Claude/Cursor/Cline)
│ 标准协议(JSON-RPC over stdio / SSE)
▼
MCP Server(你实现的工具适配层)
│
▼
真实工具(DB / Git / 浏览器 / 文件系统)
一句话:把「N 个客户端 × M 个工具 = N×M 套对接」压成「M 个 Server + 1 套协议」。
三、MCP 协议栈长什么样
MCP 是分层设计的,从上到下分别是:

- 传输层(Transport) :
stdio(本地子进程,最常用、零网络)或SSE(远程服务,走 HTTP 长连)。 - 消息层(JSON-RPC 2.0):所有通信都是 request / response / notification 三种消息。
- 协议层(Protocol):定义生命周期、能力协商、原语。
- 原语层(Primitives):真正给 AI 用的能力,下一节展开。
你实际写代码时基本只碰原语层,传输和消息层由 SDK 兜底,这也是 MCP 上手快的原因。
四、一次真实调用:握手 → 调用 → 返回
以「AI 让 MCP 去读一个文件」为例,完整时序是:

- 初始化(initialize):Client 发协议版本 + 自身能力;Server 回版本 + 自身能力(能力协商)。
- 列举(list):Client 问「你有哪些工具 / 资源 / 提示」;Server 返回清单。
- 调用(call) :AI 决定调用某个工具,Client 发
tools/call带参数。 - 返回(result):Server 执行真实操作,把结果回给 AI,AI 再组织成自然语言。
注意第 2 步:AI 不是硬编码知道有哪些工具,而是运行时「问」出来的。这点是 MCP 动态能力的核心。
下面把这三帧用真实 JSON-RPC 帧摊开看(和 MCP_DEBUG=1 抓到的完全一致):
json
// 1) initialize 请求(Client → Server):能力协商从这里开始
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": {}, "resources": {}, "prompts": {} },
"clientInfo": { "name": "my-client", "version": "1.0.0" }
}
}
json
// 2) initialize 响应(Server → Client):回协议版本 + 自身能力
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": { "listChanged": true } },
"serverInfo": { "name": "filesystem", "version": "1.2.0" }
}
}
json
// 3) tools/call 请求(AI 决定读文件后,Client → Server)
{
"jsonrpc": "2.0",
"id": 7,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": { "path": "~/test/hello.txt" }
}
}
这三帧就是 MCP 的「最小可运行单元」。你能用
MCP_DEBUG=1抓到它们,就说明协议层真的通了------抓不到,八成是 Server 进程没起来或版本协商失败(见第七坑 6)。
五、三大核心原语(Primitives)
MCP 把能力拆成三类原语,理解这三者就理解了 MCP 的 80%:

- Tools(工具) :AI 可以主动调用的执行型能力(如「查询数据库」「创建文件」)。带副作用,需要审批意识。
- Resources(资源) :AI 可以读取的数据型能力(如「读取某文件内容」「获取配置」)。只读,类 GET。
- Prompts(提示) :预定义的模板,用户手动触发(如「一键生成周报」),不是 AI 自发的。
常见误区:把所有东西都做成 Tool。其实「只读的数据」用 Resource 更合适,权限模型更清晰。
验收标准:你可以自己复现
别光看我说,按下面 4 步自己跑一遍,能跑通才算真懂:
- 装一个现成 Server :
npx -y @modelcontextprotocol/server-filesystem ~/test,确认进程能起来且打印 MCP 日志。 - 接一个 Client :用 Claude Desktop 或 Cline 配置该 Server,重启后能在工具列表里看到「读文件」。
- 真调一次 :让 AI「读一下 ~/test/hello.txt」,AI 发出
tools/call,你能在 Server 日志看到对应的read_file调用。 - 看协议帧 :用环境变量
MCP_DEBUG=1启动,能看到完整的initialize → tools/list → tools/call三帧 JSON-RPC。四帧全看到 = 协议理解达标。
六、实测:MCP 带来的真实收益
我在三个项目里接入 MCP 的前后对比:
- 对接成本 :原来接 3 个客户端 × 4 个工具 = 12 套代码;换成 MCP 后 = 4 个 Server + Client 自带支持 = 实际只写 4 套,下降约 65%。
- 维护成本:某工具接口变更,原来要改 3 处客户端代码;现在只改 1 个 Server。
- 冷启动:第一个 Server 约半天(熟悉协议),第二个起每个 1~2 小时。
收益曲线是「第一个慢、后面指数快」------前期学习成本要摊到 3 个以上工具才划算。
七、我踩过的 6 个坑
坑 1:stdio 模式下 Server 进程被客户端「悄悄杀掉」
现象:配好 Server 后偶尔「工具列表为空」。根因:客户端只在首次启动时拉起子进程,你改了 Server 代码但没重启客户端,用的是旧进程。解决 :改完 Server 必须彻底重启客户端(不是 reload)。预防:本地开发时让客户端输出 Server 日志。
坑 2:工具描述写得太含糊,AI 不调用
现象:工具明明注册了,AI 从不调用。根因:Tool 的 description 只有「查询数据」四个字,AI 不知道何时该用。解决 :描述写成「当用户想查 XX 业务表的 YY 字段时使用」。预防:描述里明确触发场景 + 参数含义。
坑 3:返回内容太大,撑爆上下文
现象:读一个 5MB 文件直接 OOM 或 AI 失忆。根因:Resource 把整个文件塞回上下文。解决 :Server 端做截断 / 分页(如只回前 200 行 + 总行数)。预防:给所有返回加 size 上限。
坑 4:Tools 带副作用却没确认
现象:AI 直接「删了数据库一行」,吓出冷汗。根因:把写操作做成 Tool 且无确认。解决 :写操作前加确认步骤 / 走 dry-run。预防:凡 Tool 有副作用,默认要求人工确认。
坑 5:SSE 远程模式忘了鉴权
现象:公网部署的 MCP Server 被人白嫖算力。根因:SSE 模式走 HTTP,没加 token。解决 :反向代理 + Bearer Token + IP 白名单。预防:SSE 模式默认当公网服务对待,必须鉴权。
坑 6:协议版本不匹配,握手直接失败
现象:initialize 后客户端报错退出。根因:Server 实现的是旧版协议(2024-11-05),Client 要求新版(2025-03-26)。解决 :双方对齐同一协议版本,或直接用官方 SDK 自动协商。预防:别手写协议层,用 SDK。
八、适合谁 / 不适合谁
✅ 适合上 MCP
- 你有 2 个以上工具要被 AI 调用;
- 你希望同一套工具能被多个 AI 客户端复用;
- 工具接口会频繁变化,想降低维护成本。
⚠️ 暂时别上
- 就一个工具、一个客户端:直接写 HTTP 接口更快,MCP 是过度设计;
- 对延迟极度敏感(微秒级):MCP 的 JSON-RPC 封装有开销。
九、总结
MCP 的本质是「AI 世界的 USB-C 标准」------它不改变工具本身,而是统一了接入方式 。对有多工具、多客户端需求的团队,它是降本增效的利器;对单场景小项目,则属于杀鸡用牛刀。下一篇我们深入它最容易被混淆的一对概念:有状态 vs 无状态 Server。
📢 下篇预告
第 2 篇《有状态 vs 无状态:MCP 两种服务形态怎么选》------同样一个 MCP Server,为什么有的要存会话、有的纯函数式?这两种形态在扩展性、成本、状态管理上差在哪?实测数据说话。
💬 聊聊 + 关注
你现在的 AI 工具链里,最痛的「重复对接」是哪一块?是数据库、Git,还是内部系统?评论区说说你的场景,我挑典型的在下一篇展开,也帮你看架构哪里该改。
👉 如果这篇帮你理清了 MCP,点个「关注」------专栏后续还有:MCP 无状态大版本解读、手写 Java MCP Server 深更、A2A 多智能体协作、Spring AI 全链路实战。关注后新篇直接推给你,不迷路。
附:速查表与客户端配置
客户端接入配置(直接复制)
json
// Claude Desktop 配置(macOS: ~/Library/Application Support/Claude/claude_desktop_config.json)
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "~/test"]
},
"sqlite": {
"command": "uvx",
"args": ["mcp-server-sqlite", "--db-path", "~/app.db"]
}
}
}
表 1:MCP vs 手写 HTTP vs Function Calling
| 维度 | 手写 HTTP 接口 | OpenAI Function Calling | MCP |
|---|---|---|---|
| 客户端耦合 | 每客户端一套对接 | 绑 OpenAI 生态 | 一次实现,全客户端复用 |
| 工具发现 | 无(硬编码) | 无(硬编码) | 运行时 tools/list 动态发现 |
| 标准化 | 各自为政 | 厂商私有协议 | 开放协议(Anthropic 主导) |
| 多工具维护 | N×M 套代码 | 随模型升级重写 | M 个 Server + 1 套协议 |
表 2:三大原语对比
| 原语 | 方向 | 是否有副作用 | 典型例子 | AI 是否自发 |
|---|---|---|---|---|
| Tools | Client→Server 调用 | ✅ 可写 | 查库、建文件、发消息 | 是(AI 决策) |
| Resources | Client 读 Server | ❌ 只读 | 读文件、取配置 | 否(上下文触发) |
| Prompts | 用户触发模板 | ❌ 模板 | 一键周报、SQL 生成器 | 否(用户手动) |
表 3:传输方式对比
| 传输方式 | 部署形态 | 是否需要鉴权 | 适用场景 | 复杂度 |
|---|---|---|---|---|
| stdio | 本地子进程 | 不需(本机) | 个人工具、桌面客户端 | 低 |
| SSE | 远程 HTTP 长连 | 必须 Token | 团队共享、云端 Server | 中 |
表 4:主流客户端支持矩阵
| 客户端 | stdio | SSE | 备注 |
|---|---|---|---|
| Claude Desktop | ✅ | ❌ | 仅本地 |
| Cursor | ✅ | ✅ | 支持远程 |
| Cline | ✅ | ✅ | 支持远程 |
| Trae | ✅ | ✅ | 支持远程 |
表 5:三大原语选型
| 你的需求 | 用哪个原语 | 理由 |
|---|---|---|
| AI 要执行动作(发消息 / 改数据) | Tools | 需 AI 决策调用 |
| AI 要读一段数据(文件 / 配置) | Resources | 只读、类 GET |
| 用户要套固定模板(周报 / SQL) | Prompts | 手动触发、可复用 |