Claude Code 如何连接并暴露 MCP 工具
文章梳理 MCP 服务从配置合并、策略过滤、用户批准到传输连接的接入链路。其核心解释是 Claude Code 如何将外部工具纳入 Agent 循环已有的统一工具接口,本文属于系列导览。
完整中文译文
MCP 为 Claude Code 提供了第二个能力来源。内置工具并不是它的全部能力:连接服务器后,服务器提供的工具、资源和 prompt 就会对客户端开放。有意思的是,Claude Code 并没有为这些工具另建一套 Agent 运行时,而是把外部工具转换成 Agent 循环所使用的通用工具接口。
这个设计选择,是贯穿本系列的主线:
系统越容易扩展,单一、统一的接口就越重要。
本篇开篇文章会先勾勒整体脉络。后续文章将沿着这条处理流程,逐一深入各个环节。
从配置到可调用工具的路径
在 .mcp.json 或用户设置中添加一条服务器配置,并不意味着模型立刻就能调用它。它还要经过几道关卡:
-
合并配置作用域。Claude Code 汇总相关配置来源,并处理覆盖关系。
-
应用策略。允许列表、拒绝列表和企业规则,可能在尝试连接之前就把服务器排除。
-
获取批准。项目级服务器可能需要用户批准,才能首次使用。
-
通过选定的传输方式连接。本地子进程和远程 HTTP 服务走的是不同的连接路径。
-
协商能力。客户端和服务器确定双方支持哪些 MCP 功能。
-
发现能力。客户端获取服务器提供的工具、资源和 prompt。
-
适配工具。每个服务器工具都会转换成一个 MCPTool,并获得兼容 Claude Code 的名称和 schema。
-
加入 Agent 的工具列表。到这一步,LLM 就能像选择普通工具一样选择它。
各个阶段的失败方式不同。连接未能建立,会表现为连接失败;授权过期,会表现为身份验证问题;策略拒绝则更安静:用户可能还没看到任何连接状态,服务器就已经被排除了。
调试 MCP 时,这种区别很重要。“工具不见了”可能意味着配置合并出了问题、策略作出了拒绝决定、还需要用户批准、身份验证失败,或者传输失败,而不只是 tools/list 调用失败。
关于面向用户的配置方式和支持的作用域,可参阅 Claude Code 官方 MCP 文档。
连接是一个生命周期,而不是一次请求
在内部,服务器并不是简单地处于“已连接”或“已断开”两种状态。连接层会区分已连接、失败、等待中、已禁用、需要身份验证等状态。这样的状态模型,可以避免把临时传输错误与仍在等待用户通过浏览器作出决定的 OAuth 流程混为一谈。
实现上,连接也被视为一种可缓存的资源。系统会根据服务器名称和配置记忆化连接,并将发现的工具、资源等派生数据一并缓存。传输关闭时,这些缓存会被清除,让下次请求走重新连接的路径,而不是继续使用过时的能力发现结果。
这对远程 MCP 服务器尤其重要。即使端点仍然可以访问,会话也可能已经过期。Claude Code 会识别相应的 JSON-RPC 会话过期错误,清除缓存的连接状态,重新连接,然后重试一次。这条恢复规则很小,实际作用却很大:“服务器还在运行”并不等于“当前会话仍然有效”。
重试行为也有意作了区分。远程传输可以按指数退避进行次数有限的自动重连,本地 stdio 和基于 SDK 的进程则不在此列。网络连接可能在短暂中断后恢复;本地进程退出,则更可能是命令有误、缺少环境变量,或者确实发生了崩溃。盲目重试反而会掩盖诊断线索。
标准传输与产品传输
MCP 规范定义了标准的 stdio 和 Streamable HTTP 传输方式;较早的 HTTP 加 SSE 方案已被弃用。协议对传输的规定有意保持克制:它标准化的是可互操作的 JSON-RPC 消息交换方式,而不是产品可能需要的每一种集成方式。具体可参阅 MCP 传输规范。
实际使用中,Claude Code 客户端的传输分支更多。除了标准的本地和远程路径,代码库还支持用于兼容的 SSE 路径、基于 WebSocket 的路径、面向 IDE 的变体、SDK 桥接、Claude.ai 代理,以及进程内传输。
这并不矛盾,而是协议与产品之间的边界:
-
协议定义独立客户端与服务器之间可以共享的、可移植的契约。
-
产品仍然需要处理 IDE、浏览器、SDK 和内部进程边界上的集成。
进程内传输让这种区别变得直观。它通过内存队列传递消息,而不是网络连接或子进程。SDK 桥接也类似,会通过 Claude Code 自身的控制通道传递 MCP JSON-RPC 消息。两者都没有改变模型所看到的工具形态,解决的都是特定部署场景下的底层连接问题。
外部工具如何变成 Claude Code 工具
关键的适配机制是命名。发现的 MCP 工具会以这样的名称暴露:
mcp__<server>__<tool>
这个前缀为不同服务器的工具提供了稳定的命名空间,也让 Claude Code 的其他部分可以把它们当作同一份列表中的条目处理。工具的 inputSchema 会直接作为 JSON Schema 传递,而不是转换成另一套手写的校验模型。
最终结果刻意保持简单:模型看到的是工具名称、描述和 schema。它不需要为“MCP 模式”建立另一套理解方式。
这层适配也暴露了所有基于字符串的命名空间都存在的一个局限:如果服务器名称包含分隔符,就可能产生歧义。名称适合作为面向人的标识符,但如果后续解析还要从中还原结构边界,它就是一种脆弱的序列化格式。
Claude Code 还会在全局注册资源列表和资源读取功能,而不是为每台服务器分别注册。这样,连接更多服务器时,模型就不会面对一大堆几乎相同的资源工具。体积较大或二进制格式的资源结果可以保存为文件,再用路径引用替代;MCP 输出也有可配置的大小上限。这两项措施都能避免功能强大的外部服务器耗尽整个工作上下文。
MCP 权限:特殊的匹配方式,通用的决策机制
Claude Code 的权限规则语法为 MCP 提供了一个值得关注的扩展:一条规则可以匹配整台服务器,例如:
mcp__calendar
mcp__calendar__*
如果一台服务器提供的是一组职责一致、值得信任的能力,这就比逐个批准工具更实用。用户或管理员也可以在安装集成时所使用的同一抽象层级上,拒绝整个集成。
但 MCP 工具本身并没有一套私有的权限引擎。它的本地权限检查返回 passthrough,实际的规则匹配由共享权限系统完成。如果没有规则能决定如何处理请求,通用引擎就会回退到询问用户。
这种职责划分很实用。像 Bash 这样的工具,可能需要针对具体命令进行安全分析;MCP 工具的种类太多,无法用一条通用的语义规则覆盖。Claude Code 因此把决策集中到策略层,再通过服务器命名空间提供必要的分组机制。
工具之外:资源、prompt 与 elicitation
MCP 经常被描述为“一种添加工具的方式”,但工具只是它三大能力类别之一:
-
Tools 让模型执行操作。
-
Resources 让服务器提供可读取、可寻址的信息。
-
Prompts 让服务器提供可复用的 prompt 模板。
能力协商完成后,Claude Code 会分别判断是否启用各项后续功能。服务器可以只提供工具、不提供资源,依然很有用;反过来也一样。
Elicitation 是交互性更强的一项扩展。它允许服务器在交互过程中请求结构化输入。Claude Code 支持表单和 URL 两种模式,并在 UI 之前设置 hooks,让具体安装环境可以通过程序处理某些请求。这很好地说明了“采用一项 MCP 功能”和“把它交付到真实产品中”的区别:协议支持确定消息如何交换,客户端仍然要决定用户如何看到、批准或自动处理这些交换。
身份验证是工具体验的一部分
对于 HTTP 服务器,授权并不是一个独立于工具使用流程的设置页面。授权失败时,模型可能会收到一个合成的身份验证工具结果,其中包含继续授权流程所需的 URL。底层客户端采用带 PKCE 的授权码 OAuth 流程,并使用本地回环回调、超时机制和安全的凭据存储。
这样,身份验证就成了生命周期中的又一次状态转换,而不是一个缺乏结构的致命错误。企业环境还会增加一层机制:通过 token 交换流程,在符合条件的服务器之间复用现有的身份提供方会话,从而减少重复登录,同时保持核心工具接口不变。
Claude Code 可以反过来充当服务器
把方向反过来看,架构就更清楚了。Claude Code 也可以启动 MCP 服务器,通过 tools/list 暴露自身的内部工具,再由另一个 MCP 客户端通过 stdio 使用。
之所以能这样做,是因为工具定义本质上并不绑定某一种传输方式。同一份内部 schema,既可以直接供 Agent 循环使用,也可以转换成 JSON Schema,通过 MCP 对外公布。因此,Claude Code 并不永远只是“一个 MCP 客户端”;MCP 只是它的工具模型跨越进程边界的一种方式。
本系列接下来会讲什么
沿着这张全景图,后续章节将依次展开:
-
连接配置、作用域与握手。
-
本地和远程传输。
-
工具发现、命名、schema 与输出控制。
-
服务器级权限规则。
-
OAuth 与企业身份验证。
-
资源与 elicitation。
-
Claude Code 作为 MCP 服务器。
-
MCP 的边界,以及 Skills、内置 Tools 和 Plugins 从哪里接手。
核心问题并不是“如何再添加一个工具”,而是:一个 Agent 如何接入大量独立构建的能力,又不至于变成一堆特殊情况的集合?Claude Code 的答案是,让边界具备适配能力,再让面向 Agent 的接口保持统一。
如需采取进一步行动,你可以考虑屏蔽此人和/或举报滥用行为。