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 大致可以这样设计:
- 在 extension factory 中读取
.pi/settings.json或 package 配置。 - 启动或连接 MCP server。
- 拉取 server 的 tool 列表。
- 为每个 tool 调用
pi.registerTool()。 - 在 tool
execute()中把参数转发给 MCP server。 - 把 MCP response 映射为
AgentToolResult.content/details。 - 用
pi.registerCommand("mcp", ...)提供管理命令。 - 用
pi.appendEntry()保存连接状态或授权信息。
这样的 adapter 不需要修改 agent-loop.ts,也不会污染低层 runtime。
设计启发¶
- 不要把“所有流行协议”都塞进核心;先确保核心有稳定的能力注册边界。
- 如果协议带有生命周期、权限、UI、配置和资源发现,它通常更适合放在插件层。
- 工具协议最终都应收敛到统一
AgentTool,这样 agent loop 不需要知道来源。 - “No MCP” 不是拒绝集成,而是拒绝把 MCP 作为核心抽象中心。