Local-only Anthropic Messages API proxy that replaces selected Claude models with GPT models served via Codex, while everything else continues to Anthropic untouched. Claude Code keeps requesting its normal models; per-family routing decides which requests are rewritten for Codex and which relay to Anthropic, so a session can, for example, run sonnet and haiku traffic on GPT while opus stays on Anthropic. The built-in mapping:
| Requested family | Sent to Codex |
|---|---|
| opus | gpt-5.6-sol |
| sonnet | gpt-5.6-terra |
| haiku | gpt-5.6-luna |
Matching is by family substring on POST /v1/messages, so full ids
(claude-opus-5, dated haiku ids) and bare aliases both match. Toolless
Messages requests relay to Anthropic as side queries, except explicit gpt-*
model ids, which pass to Codex unchanged. Any other model (e.g. fable) and
every other path relay to Anthropic with bodies unmodified; headers pass through
minus hop-by-hop, with Host rewritten.
routing.json in the proxy config directory controls which Claude families use
Codex. The directory is CCP_CONFIG_DIR when set, otherwise
XDG_CONFIG_HOME/claude-code-proxy, otherwise ~/.config/claude-code-proxy.
{"models":{"sonnet":"gpt-5.6-terra","haiku":"anthropic"}}models accepts only opus, sonnet, and haiku. Each value is an upstream
allowlisted gpt-* model id or "anthropic". Omitted tiers and "anthropic" relay to
Anthropic. With no file, the built-in table above applies. The proxy reloads
the file before each Messages request. Invalid updates retain the last valid
mapping and are logged; deleting the file restores the built-in defaults.
Models selected by this file bypass the upstream global Codex model override.
Built-in defaults remain subject to codex.model or CCP_CODEX_MODEL.
After each Codex-handled Messages request, the proxy writes Codex subscription
usage for statusline consumers to $XDG_RUNTIME_DIR/claude-codex-proxy/usage.json.
Without XDG_RUNTIME_DIR, it uses /tmp/claude-codex-proxy-<uid>.json.
The file is private and atomically replaced.
{"windows":[{"label":"5h","used_percentage":42.0,"resets_at":1755763200,"window_minutes":300}],"credits":{"has_credits":true,"balance":12.5},"limit_reached":false,"captured_at":1755760000}windows can also use "weekly", <minutes>m, or "unknown" labels. Add
"usage_file": false at the top level of routing.json to disable writing
and remove the existing sidecar. The key defaults to true when omitted or
when routing.json is absent.
Codex responses carry the most recently relayed Anthropic rate-limit headers so the client's quota display stays populated during Codex traffic.
cd packaging/arch && makepkg -siInstalls the claude-codex-proxy binary, the claudex launcher, and systemd
user units. The PKGBUILD builds from the local git HEAD, so the repo needs at
least one commit. Elsewhere: cargo install --path ..
systemctl --user enable --now claude-codex-proxy.socketThe service has no [Install] section; the socket unit is what's enabled
for socket activation on 127.0.0.1:8787. claudex also starts the socket
itself if it isn't already running, so this step is only needed to have it
available without running claudex first.
claudex [claude arguments...]claudex runs Codex login on first use, starts the socket-activated proxy,
sets ANTHROPIC_BASE_URL, and executes claude. Concurrent invocations are
fine; they share one proxy. The proxy exits after 15 idle minutes
(--idle-timeout seconds, 0 disables) and systemd restarts it on the next
connection.
Manual operation:
claude-codex-proxy login
claude-codex-proxy serve --port 8787journalctl --user -u claude-codex-proxy. The unit sets RUST_LOG=info;
manual runs need it exported.
Binds 127.0.0.1 only. Anthropic credentials pass through untouched and are
never stored; the Codex path never carries them. Codex OAuth tokens live at
~/.config/claude-code-proxy/codex/auth.json (managed by the upstream
claude-code-proxy crate). Using ChatGPT subscription auth outside Codex CLI
is against OpenAI ToS.
CI enforces cargo fmt --check, cargo clippy --all-targets -- -D warnings,
timeout 300 cargo test, and shellcheck scripts/claudex.