ai-bridge:把本机多个 AI 编程 CLI 收成一个 MCP 调度台

发布于 2026-10-27MCP · 多 Agent · 工程实践

一句话:它把本机安装的 12 个 AI 编程 CLI(qoder / codely / opencode / workbuddy / atom-code / claude-code …) 收成 4 个 MCP 工具 + 一套 HTTP API,让任何支持 MCP 的客户端都能把任务派给它们,并带自动降级。

一、为什么需要它

本机同时装着好几个 AI 编程工具,各有各的登录态、参数和输出格式。真正干活时的痛点是:

  • 切换成本:同一个任务想在 2–3 个工具上跑一遍对比,得手工复制粘贴;
  • 长任务占会话:一个重构任务跑 10 分钟,主会话就干等着;
  • 能力差异:Qoder 的订阅额度、OpenCode 的免费模型、Codely 的别名池,各有各的强项;
  • 故障转移:某个 CLI 登录失效时,希望自动换下一个,而不是整条链路失败。

ai-bridge 就是这一层的粘合剂:统一入口、并行分发、自动降级、结果回收。

二、架构

MCP 客户端(qidicode / Claude Desktop / 任意 MCP Host)
        │  stdio(bridge-stdio.js)
        ▼
ai-bridge Hub  ── 127.0.0.1:9800(只绑本机,Bearer Token 鉴权)
        │
        ├─ qoder        (qodercli -p)
        ├─ codely / codely-k3
        ├─ opencode / opencode-flash / opencode-k3 / opencode-m31free
        ├─ workbuddy    (codebuddy -p)
        ├─ atom-code    (GLM)
        ├─ claude-code
        └─ agnes-mcp / openclaw

三个关键文件:

  • tools.json:工具注册表(命令、参数模板、别名、描述);
  • switches.json:每个工具的启停开关,持久化;
  • clients-acl.json:允许接入的 MCP 客户端。

三、4 个 MCP 工具

工具作用参数
list_tools列出工具与可用/开关状态—
list_switches只看开关(更简洁)—
toggle_tool开/关某个工具(持久化)tool, enabled
dispatch把任务分发给一个或多个工具task, tools[](空=全部已开启)

四、HTTP API(不走 MCP 也能用)

# 鉴权:Authorization: Bearer $AI_BRIDGE_TOKEN
curl -s http://127.0.0.1:9800/api/tools      -H "Authorization: Bearer $AI_BRIDGE_TOKEN"
curl -s http://127.0.0.1:9800/api/health     -H "Authorization: Bearer $AI_BRIDGE_TOKEN"
curl -s http://127.0.0.1:9800/api/stats      -H "Authorization: Bearer $AI_BRIDGE_TOKEN"

# 派活(缺 task 会返回 400 {"error":"缺少 task 参数"})
curl -s -X POST http://127.0.0.1:9800/api/dispatch \
  -H "Authorization: Bearer $AI_BRIDGE_TOKEN" -H "Content-Type: application/json" \
  -d '{"task":"给 utils.py 补 8 个边界用例","tools":["qoder","opencode-flash"]}'

# 异步任务的查询
curl -s http://127.0.0.1:9800/api/task/ -H "Authorization: Bearer $AI_BRIDGE_TOKEN"

Python 调用同样简单:

import json, os, urllib.request as u

TOKEN = os.environ["AI_BRIDGE_TOKEN"]
req = u.Request("http://127.0.0.1:9800/api/dispatch",
                data=json.dumps({"task": "写一个 LRU 缓存", "tools": ["codely"]}).encode(),
                headers={"Authorization": "Bearer " + TOKEN,
                         "Content-Type": "application/json"})
print(json.loads(u.urlopen(req, timeout=300).read()))

五、自动降级

dispatch 会按 tools.json 的注册顺序扫描可用工具。实测:当 Qoder 未登录(返回鉴权错误)时, 链路会自动落到下一个可用工具(例如 opencode-flash),整条请求仍然成功。 这就是"一台机器上多个订阅互补"的价值——任何一家掉线都不至于卡死。

六、和「子代理」不是一回事(重要)

维度ai-bridge dispatch原生子代理(spawn)
本质把任务交给外部 CLI宿主内置的父子会话
上下文不共享,只收最终文本独立但受宿主管理
生命周期Hub 管理,可异步查询父会话管理
工具面由对端 CLI 决定宿主投影

所以它不能当作"嵌套子代理"用:没有父子链、没有深度约束、也拿不到对端的中间过程。 它的定位是委派:适合"这件事交给另一个 CLI 干完给我结果"。

七、踩坑清单

  1. Qoder 的 CLI 与桌面 IDE 是两个应用,登录态独立——IDE 登了不代表 qodercli 登了;
  2. 长文本必须走 stdin:arg 模式传多行任务会被截断(实测丢行),适配器已改为 stdin 传参;
  3. 结果有截断(约 2000 字符):要完整报告就让对方写文件,再从文件读;
  4. Hub 别用 shell 的 Start-Process 拉起:会被父进程的 Job Object 连带杀掉;用 WMI Win32_Process.Create 或注册服务;
  5. 空返回等于失败:dispatch 无内容时按失败处理,别默认成功;
  6. 只绑 127.0.0.1:它是本机服务,不要暴露到局域网/公网(Token 只是最后一道闸)。

八、我们的实测数据

/api/stats 累计(截至 2026-10-27):

  • 15,178 次调用,输入 37.75 亿 token、输出 171 万 token;
  • 调用量前列:opencode 系、atom-code、qoder、workbuddy;
  • 单次任务耗时从 20 秒(短问答)到 10+ 分钟(整文件重构)不等。

这些数字说明它已经在日常承担真实工作量,而不是玩具。

九、适合与不适合

适合不适合
把长任务外包给另一个 CLI,主会话继续干别的需要共享上下文的连续对话
同一任务多工具并行,比较产出质量需要严格权限边界的敏感操作
某家额度用完时自动切换把它当"更深一层的子代理"
批量/定时任务(配合脚本)需要实时流式反馈的交互

小结

多 AI 工具并存的现实不会消失,与其在它们之间手工搬运,不如做一层协议化的调度: MCP 负责接入、Hub 负责分发、注册表负责能力声明、自动降级负责可用性。 这套东西不复杂,但它把"我有好几个工具"变成了"我有一个会用工具的系统"。

← 返回技术博客