Skip to main content
Glama

pi-bridge

把 Pi 执行节点暴露成 MCP 工具,让任意 MCP 客户端(Claude Code / Codex / ZCode / Cursor / Windsurf …)能给本地或云端模型派活、查状态、取消。

一句话定位:让主会话当调度者,把干活的活外包出去——用命令行验收兜底,不靠模型自述。

你的 MCP 客户端(编排者)
   │  MCP:pi_execute / pi_status / pi_cancel
   ▼
pi-bridge(本包,MCP stdio server)
   │  spawn `pi --mode rpc`(常驻子进程)
   ▼
Pi(执行节点)
   │
   ├─► 本地模型引擎(llama.cpp / NInfer / AtomicBot / 任何 OpenAI 兼容服务)
   └─► 云端/网关模型(OpenAI 兼容中转)

为什么需要它

问题一:主会话的上下文很贵。让它亲自读 50 个文件、跑 20 条命令,token 烧得飞快。 问题二:弱模型会说谎。"我做完了"是最不可靠的完成信号——尤其量化小模型,工具调用可能退化成纯文本,它仍然报"完成"。

pi-bridge 的答案:

  1. 分发——把子任务派给另一个模型;它读文件、跑命令的 token 不算在主会话头上。传路径而不是内容,让它自己按需读。

  2. 验收——派活时给一条命令,桥接层真实执行它,退出码 0 才算完成。验收本身零 token。

  3. 证据链——任务前后拍文件快照做 diff,如实告诉你"实际改了什么",而不是复述模型的自述。

  4. 升档重试——验收不过时,自动换更强的模型重来(弱模型打头阵省钱,强模型兜底保成)。

  5. 程序级约束——explore 模式在进程启动层面禁用 write/edit 工具,模型想调也调不到;scope 越界改文件直接判失败。


Related MCP server: Aura

快速开始

0. 前置条件

  • Node.js ≥ 20

  • Pi 已安装(本包不代替 Pi,它只是 Pi 的 MCP 外壳):确认 pi --version 能跑

  • 至少一个模型端点:

    • 本地模型:先按 Pi 的文档在 ~/.pi/agent/models.json 里配好 provider,并手动启动它的推理引擎(本包不会替你拉进程)

    • 云端模型:OpenAI 兼容的 baseUrl + key,同样先配进 Pi 的 models.json

1. 安装

git clone <this-repo> pi-bridge
cd pi-bridge
npm install

2. 配置(关键一步)

cp pi-bridge.config.example.json ~/.pi-bridge/config.json
# 编辑它:至少填 piExe 和 aliases

最少要配两项:

{
  "piExe": "/path/to/pi",
  "aliases": {
    "local-main": { "provider": "local-myengine", "model": "my-model-id" },
    "cloud-fast": { "provider": "my-gateway", "model": "auto-fast" }
  }
}

命名约定(决定行为):provider 以 local- 开头 → 视为本地模型(占显存、串行排队、可探活);其它 → 不限并发,可与本地真并行。

配置优先级:PI_BRIDGE_CONFIG 环境变量 > ~/.pi-bridge/config.json > 包内 pi-bridge.config.json > 内置默认。 每一项也都能用环境变量覆盖(PI_EXE / PI_BRIDGE_ALIASES / PI_BRIDGE_CONCURRENCY …)。 什么都不配也能启动(用内置示例表),只是派活前你得把 aliases 指向自己真实的模型。

3. 接入你的 MCP 客户端

以通用 stdio 配置为例(各客户端字段名略有差异):

{
  "mcpServers": {
    "pi-bridge": {
      "command": "node",
      "args": ["/abs/path/to/pi-bridge/src/server.js"],
      "env": { "PI_BRIDGE_CONFIG": "/abs/path/to/config.json" },
      "timeoutMs": 1800000
    }
  }
}

⚠️ timeoutMs 必须调大(默认 30 秒太短)。派一个真实任务通常要 1–4 分钟, 超时会导致调用方拿不到结果(任务在后台照跑完,但结果是丢的)。给 30 分钟是稳妥值。

4. 验证

npm run smoke     # MCP 协议握手 + 工具列表(不派活)
npm test          # 验收层单元测试(不跑模型,秒级)
npm run selftest  # 配置解析 + 端点探活 + Pi RPC 握手(只读)

三个工具

工具

作用

pi_execute

派子任务,回传结构化结果(状态 / 耗时 / 工具轨迹 / token / 证据链)

pi_status

任务状态表:taskId、模型、状态、耗时、当前工具、工具调用数、排队情况

