模型 / 数据集
nicobailon/pi-mcp-adapter avatar
nicobailon/pi-mcp-adapter

pi-mcp-adapter:用一个代理工具换掉上百个 MCP 工具定义

Token-efficient MCP adapter for Pi coding agent

1,473 个 Star339 个 ForkTypeScriptMIT
GitHub

秒懂

它是什么?
这个适配器把 MCP 服务器的工具定义压缩成一个约 200 token 的代理工具,服务器默认懒加载。它解决的是上下文窗口被工具描述吃掉的问题,代价是每次调用多一次往返,并且依赖元数据缓存。
适合谁用?
如果你的 Pi 会话经常在对话开始前就被 MCP 工具定义吃掉大半上下文,并且能接受多一次工具调用往返,这个适配器值得装;如果你需要模型直接看到全部工具签名并一次性并行调用,或者你的工作流依赖宿主配置被自动加载,它就不合适。装完先做两件事:运行 pi-mcp-adapter init 看它扫描到哪些宿主配置,再打开 /mcp 确认实际生效的是哪个文件;然后故意调用一个冷启动服务器,观察首次连接的延迟是否在你的容忍范围内。
能商用吗?
可以。MIT 是宽松许可证:你可以使用、修改并销售基于它的软件,只需保留版权和许可证声明。
还在维护吗?
在维护。仓库最近一次提交在 1 天前。
用什么语言写的?
主要是 TypeScript(依据 GitHub 的语言统计)。

以上回答依据项目的 GitHub 数据(最近同步于 2026年9月15日)和我们的分析,不构成法律意见。

开源项目深度解析

上下文窗口被工具定义吃掉,而不是被对话吃掉

README 引用了 Mario Zechner 的一篇帖子,标题是 why you might not need MCP。帖子的论点很直接:工具定义太啰嗦,单个 MCP 服务器可以消耗 10k 以上的 token,而且不管你这次用不用这些工具,这笔开销都要付。接几个服务器,对话还没开始,上下文窗口就没了一半。作者给出的建议是干脆不用 MCP,改写成简单的 CLI 工具。

这个项目的立场是折中:MCP 生态里确实有数据库、浏览器、API 这类现成能力,全部放弃不现实,但可以只暴露一个代理工具,把工具发现推迟到真正需要的时候。README 的说法是一个约 200 token 的代理工具替代上百个工具定义。目标用户是已经在用 Pi 编码代理、同时挂着多个 MCP 服务器的人。如果你的 Pi 只接了一个服务器、工具只有三五个,这个适配器带来的收益接近于零,反而多了一层间接调用。

两次调用完成一次工具使用:search、describe、call

机制上,适配器向模型只注册一个名为 mcp 的工具,参数是 search、tool、args 这类字段。模型先用 search 找到候选工具,比如 mcp({ search: "screenshot" }),返回的是工具名加描述加参数列表,README 里的示例输出是 chrome_devtools_take_screenshot 及其 format、fullPage 参数。确认之后再用 mcp({ tool: "chrome_devtools_take_screenshot", args: { format: "png" } }) 真正执行。README 把这总结为两次调用代替 26 个工具占据上下文。

服务器默认是懒加载的,也就是在你真正调用它的某个工具之前不会连接。这一点能成立,靠的是适配器缓存工具元数据:search 和 describe 不需要活的连接就能工作。这是一个明确的取舍。冷启动的服务器在第一次调用时会经历连接建立,延迟落在这一次调用上;而元数据缓存与真实服务器状态之间如果出现偏差,search 返回的内容就可能过时。文档没有说明缓存如何失效或刷新,这是采用前值得自己确认的地方。

args 参数接受 JSON 对象或 JSON 字符串两种形式。README 建议在模型能稳定处理对象时优先用对象形式,字符串形式保留给需要更简单 schema 的 provider。这个细节说明适配器面对的不是单一模型,兼容性成本被显式地留在了接口上。

安装、初始化与 /mcp setup 三条入口

安装命令是 pi install npm:pi-mcp-adapter,装完需要重启 Pi。

