MCP 与集成取舍

Pi 当前没有内置 MCP。这个结论来自源码和文档:packages/coding-agent/README.md 的 Philosophy 部分明确写了 “No MCP”,并建议通过 CLI tools + README/Skills,或者通过 extension 自己实现 MCP support。

本章涉及的 README 依据、扩展落点和 RPC 集成行号见源码索引

这不是能力缺失,而是边界选择

Pi 的取舍是:

  • 核心不内置 MCP client/server。
  • 核心提供足够强的 extension API。
  • 具体工作流,例如 MCP、sub-agent、plan mode、permission popup、todo、background bash,都可以由扩展或包实现。

这和很多 agent 产品不同。很多产品会把 MCP 做成内置协议层;Pi 则把它视为“可安装能力”,不让核心 runtime 对某个外部协议产生结构性依赖。

Pi 已经具备的集成基座

虽然没有内置 MCP,但 Pi 有几类很适合承载 MCP adapter 的接口:

Pi 接口 可承载的 MCP 类能力
registerTool() 把 MCP server 的 tools 暴露成 AgentTool
resources_discover 把外部资源路径转成 skills/prompts/themes/context resources
before_provider_request 注入 provider 请求层 metadata/header
context 在发给模型前注入或裁剪外部上下文
ExtensionUIContext 给 MCP 授权、选择 server/tool 等提供 UI
appendEntry / custom 持久化 MCP adapter 状态
registerCommand() 提供 /mcp 管理命令

也就是说,Pi 没有 MCP 内核,但具备把 MCP 作为扩展接入的工程基础。

为什么可能不内置 MCP

从代码结构看,Pi 的核心目标是保持 agent runtime 简洁:

  • agent-loop.ts 只认识 AgentTool,不认识工具来自哪里。
  • AgentSession 管理工具 registry,但不绑定工具协议。
  • ExtensionRunner 统一处理扩展工具、扩展命令和 provider 注册。
  • ResourceLoader 已经有项目/全局/package 资源发现。

如果把 MCP 直接塞进 core,会带来额外复杂度:

  • server 生命周期管理。
  • transport/auth 配置。
  • tool schema 转换和冲突处理。
  • 权限与信任边界。
  • 资源与 prompt 的协议映射。
  • 错误恢复和 UI 管理。

这些更像产品工作流,不像低层 agent loop 的职责。

CLI Tools + Skills 的路线

Pi README 建议的一种替代方式是“CLI tools with READMEs”。在 Pi 的系统提示和 skills 机制中,模型可以读取工具说明,再用 bash 执行外部 CLI。

优点:

  • 工具可被人类和 agent 同时使用。
  • 不需要额外协议桥接。
  • 权限边界清晰:它就是本地命令。
  • 文档可以直接成为 skill 或项目上下文。

缺点:

  • 不如 MCP 工具发现自动化。
  • 交互式授权和结构化资源暴露需要自己设计。

通过扩展实现 MCP 的可能形态

一个 MCP extension 大致可以这样设计:

  1. 在 extension factory 中读取 .pi/settings.json 或 package 配置。
  2. 启动或连接 MCP server。
  3. 拉取 server 的 tool 列表。
  4. 为每个 tool 调用 pi.registerTool()
  5. 在 tool execute() 中把参数转发给 MCP server。
  6. 把 MCP response 映射为 AgentToolResult.content/details
  7. pi.registerCommand("mcp", ...) 提供管理命令。
  8. pi.appendEntry() 保存连接状态或授权信息。

这样的 adapter 不需要修改 agent-loop.ts,也不会污染低层 runtime。

设计启发

  • 不要把“所有流行协议”都塞进核心;先确保核心有稳定的能力注册边界。
  • 如果协议带有生命周期、权限、UI、配置和资源发现,它通常更适合放在插件层。
  • 工具协议最终都应收敛到统一 AgentTool,这样 agent loop 不需要知道来源。
  • “No MCP” 不是拒绝集成,而是拒绝把 MCP 作为核心抽象中心。