MCP 协议:AI 工具互联的 USB-C
在 MCP 出现之前,每个 AI 工具集成都是一次定制开发。想让 ChatGPT 连数据库?写一个插件。想让 Claude 调 GitHub API?写一个 Function Calling 定义。想让 Copilot 访问你的内部系统?写一个 Custom Tool。
每次都是同一件事:定义接口、写适配代码、处理认证、管理错误。轮子被重复发明了无数次。
MCP(Model Context Protocol)要解决的问题很简单:给 AI Agent 一个标准的工具连接协议。 就像 USB-C 给电子设备提供了一个通用的连接接口,MCP 给 AI Agent 提供了一个通用的工具接口。
MCP 是什么
MCP 是一个开源协议,定义了 AI Agent(客户端)和外部工具服务(服务端)之间的通信标准。它规定了:
- 工具怎么被描述(名字、参数、返回值)
- 工具怎么被调用(请求格式、响应格式)
- 错误怎么被报告(错误码、错误信息)
- 资源怎么被共享(文件、数据、上下文)
实现了 MCP 协议的工具服务可以被任何 MCP 客户端调用。Claude Code 是一个 MCP 客户端,Cursor 是另一个,Claude Desktop 也是。同一个 MCP 服务端(比如一个数据库查询服务)可以被多个不同的 AI Agent 使用,不需要为每个 Agent 写不同的集成代码。
JSON-RPC over stdio
MCP 的传输层选择值得咀嚼:JSON-RPC over stdio(标准输入输出)。
不是 HTTP,不是 gRPC,不是 WebSocket。是 stdio——进程的标准输入和输出流。
这意味着 MCP 服务端是一个本地进程,客户端通过启动这个进程、向它的 stdin 发送 JSON-RPC 请求、从它的 stdout 读取响应来通信。
这个选择看起来"原始",实际有几个精妙的好处:
零网络配置。 stdio 是进程级别的,不需要端口、不需要防火墙规则、不需要 HTTPS 证书。启动即用。
天然安全。 stdio 通信只在本地进程之间发生,不经过网络栈。没有暴露的端口意味着没有攻击面。MCP 服务端不需要认证机制——谁能启动这个进程,谁就能用它。这是操作系统级别的权限控制。
跨语言。 JSON-RPC 是语言无关的。MCP 服务端可以用 Python 写,客户端可以用 TypeScript 写,它们通过 JSON 通信。任何有 JSON 序列化和进程管理能力语言都可以实现 MCP。
简单调试。 你可以直接用 cat 或 echo 向 MCP 服务端的 stdin 发送请求,用眼睛看 stdout 的响应。不需要 curl、不需要 Postman、不需要网络抓包工具。
代价也很明确:只能本地运行。 stdio 不支持远程连接。如果你想让 AI Agent 调用远程服务,需要一个本地代理进程做桥接。MCP 通过 stdio 传输方式解决了本地工具集成,远程集成需要额外的传输层实现(如 HTTP SSE)。
工具发现机制
MCP 有一个精巧的工具发现机制。客户端不需要预先知道服务端提供了哪些工具——它在连接时自动发现。
流程是这样的:
- 客户端启动 MCP 服务端进程
- 客户端发送
initialization请求 - 服务端返回能力声明:支持的工具列表、资源列表、协议版本
- 客户端根据能力声明构建工具定义
- 工具定义被注入到 Agent 的 system prompt
这意味着 MCP 服务端可以自己注册新工具,客户端自动适配。不需要客户端发新版、不需要重新配置。插上一根 USB-C 线,系统自动识别设备——MCP 的工具发现就是同样的逻辑。
MCP 与内置工具的关系
Claude Code 有内置工具(read_file、write_file、bash……),也有 MCP 工具(通过协议连接的外部服务)。两者在 Agent 眼里没有区别——都是"可调用的工具",都有名字、描述、参数。
区别在架构层面:
- 内置工具是硬编码在 Claude Code 进程里的。它们是 Agent 的"原生能力",启动时就可用,不需要额外进程。
- MCP 工具是外部进程提供的。它们是 Agent 的"扩展能力",连接时才发现,断开时消失。
内置工具像操作系统的内核模块,MCP 工具像外接设备。内核模块稳定但固定,外接设备灵活但可插拔。
配置的简洁性
MCP 的配置文件(.claude/settings.json)体现了它的设计哲学——尽量简单:
{
"mcpServers": {
"database": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/mydb"]
}
}
}不需要 URL、不需要认证 token、不需要端口号。只需要告诉客户端"怎么启动这个服务"——命令和参数。客户端负责启动进程、建立 stdio 通道、发现工具。
这种"命令即配置"的模式和 npm scripts、Makefile 一脉相承。它假设用户已经熟悉命令行操作,不需要额外的抽象层。
MCP 的生态意义
MCP 的真正价值不在协议本身,在生态效应。
当足够多的工具实现了 MCP 协议,AI Agent 的能力边界被指数级扩展。不需要每个 Agent 单独集成每个工具——一次实现,到处可用。
这类似于浏览器和 HTTP 的关系。在 HTTP 标准化之前,每个网络应用都有自己的通信协议。HTTP 标准化后,任何一个网站都可以被任何浏览器访问。MCP 对 AI Agent 生态可能产生类似的效果:任何一个 MCP 工具都可以被任何 MCP 客户端使用。
MCP 的局限
MCP 不是银弹。它有明确的边界:
它只解决工具连接,不解决数据格式。 MCP 规定了"怎么调用工具",但没规定"工具返回什么格式的数据"。数据库查询返回 JSON?SQL 结果集?CSV?由工具自己决定。
它不解决权限管理。 MCP 假设"能启动进程的人有权使用工具"。这在个人使用场景够用了,但在团队协作或多租户场景下不够精细。
它不解决版本兼容。 如果 MCP 服务端升级、改了工具定义,客户端可能需要适配。MCP 有协议版本号,但工具级别的版本管理还没有成熟方案。
延伸阅读:BYF 的 McpConnectionManager 与 /mcp-config
BYF 在 MCP 集成上有一个创新——对话式配置。
Claude Code 的 MCP 配置靠手动编辑 JSON 文件(.claude/settings.json)。BYF 提供了一个 /mcp-config 命令,让你在对话中直接添加、编辑、认证 MCP 服务器——不需要手改 JSON。配置变更通过代理(带有 Skill 的治理规则)自动审计和重写,降低了 MCP 的采纳门槛。
BYF 的 McpConnectionManager 管理 MCP 服务器连接的生命周期:启动(通过 stdio 或 HTTP/SSE)、工具发现(按稳定性排序,内置工具在前、MCP 工具在后)、OAuth 认证和自动重连。BYF 还将 MCP 传输分为三类——stdio(本地进程)、Streamable HTTP(新一代 MCP 传输)、传统 SSE(向后兼容)——每种传输方式对应不同的生命周期管理策略。
一个细节值得提:BYF 在工具缓存排序中(ADR 0011)明确将 MCP 工具排在最后。原因是 MCP 工具可能连接/断开,导致工具定义变化——如果把 MCP 工具混在稳定的内置工具中间,一次连接变化会使整个缓存边界失效。BYF 通过稳定性排序 + 固定哨兵标记解决了这个问题。这是"渐进式披露"在缓存层面的体现:不稳定的工具不应该污染稳定的缓存区域。
下一篇
MCP 让 Agent 连接外部工具。但有了更多工具不代表会用得更好——Agent 需要知道什么时候该先规划再行动。下一篇文章我们要拆解 Plan Mode:为什么"只读规划"模式能显著提高代码质量?读-想-写的分离为什么是 AI 编程的关键分水岭。
本系列基于 Claude Code 官方源码项目进行架构分析,聚焦设计思想而非代码实现。