Skip to content

m0n0x41d/claudex

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

claudex

Run Claude Code over your ChatGPT subscription.

claudex is a local proxy that translates Anthropic Messages API to the OpenAI Responses API used by the Codex backend, and authenticates with your ChatGPT Plus/Pro account via the same OAuth device flow the codex CLI uses. Your Claude Code stays unchanged — it just points at ANTHROPIC_BASE_URL=http://127.0.0.1:<port> and talks to the proxy.

Status: works for me, not battle-tested. SSE event shape from the Codex backend drifts; expect rough edges around tool-use and reasoning streams.

Install

cargo install --git https://github.com/m0n0x41d/claudex

or from a clone:

cargo install --path .

Use

claudex auth                      # one-time: ChatGPT device-flow login
claudex init                      # write default config to ~/.claudex/config.yaml
claudex                           # spawn the proxy and run `claude` through it
claudex status                    # show current token state
claudex --resume <session_id>     # any unknown args are forwarded to `claude`
claudex -- --print "hello"        # use `--` to be explicit

Arg order to claude: claude.default_args from config, then whatever you passed to claudex.

claudex with no subcommand binds an ephemeral port, exports ANTHROPIC_BASE_URL + a dummy ANTHROPIC_API_KEY, then execs claude with whatever args you pass after it. When claude exits, the proxy is dropped. No daemon, no persistent ports.

Logs go to ~/.claudex/claudex.log while claude is running (stderr is left alone so the TUI stays clean). tail -f ~/.claudex/claudex.log to watch traffic.

If claude is already signed in to claude.ai, run claude /logout inside it once and answer No to the API key approval prompt — otherwise the claude.ai token takes precedence over the proxy.

Config

~/.claudex/config.yaml:

proxy:
  bind: 127.0.0.1
  port: 0                # 0 = ephemeral
  log_level: info
codex:
  base_url: https://chatgpt.com/backend-api/codex
  default_model: gpt-5.5
  reasoning_effort: medium      # low | medium | high
  reasoning_summary: concise    # auto | concise | detailed
  originator: claudex
claude:
  command: claude
  default_args: []
model_map: {}                   # claude-opus-4-7: gpt-5.5

Available models depend on your ChatGPT tier — the Codex backend gates them by client_version. Probe with:

curl -s -H "Authorization: Bearer $(jq -r .access_token ~/.claudex/auth.json)" \
     -H "chatgpt-account-id: $(jq -r .account_id ~/.claudex/auth.json)" \
     'https://chatgpt.com/backend-api/codex/models?client_version=1.0.0' | jq '.models[].slug'

Architecture

Layered, bottom-up. Each layer depends only on the layer below.

types/      L0  algebraic data (Anthropic + Responses wire types, TokenSet, Config)
translate/  L1  pure Anthropic↔Responses (incl. StreamReconciler state machine)
auth/       L2  pure auth state machine (classify, device-flow parsing)
ports/      L3  effect traits + their concrete impls (http, fs, subprocess, …)
app/        L4  use cases: authenticate, AuthService, serve, launch_session
cli/        L5  argv dispatch

Side effects live only in ports/ and app/. Translation and auth state are pure and unit-tested. The proxy is spawn-per-invocation: one claudex process = one claude session = one ephemeral listener.

License

MIT.

About

You have angered the gods by your blasphemous fusion of rival pantheons. claudex is the unholy proxy that tricks your ChatGPT subscription into funding Claude Code. Sam and Dario will pretend not to notice. The tokens flow regardless.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages