Give Claude Code a gpt subagent, backed by the Codex CLI you already have installed.
Ask the gpt agent to review src/auth.ts for race conditions
It renders as a normal subagent — its own box, its own context, a progress display, a completion notification. The inference happens on OpenAI's side.
Claude Code's agent runner only instantiates Claude models. model: in an agent definition takes opus, sonnet, haiku, fable, or inherit, and nothing else. But a model calls tools, and a tool is just a process — what sits behind it is opaque to the caller. This bridge routes a subagent through the local Codex CLI.
Useful for:
- Second opinions. A different model family finds different bugs.
- Cross-model review. Have GPT review Claude's work, or the reverse.
- Side-by-side comparison on the same prompt, in the same repo, with the same files in front of both.
Install and log into the Codex CLI first. This is not optional and the plugin cannot check it for you: it declares an MCP server that runs codex mcp-server, and if that binary is missing or unauthenticated the server never starts. The agent's tools then resolve to nothing and Claude Code refuses to spawn it, with an error that says nothing about Codex:
Agent 'codex-bridge:gpt' would be spawned with zero tools — refusing.
If you see that, this is why.
| Claude Code | claude on PATH |
| Codex CLI | codex on PATH, and logged in (codex login) |
Check both before installing:
codex --version && codex login status && claude --versioninstall.sh performs these checks and refuses to proceed without them. The plugin install path has no preflight — nothing runs until Claude Code starts the server.
Codex calls bill against your ChatGPT or OpenAI account, not your Claude usage.
Developed and tested on macOS, where Codex sandboxes model-generated commands with Seatbelt. Codex itself supports Linux through Landlock, so the bridge should work there, but it has not been tested and the sandbox sections of these docs name Seatbelt specifically. Windows sandbox support is not in Codex's shipped feature set — treat Windows as unsupported.
/plugin marketplace add buchmark/codex-bridge-for-claude-code
/plugin install codex-bridge
Available in every project. Restart Claude Code afterwards.
git clone https://github.com/buchmark/codex-bridge-for-claude-code
cd codex-bridge-for-claude-code
./install.sh --project # this directory only (default)
./install.sh --global # every project on this machine
./install.sh --uninstall # remove what it installed, from the chosen scope
./install.sh --force # proceed past the safety refusals belowThe script preflights codex, warns if Codex is not authenticated, and is safe to re-run.
It never destroys configuration it did not create:
| Situation | Behaviour |
|---|---|
An unrelated gpt.md is already there |
Backed up to gpt.md.bak.<epoch>, restored on uninstall |
An MCP server named codex exists that it did not create |
Aborts; --force replaces it and says the original cannot be restored |
| Any step fails mid-install | Rolls back the agent file and marker, leaving the prior state |
| Uninstalling an agent file it cannot prove it owns | Left alone unless --force |
claude missing at uninstall |
Removes local files anyway, warns that the MCP entry remains |
What it created is recorded in .claude/.codex-bridge-install, and uninstall works from that record.
Two files, nothing hidden.
1. Register the MCP server.
claude mcp add codex -s project -- codex mcp-server -c sandbox_mode=read-only # this project
claude mcp add codex -s user -- codex mcp-server -c sandbox_mode=read-only # global2. Copy the agent to .claude/agents/gpt.md (project) or ~/.claude/agents/gpt.md (global).
Restart Claude Code. /mcp should list codex as connected, and gpt should appear among the available agents.
Gotcha 1: a plugin's
.mcp.jsonis a bare server map, while a project's.mcp.jsonwraps the same content in"mcpServers": { … }. Copying one into the other's position silently fails.Gotcha 2: plugins namespace their MCP tools —
mcp__plugin_codex-bridge_codex__codexinstead ofmcp__codex__codex. An agent listing only one form resolves to zero tools under the other, and Claude Code refuses to spawn it.agents/gpt.mdlists both, so either install path works.
| Global | Project | |
|---|---|---|
| MCP server | claude mcp add -s user |
claude mcp add -s project → .mcp.json |
| Agent | ~/.claude/agents/gpt.md |
.claude/agents/gpt.md |
| Committed to the repo | no | yes, if you commit .mcp.json |
Project scope prompts once to trust the directory's MCP servers.
There is no command syntax to learn. Ask for the agent in plain language:
Ask the gpt agent to review src/auth.ts for race conditions
Have the gpt agent look at the diff on this branch
Name a model in the same sentence to override the default:
Ask the gpt agent, using gpt-5.5, whether this migration is reversible
Get gpt-5.6-terra to explain what src/parser.rs does
Claude relays the named model to the agent; with none named, Codex uses your configured default.
If a request ever comes back on the wrong model, say it explicitly instead — this line is the contract the agent actually parses, and it is unambiguous:
Model: gpt-5.5
Nothing fires on its own. The agent runs when you ask for it, because each call bills against your OpenAI account.
Every response ends with a threadId. Pass it back to resume with context intact instead of starting cold:
Continue thread 019fc264-… and ask gpt to also check the error paths
The bridge never hardcodes a model. With none specified it uses the model set in your ~/.codex/config.toml, so it works unmodified on any machine.
Your actual catalog:
codex debug models | python3 -c 'import json,sys;[print(m["slug"],"—",m.get("description","")) for m in json.load(sys.stdin)["models"]]'Two ways to choose:
| Scope | How |
|---|---|
| One call | Name the model in the request: Ask the gpt agent, using gpt-5.5, to … |
| Everything | Edit model in ~/.codex/config.toml — also changes your Codex TUI |
Codex reads model_reasoning_effort from ~/.codex/config.toml and applies it to whichever model runs — which matters, because the ceilings differ:
| Model | Highest accepted |
|---|---|
gpt-5.6-terra |
ultra |
gpt-5.6-luna |
max |
gpt-5.5, gpt-5.4-mini |
xhigh |
Asking a model for more than it supports is a hard 400 unsupported_value, not a quiet downgrade. So a global model_reasoning_effort = "max" breaks every call to gpt-5.5.
The agent works around this: whenever a call names a model explicitly, it pins effort to xhigh — the highest level all models accept. To go higher on a model that allows it, ask for it:
Ask the gpt agent on max reasoning to audit this migration
Check what a full catalog supports:
codex debug models | python3 -c 'import json,sys;[print(m["slug"], [l["effort"] for l in m.get("supported_reasoning_levels",[])]) for m in json.load(sys.stdin)["models"]]'To confirm which model actually ran, read the session log rather than trusting the reply — models misreport their own identity:
grep -o '"model":"[^"]*"' ~/.codex/sessions/*/*/*/*.jsonl | sort -u | tail -5Codex executes model-generated shell commands. The sandbox is the boundary, so it is worth being precise about what is enforced and what is merely arranged.
Enforced by the OS. Codex builds a macOS Seatbelt profile around every command its model generates. Under workspace-write, writes are confined to the working directory the call names. This holds regardless of what any model decides.
A default, not a floor. The MCP server is registered with sandbox_mode=read-only, which applies when a call omits the sandbox parameter. It is not a ceiling: a call that passes workspace-write gets it. So the read-only posture of any individual call depends on the wrapper following its instructions, not on a lock.
Arranged by instruction. The agent asks for workspace-write only for tasks that must change files, and refuses danger-full-access outright — that mode removes the sandbox entirely and hands a remote model your machine. approval-policy is never, because a non-interactive run has nobody to answer a prompt, which leaves the sandbox as the only remaining boundary.
If you need a guarantee rather than an arrangement, do not send write tasks through this agent. Nothing in this bridge can stop a wrapper that ignores its instructions from requesting workspace-write — and the blast radius of that, by design, stops at the working directory.
Anything you send to the gpt agent — code, paths, file contents — leaves your machine for OpenAI. Treat it exactly as you treat pasting into ChatGPT.
Fair question, and self-reports do not answer it. A model asked "which model are you?" can be wrong or simply instructed to say anything.
The check that settles it is where the process connects, captured live with lsof and resolved against OpenAI's and Anthropic's DNS records. Step-by-step in docs/verify.md.
Short version: the traffic goes to chatgpt.com, not api.anthropic.com. Different netblock, different operator. Substitution by a Claude model is ruled out at the network layer.
- Not a native subagent. A Haiku wrapper forwards the call, which costs one short extra turn per dispatch. Why it has to work this way.
- The model label is unverifiable. That the request reached OpenAI is provable. Which model served it is OpenAI's word — true of every API client.
- No streaming. Output arrives when the Codex call completes.
- Restart required after install. Agents and MCP servers load at session start.
See docs/how-it-works.md for the call path, the failure modes the wrapper's instructions exist to prevent, and why model selection is left to your Codex config.
Point a marketplace at a local checkout instead of GitHub:
claude plugin marketplace add /absolute/path/to/your/checkout
claude plugin install codex-bridge@codex-bridgeEdits to the checkout are not picked up automatically — the installed copy is cached and refreshed by version, so an unchanged version reports "already at the latest version" no matter what you edited. The loop is:
# 1. bump "version" in .claude-plugin/plugin.json
claude plugin marketplace update codex-bridge
claude plugin update codex-bridge@codex-bridge
# 2. restart Claude CodeValidate before publishing:
claude plugin validate ./codex-bridgeMIT