























claude-codex-proxy lets you use
Claude Code with your ChatGPT Plus or
Pro subscription.
Quick start · How it works · Configuration · Limitations
I feel Claude Code is still the best harness around, despite occasional frustrations caused by updates. However, Anthropic keeps tightening the usage limits, while OpenAI is still much more generous.
If you want to use OpenAI plans, your best options seem to be OpenCode and Codex. I tried OpenCode, but the UX has many rough edges, especially around skills feeling like a second-class feature. Fortunately it's open source and I ended up forking it and applying some patches, but would much rather not do it.
Homebrew (macOS and Linux):
brew install raine/claude-codex-proxy/claude-codex-proxy
Install script (macOS and Linux):
curl -fsSL https://raw.githubusercontent.com/raine/claude-codex-proxy/main/scripts/install.sh | bashManual: download a prebuilt binary for your platform from the releases page.
Open a browser (PKCE flow):
claude-codex-proxy auth login
Or, on a headless machine (device code flow):
claude-codex-proxy auth device
Either command prints a URL. Sign in with your ChatGPT Plus/Pro account. On macOS, credentials are stored in Keychain. On other platforms, they are stored locally for reuse by the proxy.
Verify it stuck:
claude-codex-proxy auth status
claude-codex-proxy serve
Defaults to http://127.0.0.1:18765 (loopback only). Override with
PORT=11435 claude-codex-proxy serve.
One-shot:
ANTHROPIC_BASE_URL=http://localhost:18765 \ ANTHROPIC_AUTH_TOKEN=unused \ ANTHROPIC_MODEL=gpt-5.4 \ CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 \ claude
Or set it persistently in ~/.claude/settings.json:
{
"env": {
"ANTHROPIC_BASE_URL": "http://127.0.0.1:18765",
"ANTHROPIC_AUTH_TOKEN": "unused",
"ANTHROPIC_MODEL": "gpt-5.4",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": 1
}
}Set ANTHROPIC_MODEL to a model your ChatGPT subscription is allowed to use.
Confirmed working on Plus:
gpt-5.4gpt-5.3-codexAlso verified working on this project:
gpt-5.2gpt-5.4-miniThe proxy also accepts a small set of convenience aliases and resolves them before calling the upstream Codex backend:
haiku, claude-haiku-4-5, claude-haiku-4-5-20251001 → gpt-5.4-minisonnet, claude-sonnet-4-6 → gpt-5.4opus, claude-opus-4-7 → gpt-5.4These aliases are only shorthand for portability and cheaper subagent configs; they are not semantic equivalents of the Claude models they resemble.
If the resolved model isn't supported by your account, upstream returns a 400
like
"The 'gpt-4.1' model is not supported when using Codex with a ChatGPT account.".
The proxy surfaces that verbatim.
For example, you can now point Claude Code or a subagent at the proxy with:
ANTHROPIC_MODEL=haiku claude
and the proxy will send gpt-5.4-mini upstream.
sequenceDiagram
autonumber
participant CC as Claude Code
participant P as claude-codex-proxy
participant AUTH as auth.openai.com
participant CGX as chatgpt.com/<br/>backend-api/codex
Note over P,AUTH: One-time: PKCE or device OAuth<br/>tokens cached locally for reuse
CC->>P: POST /v1/messages (Anthropic shape, stream: true)
alt access token expiring
P->>AUTH: POST /oauth/token (refresh_token)
AUTH-->>P: new access + refresh
end
P->>P: translate request<br/>• strip max_tokens / temperature / cache_control<br/>• system blocks → top-level "instructions"<br/>• tool_use.id = call_id (identity)<br/>• prompt_cache_key = session id
P->>CGX: POST /responses<br/>Bearer + ChatGPT-Account-Id + originator=claude-codex-proxy
CGX-->>P: Responses API SSE<br/>(output_item.*, output_text.delta, function_call_arguments.*, codex.rate_limits, response.completed)
P->>P: reducer: typed events<br/>(text/tool start/delta/stop, finish)
P-->>CC: Anthropic SSE<br/>(message_start, content_block_*, message_delta, message_stop)
| Command | Description |
|---|---|
serveStarts the HTTP proxy and blocks. Binds to 127.0.0.1 only. Logs to
$XDG_STATE_HOME/claude-codex-proxy/proxy.log (rotated at 20 MiB). Set
CCP_LOG_STDERR=1 to mirror log lines to stderr while running.
claude-codex-proxy serve PORT=11435 claude-codex-proxy serve CCP_LOG_STDERR=1 claude-codex-proxy serve
Prints the exact ANTHROPIC_BASE_URL / ANTHROPIC_MODEL env vars to export on
startup. Refuses to start traffic until auth login (or auth device) has
stored a token.
auth loginRuns the PKCE browser flow against auth.openai.com using the Codex CLI's
client ID. Prints a URL, opens a local callback listener on port 1455, waits for
the browser to redirect back, and stores the resulting access / refresh tokens
in Keychain on macOS or locally on other platforms. The process exits
automatically once the tokens are saved.
claude-codex-proxy auth login
Sign in with your ChatGPT Plus/Pro account, not an OpenAI API account. The
token file includes the extracted chatgpt_account_id so the proxy can set the
ChatGPT-Account-Id header on every upstream call.
auth deviceSame OAuth flow, but for headless machines. Prints a short user code and a URL;
you enter the code from any browser on any other device, and the CLI polls
auth.openai.com until you authorize, then stores the token.
claude-codex-proxy auth device
Useful over SSH, inside a container, or on any host that can't open a browser.
auth statusShows whether credentials are stored, the account ID, and how long until the access token expires. Non-zero exit if no auth is present.
claude-codex-proxy auth status
Example output:
Account: 79342a5e-57b7-44ea-bfdc-a83ba070dad6
Expires: 2026-04-28T16:46:04.827Z (in 863946s)
Storage: macOS Keychain
The proxy refreshes the access token 5 minutes before expiry with a single-flight guard, so concurrent requests never trigger stampedes of refresh calls.
auth logoutRemoves stored auth credentials. On macOS this deletes the Keychain entry. No server call is needed; the refresh token just becomes dead.
claude-codex-proxy auth logoutRun auth login again to re-authenticate.
The proxy speaks enough of the Anthropic API for Claude Code:
POST /v1/messages: the main turn endpoint (streaming and non-streaming)POST /v1/messages?beta=true: same (Claude Code always sends ?beta=true)POST /v1/messages/count_tokens: local token count via gpt-tokenizer
(o200k_base); used by Claude Code's compaction logicGET /healthz: liveness checkSettings are environment variables on the proxy process, not a config file.
| Variable | Default | Purpose |
|---|---|---|
$XDG_STATE_HOME/claude-codex-proxy/proxy.log: JSON-lines log, rotated at 20
MiB. Secrets (authorization, access, refresh, id_token,
ChatGPT-Account-Id, …) are redacted before write.codex.rate_limits.limit_reached is surfaced as HTTP 429 with retry-after.function_call_output only
takes a string, so image blocks nested inside tool_result are replaced with
a [image omitted: <media_type>] placeholder. Top-level user-message images
do pass through.output_config.format: translated to Responses API
text.format (json_schema with strict: true); other Anthropic-specific
output_config fields are dropped.bunx tsc --noEmit # typecheck bun src/cli.ts serve # run locally tail -f ~/.local/state/claude-codex-proxy/proxy.log | jq .
Install a compiled dev build globally: compile the current working tree to a
binary and place it on your PATH without linking:
mkdir -p ~/.local/bin bun build ./src/cli.ts --compile --outfile ~/.local/bin/claude-codex-proxy
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。