深入 Claude Code 源码(五):MCP 协议——Claude Code 连接外部世界的方式
AI 工具的能力边界很大程度上取决于它能接入多少外部系统。一个只能操作本地文件的助手和一个可以查数据库、发 Slack 消息、操作 GitHub Issues 的助手解决的是完全不同量级的问题。如何让 AI 工具和形形色色的外部服务打通同时不要为每一个服务写一套专门的集成代码——这是 AI 工具平台面临的共同挑战。Claude Code 的解决方案是遵循一套开放标准把集成的复杂性推给服务提供方Claude Code 自己只负责「按标准说话」。这个标准就是MCPModel Context Protocol模型上下文协议。本文带大家拆解 Claude Code 里 MCP 协议的完整实现从传输层到工具调用到 OAuth 鉴权到 Elicitation 双向通信。一、MCP 是什么MCP 是 Anthropic 推出的一套工具暴露标准。任何外部服务只要实现了 MCP Server 接口就能把自己的能力作为工具暴露给任何支持 MCP 的 AI 客户端Claude Code、Claude Desktop 等。这就类似于苹果手机的 App Store——不管是谁写的 App只要按照苹果的规范开发并上架所有 iPhone 用户都可以安装使用。MCP 也是如此不管是 GitHub、Slack、本地数据库还是你自己写的工具只要实现了 MCP 接口Claude 就能「学会」使用它们不需要 Anthropic 为每一个服务专门编写集成代码。MCP 协议的核心设计思想是工具自我描述——服务器动态告诉客户端「我有哪些工具每个工具接受什么参数有什么效果」客户端这里是 Claude通过这个描述自主决定何时调用哪个工具。这和传统 REST API 集成「调用方需要事先了解所有接口」的思路有根本的不同。二、三种传输层Claude Code 的 MCP 客户端src/services/mcp/client.ts支持三种传输协议对应不同的 MCP Server 部署方式Stdio 传输SSE 传输Streamable HTTP 传输Claude CodeMCP Client本地子进程命令行工具本地 HTTP 服务Docker 容器等远程 HTTP 服务云端 MCP ServerStdio标准输入输出MCP Server 以子进程形式运行通过stdin/stdout交换 JSON-RPC 消息。配置格式是{ type: stdio, command: npx, args: [some/mcp-server] }。这是最简单的部署方式不需要启动单独的服务Claude Code 启动时会自动拉起对应的子进程。SSEServer-Sent EventsMCP Server 通过 HTTP 长连接推送事件流。适合本地运行的 HTTP 服务比如跑在 Docker 里的数据库 MCP Server。Streamable HTTP较新的传输方式支持双向流式通信适合需要高吞吐量或低延迟的场景也是大多数云端 MCP Server 推荐的方式。三种传输层在代码里的选择逻辑很清晰if(config.typestdio){transportnewStdioClientTransport({command,args,env})}elseif(config.typesse){transportnewSSEClientTransport(url,fetchOptions)}else{transportnewStreamableHTTPClientTransport(url,options)}传输层之上是统一的Client类来自modelcontextprotocol/sdk负责 JSON-RPC 消息的序列化/反序列化和协议握手上层代码不需要关心底层用的是哪种传输。三、连接启动枚举工具和资源Claude Code 启动时会对每一个已配置的 MCP Server 发起连接然后调用tools/list和resources/list拿到这个 Server 暴露的所有能力。这个过程在getMcpToolsCommandsAndResources()里完成对应src/services/mcp/client.ts。枚举回来的每一个 MCP 工具都会被包装成一个MCPTool实例——这就是第三篇里提到的「MCP 工具适配器」。从 Claude 的视角看这些工具和BashTool、FileReadTool没有任何区别都以相同格式出现在 system prompt 里。除了工具MCP Server 还可以暴露资源Resources——类似于「可读取的文档或数据集」。Claude Code 提供了两个专门工具来访问 MCP 资源ListMcpResourcesTool列出某个 MCP Server 暴露的所有资源ReadMcpResourceTool读取特定资源的内容资源和工具的区别在于工具是「做某件事」有副作用资源是「读某个东西」无副作用。一个数据库 MCP Server 可能同时暴露「执行 SQL 查询」工具和「数据库 schema」资源。四、OAuth 鉴权很多 MCP Server 需要鉴权——访问 GitHub、Slack、Google Drive 的 MCP Server 需要知道「是哪个用户在操作」。Claude Code 内置了完整的 OAuth 2.0 流程让这些鉴权对用户尽量透明。自动 token 刷新当 MCP 工具调用返回 HTTP 401 错误时handleOAuth401Error()会先检查本地是否有缓存的 token如果 token 过期就调用checkAndRefreshOAuthTokenIfNeeded()自动刷新然后重试工具调用。整个过程对用户是透明的不会弹出任何提示。首次授权流程如果没有缓存的 token比如第一次使用某个需要鉴权的 MCP ServerClaude Code 会触发 OAuth 授权流程显示一个授权链接或二维码等用户在浏览器里完成授权再把 token 存到本地 Keychain后续调用就可以自动使用了。McpAuthTool主动授权工具还有一个特殊的工具叫McpAuthTool——当某些 MCP Server 需要用户主动触发授权而不是在工具调用失败时被动触发时Claude 可以主动调用这个工具让用户在终端里完成授权操作。五、ElicitationMCP Server 主动询问MCP 2.0 协议引入了一个有趣的能力——Elicitation主动询问。通常是「Claude 调用 MCP 工具」但 Elicitation 反过来MCP Server 在工具执行过程中主动向 Claude或用户请求额外信息。典型场景一个文件同步工具在执行同步之前需要知道「目标路径是什么」「是否覆盖已有文件」与其要求调用方在调用时就提供所有参数不如在执行过程中动态询问。在 Claude Code 里MCP Server 发起 Elicitation 的技术信号是一个-32042错误码。QueryEngine收到这个信号后调用handleElicitation回调// QueryEngineConfig 里handleElicitation?:ToolUseContext[handleElicitation]这个回调最终会在终端 UI 里渲染一个类似AskUserQuestionTool的交互界面让用户填写所需信息再把结果返回给 MCP Server让它继续执行。整个流程如图所示用户MCP ServerMCP ClientClaude用户MCP ServerMCP ClientClaude调用 MCP 工具tool_useJSON-RPC 请求返回 -32042 Elicitation 请求\n需要额外信息目标路径触发 handleElicitation 回调显示交互表单\n「请输入目标路径」填写并确认提供请求的额外信息正常执行并返回结果工具调用成功六、官方 MCP 注册表预取main.tsx启动时有一行不太引人注意但很有意思的代码prefetchOfficialMcpUrls()Claude Code 维护一个官方 MCP Server 列表里面包含由 Anthropic 或主流服务提供的 MCP Serversrc/services/mcp/officialRegistry.ts。启动时就预取这个列表是为了让/mcp add命令能立刻弹出「推荐的 MCP Server」列表不需要现场等待网络请求。这个设计背后的思路是用户在使用/mcp add时处于「想要扩展能力」的高意图状态任何加载延迟都会打断这个体验。提前预热让用户在需要的那一刻看到「丝滑」的响应而不是一个菊花转圈。七、MCP Server 的审批机制Claude Code 不会在未经用户确认的情况下静默连接任何 MCP Server。src/services/mcpServerApproval.tsx实现了 MCP Server 的信任审批流程首次连接某个 MCP Server 时会显示服务器信息和它暴露的工具列表请用户确认是否信任审批结果存在本地配置里下次启动不需要重新确认远程管理的 MCP Server通过remoteManagedSettings下发的有单独的审批通道企业可以统一配置这个审批机制的存在是有必要的——MCP Server 本质上是在用户机器上运行的代码能访问文件系统、执行网络请求、操作用户数据。不加审批地允许任意 MCP Server 连接相当于无条件信任任何第三方脚本。学习完本篇大家对以下问题应该有了清晰的认识MCP 是一套开放的工具暴露标准让任何服务都能以统一方式接入 Claude三种传输层Stdio、SSE、Streamable HTTP对应不同部署场景上层接口统一OAuth 鉴权对用户尽量透明包括自动 token 刷新和首次授权引导Elicitation 是 MCP Server 向 Claude 主动询问信息的机制双向通信MCP Server 首次连接需要用户明确审批不静默信任接下来进入最后一篇——多智能体协调AgentTool和 Coordinator Mode 是如何让多个 Claude 实例协同工作的。