|
| 1 | +# codex CLI 直接通信能力研究 |
| 2 | + |
| 3 | +| 字段 | 内容 | |
| 4 | +|---|---| |
| 5 | +| 状态 | **research-only 完成** — 不动业务码,仅出方案 | |
| 6 | +| 提出 | 2026-05-13 | |
| 7 | +| 作者 | 通信SDK马 | |
| 8 | +| 任务来源 | Vincent telegram 3871 → 通信龙转单 | |
| 9 | +| 关联 | [Phase 1 SDK 升级 baseline](sdk-upgrade-2026-05-12-baseline.md) / [SDK-VERSION-DRIFT-MEMO](https://github.com/sleep2agi/agent-network/blob/main/docs/sdk-upgrade-2026-05-12-baseline.md) R39 已分析 `codex --config` inline 注入 | |
| 10 | + |
| 11 | +## 摘要 |
| 12 | + |
| 13 | +**TL;DR**:**codex CLI v0.128.0 完全支持 MCP server 注入**(命令行 + TOML config + spawn-as-server)。**anet 当前缺 `codex-code-cli` runtime 来利用这能力**。可用 ~50 行代码在 `agent-network/bin/cli.ts` 加 `codex-code-cli` runtime 类比 `claude-code-cli` 实现,让 codex CLI 直接接 commhub MCP 跟其他 agent 通信。 |
| 14 | + |
| 15 | +## 1. codex CLI MCP 注入能力(v0.128.0 实测) |
| 16 | + |
| 17 | +### `codex mcp` 子命令家族 |
| 18 | + |
| 19 | +``` |
| 20 | +codex mcp list # 列出当前注册 MCP servers |
| 21 | +codex mcp get <name> # 看具体 server 配置 |
| 22 | +codex mcp add <name> ... # 注册 MCP server |
| 23 | +codex mcp remove <name> # 卸载 |
| 24 | +codex mcp login / logout # OAuth flow (for hosted MCP servers) |
| 25 | +``` |
| 26 | + |
| 27 | +### `codex mcp add` 两种 transport |
| 28 | + |
| 29 | +**1. Streamable HTTP MCP**(远程,anet commhub 用这条): |
| 30 | + |
| 31 | +```bash |
| 32 | +codex mcp add commhub \ |
| 33 | + --url http://127.0.0.1:9200/mcp \ |
| 34 | + --bearer-token-env-var COMMHUB_TOKEN |
| 35 | +``` |
| 36 | + |
| 37 | +**2. Stdio MCP**(本地 spawn 子进程): |
| 38 | + |
| 39 | +```bash |
| 40 | +codex mcp add my-tool -- /usr/local/bin/my-mcp-server --flag value |
| 41 | +codex mcp add my-tool --env FOO=bar -- /path/to/bin |
| 42 | +``` |
| 43 | + |
| 44 | +### `codex --config` inline 注入(不污染磁盘 config.toml) |
| 45 | + |
| 46 | +```bash |
| 47 | +codex exec --config 'mcp_servers.commhub.url="http://127.0.0.1:9200/mcp"' \ |
| 48 | + --config 'mcp_servers.commhub.bearer_token_env_var="COMMHUB_TOKEN"' \ |
| 49 | + "你的 prompt" |
| 50 | +``` |
| 51 | + |
| 52 | +适合 wrapper 程序按 session 注入(同 R39 给 codex-sdk 提的方案,CLI 直跑版)。 |
| 53 | + |
| 54 | +### `codex mcp-server` — codex 作 MCP server |
| 55 | + |
| 56 | +``` |
| 57 | +codex mcp-server [OPTIONS] # Start Codex as an MCP server (stdio) |
| 58 | +``` |
| 59 | + |
| 60 | +让 codex **暴露**为 MCP server 让 Claude Code 或其他 host 调用。**反向能力,本研究不重点**(重点是 codex 作 client)。 |
| 61 | + |
| 62 | +### `~/.codex/config.toml` 的 MCP servers TOML 格式 |
| 63 | + |
| 64 | +```toml |
| 65 | +[mcp_servers.commhub-proxy] |
| 66 | +command = "bun" |
| 67 | +args = ["/path/to/proxy.ts"] |
| 68 | + |
| 69 | +[mcp_servers.commhub-proxy.env] |
| 70 | +COMMHUB_ALIAS = "my-agent" |
| 71 | +COMMHUB_URL = "http://127.0.0.1:9200" |
| 72 | + |
| 73 | +# 可选:per-tool approval policy |
| 74 | +[mcp_servers.commhub-proxy.tools.get_task] |
| 75 | +approval_mode = "approve" |
| 76 | + |
| 77 | +# 或 HTTP transport: |
| 78 | +[mcp_servers.commhub] |
| 79 | +url = "http://127.0.0.1:9200/mcp" |
| 80 | +bearer_token_env_var = "COMMHUB_TOKEN" |
| 81 | +``` |
| 82 | + |
| 83 | +--- |
| 84 | + |
| 85 | +## 2. v0.128 版本 MCP 成熟度 |
| 86 | + |
| 87 | +`codex mcp` 子命令家族(list/get/add/remove/login/logout)+ `mcp-server` + `--config` inline + TOML config 全套都在 v0.128。MCP 支持已经**生产级成熟**,不是实验性功能。 |
| 88 | + |
| 89 | +OpenAI codex MCP support 已落地多个 minor 版本(具体起始版本未细查,但 v0.128 已 stable)。 |
| 90 | + |
| 91 | +--- |
| 92 | + |
| 93 | +## 3. anet 现状:**没有 `codex-code-cli` runtime** |
| 94 | + |
| 95 | +### RuntimeName 定义(`agent-network/bin/cli.ts:133`) |
| 96 | + |
| 97 | +```ts |
| 98 | +type RuntimeName = \"claude-code-cli\" | \"codex-sdk\" | \"claude-agent-sdk\" | \"http-api\"; |
| 99 | +``` |
| 100 | +
|
| 101 | +**4 个 runtime,没 `codex-code-cli`**。 |
| 102 | +
|
| 103 | +### claude-code-cli runtime 实现(参考模板,`bin/cli.ts:1640-1680`) |
| 104 | +
|
| 105 | +```ts |
| 106 | +const claudeArgs: string[] = []; |
| 107 | +if (profile.flags.dangerouslySkipPermissions) claudeArgs.push(\"--dangerously-skip-permissions\"); |
| 108 | +for (const ch of profile.channels) { |
| 109 | + if (ch.startsWith(\"server:\")) claudeArgs.push(\"--dangerously-load-development-channels\", ch); |
| 110 | + else if (ch === \"telegram\") claudeArgs.push(\"--channels\", \"plugin:telegram@claude-plugins-official\"); |
| 111 | + else claudeArgs.push(\"--channels\", ch); |
| 112 | +} |
| 113 | +// session 续接 / --session-id / --resume 逻辑 |
| 114 | +claudeArgs.push(\"-n\", displayName); |
| 115 | +const child = spawn(\"claude\", claudeArgs, { env, stdio: \"inherit\", shell: true }); |
| 116 | +``` |
| 117 | +
|
| 118 | +anet 把 commhub MCP 注入到 claude CLI 是**通过 `--channels` 加自定义 channel 名 → claude 内部 `.mcp.json` mechanism**(plugin 体系)。 |
| 119 | +
|
| 120 | +### Vincent 自己已经在尝试(半成品) |
| 121 | +
|
| 122 | +Vincent 的 `~/.codex/config.toml` 里有: |
| 123 | +
|
| 124 | +```toml |
| 125 | +[mcp_servers.commhub-proxy] |
| 126 | +command = \"bun\" |
| 127 | +args = [\"/home/vansin/agent-orchestra/proxy/commhub-proxy.ts\"] |
| 128 | + |
| 129 | +[mcp_servers.commhub-proxy.env] |
| 130 | +COMMHUB_ALIAS = \"codex-硅谷\" |
| 131 | +COMMHUB_URL = \"http://127.0.0.1:9200\" |
| 132 | +``` |
| 133 | + |
| 134 | +但**该 proxy 文件 `agent-orchestra/proxy/commhub-proxy.ts` 不存在**(grep find 返回空)。这是 stale config — Vincent 早期尝试但没完成 / 后续删了。 |
| 135 | + |
| 136 | +**结论**:用户侧(Vincent)已经在手动试,但没产品化。anet CLI 不暴露 `codex-code-cli` runtime 让所有用户都能用。 |
| 137 | + |
| 138 | +--- |
| 139 | + |
| 140 | +## 4. POC 设计:给 anet 加 `codex-code-cli` runtime |
| 141 | + |
| 142 | +### 4.1 RuntimeName 扩展 |
| 143 | + |
| 144 | +```diff |
| 145 | +- type RuntimeName = \"claude-code-cli\" | \"codex-sdk\" | \"claude-agent-sdk\" | \"http-api\"; |
| 146 | ++ type RuntimeName = \"claude-code-cli\" | \"codex-code-cli\" | \"codex-sdk\" | \"claude-agent-sdk\" | \"http-api\"; |
| 147 | +``` |
| 148 | + |
| 149 | +### 4.2 normalizeRuntime 加分支 |
| 150 | + |
| 151 | +```diff |
| 152 | +function normalizeRuntime(profileOrRuntime?: Profile | string): RuntimeName { |
| 153 | + if (typeof profileOrRuntime === \"string\") { |
| 154 | ++ if (profileOrRuntime === \"codex-code-cli\" || profileOrRuntime === \"codex-cli\") return \"codex-code-cli\"; |
| 155 | + if (profileOrRuntime === \"codex\" || profileOrRuntime === \"codex-sdk\") return \"codex-sdk\"; |
| 156 | + // ... rest unchanged |
| 157 | + } |
| 158 | +} |
| 159 | +``` |
| 160 | + |
| 161 | +### 4.3 spawn codex CLI 路径(类比 claude-code-cli) |
| 162 | + |
| 163 | +新增 1640 行附近的 \"spawn claude CLI\" 之后一段 \"spawn codex CLI\": |
| 164 | + |
| 165 | +```ts |
| 166 | +// 新增:spawn codex CLI runtime |
| 167 | +if (runtime === \"codex-code-cli\") { |
| 168 | + const env: NodeJS.ProcessEnv = { |
| 169 | + ...process.env, |
| 170 | + COMMHUB_ALIAS: profile.alias, |
| 171 | + ...(token ? { COMMHUB_TOKEN: token } : {}), |
| 172 | + }; |
| 173 | + for (const [k, v] of Object.entries(profile.env)) { |
| 174 | + env[k] = v.replace(/^~/, home); |
| 175 | + } |
| 176 | +
|
| 177 | + const codexArgs: string[] = [\"exec\"]; |
| 178 | +
|
| 179 | + // inline 注入 commhub MCP — 不污染 ~/.codex/config.toml |
| 180 | + codexArgs.push(\"--config\", \`mcp_servers.commhub.url=\"\${commhubUrl}/mcp\"\`); |
| 181 | + codexArgs.push(\"--config\", \`mcp_servers.commhub.bearer_token_env_var=\"COMMHUB_TOKEN\"\`); |
| 182 | +
|
| 183 | + // 沙箱 / 危险模式 flag |
| 184 | + if (profile.flags.dangerouslyBypass) { |
| 185 | + codexArgs.push(\"--dangerously-bypass-approvals-and-sandbox\"); |
| 186 | + } |
| 187 | +
|
| 188 | + // 隔离 host 用户 codex config(per R8 SaaS 沙箱化建议) |
| 189 | + codexArgs.push(\"--ignore-user-config\", \"--ignore-rules\"); |
| 190 | +
|
| 191 | + // session 续接(codex resume) |
| 192 | + if (profile.session) { |
| 193 | + codexArgs.push(\"resume\", profile.session); |
| 194 | + } |
| 195 | +
|
| 196 | + const child = spawn(\"codex\", codexArgs, { env, stdio: \"inherit\", shell: true }); |
| 197 | + // ... pid file / exit handler 同 claude 路径 |
| 198 | +} |
| 199 | +``` |
| 200 | + |
| 201 | +### 4.4 anet setup 加 codex-code-cli 选项 |
| 202 | + |
| 203 | +```diff |
| 204 | + const runtimeSelections = await checkbox<RuntimeName>({ |
| 205 | + message: \"你需要哪些 runtime?\", |
| 206 | + choices: [ |
| 207 | + { name: \`claude-code-cli — Claude Code CLI\${...}\`, value: \"claude-code-cli\" }, |
| 208 | ++ { name: \`codex-code-cli — Codex CLI (实验性) \${isInstalled(versions.codex) ? \"(已就绪 ✅)\" : \"(需安装 codex CLI)\"}\`, value: \"codex-code-cli\" }, |
| 209 | + { name: \`claude-agent-sdk — Claude Agent SDK\`, value: \"claude-agent-sdk\" }, |
| 210 | + { name: \`codex-sdk — Codex SDK\`, value: \"codex-sdk\" }, |
| 211 | + ], |
| 212 | + }); |
| 213 | +``` |
| 214 | + |
| 215 | +### 4.5 minimal POC 命令 |
| 216 | + |
| 217 | +用户体验: |
| 218 | + |
| 219 | +```bash |
| 220 | +# 安装 codex CLI(必备) |
| 221 | +npm install -g @openai/codex |
| 222 | +
|
| 223 | +# 用 anet setup 配置 codex-code-cli runtime |
| 224 | +anet setup |
| 225 | +# 选 codex-code-cli |
| 226 | +
|
| 227 | +anet node create my-codex --runtime codex-code-cli |
| 228 | +anet node start my-codex |
| 229 | +
|
| 230 | +# 节点启动后 codex CLI 自动接 commhub MCP |
| 231 | +# 直接在 codex TUI 内可用 commhub tools: |
| 232 | +# send_task / get_inbox / get_all_status / etc |
| 233 | +# Codex 跟其他 agent 直接通信 ✅ |
| 234 | +``` |
| 235 | + |
| 236 | +### 4.6 实施量级估算 |
| 237 | + |
| 238 | +- `bin/cli.ts` 改动:~50-80 行 |
| 239 | +- 新 spawn 分支 + RuntimeName + normalizeRuntime + setup UI |
| 240 | +- 不动 agent-node / commhub-server |
| 241 | +- 风险:低(独立新 runtime,不影响现有 4 个) |
| 242 | + |
| 243 | +--- |
| 244 | + |
| 245 | +## 5. 跟 claude-code-cli runtime 对照 |
| 246 | + |
| 247 | +| 维度 | claude-code-cli | codex-code-cli(提议) | |
| 248 | +|---|---|---| |
| 249 | +| Binary | `claude` (npm @anthropic-ai/claude-code) | `codex` (npm @openai/codex) | |
| 250 | +| MCP 注入机制 | `--channels` flag + claude plugin 体系 | `--config 'mcp_servers.X.url=Y'` 或 `codex mcp add` | |
| 251 | +| Session 续接 | `--session-id` / `--resume` (uuid) | `codex resume <id>` (codex session UUID) | |
| 252 | +| 沙箱 | `--dangerously-skip-permissions` | `--dangerously-bypass-approvals-and-sandbox` | |
| 253 | +| host config 隔离 | claude CLI 自身管理 | `--ignore-user-config` + `--ignore-rules` | |
| 254 | +| Telegram channel | `--channels plugin:telegram@...` | codex 暂无 channel 体系(仅 MCP 接入)| |
| 255 | + |
| 256 | +--- |
| 257 | + |
| 258 | +## 6. Roadmap / 建议 |
| 259 | + |
| 260 | +### 优先级 |
| 261 | + |
| 262 | +**Medium-high**: |
| 263 | +1. codex CLI 用户基数大(Vincent 已经在用),加 anet 接入入口能让所有 anet 用户都用上 |
| 264 | +2. 跟 claude-code-cli 对称(用户从 \"我的 claude/codex 订阅\" 来选 runtime 更自然) |
| 265 | +3. 不需要重构现有架构,独立加分支 |
| 266 | + |
| 267 | +**实施时机**: |
| 268 | +- 单独 RFC(候选 RFC-006)+ 单独 PR |
| 269 | +- 不阻塞 SDK 升级 Phase 3 / RFC-003 telemetry / SaaS Skills mode 等其他议题 |
| 270 | +- 等 Vincent 排期 |
| 271 | + |
| 272 | +### 不建议优先做的子工作 |
| 273 | + |
| 274 | +- ❌ 不要先做 commhub-proxy.ts bridge(Vincent stale config 暗示的方向):HTTP MCP transport(commhub-server 直接支持)比 stdio proxy 更简单稳健 |
| 275 | +- ❌ 不要等 OpenAI 加更多功能(v0.128 MCP support 已足够) |
| 276 | + |
| 277 | +### 风险点 |
| 278 | + |
| 279 | +1. **codex 升级节奏**:codex CLI 0.128 → 0.130 12 minor 我们已验证 SDK 冻结,但 CLI 二进制可能 break flag。`codex --config` flag 出现于 0.x 哪个版本?需要 verify minimum codex CLI version。 |
| 280 | +2. **codex session 续接** semantics 跟 claude 不同(codex 是 thread.id,claude 是 session UUID)。POC 实施时需对齐 |
| 281 | +3. **commhub auth**:`--bearer-token-env-var COMMHUB_TOKEN` 假设 commhub 接受 Bearer,本研究没验证 commhub-server `WebStandardStreamableHTTPServerTransport` 是否要求特定 header 格式。Phase 实施时需 sanity check |
| 282 | + |
| 283 | +--- |
| 284 | + |
| 285 | +## 7. 跟 SDK 升级 Phase 3 + RFC-003 的关系 |
| 286 | + |
| 287 | +| 议题 | 跟本研究关系 | |
| 288 | +|---|---| |
| 289 | +| SDK 升级 Phase 3 codex-sdk 0.118→0.130 | 不冲突(不同维度:CLI vs SDK)| |
| 290 | +| RFC-003 节点遥测层 | 共享 — codex-code-cli runtime 也会享受 RFC-003 progress events | |
| 291 | +| SaaS skills mode | 不影响(SaaS 主要用 SDK runtime,CLI 是 dev/user 体验维度)| |
| 292 | +| Vincent 个人 codex-硅谷 config | 本研究可作为产品化路径 — Vincent 不用再维护私人 proxy | |
| 293 | + |
| 294 | +--- |
| 295 | + |
| 296 | +## 8. 输出建议 |
| 297 | + |
| 298 | +按 telegram 3871 \"research-only 不动业务码\" 守住: |
| 299 | + |
| 300 | +- ✅ 本 doc 落地 `docs/codex-cli-direct-comm-research.md` 后 push main |
| 301 | +- ❌ 不在本 round 改 `bin/cli.ts` 加 codex-code-cli runtime |
| 302 | +- ❌ 不发 npm |
| 303 | +- ✅ 等 Vincent / 通信龙 review + 决策: |
| 304 | + - **A. 加 codex-code-cli runtime**(独立 RFC-006 + 实施 PR) |
| 305 | + - **B. 不加,让用户自己配 codex MCP**(保留现状) |
| 306 | + - **C. 先文档化教用户怎么自配 codex CLI + commhub**(轻量妥协方案) |
| 307 | + |
| 308 | +--- |
| 309 | + |
| 310 | +## 状态变更 |
| 311 | + |
| 312 | +- 2026-05-13 codex CLI MCP 直接通信能力研究完成(通信SDK马)。等 Vincent / 通信龙 review + 决策路径 A/B/C。 |
0 commit comments