Bridge Claude Code → OpenAI Codex: /codex slash command (+ optional MCP server)
Keep Claude Code (CC) as your main console and call OpenAI Codex on demand. There are two independent ways to wire this up — pick one, or run both (they do not conflict):
- Approach A —
/codex slash command (manual, recommended default): a CC command that shells out to codex exec. You type /codex; you control the sandbox + guardrails; it is portable as one file.
- Approach B — official
codex mcp-server (optional): registers Codex as an MCP server so CC can call it as a native tool (codex, codex-reply) — enables multi-turn + inline use, but has no custom guardrails.
Verified on macOS, codex-cli 0.141.0, Claude Code 2.1.x — smoke-tested end-to-end; both paths returned correct answers from the real repo.
Which approach?
|
A /codex |
B codex mcp-server |
| Invoked by |
you (type /codex) |
the model (calls it mid-reasoning) |
| Trigger type |
slash command (a file) |
MCP tool |
| Sandbox / guardrail |
baked into the command prompt (read-only default, no-auto-trust, return-verbatim, show-diff) |
per-call params (sandbox, approval-policy) |
| Multi-turn |
no — one-shot (--ephemeral) |
yes — codex-reply continues a thread |
| Portable / inspectable |
yes — one markdown file (copy from this issue) |
no — binary behavior |
| Idle context cost |
~0 (loads only when you run it) |
low (tools are deferred/lazy on supporting harnesses) |
Recommendation: start with A — it covers the main use (deliberate delegation, QA review, second opinion) with guardrails and zero idle cost. Add B only if you will use multi-turn conversations or want CC to call Codex inline as a tool. They coexist fine (see "Running both").
Prerequisites
- OpenAI Codex CLI installed —
codex --version.
- Logged in —
codex login status → e.g. Logged in using ChatGPT. Each Codex turn spends tokens against that plan (~tens of thousands).
Approach A — /codex slash command (recommended default)
Ensure the commands directory exists (a fresh Claude Code install may not have it), then create the file:
mkdir -p ~/.claude/commands
File contents — ~/.claude/commands/codex.md:
---
description: Delegate a one-shot task to OpenAI Codex (codex exec) and return its answer — read-only by default, --write to let Codex edit
argument-hint: [--write] <task for Codex>
allowed-tools: Bash(codex exec:*), Bash(codex --ask-for-approval never exec:*), Bash(mktemp:*), Bash(cat:*), Bash(rm:*), Read
---
# /codex — bridge to OpenAI Codex as an on-demand sub-agent
You are bridging from Claude Code (the main console) to **OpenAI Codex** for a one-shot, non-interactive task. Treat Codex as a specialist / second opinion — its output is data for you and the user to review, not ground truth to act on blindly.
The user's request for Codex:
$ARGUMENTS
## Steps
1. **Pick the sandbox.**
- Default = **read-only** (Codex can read/analyze the repo, run nothing that mutates).
- If `$ARGUMENTS` begins with the token `--write`, strip it and use **workspace-write** (Codex may edit files in the current project during its run). Anything else → read-only.
2. **Run Codex non-interactively** via the Bash tool, scoped to the current working directory, capturing only its final message. Use a generous timeout (a Codex turn often takes 30–120 s):
Read-only (default) — the trailing `</dev/null` is REQUIRED: without it `codex exec` can block on "Reading additional input from stdin..." when the caller leaves stdin open (e.g. backgrounded runs), and capture nothing.
```bash
OUT=$(mktemp)
codex exec --ephemeral --skip-git-repo-check --color never \
-s read-only -C "$(pwd)" -o "$OUT" \
"<the task text, with --write stripped if present>" </dev/null
cat "$OUT"; rm -f "$OUT"
```
Write mode (`--write` given) — add `--ask-for-approval never` so it never blocks on a prompt:
```bash
OUT=$(mktemp)
codex --ask-for-approval never exec --ephemeral --skip-git-repo-check --color never \
-s workspace-write -C "$(pwd)" -o "$OUT" \
"<the task text>" </dev/null
cat "$OUT"; rm -f "$OUT"
```
3. **Return Codex's answer verbatim** inside a quoted block, then add one line: which sandbox was used + token count if Codex printed one.
4. **Do not auto-trust.** If Codex proposed changes or claims, surface them for review. In write mode, Codex edited inside its own sandboxed run — still show a `git status` / diff summary and let the user decide whether to keep them; never commit on Codex's behalf without being asked.
## Notes / guardrails
- Auth is the ChatGPT plan login (`codex login status`); each call spends tokens against that plan (~tens of thousands per turn). Don't loop it without reason.
- Codex runs its own hooks (claude-mem / 8-habit / governance) inside `exec`; `--ephemeral` stops it persisting session state. Keep a single CHANGES.log handoff entry per unit of work so the two agents don't double-log.
- Keep the default read-only unless the user explicitly wants Codex to edit. Escalate sandbox deliberately, per call.
- If Codex errors or times out, report the stderr tail rather than retrying blindly.
Gotchas (learned the hard way)
</dev/null is REQUIRED. Without redirecting stdin, codex exec can block on Reading additional input from stdin... whenever the caller leaves stdin open (notably when CC runs the command in the background) and capture nothing. Redirect </dev/null so Codex sees EOF and uses only the prompt argument.
- read-only by default;
--write to escalate. Default -s read-only; only -s workspace-write when Codex must edit. Write mode needs --ask-for-approval never or it hangs on an approval prompt.
- Capture cleanly with
-o <file>. codex exec streams events to stdout; -o writes only the final agent message to a file — read that back.
- Useful flags:
--ephemeral (no persisted session), -C <dir> (working root), --skip-git-repo-check, --json (JSONL events), --output-schema <file> (structured output).
- Cost: a trivial turn was ~40k tokens. It is not free.
Verify Approach A
cd <any-repo>
OUT=$(mktemp)
codex exec --ephemeral --skip-git-repo-check --color never -s read-only -C "$(pwd)" -o "$OUT" \
"In one sentence, name the main entry point of this project." </dev/null
cat "$OUT"; rm -f "$OUT"
Then in Claude Code: /codex summarize what this module does (read-only) and /codex --write add a docstring to <function> (write).
Approach B — official codex mcp-server (optional: inline + multi-turn)
codex mcp-server runs Codex as a stdio MCP server so CC can call it as a native tool. user scope is recommended — Codex is a generic agent that works against whatever project you are in, so you usually want it in every repo:
claude mcp add codex --scope user -- codex mcp-server
claude mcp get codex # expect: Status: ✔ Connected
Scope (-s, default local): user = all your projects (~/.claude.json) · local = current project only · project = team-shared via a committed .mcp.json.
What it exposes (verified by probing the server):
- tools —
codex (run a session; params include prompt, sandbox, approval-policy, cwd, model) and codex-reply (continue a session by threadId → multi-turn, which Approach A cannot do).
- no MCP prompts — so nothing from B enters the
/ slash menu. Therefore, even with both A and B installed, typing /codex always runs Approach A (slash commands and MCP tools are separate namespaces). B's tools are invoked by the model, never by typing /.
Remove anytime: claude mcp remove codex -s user.
Running both (no conflict)
Installing A + B gives two independent channels to the same Codex engine:
/codex … → you invoke A — guarded, deliberate, portable.
codex / codex-reply tools → the model invokes B — inline, structured, multi-turn.
Caveat: B lets the model spend Codex tokens autonomously, so watch for unnecessary calls. On harnesses that lazy-load MCP tools, idle cost is low — keeping B installed is cheap even if used rarely.
Companion: #10 — the QA-loop pattern (use /codex as an independent QA gate).
Bridge Claude Code → OpenAI Codex:
/codexslash command (+ optional MCP server)Keep Claude Code (CC) as your main console and call OpenAI Codex on demand. There are two independent ways to wire this up — pick one, or run both (they do not conflict):
/codexslash command (manual, recommended default): a CC command that shells out tocodex exec. You type/codex; you control the sandbox + guardrails; it is portable as one file.codex mcp-server(optional): registers Codex as an MCP server so CC can call it as a native tool (codex,codex-reply) — enables multi-turn + inline use, but has no custom guardrails.Which approach?
/codexcodex mcp-server/codex)sandbox,approval-policy)--ephemeral)codex-replycontinues a threadRecommendation: start with A — it covers the main use (deliberate delegation, QA review, second opinion) with guardrails and zero idle cost. Add B only if you will use multi-turn conversations or want CC to call Codex inline as a tool. They coexist fine (see "Running both").
Prerequisites
codex --version.codex login status→ e.g.Logged in using ChatGPT. Each Codex turn spends tokens against that plan (~tens of thousands).Approach A —
/codexslash command (recommended default)Ensure the commands directory exists (a fresh Claude Code install may not have it), then create the file:
mkdir -p ~/.claude/commandsFile contents —
~/.claude/commands/codex.md:Gotchas (learned the hard way)
</dev/nullis REQUIRED. Without redirecting stdin,codex execcan block onReading additional input from stdin...whenever the caller leaves stdin open (notably when CC runs the command in the background) and capture nothing. Redirect</dev/nullso Codex sees EOF and uses only the prompt argument.--writeto escalate. Default-s read-only; only-s workspace-writewhen Codex must edit. Write mode needs--ask-for-approval neveror it hangs on an approval prompt.-o <file>.codex execstreams events to stdout;-owrites only the final agent message to a file — read that back.--ephemeral(no persisted session),-C <dir>(working root),--skip-git-repo-check,--json(JSONL events),--output-schema <file>(structured output).Verify Approach A
Then in Claude Code:
/codex summarize what this module does(read-only) and/codex --write add a docstring to <function>(write).Approach B — official
codex mcp-server(optional: inline + multi-turn)codex mcp-serverruns Codex as a stdio MCP server so CC can call it as a native tool.userscope is recommended — Codex is a generic agent that works against whatever project you are in, so you usually want it in every repo:claude mcp add codex --scope user -- codex mcp-server claude mcp get codex # expect: Status: ✔ ConnectedScope (
-s, defaultlocal):user= all your projects (~/.claude.json) ·local= current project only ·project= team-shared via a committed.mcp.json.What it exposes (verified by probing the server):
codex(run a session; params includeprompt,sandbox,approval-policy,cwd,model) andcodex-reply(continue a session bythreadId→ multi-turn, which Approach A cannot do)./slash menu. Therefore, even with both A and B installed, typing/codexalways runs Approach A (slash commands and MCP tools are separate namespaces). B's tools are invoked by the model, never by typing/.Remove anytime:
claude mcp remove codex -s user.Running both (no conflict)
Installing A + B gives two independent channels to the same Codex engine:
/codex …→ you invoke A — guarded, deliberate, portable.codex/codex-replytools → the model invokes B — inline, structured, multi-turn.Caveat: B lets the model spend Codex tokens autonomously, so watch for unnecessary calls. On harnesses that lazy-load MCP tools, idle cost is low — keeping B installed is cheap even if used rarely.
Companion: #10 — the QA-loop pattern (use
/codexas an independent QA gate).