codex-workbuddy-mcp
by Aaperture
README.md
# codex-workbuddy-mcp
让 **Codex 负责规划和评审,WorkBuddy 负责本地开发与自测** 的独立 MCP 服务。
```text
需求 → Codex 规划和验收标准 → WorkBuddy 开发/自测
↓
交付 ← Codex 验收通过 ← 代码检查和独立验证
↓ 不通过
原 WorkBuddy 会话返工
```
使用本机 WorkBuddy 桌面版内置 CLI,通过 stdio MCP 暴露任务执行、查询、评审、续接和取消能力。参考 [LinHaiJ/workbuddy-mcp](https://github.com/LinHaiJ/workbuddy-mcp) 的 CLI 桥接设计,服务与任务管理由本项目实现,无需 DSH。参考项目许可证保留在 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
## 环境要求
- Node.js 22 或更新版本。
- 本机已安装并登录 WorkBuddy;已在 macOS / WorkBuddy 5.5.6 验证。
- 默认调用 `/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy`,可以用 `WB_CLI` 指定其他 **JavaScript CLI 启动脚本**。
当前实现面向 macOS,其他平台与 WorkBuddy 版本需另行验证。模型和账号可用性由 WorkBuddy 提供。
## 安装与接入
```sh
git clone git@github.com:Aaperture/codex-workbuddy-mcp.git
cd codex-workbuddy-mcp
npm ci --ignore-scripts
npm test
```
在 Codex 的 MCP 配置中添加以下内容,并将示例路径替换成实际绝对路径:
```toml
[mcp_servers.workbuddy_local]
command = "node"
args = ["/absolute/path/to/codex-workbuddy-mcp/src/server.mjs"]
startup_timeout_sec = 20
tool_timeout_sec = 30
[mcp_servers.workbuddy_local.env]
WB_CLI = "/Applications/WorkBuddy.app/Contents/Resources/app.asar.unpacked/cli/bin/codebuddy"
WB_MODEL = ""
WB_ALLOWED_ROOTS = '["/absolute/path/to/your/projects"]'
WB_STATE_DIR = "/absolute/path/to/codex-workbuddy-mcp/.state"
```
如果桌面客户端找不到 `node`,把 `command` 改成 `node -p 'process.execPath'` 输出的绝对路径。保存后重新加载 MCP 或重启客户端。[Codex 官方 MCP 配置文档](https://learn.chatgpt.com/docs/extend/mcp?surface=cli)
其他 MCP 客户端可参考 [mcp-config.example.json](mcp-config.example.json)。该文件包含占位路径,使用前需要修改。
## MCP 参数
| 环境变量 | 含义 | 默认值 |
| --- | --- | --- |
| `WB_CLI` | WorkBuddy 的 JavaScript CLI 启动脚本绝对路径 | macOS 应用内置脚本 |
| `WB_MODEL` | 默认模型 ID,填写当前账号可用的 ID | 留空,由 WorkBuddy 选择 |
| `WB_ALLOWED_ROOTS` | 允许提交任务的根目录,JSON 字符串数组 | 服务的当前工作目录 |
| `WB_STATE_DIR` | 任务状态、提示词和事件日志存放目录 | 当前目录的 `.state` |
参数在服务启动时读取,修改后重新加载 MCP。
### 指定默认模型
在 MCP 环境参数中填写:
```toml
WB_MODEL = "your-model-id"
```
- 新任务显式传入 `model` 时优先使用它;否则使用 `WB_MODEL`,均未设置时由 WorkBuddy 自行选择。
- 新任务选定的默认模型会写入任务记录,服务默认值变化不会改变已有任务。
- 续接未传 `model` 时继承原任务;显式传入时切换模型。
- 没有固定模型的旧任务交给 WorkBuddy 按原会话恢复。
`workbuddy_status` 不传 taskId 会返回当前 `defaultModel`;任务结果的 `model` 和 `modelSource` 表示实际选择与来源。`modelSource` 取值为 `request`、`server_default`、`inherited` 或 `workbuddy_default`。
MCP 不维护固定模型清单。可运行本机 CLI 的 `--help` 查看其列出的模型;账号权限与实际调用结果仍由 WorkBuddy 决定。
## 五个工具
| 工具 | 用途 |
| --- | --- |
| `workbuddy_start` | 提交规划、验收标准和工作目录,异步返回任务 ID |
| `workbuddy_status` | 查询状态、最终答复、工具轨迹、日志路径和评审 |
| `workbuddy_review` | Codex 提交独立验证证据,并记录 `request_changes` 或 `approve` |
| `workbuddy_continue` | 在原 WorkBuddy 会话中执行已记录的返工意见,返回新任务 ID |
| `workbuddy_cancel` | 终止任务和进程组,保留已生成文件供检查 |
`workbuddy_start` 必填参数是 `prompt`、`cwd`、`acceptanceCriteria`;`cwd` 必须是存在的绝对路径。
可选参数:`model`、`effort`、`timeoutSeconds`、`maxTurns`、`maxReviewRounds`。`effort` 支持 `minimal` / `low` / `medium` / `high` / `xhigh` / `max`,是否生效取决于 WorkBuddy 模型。
单次执行默认最多600秒和20个执行轮次;评审总轮数默认3(包含第一次),最多可设10。续接默认继承原参数,达到评审轮数上限后不会继续。
`status=succeeded` 表示 CLI 正常返回,**不等于测试或验收已经通过**。`review.verdict=approve` 才表示 Codex 已记录验收。服务器保存验证证据,但不自行判断自然语言要求是否满足。
## 在 Codex 中使用
可以这样发出任务:
> 使用 workbuddy_local:先制定方案与可验证标准,让 WorkBuddy 开发、自测。你读取实际文件和差异,独立验证关键测试;不通过就记录 request_changes 并续接,满足标准后记录 approve。失败、超时或模型请求停滞时,先检查已有产物再决定如何处理。
任务以 session ID 续接,避免全局 `--continue` 串任务。每次续接都保留原验收标准;同一目录或父子重叠目录的未完成任务不能同时启动。
## 本地诊断客户端
`scripts/call.mjs` 使用正式 MCP SDK 连接本项目服务,通过 JSON 文件传递工具参数:
```sh
node scripts/call.mjs workbuddy_start /absolute/path/to/task.json --wait
node scripts/call.mjs workbuddy_status /absolute/path/to/status.json
```
任务 JSON 示例:
```json
{
"cwd": "/absolute/path/to/project",
"prompt": "实现需求,运行测试并报告结果",
"acceptanceCriteria": ["功能满足规划", "相关测试通过"],
"timeoutSeconds": 600
}
```
查询 JSON 示例:`{"taskId":"工具返回的任务UUID"}`。`--wait` 保持连接到任务结束;连接断开时服务会中止未完成任务。
同一状态目录只允许一个服务进程。如果 Codex 已连接服务,请使用它暴露的 MCP 工具。独立诊断客户端可以配置其他 `WB_STATE_DIR`,但不同状态目录的任务锁不共享,不要向同一个代码目录并行派发任务。
## 执行边界与故障处理
- 使用 `spawn` 的参数数组和 `shell:false`,多行任务通过 stdin 传递。
- 限制日志大小并按 UTF-8 分块解析输出;识别错误结果,支持超时与进程组终止。
- 通过进程级设置允许 Read/Write/Edit/Glob/Grep/Bash,使用 `dontAsk` 模式,限制代理委托和消息类工具,并禁用其他 MCP。不会修改 WorkBuddy 的全局权限。
- 进程级关闭自动记忆与提取。WorkBuddy 自身仍会管理登录态、会话记录与运行日志。
- 工作目录检查限制派发入口,**不是操作系统沙箱**。允许的 Bash 与文件工具仍可能访问目录外路径;需要强隔离时应另加容器或系统沙箱。
- 正常关闭服务会停止子任务;强制杀死服务后,重启会把未完成记录标为 `interrupted`,需要先检查文件和可能遗留的进程。
- 没有自动选择备用模型的策略;调用方可以检查日志,再显式指定模型续接。
`.state` 含任务描述、代码输出与路径,默认不提交 Git。项目忽略本机环境文件、日志、密钥文件和依赖目录。
## 示例与验证
- [计算器示例](demo/calculator/README.md):四则运算、括号、小数、一元号、输入限制与错误处理。
- [Unicode slugify 示例](demo/slugify/README.md):规范化、Unicode字母/数字处理与CLI。
示例源码由 WorkBuddy 开发并自测,再由 Codex 检查和验证。公开仓库保留源码和规划,本机执行日志、账号信息与私有路径不发布。
MCP测试使用假的 CLI 检查协议、进程控制、默认模型透传、续接继承和评审状态;运行 `npm test` 验证。可分别在两个示例目录运行 `npm test` 验证示例。
## 贡献与许可证
欢迎通过 fork/PR 提交建议,主干由 **@Aaperture** 推送和合入,详见 [CONTRIBUTING.md](CONTRIBUTING.md)。仓库规则负责执行主干访问限制。
本项目使用 [Apache-2.0](LICENSE) 许可证。参考项目的 MIT 许可证与归属信息见 [THIRD_PARTY_NOTICES.md](THIRD_PARTY_NOTICES.md)。
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues