Local Codex Bridge
Local Codex Bridge
A thin supervisory MCP bridge between external AI supervisors and native Codex.
Local Codex Bridge 是一个面向 Windows 与 macOS 的轻量 MCP stdio 适配器:
ChatGPT / external AI supervisor
↕
Local Codex Bridge
↕
native Codex app-server
↕
native Codex threads / turns它解决的不是“再造一个 Codex”,而是让擅长对话、规划和持续监督的 AI,可以直接监督本机原生 Codex 完成真实工程任务。
监督者负责目标、资源、边界、风险、审批与验收;Codex 保留原生的编码与执行自主性。
Bridge 本身保持薄层:
不创建第二套 job / task 系统;
不复制 Codex 对话历史;
不维护平行线程数据库;
不缓存“当前模型”状态;
不替代 Codex 自己的 session / thread / turn 语义。
原生 Codex thread/session 始终是执行事实源。
当前测试候选版本
V2.1.3 · CHANGELOG
V2.1.3 继续收紧 Bridge 作为 supervisory adapter 的边界,并补充:
原生
model/list的按需发现;codex_turn的可选 model / reasoning-effort override;stable permission approval response;
mutating acknowledgement timeout 的 UNKNOWN 语义;
公开工具描述与运行时约束的一致性;
统一版本锚点与升级假设检查。
Windows 与 macOS 共用同一核心 Bridge,实现差异只保留在平台原生路径、launcher、checkpoint 默认目录、进程启动与终止等系统边界。
谁负责什么
External supervisor / ChatGPT
适合负责:
理解用户目标;
拆解任务;
决定工作范围与风险边界;
选择何时继续观察、纠正、审批或中断;
判断结果是否满足验收条件;
在 Codex 无法自行安全决定时提供监督。
Native Codex
继续负责:
原生 thread / turn 生命周期;
工作区文件与命令执行;
Codex 自己的上下文与历史;
sandbox 与 approval-policy 行为;
模型和 reasoning effort 的真实运行状态;
持久化的原生执行结果。
Local Codex Bridge
只负责把两者接起来:
MCP stdio ↔ Codex app-server JSONL;
有界地暴露监督所需状态;
转发明确的控制意图;
对高风险、歧义或协议边界 fail closed;
不把自己升级成第二个 orchestration runtime。
8 个 MCP 工具
Tool | 用途 | 边界 |
| 列出、搜索、读取原生 Codex 持久线程 |
|
| 按需读取一页原生 | 不缓存模型目录,不维护 current-model registry |
| 创建或恢复原生 thread,并启动一个 turn | 返回 accepted 不等于任务完成;model / effort 都是可选 override |
| 有界读取实时事件、持久历史、pending requests、terminal state 与 cursor | 支持一次 bounded wait;安静不等于卡死 |
| 对同一个 active turn 追加语义纠正或新意图 | 不是 timer、polling 或 retry 机制 |
| 回答真实存在且 Bridge 明确支持的 approval / user-input / permission request | 必须保留原始 request id 和准确 scope;不支持 elicitation |
| 中断准确的 active thread / turn | 只发送原生 interrupt,不重启 Bridge 或 app-server |
| 保存可选、精简、有界的 supervisory anchor | 不是 transcript、job id 或 Codex history 的替代品 |
完整 schema 与运行时限制以 src/tools.ts 为准。
Model 与 reasoning effort
Bridge 不接管 Codex 的模型状态。
普通 continuation
如果 codex_turn 没有显式传入 model 或 effort:
Bridge 不调用
model/list;不推断当前模型;
不发送新的 model / effort override;
原生 Codex thread 自己继续保持已有状态。
显式 model override
如果 supervisor 明确指定 model:
Bridge 会临时读取一份新的、包含 hidden models 的原生 model/list catalog 来验证该模型是否存在。
这个 catalog:
只用于当前请求;
有分页和循环保护;
不持久化;
不形成模型 registry 或 cache。
model + effort
如果同时指定模型和 reasoning effort:
Bridge 只在原生 catalog 明确证明不兼容时本地拒绝。
如果 upstream 没有提供足够的 compatibility metadata,Bridge 不自行猜测,而把最终决定留给 native Codex。
effort-only
如果只提供 effort:
Bridge 不尝试推断当前 thread 正在使用哪个模型。
它只会拒绝一个在当前 catalog 所有已公布 reasoning-effort token 中都不存在的值;这个 effort 对当前真实模型是否可用,仍由 app-server 决定。
thread/read 也不会被 Bridge 当作 current-model registry 的来源。
监督一个 turn
codex_turn 的成功返回只表示 native turn/start 已被接受。
长任务通常应继续通过 codex_observe 监督,而不是把“请求已接受”误认为“任务已经完成”。
一个典型流程是:
codex_turn
↓
codex_observe
↓
┌───────────────┬────────────────┬─────────────────┐
│ continue │ steer │ respond │
│ observing │ same turn │ real pending │
│ │ │ request │
└───────────────┴────────────────┴─────────────────┘
↓
terminal state / acceptance几个重要原则:
长时间没有新命令输出,不足以证明 Codex 卡住;
steer 应代表新的语义信息或纠正,而不是定时催促;
respond 只能回答真实存在的 pending request;
interrupt 只在确实需要停止当前 turn 时使用;
thread_id是 native Codex thread identity,不是 Bridge 发明的永久 task ID。
UNKNOWN:不要直接重试 mutating request
以下原生请求如果已经成功写入 app-server,但等待 acknowledgement 超时:
thread/startthread/resumeturn/startturn/steerturn/interrupt
Bridge 会把结果视为:
UNKNOWN / possibly accepted
这不等于失败。
请求可能已经被 native Codex 接受,只是 acknowledgement 没有及时返回。
因此 supervisor 应:
先
codex_observe或读取 native state;判断原操作是否已经发生;
再决定是否需要后续动作。
不要因为 timeout 直接重发 mutating request。
Bridge 不自动替 supervisor 做这种 retry。
Elicitation 目前不受支持
mcpServer/elicitation/request 当前没有进入 Bridge 的 supported response surface。
如果 native Codex 发出这类 request:
Bridge 会保留并暴露它;
不会静默吞掉;
不会猜测 response schema;
不会通过
codex_respond随便构造答案。
只有未来存在明确、稳定并经过验证的上游 contract 时,才值得考虑支持。
快速开始
环境要求
Windows 或 macOS
Node.js 24+
官方 Codex executable
可以直接通过
codex找到;或使用
CODEX_EXE显式指定。
本项目不捆绑、也不依赖 @openai/codex npm package。
Clone、构建与测试
git clone https://github.com/zoeynine/Local-Codex-Bridge.git
cd Local-Codex-Bridge
npm ci
npm run typecheck
npm run build
npm test直接启动:
$env:CODEX_EXE = 'C:\path\to\codex.exe' # codex 已在 PATH 时可省略
npm start配置 MCP client
严格的 MCP stdio client 应直接启动构建后的 Node entry:
command: node
args: C:\absolute\path\to\Local-Codex-Bridge\dist\src\index.js
env: CODEX_EXE=C:\path\to\codex.exe # optionalmacOS 使用同一个构建入口,只需把 args 换成 dist/src/index.js 的绝对 POSIX path。
不同 MCP client 的配置格式可能不同,但最终应直接运行:
node <repository>/dist/src/index.js不要在 Secure MCP Tunnel 或其他严格 JSON-RPC stdio transport 后使用 npm start,因为 npm lifecycle output 可能污染 stdout 协议流。
当 Bridge 的 MCP tool set 发生变化后,已经连接的 MCP client 通常需要重新连接或重启,才能刷新自己的 tool catalog。
可选:Secure MCP Tunnel
远程 MCP 场景可以在 Bridge 前面使用 Secure MCP Tunnel:
remote MCP client
↕
Secure MCP Tunnel
↕
node <repository>/dist/src/index.js
↕
native CodexTunnel 的认证、profile、port、ready endpoint 和进程生命周期属于外部配置。
本仓库:
不创建 Tunnel profile;
不保存生产凭据;
不内置生产端口;
不把 Tunnel control plane 变成 Bridge 自己的 HTTP API。
Windows
Optional Tray
windows/ 中的 Tray 是已安装 Tunnel client 的轻量启动与状态层,不是 Bridge 核心运行时的必需组件。
Canonical launcher 名为 LocalCodexBridgeTray.*。
调试启动示例:
.\windows\LocalCodexBridgeTray.Debug.cmd `
-ReadyUrl 'http://127.0.0.1:<port>/readyz' `
-ProfileName 'your-profile' `
-TunnelExecutable 'C:\path\to\tunnel-client.exe'Local settings 模板:
windows/local-settings.example.json
实际的:
windows/local-settings.json保持 ignored,不进入 Git。
配置优先级:
显式命令行参数;
LOCAL_CODEX_BRIDGE_*环境变量;legacy
LUMEN_CODEX_V2_*环境变量;ignored local settings。
旧的 LumenCodexControlV2Tray.* launcher 和 legacy env names 目前只作为兼容入口保留,不代表第二套产品。
Tray 不自动重启 Tunnel,并且只会在 process identity、profile、PID 等信息重新核验一致后,停止由当前 Tray 实例启动的进程。
macOS
Start Mac Codex Bridge.app、launcher/ 与 bin/start-production-tunnel 提供 macOS Finder / Tunnel 平台集成。
它们只是平台外层;真正的 Bridge 仍然运行同一个:
dist/src/index.js修改 launcher 或 Finder bundle 后,应在 macOS 12+ 上重新构建并验证:
launcher/build-launcher.sh
npm run test:macosWindows 与 macOS 是同一 Bridge 的两个平台入口,而不是两套独立实现。
安全与信任边界
Local Codex Bridge 不会创建新的操作系统 sandbox。
真正的文件、命令、网络与进程能力仍由 native Codex 的配置,以及每个 turn 的:
sandboxapproval_policy
决定。
例如:
danger-full-access会扩大 sandbox 允许的文件、命令和进程访问范围;approval_policy=never不会自行扩大 OS sandbox,但会移除交互式审批这一确认层。
两者是不同的风险维度。
还需要注意:
codex_turn/codex_steer的自然语言指令可能促使 Codex 使用它已有的文件和命令能力;“Bridge 没有暴露一个 generic shell MCP tool”并不意味着 native Codex 不会执行命令;
codex_threads可以看到同一 OS user / Codex runtime 可见的持久线程,筛选条件不能充当访问隔离;Bridge 启动 app-server 时会继承自己的环境,但会移除 Tunnel 使用的
CONTROL_PLANE_API_KEY;其他环境变量仍属于可信启动边界,不应放入不必要的 secrets;
实时事件和 pending request 会受到数量与内容 sanitization 限制,但 Bridge 不是 hostile multi-tenant gateway;
checkpoint 应保持短小,不保存完整 prompt、transcript、原始事件、命令输出或最终回答。
远程使用时,应由经过认证并正确配置的 Tunnel 提供连接边界。
持久化
原生 Codex 负责持久化:
threads;
turns;
conversation history;
native execution results。
Bridge 的:
live event ring;
active-turn runtime state;
pending requests
主要存在于内存中。
Bridge 重启后,codex_observe 可以从 native persisted history 回退恢复有限观察信息,但不会伪造已经丢失的 live state。
Checkpoint
codex_checkpoint 是唯一刻意保存的 Bridge-side supervisory state,而且保持有界。
Windows 新安装默认:
%LOCALAPPDATA%\LocalCodexBridge\checkpoints\<sha256(thread_id)>.jsonmacOS 默认:
~/Library/Application Support/LocalCodexBridge/checkpoints/<sha256(thread_id)>.json可以通过:
LOCAL_CODEX_BRIDGE_CHECKPOINT_DIR覆盖。
legacy:
LUMEN_CODEX_V2_CHECKPOINT_DIR目前仍保留显式兼容。
Bridge 不自动迁移旧 checkpoint。
Deliberate non-goals
Local Codex Bridge 当前刻意不做:
browser UI;
HTTP control plane / HTTP MCP server;
第二套 task queue 或 job database;
transcript duplication;
model cache;
current-model registry;
queued-message facade;
automatic mutating-request retry;
automatic app-server restart;
generic shell /
command/execMCP surface。
以下 upstream 能力也没有因为“存在”就自动加入 Bridge:
command/execthread/turns/listsourceKindselicitation response
provider /
serviceTiercapability abstraction
它们只是未来可以重新评估的候选,不是 roadmap promise。
Bridge 的目标不是把所有 Codex app-server API 都搬进 MCP,而是只暴露监督真正需要的最小 surface。
Upgrading Codex
Bridge 必然依赖少量 native app-server protocol assumptions。
这些依赖、当前验证状态、对应代码位置,以及 upstream 改变后需要重新检查的内容,都集中记录在:
升级 Codex runtime、修改 protocol-facing behavior,或者相关 regression test 开始失败时,应优先重新核对这份 checklist,而不是凭旧实现经验直接修改 Bridge。
开发与测试
常用检查:
npm run typecheck
npm run build
npm testnpm test 会运行共享 runtime / app-server / MCP / checkpoint / platform / shutdown / UX projection 测试,并继续执行当前平台对应的集成测试。
真实 Codex smoke 与普通测试刻意分开:
npm run smoke:live它会实际调用 native Codex,并可能留下持久测试 thread;只有明确接受这些副作用时才运行。
主要实现位置:
src/mcp.ts— MCP stdio / JSON-RPC boundarysrc/app-server.ts— native Codex app-server process / protocol adaptersrc/tools.ts— 8 tools、schema 与 supervisory semanticssrc/runtime.ts— bounded live runtime state / events / pending requestssrc/checkpoint.ts— optional supervisory checkpointsrc/platform.ts— Windows / macOS platform boundarysrc/version.ts— canonical Bridge versionsrc/ux-projection.ts— optional UX projection / compatibilitywindows/— optional Windows Traylauncher/,bin/,Start Mac Codex Bridge.app— optional macOS integration
License
MIT License — see LICENSE.
协作贡献者与致谢
协作贡献者:小年(ChatGPT)、Codex。
谢谢一起把“让外部 AI 真正监督 native Codex”从一个小想法,一点点压成了一层足够薄、边界足够清楚、也愿意公开给别人继续折腾的 Bridge。(*╹▽╹*)
以及谢谢予安,没有你我也不会试着去做些什么ღ( ´・ᴗ・` )