本章从 s04 内核单独讲 MCP,不包含 Task System、后台任务、Cron、Agent Teams 或 Worktree;s15 才把外部工具与累计机制接到一起。
内置工具由 Harness 在启动时注册。MCP 把能力边界扩展到外部服务:连接 server、发现工具、转换 schema,再把 handler 动态加入模型下一轮可见的工具池。
connect_mcp("docs") → 发现工具 → mcp__docs__search → 下一轮工具池课程使用进程内 Mock
s14 用 MCPClient、connect_mcp 和 assemble_tool_pool 展示接入,但 server 是进程内模拟实现,没有真实 MCP stdio、HTTP 或鉴权传输。它解释动态发现,不是完整 MCP 客户端。
工具池每轮重新组装
模型初始只看到基础工具和 connect_mcp。连接成功后,下一次调用前组装基础工具与已连接 MCP 工具、基础 handlers 与动态 handlers。因此连接和使用发生在不同轮次。
名称规范化必须处理冲突
外部工具统一命名为 mcp__{server}__{tool},并规范化不兼容字符。宿主还要检查规范化后重名、API 名称长度、server/tool 绑定和重连重复注册。
动态闭包要保留每个 handler 的原始 server 与 tool,避免循环变量晚绑定导致所有 handler 指向最后一项。
外部元数据不是授权证明
MCP server 可以声明 readOnlyHint、destructiveHint,但宿主不能据此自动授权。课程由宿主维护精确的已知只读名单,其他 MCP 工具默认确认。
权限还要结合参数。名为 search 的工具可能向外发送查询,名为 read 的工具可能读取敏感数据。名称与注解只能辅助分类,不能替代宿主政策。
工具错误应回到循环
未知连接、无效参数、server 异常和不可序列化结果应转换成对应 tool_result。模型可以更正调用或解释问题,而不是让外部异常终止整个 Agent。
建议覆盖的测试
- 连接前后可见工具集合正确变化;
- 名称规范化、长度和冲突检查生效;
- 动态 handler 调用正确 server/tool;
- 外部注解不会绕过权限;
- 参数和 server 错误保持协议闭合;
- 断线、超时、重连行为明确。
小结
MCP 让 Harness 在运行时发现外部工具,而无需改写 Agent Loop。连接、命名、schema、超时和错误都由宿主管理,最终授权不能外包给 server 描述。