Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.<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.

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.

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.
  • 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 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

About

Claude Code plugin that adds a `gpt` subagent, backed by your local Codex CLI

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages