Pi 曾公开拒绝 MCP,一年后把它做成了内置扩展

开源AgentAI

2026 年 9 月 29 日发布的 Pi 0.99.0,把 codemode、tool search 和 MCP 支持合并为三个内置扩展。而在这之前,访问 pi.dev 首页看到的是一句立场相反的声明:Pi 不支持 MCP。团队在播客里不止一次表达对 MCP 的保留态度,Earendil 的工程师 Mario Zechner 也专门写过批评 MCP 的文章。一年时间,立场完全翻转,官方随后在《"You Said No MCP!"》一文中把反转的完整原因讲了一遍。对一个 11 万 star 的开源 Agent 来说,这样一份公开的决策复盘比版本号本身更有信息量。

Pi 仓库卡片

一年前说不,现在改口,官方给出两个理由

Earendil 把原因归为两类:世界变了,自己的底座也够了。

第一类是 MCP 自身的演进。Pi 团队跟踪 MCP 有一年时间,得出的判断写在博客里:今天的 MCP 已经不是昨天的 MCP。2026 年 7 月 28 日定稿的新版规范对协议核心做了自发布以来最大的一次重构,细节见下一节。

第二类是 Pi 自己的工具系统改造。官方提到,Pi 近几个月为 deferred tool loading(工具延迟加载)、会话中途系统消息、推理等级切换做了大量工作,工具系统有了足够细的元数据来标注"哪些工具给模型看、哪些只在沙箱里用"。官方还承认:MCP 本可以继续作为第三方扩展存在,甚至可以做成一个官方推荐的扩展。把它搬进内置,是团队重新讨论后的决定。用官方原话说,"拥抱一样东西,是影响它最好的方式"(We believe the best way to positively influence something is to embrace it)。

MCP 这一年:从有状态会话到无状态协议

2026-07-28 版规范最核心的变化,是协议层彻底无状态化。六个 SEP(规范增强提案)配合完成:initialize 握手删除,Mcp-Session-Id 会话头删除,协议版本、客户端信息和能力声明改为随每次请求的 _meta 字段携带。新增 server/discover 方法,客户端需要时可以主动拉取服务器能力。

维度2025-11-25 版2026-07-28 版
连接模型initialize 握手 + 会话 ID无握手、无会话,请求自包含
客户端信息连接时交换一次每次请求随 _meta 携带
部署要求粘性路由、共享会话存储普通轮询负载均衡即可
服务器→客户端请求依赖长连 SSE 流InputRequiredResult + requestState,任意实例可接续
扩展机制存在但无正式流程反向 DNS ID、独立版本、ext-* 仓库
长任务实验性核心功能Tasks 扩展:tasks/get、tasks/update、tasks/cancel
服务端 UI无MCP Apps:沙箱 iframe 渲染服务器下发的 HTML
工具 Schema受限完整 JSON Schema 2020-12,支持 oneOf、$ref
Roots/Sampling/Logging核心功能标注性弃用,至少保留一年移除窗口

官方给运维侧举的例子很具体:以前一台远程 MCP 服务器要跑在生产环境,需要粘性会话、共享 session store,网关还得做深度包检查;现在流量落在任意实例上都能处理,负载均衡靠 Mcp-Method 和 Mcp-Name 两个 HTTP 头就能路由,tools/list 的结果按服务器给的 ttlMs 缓存。授权部分也做了硬化,客户端必须按 RFC 9207 校验授权响应的 iss 参数,堵住一类 mix-up 攻击。

Pi 的接法:工具进沙箱,模型写代码调

Pi 0.99.0 的 changelog 把三个内置扩展讲得很具体。

mcp 扩展负责连接:支持 stdio 或 streamable HTTP 传输,带 OAuth;配置写在 mcp.json 里(全局生效,或项目信任后生效),也可以运行时用 pi.registerMcpServer() 注册;交互管理走 /mcp 命令和 pi mcp add|remove|list|login|logout 子命令。