首次运行的行为取决于你机器上已有什么。如果已经有 .mcp.json 或 ~/.config/mcp/mcp.json,Pi 会直接使用,不需要额外配置;第一次打开 /mcp 时会看到一段说明,告诉你 Pi 检测到了哪个文件,以及 Pi 只会把适配器专属的覆盖项写进自己的文件。如果只有 Cursor、Claude Code、Codex 这类宿主专属配置而没有标准 MCP 文件,运行 /mcp setup 可以把它们导入 Pi,流程会展示发现了什么、让你挑选、并在写入前预览具体的文件改动。如果什么都没有,同样是 /mcp setup,选择项目级 .mcp.json 还是全局 ~/.config/mcp/mcp.json,然后搭一个最小配置、加入一个已知服务器、快速添加 RepoPrompt,或者查看适配器在本机发现了什么。

偏好终端的人可以在安装后运行 pi-mcp-adapter init,扫描宿主专属配置并把缺失的兼容导入写进 Pi agent 目录,默认是 ~/.pi/agent/mcp.json,设置了 $PI_CODING_AGENT_DIR 时则是 $PI_CODING_AGENT_DIR/mcp.json。

项目级配置的写法在 README 里有完整示例:mcpServers 下面一个 chrome-devtools 条目,command 为 npx,args 为 ["-y", "chrome-devtools-mcp@1.6.0"]。注意这里把版本号钉死在 1.6.0,这类固定版本号的写法在 MCP 服务器上很常见,好处是可复现,代价是要手动升级。

六层配置的优先级,以及禁用标记为什么不改写源文件

适配器读取的配置来源有明确顺序,后面的覆盖前面的:~/.config/mcp/mcp.json,然后是 ~/.agents/mcp.json,再是 ~/.agents/mcp/mcp.json,接着是 <Pi agent dir>/mcp.json,再是项目里的 .mcp.json,最后是 .pi/mcp.json。前三个是共享的、跨工具的文件,后三个属于 Pi 自己。README 特别说明 Pi 自己的文件不是额外的常规配置入口,它们存放 Pi 专属设置、兼容导入和适配器专属覆盖项。

禁用和启用命令的行为值得单独说。/mcp disable <server> 和 /mcp enable <server> 只把 disabled 字段持久化到项目本地的 .pi/mcp.json,也就是优先级最高的那一层。启用时会移除项目层的标记(如果更低的层本来就是启用的),必要时写入 false 来覆盖更低层的禁用。关键在于:即使生效的服务器来自共享的全局或项目文件、导入的宿主配置,或者 configPath,源文件都不会被改写,凭据也不会被复制。改动之后要运行 /reload,让已注册的工具面刷新。手工等价做法是在任意常规 MCP 配置里给服务器加上 { "disabled": true }。

这里有一个边界:通过 createMcpAdapter({ config }) 传进去的内存配置是隔离的,不读也不写这个项目覆盖文件,相应的命令在这种模式下不可用。如果你打算在代码里嵌入这个适配器,禁用管理这套交互是用不上的。

宿主配置发现默认关闭,这是刻意的

README 用了一段不小的篇幅讲宿主配置的发现策略。/mcp setup 和 pi-mcp-adapter init 会检测并展示宿主专属配置,但这些是兼容性输入,不是常规配置路径,也不会被自动加载。当 settings.hostConfigDiscovery 为 "off" 时,常规的 /mcp 面板不会扫描宿主专属文件。默认值就是 "off"。要显式选择加入回退发现,可以把 settings.hostConfigDiscovery 设为 "on",或者运行 pi-mcp-adapter init --discover-host-configs。还有一个 "prompt" 值,给那些想检测但不想激活的集成使用。

宿主配置的优先级低于所有共享来源和 Pi 自有来源。发现过程会报告来源路径、来源出处和同名冲突;文档明确说它从不写入外部宿主文件,也不会静默地从那些文件里启动命令。这个设计选择偏向保守,代价是首次使用时的便利性下降:你机器上明明有可用的 Cursor 或 Claude Code 配置,Pi 默认不会去用,得手动走导入流程。对于在意配置来源可审计的团队,这个默认值是对的;对于只想快点跑起来的人,会多一步。

Agent Plugins 与懒加载之外的失败面

适配器可以从 Agent Plugins 包加载 MCP 服务器,方式是在 settings.agentPluginPaths 里列出插件目录,例如 ["./plugins/acme-tools"],同时 mcpServers 可以是空对象。每个目录必须包含合法的 Agent Plugins 1.0 plugin.json。README 在这一点上被截断了,plugin.json 具体需要哪些字段、校验失败时是什么表现,从现有材料看不出来。如果你的团队用 Agent Plugins 分发内部工具,这块需要先自己验证。

真正的限制集中在懒加载和元数据缓存上。第一,search 依赖缓存而不是实时连接,服务器端新增或修改了工具,适配器未必立刻反映出来。第二,冷启动的服务器把连接成本压到第一次调用上,如果你的工作流是让模型先批量 search 再批量 call,延迟会集中爆发。第三,多一次往返意味着模型必须正确地把 search 结果映射到 tool 名称和参数,参数 schema 复杂时这一步会出错,README 对 args 支持对象和字符串两种形式,本身就是对这种不稳定性的让步。第四,如果你的场景是让模型一次性看到全部工具签名然后并行调用,代理模式天然做不到,因为模型在 search 之前不知道有哪些工具存在。

与「干脆不用 MCP」这条路线比,差在哪

README 提到的替代方案不是另一个适配器,而是 Mario Zechner 的建议:跳过 MCP,直接写简单的 CLI 工具。两者的差别不在功能,在成本结构。CLI 工具的描述可以写得非常短,参数通过命令行传递,模型只需要知道命令名和几个 flag,没有协议握手、没有服务器进程、没有工具元数据缓存这一层。代价是你得自己写这些工具,而且每个工具都要单独维护,跨项目复用靠的是命令行约定而不是配置合并。

这个适配器选择保留 MCP 协议的全部能力,把开销压到一次代理调用上。它适合已经有现成 MCP 服务器、不想重写的人;CLI 路线适合工具数量少、愿意自己动手、并且对上下文极度敏感的人。两条路线的分界大致是:如果你要接的是数据库、浏览器这类别人已经维护好的服务器,适配器的收益明显;如果你的需求只是几个固定的 shell 操作,写 CLI 更省事,而且没有缓存一致性问题。

维护成本、许可证与升级时要看的东西

许可证是 MIT,仓库未归档,最近一次推送在 2026-09-05,最近的发布是 v2.32.1(2026-09-01),往前是 v2.32.0 和 v2.31.0,间隔都在几天到一周。这个发布节奏说明项目处于活跃维护状态,同时也意味着配置格式和 settings 键有变动的可能。README 里出现的 settings 键至少有 hostConfigDiscovery 和 agentPluginPaths,升级前值得对照 release notes 确认这些键的语义有没有变。

MIT 许可证本身对商用和修改都很宽松,但它只覆盖这个适配器;你通过它连接的每个 MCP 服务器各有自己的许可证,导入宿主配置时也不会复制对方的凭据,这一点文档写得很清楚。至于适配器自身的依赖链和 Pi 的版本兼容范围,现有材料没有给出,需要自己看 package.json。

升级的实际成本主要在配置层:Pi 自有文件(~/.pi/agent/mcp.json 和 .pi/mcp.json)会随兼容导入和适配器专属设置变化,而共享文件(~/.config/mcp/mcp.json、.mcp.json)理论上不该被改写。如果你在多个项目里共用一份全局配置,升级后先跑 /mcp 确认生效来源,比直接改文件更稳妥。

编辑结论

如果你的 Pi 会话经常在对话开始前就被 MCP 工具定义吃掉大半上下文,并且能接受多一次工具调用往返,这个适配器值得装;如果你需要模型直接看到全部工具签名并一次性并行调用,或者你的工作流依赖宿主配置被自动加载,它就不合适。装完先做两件事:运行 pi-mcp-adapter init 看它扫描到哪些宿主配置,再打开 /mcp 确认实际生效的是哪个文件;然后故意调用一个冷启动服务器,观察首次连接的延迟是否在你的容忍范围内。

官方来源

  1. Issues
  2. License: MIT
  3. nicobailon/pi-mcp-adapter on GitHub
  4. README
  5. Releases
社区笔记

社区笔记