Skip to main content
Glama
README.md
# codemode-mcp

把本地多个 stdio MCP server 聚合成 **一个** Cloudflare Code Mode `code` 工具。

Agent 不再面对一堆工具定义,只见一个 `code` 工具;模型在隔离 sandbox 里写代码,以 `codemode.<prefix>_<tool>(...)` 编排各 MCP server 的工具,中间结果留在 sandbox,不进入对话上下文。

```text
Agent ── 只见 1 个 code 工具 ──> http://localhost:8787/mcp
                                      │ sandbox: codemode.<prefix>_<tool>()
                                      ▼
                    桥 :9230(官方 MCP SDK,stdio ↔ Streamable HTTP)
                                      │  按 mcp.jsonc 拉起各 stdio server
                                      ▼
                     chrome-devtools-mcp ──> 你的 Chrome(--auto-connect)
                     @modelcontextprotocol/server-filesystem ──> 文件系统
                     ...任何 stdio MCP server
```

## 快速开始

要求:[Bun](https://bun.sh) 1.3+;连接本机 Chrome 需 Chrome 144+ 并在 `chrome://inspect/#remote-debugging` 开启远程调试。

```bash
bun install
bun run dev
```

`bun run dev` 会依次:读取 `mcp.jsonc`(首次运行自动从 `mcp.jsonc.example` 生成)→ 拉起各 stdio MCP server → 启动桥(:9230)→ 启动 wrangler dev(:8787)。`Ctrl+C` 一次清理全部子进程。

Agent / MCP 客户端接入:

```json
{
  "mcpServers": {
    "codemode": { "url": "http://localhost:8787/mcp" }
  }
}
```

也可用 [MCP Inspector](https://github.com/modelcontextprotocol/inspector) 图形化验证:`npx @modelcontextprotocol/inspector@latest`,Streamable HTTP 连接 `http://localhost:8787/mcp`,List Tools 应只见一个 `code`,其描述中包含各 server 的 `<prefix>_<tool>` 方法。

## 配置:mcp.jsonc

唯一需要编辑的文件(JSONC,支持注释;已被 .gitignore 忽略,可放心写个人配置):

```jsonc
{
  "mcpServers": {
    "chrome-devtools": {
      "command": "bun",
      "args": ["x", "chrome-devtools-mcp", "--auto-connect"]
    },
    "filesystem": {
      "command": "bun",
      "args": ["x", "@modelcontextprotocol/server-filesystem", "/data"]
      // "prefix": "fs"   // 可选,默认取名字首段:chrome-devtools -> chrome
    }
  }
}
```

- `command` / `args` / `env`:MCP 生态通用格式,与 Claude Desktop、opencode 等一致;
- `prefix`:sandbox 方法前缀(可选,默认取名字首段,前缀冲突会在启动时报错);
- 新增 server 无需改任何代码,重启 `bun run dev` 生效;
- 单个 server 启动失败只降级跳过(日志标明),不影响其余 server。

## 工作原理

| 文件 | 职责 |
| --- | --- |
| `mcp.jsonc` | MCP server 清单(唯一配置源,首次自动生成) |
| `scripts/dev.ts` | 本地编排:起桥 → 等就绪 → 起 wrangler,统一清理 |
| `scripts/bridge.ts` | 按 mcp.jsonc 拉起各 stdio server,在 :9230 以 `/mcp/<name>` 路径复用暴露为 Streamable HTTP,并提供 `GET /servers` 发现端点 |
| `scripts/load-mcp-config.ts` | JSONC 解析(微软 jsonc-parser)与 prefix 派生 |
| `scripts/demo-stdio-server.ts` | 演示用 stdio server(echo 工具),可从配置中移除 |
| `src/server.ts` | Worker 入口:聚合 + `codeMcpServer()` 包装 |
| `src/bridge-servers.ts` | Worker 侧:经 `/servers` 发现各 server,`listTools` 动态注册转发工具 |

几个设计要点:

- **为什么需要桥**:`codeMcpServer()` 只接受进程内 `McpServer` 实例,而 stdio MCP server(如 chrome-devtools-mcp)无法在 workerd 里 spawn。桥用官方 `@modelcontextprotocol/sdk` 做 stdio ↔ HTTP 协议转换,工具定义与执行全程走 MCP 协议。
- **动态发现**:Worker 不读配置文件,每次请求经桥的 `/servers` 端点获取列表再 `listTools` 注册——上游 server 升级新增工具后无需改动本项目。
- **JSON Schema → zod**:Worker(workerd)禁止 `eval`,故选用运行时直接构造 zod 对象的 [`@dmitryrechkin/json-schema-to-zod`](https://github.com/dmitryrechkin/json-schema-to-zod)(Cloudflare Workers 兼容)。
- **运行时分工**:bun 跑桥与编排(Node 环境),wrangler(workerd)跑 Worker;两者在 9230 端口以 HTTP 对话。

## 说明与限制

- 本项目是**本地链路**:`wrangler deploy` 部署到 Cloudflare 后,线上 Worker 无法访问 `127.0.0.1:9230` 的桥与本机 Chrome;如需远程部署,把桥跑在 Worker 可达的主机上并修改 `wrangler.jsonc` 的 `vars.MCP_BRIDGE_URL`。
- chrome-devtools 的 `--auto-connect` 依赖 Chrome 144+ 的远程调试开关(`chrome://inspect/#remote-debugging`);也可用 `--browserUrl` 指向传统 CDP 端口(`--remote-debugging-port`,Chrome 136+ 需配合非默认 `--user-data-dir`)。
- 在 TUN 透明代理环境下若 `bunx` 下载依赖失败(DNS 返回 IPv6 而 TUN 只接管 IPv4),给桥进程设置 `HTTPS_PROXY` 指向本地代理端口即可(`scripts/bridge.ts` 已默认注入 `http://127.0.0.1:7890`,可按需修改)。

## 依赖

- [Cloudflare Code Mode](https://github.com/cloudflare/agents)(`@cloudflare/codemode`)— 单 `code` 工具与隔离执行
- [chrome-devtools-mcp](https://github.com/ChromeDevTools/chrome-devtools-mcp) — 浏览器自动化
- [Model Context Protocol TypeScript SDK](https://github.com/modelcontextprotocol/typescript-sdk) — MCP 协议实现
- [jsonc-parser](https://github.com/microsoft/node-jsonc-parser) — JSONC 解析
- [Wrangler](https://developers.cloudflare.com/workers/wrangler/) — workerd 本地运行时