--- title: "MCP 协议" description: "从配置到可用工具:MCP 连接管理、内置 vs 外部两种模式、工具发现和执行链路的设计。" keywords: ["MCP", "Model Context Protocol", "工具扩展", "MCP 客户端", "工具发现"] --- ## 核心问题 MCP 让 Claude Code 使用外部工具。但连接外部服务有延迟、可能失败、工具列表可能变化。如何管理这些不确定性? ## 架构总览 ``` 配置(多来源合并) → 连接管理(缓存) → 工具发现(MCP 协议) → 工具执行 ``` ## 两种 MCP 模式 ### 内置 MCP 服务器 Computer Use、Chrome 控制等内置功能通过 MCP 协议暴露,但运行在**同进程内**——不启动子进程,无网络开销,无 IPC 序列化。 **设计洞察**:内置服务器使用与外部服务器完全相同的 MCP 协议(`tools/list`、`tools/call`),但通过 `InProcessTransport` 在进程内通信。这意味着所有工具发现、权限检查、执行逻辑都是同一套代码——内置和外部工具的唯一区别是传输方式。 ### 外部 MCP 服务器 用户配置的外部工具,通过子进程(stdio)或网络连接(SSE/HTTP/WS)运行。 | 维度 | 内置 | 外部 | |------|------|------| | 进程模型 | 同进程 | 子进程或网络 | | 启动开销 | 零 | 子进程启动或网络握手 | | 权限 | 自动授权 | 需要用户确认 | | 配置来源 | 动态注册 | settings.json / .mcp.json | | 名称保护 | 保留名,不可覆盖 | 自由命名 | ## 连接管理 ### 缓存机制 连接使用 memoize 缓存——相同的配置不会重复建立连接。缓存 key 包含服务器名和配置内容,配置变化时自动失效。 ### 重连机制 远程连接有连续错误计数器。遇到网络错误(ECONNRESET、ETIMEDOUT 等)连续 3 次后,主动关闭连接触发重连。 **设计考量**:网络连接是脆弱的——临时故障不应该永久禁用一个 MCP 服务器。自动重连确保服务恢复后工具能继续使用。 ### 清理策略 stdio 类型的子进程清理使用信号升级策略: ``` SIGINT (100ms) → SIGTERM (400ms) → SIGKILL ``` 总清理时间上限 600ms。防止 MCP 服务器关闭阻塞 CLI 退出。 ### 并发控制 | 类型 | 并发上限 | 原因 | |------|---------|------| | 本地(stdio) | 3 | 每个子进程是重量级资源 | | 远程(HTTP) | 20 | 轻量级 HTTP 请求 | ## 工具发现 ### 从 MCP 到 Tool 接口 MCP 服务器通过 `tools/list` 方法暴露工具列表。每个工具被包装为 Claude Code 统一的 Tool 接口,工具名格式为 `mcp____`。 ### 工具描述截断 MCP 工具描述上限 2048 字符。OpenAPI 生成的 MCP 服务器曾观察到 15-60KB 的描述文档——截断防止这些巨大描述占满 System Prompt。 ### 工具能力标注 MCP 工具通过 `annotations` 声明自身特性: | 注解 | 含义 | |------|------| | `readOnlyHint` | 只读操作,可并行 | | `destructiveHint` | 破坏性操作 | | `openWorldHint` | 开放世界(不可枚举所有行为) | 这些标注影响权限检查——只读工具在更多权限模式下被自动放行。 ### 权限检查 MCP 工具默认进入权限确认流程(`passthrough`),通过 `mcp__` 前缀匹配权限规则。用户可以为特定 MCP 服务器配置 allow/deny 规则。 内置 MCP 工具通过白名单自动授权,不触发权限提示。 ## 执行链路 ``` AI 调用 MCP 工具 → 确保连接有效 → 通过 MCP 协议执行 → 处理结果 → Session 过期?自动重试一次 → 结果过大?截断 + 持久化到磁盘 → 包含图片?自动 resize + 持久化 ``` **设计考量**:MCP 工具的执行结果可能很大(数据库查询结果、API 响应)。截断 + 持久化确保大型结果不会耗尽上下文窗口,同时 AI 仍然知道结果在哪里可以找到。 ## 接下来 - **MCP 配置** — 理解多来源合并和企业管控 - **工具系统** — 理解所有工具的统一接口 - **权限模型** — 理解 MCP 工具的权限检查