Install
$ agentstack add mcp-buchmark-codex-bridge-for-claude-code ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
codex-bridge
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.
Why
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.
Requirements
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 --version
install.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.
Platform
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.
Install
Option A — plugin (global)
/plugin marketplace add buchmark/codex-bridge-for-claude-code
/plugin install codex-bridge
Available in every project. Restart Claude Code afterwards.
Option B — install script
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 below
The 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., 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.
Option C — by hand
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 # global
2. 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.json is a bare server map, while a project's .mcp.json wraps 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__codex instead of mcp__codex__codex. An agent listing only one form resolves to zero tools under the other, and Claude Code refuses to spawn it. agents/gpt.md lists both, so either install path works.
Scope
| | 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.
Usage
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.
Continuing a conversation
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
Choosing a model
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 |
Reasoning depth
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 -5
Security
Codex 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.
Is it really GPT?
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](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.
Limitations
- 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](docs/how-it-works.md).
- 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.
How it works
See [docs/how-it-works.md](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.
Developing on it
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-bridge
Edits 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 Code
Validate before publishing:
claude plugin validate ./codex-bridge
License
MIT
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: buchmark
- Source: buchmark/codex-bridge-for-claude-code
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.