codemode 扩展负责执行:模型写的 JavaScript 跑在 QuickJS 沙箱里,MCP 工具以函数形式被调用,可以在一段脚本里并行发起多个调用。数据管道也放宽了:bash 和 powershell 的结构化结果在沙箱里最多可拿 1 MiB(模型直接面对的输出仍限制在 2000 行、50KB 量级,超出保留首尾各 512 KiB)。这个设计的意图很明确:大数据量在沙箱里消化,摘要交给模型。

tool_search 扩展负责发现:没有预先声明给模型的工具,可以按需搜索出来再声明,避免一开机把几百个工具定义塞进上下文。

配套的是一套工具暴露元数据。0.99.0 给扩展工具 API 增加了 exposure 字段,共五档:

exposure效果
direct直接暴露给模型
model-only只给模型,codemode 不可见
codemode只在沙箱里可调用
deferred按需延迟加载
hidden完全隐藏

这套字段同时回答了博客里的一个反问:为什么不做没有 MCP 的 Codemode?因为工具需要能被标记为"只给沙箱"或"延迟加载",而这些标注此前在 Pi 的工具系统里表达不出来。此外还有 namespace、annotations、outputSchema 加 structuredContent、isError 结果、prepareLoadout(),以及供嵌套调用的 ctx.executeTool()(带 parentToolCallId 事件,调用链记录为有界的 nestedCalls)。

真正的论点:工具应该像 OpenAPI,别像堆在桌上的说明书

《"You Said No MCP!"》里分量最重的一段,是对当前 MCP server 生态的判断:很多 server 仍在为"把工具全部倒进上下文"的 harness 设计,靠在返回文本上做优化来省 token。Earendil 给出的方向写在博客里:MCP 应该更接近 OpenAPI 加智能工具发现,工具返回结构化数据,靠文档和描述可被发现。

论据来自 CLI。CLI 之所以对 agent 好用,在于模型可以用高效的 bash 语法把命令串起来;MCP 没有理由不能这样。Pi 的做法就是把工具暴露给 JS 沙箱,让模型像写脚本一样组合调用。官方提到 Codex 等 harness 也在走类似路线。

官方同样承认问题没有全部解决:即便有 codemode,MCP 在可组合性上仍然没有完全兑现("MCP doesn't fully deliver on this"),而按官方的归因,短板更多出在 server 侧的实现和各 harness 的接法,不在协议本身。

对普通开发者的实际影响

如果你在用 Pi:升级到 0.99.0 即获得全部三个扩展(当前的 0.99.1 顺带把默认 OpenAI Codex 模型切到了 GPT-6.1 Sol)。codemode 通过 defaultTools 配置里的 "+codemode" 或 --tools 参数启用,行为由 codemode.mode 和 codemode.inlineBudget 控制。分类器模型也可以从 codemode 脚本里调用:内置的 TypeSafe jev-latest,或任意 llama.cpp 模型。官方给的示例场景是用 Linear MCP 加 Jev 分类器,从 issue tracker 里找出最沮丧的 20 个评论者。

如果你在写 MCP server:这篇博客传递了两个明确信号。第一,返回结构化数据(structuredContent),减少装饰性文本,harness 侧的沙箱会直接消费你的数据;第二,把工具描述写清楚,tool_search 这类按需发现机制靠它工作。另外尽快适配 2026-07-28 的无状态语义,部署侧的收益(去掉粘性会话和共享存储)只有客户端和服务器同时升级才能兑现。

如果你只是关注 Agent 工具链:一个拒绝过 MCP 的团队最终以"内置 + 沙箱编排"的方式接入,等于给"工具元数据 + 代码级组合"这套模式背书。小 harness 各自手写工具胶水层的阶段,可能正在过去。

结尾

0.99.0 发布当天,Pi 跟进了 0.99.1。仓库 star 数 110,698(9 月 30 日 GitHub API 数据),这条 HN 帖子拿到 402 分、217 条评论。从首页声明不支持,到内置三个扩展并写出一篇完整复盘,Pi 用一年时间完成了一次有据可查的立场反转,过程全部留在了公开记录里。

来源