xcode-mcp-bridge
by qianshang
README.md
# Xcode MCP Bridge
[](LICENSE)
[](https://github.com/qianshang/xcode-mcp-bridge/stargazers)
让 Xcode 的 `mcpbridge` 以**唯一进程**长期稳定驻留,通过 HTTP/SSE 暴露给任意 MCP 客户端(如 WorkBuddy、Claude 等),消除反复授权弹窗。
## 背景:解决的两个问题
Xcode 自带的 `mcpbridge` 有两个缺陷,本桥针对性地修复:
| # | mcpbridge 缺陷 | 桥的解法 |
|---|---|---|
| 1 | 对 `2025-06-18` 协议的 `initialize` 响应后会**主动退出**(exit 0) | 桥启动时用 `2024-11-05` 协议自初始化并缓存能力;客户端发来的 `initialize` 由桥**本地应答**(回显客户端协议版本),`mcpbridge` 进程永不退出 |
| 2 | 不认识 `ping`(返回 `unknown method 'ping'`) | 桥**本地应答** `ping`,不转发 |
**效果**:`mcpbridge` 进程永不换 PID → Xcode 只授权一次 → 不再反复弹窗。
## 特性
- 🔌 **单例 SSE 桥**:一个 `mcpbridge` 子进程服务多个 SSE 客户端连接
- 🪶 **零依赖**:仅使用 Node 内置模块(`http` / `child_process` / `crypto`)
- 🔁 **常驻自愈**:launchd `KeepAlive` 自动重启;手动模式可搭配 watchdog
- 📍 **位置自适应**:所有脚本路径由自身位置推导,clone 到任意目录直接可用
## 工作原理
```
MCP 客户端 (WorkBuddy / Claude / 其他)
│ HTTP + SSE (127.0.0.1:3811)
▼
┌──────────────────────────────────────┐
│ single-sse-bridge.js │ ← 本地应答 initialize / ping
│ (Node,零第三方依赖) │ 转发其余 JSON-RPC
└──────────────────┬───────────────────┘
│ stdio (JSON-RPC 2.0, 协议 2024-11-05)
▼
┌──────────────────────────────────────┐
│ Xcode mcpbridge 子进程(唯一) │ ← 永不换 PID
└──────────────────────────────────────┘
```
握手流程:
1. 桥启动 → 用 `2024-11-05` 协议向 `mcpbridge` 发送 `initialize` 并**缓存**能力/服务信息
2. 桥向 `mcpbridge` 发送 `notifications/initialized`(协议要求,否则它不处理请求)
3. 客户端连上 `/sse` → 客户端发 `initialize` → **桥本地应答**(回显客户端协议版本)
4. 客户端发 `ping` → **桥本地应答** `{}`
5. 其余请求(`tools/list` 等)→ 转发 `mcpbridge`,响应按 JSON-RPC id 回路由到对应会话
## 目录结构
```
xcode-mcp-bridge/
├── src/
│ └── single-sse-bridge.js # 桥主程序(零依赖)
├── scripts/
│ ├── install.sh # 注册 launchd 常驻服务(推荐)
│ ├── start.sh # 手动启动(nohup 后台)
│ ├── stop.sh # 停止
│ ├── status.sh # 健康检查
│ └── xcode-mcp-bridge-watchdog.sh # 手动模式看门狗(每 8s 自愈)
├── launchd/
│ └── com.user.xcode-mcp-bridge.plist # launchd 模板(占位符,install.sh 渲染)
├── logs/ # 运行日志(已被 .gitignore 忽略)
├── package.json # 元数据 + npm scripts(无第三方依赖)
├── CHANGELOG.md
└── README.md
```
## 环境要求
- macOS(需 Xcode,含 `Contents/Developer/usr/bin/mcpbridge`)
- Node.js **>= 18**(推荐 LTS 20;脚本自动探测 `node`,兼容 nvm)
## 快速开始
### 0. 获取代码
```bash
git clone git@github.com:qianshang/xcode-mcp-bridge.git
cd xcode-mcp-bridge
```
### 1. 安装(launchd 常驻模式,推荐)
```bash
bash scripts/install.sh
```
脚本会自动完成:探测 node 绝对路径 → 渲染 plist 到 `~/Library/LaunchAgents/` → `launchctl bootstrap` → 健康检查。
### 2. 验证
```bash
curl http://127.0.0.1:3811/healthz # 期望输出: ok
bash scripts/status.sh # 期望输出: bridge OK
```
### 3. Xcode 侧配置(两步 GUI)
1. **Xcode > Settings > Intelligence > Model Context Protocol**,打开 *"Allow external agents to use Xcode tools"*
2. 首次连接时,Xcode 弹出的权限对话框点 **Allow**(之后不再反复弹窗)
### 4. 在 MCP 客户端中接入
SSE 端点:`http://127.0.0.1:3811/sse`
## 常用命令
| 命令 | 说明 |
|---|---|
| `bash scripts/install.sh` | 注册 / 重装 launchd 常驻服务 |
| `bash scripts/start.sh` | 手动启动(后台 nohup) |
| `bash scripts/stop.sh` | 停止 |
| `bash scripts/status.sh` | 健康检查 |
| `nohup bash scripts/xcode-mcp-bridge-watchdog.sh &` | 手动模式自愈看门狗 |
> 说明:`start.sh` / `watchdog.sh` 通过 `NODE=/path/to/node` 环境变量可指定 Node 可执行文件。
## 常见问题
**Q: healthz 返回 DOWN?**
A: 先确认 Xcode 已打开;再查看 `logs/bridge.log`。launchd 模式下若持续失败可运行 `bash scripts/start.sh` 观察输出。
**Q: 端口被占用?**
A: `lsof -i :3811` 查看占用进程,确认没有旧桥进程残留后重启。
**Q: 仍反复弹授权框?**
A: 确认只有一个桥进程(`bash scripts/status.sh` 正常 + `pgrep -f single-sse-bridge` 仅 1 个)。多个桥进程会导致 `mcpbridge` 换 PID。
## 开源许可
[MIT](LICENSE)
## 贡献
欢迎提交 [Issue](https://github.com/qianshang/xcode-mcp-bridge/issues) 与 [PR](https://github.com/qianshang/xcode-mcp-bridge/pulls)。