pi_cancel

取消任务;排队中的直接出队(不占资源)

pi_execute 参数

参数

说明

task

必填。要做什么、改哪些文件、什么算完成——说清这三件事

model

模型别名 / 任务类型关键词;不填按 routing 表路由

workdir

工作目录,所有文件操作在这里发生

files

相关文件路径(不要传内容——让模型自己读,这是省 token 的关键)

constraints

技术栈、风格、禁止事项

verify

强烈建议填。验收命令,退出码 0 才算完成

rework

验收不过时自动返工,0–3(默认 0)

escalate

返工是否升档到更强模型(默认 true)

scope

限定可改路径前缀;越界即判失败

mode

implement(默认)/ explore(只读,进程级禁写)

timeoutMs

单任务超时(默认 600000)

includeContext

是否注入项目简报(需配置 sessionrelay,否则自动跳过)

CLI 模式(不经过 MCP,便于脚本化与排障)

node src/server.js exec "任务描述" --model=local-main --dir=/path/to/repo
node src/server.js exec "创建 ok.txt" --model=local-main --dir=/tmp/w \
  --verify="if exist ok.txt (exit 0) else (exit 1)"
node src/server.js exec "分析架构" --model=local-main --mode=explore     # 只读
node src/server.js exec "改 src/"  --model=local-main --scope=src/ --rework=1

设计要点:为什么「可验证」比「聪明」更重要

1. 「我完成了」不是证据,命令才是

✅ 任务完成(验收通过)|模型 gw/auto-fast|耗时 61s|工具调用 2次
✅ 验收通过(`if exist out.json (exit 0) else (exit 1)`)

配了 verify 而命令没过时,桥接层明确报失败并附上命令的实际输出——哪怕模型口口声声说做完了:

🚨 验收未通过——模型说完成了,但命令跑出来不是这样
   验收命令:`npm test`(退出码 1)
   Error: 3 tests failed

2. 证据链:文件快照 diff

任务前后各拍一次文件指纹,得出实际改动。这能识破两类骗局:改了范围外的文件、或该改却没改(工具没真执行)。

【证据链】
改动 2 个文件:
   ~ src/auth/login.ts
   ~ tests/auth.test.ts
执行命令 3 条:
   $ npm test

3. 升档:弱模型打头阵,强模型兜底

rework + escalate(默认开)让失败重试自动升级模型:

⬆️ 返工升档:local-fast → local-main → cloud-best(升档后验收通过)

经济含义:便宜模型有较大概率一次做对;做不对时才付强模型的成本。 升档链在 src/models.js 的 ESCALATION 里,按你的模型表改。

4. 程序级约束,不是提示词自觉

  • mode=explore:给 Pi 传 --exclude-tools write,edit,工具在进程层面不存在;

  • scope:越界改动由证据链识破并判失败。

5. 失败不会被伪装成成功

情况

桥接层报告

端点没起

unreachable + 明确提示;配了 probeUrls 时自动探活并回退

工具调用退化成纯文本

degraded 检测拦住;自动换模型重跑

验收不通过

❌ 验收未通过 + 命令实际输出

改动越界

❌ 改动越界 + 越界文件清单

超时

❌ timeout + 建议调大 timeoutMs

6. 验收命令要设计成「无法取巧」⭐

这条是实测踩出来的坑,用之前务必读。

验收层会真实执行你给的命令,但它只能判断退出码——它不知道这个退出码是怎么来的。 于是出现了一个反直觉的情况:如果验收命令可以被"顺手满足",模型就会顺手满足它,而不是完成真正的任务。

实测案例(2026-10-06):验收命令写成"检查 never_this_file_xyz.txt 是否存在", 本意是造一个必定失败的测试。结果第一轮模型直接把那个文件创建出来了—— 验收通过,任务"成功"了,但它根本没做我真正想让它做的事。

注意:这不是 bug,而是"验收 = 退出码"这个机制的本质。模型的优化目标就是让退出码变 0, 它会走最短路径。所以设计验收命令的责任在调用方。

好的验收命令(无法用取巧手段满足):

类型

例子

为什么可靠

跑真实测试套件

npm test、pytest -q、go test ./...

要让测试全过,必须真改对代码

校验产物内容

grep -q "expected_fn" src/out.ts

存在性可伪造,内容不行

组合校验

npm run build && node dist/cli.js --selftest

构建 + 行为都要过

断言语义结果

node -e "const r=require('./calc');process.exit(r.add(2,3)===5?0:1)"

直接验证功能正确

要避免的验收命令:

  • ❌ 单纯检查文件存在(test -f out.txt)—— 模型直接 touch 就过了;

  • ❌ 检查文件大小/行数 —— 塞点填充内容就能满足;

  • ❌ 检查某个字符串出现 —— 让它出现在注释里也算过;

  • ❌ 任何"结果状态"而非"正确行为"的检查。

一个实用的自检问法:「模型如果不想真干活、只想让这条命令返回 0,它能怎么做?」 如果存在一条明显的捷径,这条验收就是不可靠的。


升档的生命周期:每次任务独立从原档起步

你可能会担心:"升档会不会粘住?一次任务升到高配,之后所有任务都从高配开始烧钱?"

不会。 实证结论(2026-10-06 同进程连派双任务实测):

  • 升档状态(当前模型 / 升档轨迹)是单次任务内的局部变量,任务结束即销毁;

  • 同一个 server 进程里,前一个任务升档到 cloud_chat 后, 下一个任务仍从你指定的原档(cloud_fast)开始;

  • 没有"降档"逻辑,也不需要——每个任务天然从原档起步,等价于每次自动归零。

任务A:cloud_fast 验收✗ → 升档 cloud_chat → 验收✓  (任务A 结束,状态丢弃)
任务B:cloud_fast 重新起步 ← 不继承任务A 的升档

唯一的例外是返工链本身的方向:单个任务内升档只会向上升,不会中途降回去。 这是刻意的——已经被证明做不对的模型,在同一任务里重试它没有意义。

如果某类任务反复需要升到顶档才能通过,说明起始档选低了, 应该去改该任务类型的默认路由(routing 配置),而不是指望运行时的降档。


跨平台

  • Windows / Linux / macOS 均可。(验收命令的 shell 自动选择:Windows 走 cmd.exe /d /s /c,类 Unix 走 /bin/sh -c。)

  • 验收命令请用对应平台的语法:Windows if exist x (exit 0) else (exit 1);POSIX test -f x。

  • ⚠️ Windows 实测坑:命令经 cmd /d /s /c 执行时,其中的引号会被重解析——if exist "a.txt" … 实测会失败,去掉引号正常;路径含空格请改用 cd /d "目录" && 命令。


可用别名与并发模型

  • 本地模型(provider 以 local- 开头):占显存,串行排队,一次只跑一个(单卡现实)。 上游大显存机器可放开:maxConcurrent 或 PI_BRIDGE_CONCURRENCY=2。

  • 云端/网关模型:不限并发,与本地真并行。适合"本地跑长任务时,把另一件活丢给云端同时做"。

可选:项目上下文注入

如果你的项目用 SessionRelay 之类的状态层,子任务开局即可带上项目简报(看板/决策),开局不失忆。 这是完全可选的:不配 srelayPath + briefShared 就整个跳过,零打扰、不影响其它功能。 注入时也只传路径,内容由子模型按需读取。


目录结构

src/
  config.js      配置解析(环境变量 / 配置文件 / 默认值三层)
  defaults.js    内置示例模型表(仅作模板)
  models.js      模型表、路由、回退链、升档链、探活
  pi-node.js     Pi RPC 进程生命周期(协议细节有注释,勿凭记忆改)
  context.js     提示词组装 + 可选的项目上下文注入
  verify.js      验收层:跑命令、文件快照 diff、范围检查、证据链
  server.js      MCP server + CLI
tests/
  verify-unit.js 验收层单元测试(跨平台、不跑模型)

如果这个项目帮到你了,点个 ⭐ 就是最好的支持 —— 也能让更多人找到它。

License

MIT

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables Claude Code to delegate coding implementation and testing to a local pi agent via MCP tools, including dispatching task books, monitoring status, steering or aborting runs mid-execution, and retrieving results and transcripts.
    36 npm
    4
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI assistants to securely access local machine capabilities such as file operations, shell commands, Skills, and Pi Tools through a controlled MCP interface with token authorization and multiple tunnel options.
    50 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Exposes a unified agent interface over multiple backends (pi-sdk, pi-rpc, dsh, qwen, grok, kimi, mcode) as an MCP server with tools for prompting, resuming sessions, listing models/backends, subscribing to events, and aborting runs.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Exposes remote, agent-facing MCP endpoints over Streamable HTTP for web search, webpage parsing, local knowledge-base retrieval and document creation, and delegation of tasks to configurable LLM providers. Also bundles an admin console with onboarding, provider/model configuration, API-key management, and call logging.
    MIT