codemode-mcp
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 本地运行时
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues