本章从 s04 内核单独讲 MCP,不包含 Task System、后台任务、Cron、Agent Teams 或 Worktree;s15 才把外部工具与累计机制接到一起。

内置工具由 Harness 在启动时注册。MCP 把能力边界扩展到外部服务:连接 server、发现工具、转换 schema,再把 handler 动态加入模型下一轮可见的工具池。

connect_mcp("docs") → 发现工具 → mcp__docs__search → 下一轮工具池

课程使用进程内 Mock

s14 用 MCPClientconnect_mcpassemble_tool_pool 展示接入,但 server 是进程内模拟实现,没有真实 MCP stdio、HTTP 或鉴权传输。它解释动态发现,不是完整 MCP 客户端。

工具池每轮重新组装

模型初始只看到基础工具和 connect_mcp。连接成功后,下一次调用前组装基础工具与已连接 MCP 工具、基础 handlers 与动态 handlers。因此连接和使用发生在不同轮次。

名称规范化必须处理冲突

外部工具统一命名为 mcp__{server}__{tool},并规范化不兼容字符。宿主还要检查规范化后重名、API 名称长度、server/tool 绑定和重连重复注册。

动态闭包要保留每个 handler 的原始 server 与 tool,避免循环变量晚绑定导致所有 handler 指向最后一项。

外部元数据不是授权证明

MCP server 可以声明 readOnlyHintdestructiveHint,但宿主不能据此自动授权。课程由宿主维护精确的已知只读名单,其他 MCP 工具默认确认。

权限还要结合参数。名为 search 的工具可能向外发送查询,名为 read 的工具可能读取敏感数据。名称与注解只能辅助分类,不能替代宿主政策。

工具错误应回到循环

未知连接、无效参数、server 异常和不可序列化结果应转换成对应 tool_result。模型可以更正调用或解释问题,而不是让外部异常终止整个 Agent。

建议覆盖的测试

  • 连接前后可见工具集合正确变化;
  • 名称规范化、长度和冲突检查生效;
  • 动态 handler 调用正确 server/tool;
  • 外部注解不会绕过权限;
  • 参数和 server 错误保持协议闭合;
  • 断线、超时、重连行为明确。

小结

MCP 让 Harness 在运行时发现外部工具,而无需改写 Agent Loop。连接、命名、schema、超时和错误都由宿主管理,最终授权不能外包给 server 描述。

参考资料