Claude Code with ChatGPT, Claude & SuperGrok
Use ChatGPT Plus/Pro, Claude Pro/Max, and SuperGrok subscriptions through Claude Code — OAuth login, any provider combo, and model aliases.
Last updated: 2026-07-23
Run Claude Code against the gateway and route work to your own consumer subscriptions:
| Product | How you authenticate | Typical use |
|---|---|---|
| ChatGPT Plus / Pro / Team | Codex OAuth (llm-gateway auth login chatgpt) |
GPT models via translation |
| Claude Pro / Max | setup-token / Claude Code login | Native Anthropic passthrough |
| SuperGrok / X Premium+ | Grok CLI import or xAI device OAuth | Grok 4.5, Composer 2.5 |
You can use any combination: GPT only, Grok only, GPT+Grok, Claude+GPT, all three, and so on.
Claude Code
│ Anthropic Messages API
▼
llm-gateway ──► Claude subscription (passthrough)
──► ChatGPT subscription (translate)
──► SuperGrok / xAI (translate)Related: Any app · Claude app · Codex · Cursor · Claude Code checklist · OAuth · xAI
Before you start
Requirements
- Gateway binary: release or
go build -o llm-gateway ./cmd/gateway - Claude Code CLI (
claudeonPATH) - At least one subscription you own (ChatGPT, Claude, and/or SuperGrok)
Security & terms of service
- Log in only with accounts you own. Tokens stay on your machine.
- Default store:
~/.config/inja-gateway/credentials.json(mode0600). On macOS this may live under~/Library/Application Support/inja-gateway/. Override withINJA_GATEWAY_AUTH_FILE. - Never commit credential files or paste tokens into tickets/chat.
- OpenAI Codex OAuth is the ChatGPT subscription path used by the open-source Codex CLI and tools that integrate with it. Tokens talk to the Codex/ChatGPT backend — not a classic Platform
sk-API key. - Anthropic restricts Free/Pro/Max OAuth for many third-party products. Prefer
claude setup-token/ official Claude Code flows and re-read Anthropic’s terms and Claude Code authentication. Do not resell multi-tenant access to consumer OAuth. - xAI may gate which SuperGrok tiers receive OAuth API access; login success does not guarantee every model id works.
This guide is for personal / single-operator use of subscriptions you already pay for.
End-to-end quick start
1. Install binary + helpers
Release binary (no git checkout needed):
# install llm-gateway from GitHub Releases onto PATH, then:
llm-gateway helpers install # alias: llm-gateway load-helpers
# writes ~/.config/inja-gateway/shell/*.sh + claude-code-subscriptions.yaml
eval "$(llm-gateway helpers source)" # or paste the source lines into ~/.zshrcFrom source:
git clone https://github.com/inja-online/llm-gateway.git
cd llm-gateway
go build -o llm-gateway ./cmd/gateway
source examples/shell/claude-code-helpers.sh # same scripts as embedded in the binary| Command | Purpose |
|---|---|
llm-gateway helpers install |
Extract shell helpers + subscription YAML from the binary |
llm-gateway load-helpers |
Same as helpers install |
llm-gateway helpers source |
Print source … lines for your shell rc |
llm-gateway helpers list |
List embedded files |
2. Log in (once per provider you need)
llm-gateway auth login chatgpt # browser → auth.openai.com (Codex / ChatGPT)
llm-gateway auth login claude # setup-token / paste Claude OAuth token
llm-gateway auth login grok # imports ~/.grok/auth.json if present, else device code
llm-gateway auth statusImport shortcuts (if you already use official CLIs):
codex login && llm-gateway auth import chatgpt
llm-gateway auth import claude # Linux credentials file; macOS prefer setup-token
llm-gateway auth import grok # recommended: ~/.grok/auth.json from Grok CLI3. HTTPS localhost + background gateway
Claude Code needs a live API. Helpers start the gateway in the background on HTTPS so you do not get ConnectionRefused:
# helpers already sourced (from step 1)
export KEY=local-dev
cc-gateway-up # gen certs if needed, nohup llm-gateway, wait for /healthz
# → https://127.0.0.1:8787 (+ NODE_EXTRA_CA_CERTS / ANTHROPIC_BASE_URL)
cc-gateway-status
cc-gateway-logs -f # http + usage lines (model, tokens, latency)
# cc-gateway-logs --usage
# cc-gateway-downLog file: ~/.local/state/inja-gateway/gateway.log. After a real request you should see:
http status=200 method=POST path=/v1/messages lat_ms=…
usage status=ok provider=… model=… tokens_in=… tokens_out=…Manual TLS (git checkout):
./examples/scripts/gen-localhost-tls.sh # prefers mkcert
export GATEWAY_TLS_CERT=$PWD/examples/certs/localhost.pem
export GATEWAY_TLS_KEY=$PWD/examples/certs/localhost-key.pem
export GATEWAY_LISTEN=127.0.0.1:8787
./llm-gateway -config examples/configs/claude-code-subscriptions.yaml
# installed layout uses ~/.config/inja-gateway/claude-code-subscriptions.yaml by defaultThat config wires each upstream with:
auth: oauth2
oauth:
credentials: chatgpt # or claude | grokThe gateway loads tokens from the auth store and refreshes ChatGPT / Grok access tokens before expiry.
4. Launch Claude Code
export KEY=local-dev
cc-gpt # auto cc-gateway-up, then Claude Code (GPT only)
cc-grok # Grok 4.5 + Composer 2.5
cc-gpt-grok # GPT + Grok
cc-multi # all threePATH wrapper (forwards every arg to claude, defaults Grok 4.6 + xhigh):
ln -sf ~/.config/inja-gateway/scripts/claude-grok ~/.local/bin/claude-grok
claude-grok --help # same as claude --help (no gateway)
claude-grok -p "ping" # Grok 4.6, effort xhighOr:
KEY=local-dev ./examples/claude-code-multi.sh gpt
KEY=local-dev ./examples/claude-code-multi.sh grok
KEY=local-dev ./examples/claude-code-multi.sh gpt+grok
KEY=local-dev ./examples/claude-code-multi.sh multiKEY is a client credential presented to the gateway (any non-empty string when edge_auth is off; a real edge key when edge auth is on). Subscription secrets never leave the gateway process.
In a session:
/model grok-4.5
/model composer-2.5
/model gpt
/model sonnetAuth CLI reference
| Command | What it does |
|---|---|
llm-gateway auth login chatgpt [--no-browser] |
ChatGPT subscription OAuth (PKCE; Codex client) |
llm-gateway auth login claude |
Claude setup-token / paste |
llm-gateway auth login grok [--device] |
Prefer Grok CLI import; --device forces xAI device code |
llm-gateway auth import chatgpt |
From ~/.codex/auth.json after codex login |
llm-gateway auth import claude |
From Claude Code credentials file (when present on disk) |
llm-gateway auth import grok |
From ~/.grok/auth.json (Grok CLI), Hermes, or OpenClaw paths |
llm-gateway auth status |
Which providers are logged in (no secrets printed) |
llm-gateway auth logout [provider|all] |
Remove stored credentials |
llm-gateway auth env [provider] |
Print export lines (sensitive — local debug only) |
./llm-gateway auth help
export INJA_GATEWAY_AUTH_FILE=$HOME/.config/inja-gateway/credentials.jsonGrok “Invalid action” in the browser
xAI’s prefilled page https://accounts.x.ai/oauth2/device?user_code=… often shows Invalid action when the browser session is wrong.
Prefer:
# Log into Grok CLI first (if you use it), then:
./llm-gateway auth import grok
# or:
./llm-gateway auth login grok # auto-imports ~/.grok/auth.json when presentDevice login opens the base URL and prints the code separately. Force device flow with auth login grok --device.
Provider combinations
Claude Code always exposes three “slots” that map to Anthropic-style aliases: opus, sonnet, and haiku (plus small-fast). The launcher fills those slots from the providers you enable.
Named profiles and combos
Separators: + · , · -
| Profile | Providers | Default opus | Default sonnet | Default haiku / small-fast |
|---|---|---|---|---|
gpt |
ChatGPT only | sol |
gpt (terra) |
luna |
grok |
SuperGrok only | grok-4.5 |
grok-4.5 |
composer-2.5 |
gpt+grok |
GPT + Grok | grok-4.5 |
gpt |
composer-2.5 |
claude |
Claude only | opus |
sonnet |
haiku |
claude+gpt |
Claude + GPT | opus |
gpt |
luna |
claude+grok |
Claude + Grok | opus |
grok-4.5 |
composer-2.5 |
multi |
All three | opus |
gpt |
composer-2.5 |
./examples/claude-code-multi.sh list
./examples/claude-code-multi.sh gpt
./examples/claude-code-multi.sh grok
./examples/claude-code-multi.sh gpt+grok
./examples/claude-code-multi.sh claude+gpt
./examples/claude-code-multi.sh claude+grok
./examples/claude-code-multi.sh multiShell helpers
source examples/shell/claude-code-helpers.sh
export KEY=local-dev
cc-gateway-up
cc-gpt # GPT only (Sol/Terra/Luna)
cc-grok # Grok 4.5 + grok-build (Composer-class)
cc-gpt-grok
cc-claude
cc-multi
cc-run gpt+grok
cc-listEnvironment overrides
| Variable | Effect |
|---|---|
GATEWAY |
Gateway base URL (default http://localhost:8787) |
KEY / GATEWAY_EDGE_KEY |
Client credential to the gateway |
CC_MODEL |
Main model for the session |
CC_OPUS_MODEL / CC_SONNET_MODEL / CC_HAIKU_MODEL |
Slot pins |
CC_GROK_HEAVY |
Default grok-4.5 |
CC_GROK_FAST |
Default composer-2.5 |
CC_GPT_HEAVY / CC_GPT_MID / CC_GPT_FAST |
Default o3 / gpt / gpt-mini |
CC_PROVIDERS |
Same as profile string (gpt,grok) |
CC_MODEL=composer-2.5 KEY=local-dev ./examples/claude-code-multi.sh grok
CC_GROK_HEAVY=grok-4.5 CC_GROK_FAST=composer-2.5 ./examples/claude-code-multi.sh gpt+grokPermanent Claude Code settings
Merge env into ~/.claude/settings.json (or project .claude/settings.json). Prefer the launcher when you switch combos often.
Example for GPT + Grok (no Claude models in the default slots):
{
"env": {
"ANTHROPIC_BASE_URL": "https://127.0.0.1:8787",
"ANTHROPIC_API_KEY": "local-dev",
"ANTHROPIC_AUTH_TOKEN": "local-dev",
"ANTHROPIC_MODEL": "gpt",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "grok-4.5",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "gpt",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "composer-2.5",
"ANTHROPIC_SMALL_FAST_MODEL": "composer-2.5"
}
}Template with more variants: examples/claude-code-settings.json.example.
Behind a custom ANTHROPIC_BASE_URL, Claude Code does not validate model names against Anthropic’s catalog — gateway aliases and provider/model ids pass through.
Model aliases (gateway config)
From examples/configs/claude-code-subscriptions.yaml:
| Alias | Routes to (Jul 2026) |
|---|---|
sonnet / claude |
anthropic/claude-sonnet-5 |
opus |
anthropic/claude-opus-4-8 |
haiku |
anthropic/claude-haiku-4-5 |
fable |
anthropic/claude-fable-5 |
gpt / terra |
chatgpt/gpt-5.6-terra |
sol |
chatgpt/gpt-5.6-sol |
luna / gpt-mini |
chatgpt/gpt-5.6-luna |
grok / grok-4.5 |
xai/grok-4.5 |
grok-4.6 |
xai/grok-4.6 (reasoning_effort: xhigh is 4.6-only) |
composer-2.5 / composer |
xai/grok-build-0.1 (Grok Build / Composer-class) |
Sources: Claude models · GPT-5.6 · xAI models.
Edit alias targets if your plan 404s (keep short names).
# Short aliases from YAML only
curl -sk https://127.0.0.1:8787/v1/models | jq -r '.data[].id'
# Live: aliases + every provider’s current /models (needs credentials)
curl -sk https://127.0.0.1:8787/v1/models?live=1 | jq -r '.data[].id' | sort
./examples/scripts/refresh-model-catalog.shAgents/maintainers: see repo root AGENTS.md (“Model aliases must stay current”).
What “translate” means
| Path | Behavior |
|---|---|
| Claude Code → Claude | Passthrough — highest fidelity (tools, betas, streaming) |
| Claude Code → ChatGPT / Grok | Translate Anthropic Messages ↔ OpenAI-compatible chat |
| Stream usage on translate | input_tokens may be 0 until the final event |
| Vendor-only fields | May drop on translate — see Deprecation policy |
How subscription OAuth is applied
Store id (oauth.credentials) |
Upstream credential | Typical base_url |
|---|---|---|
chatgpt |
Bearer access token (auto-refresh) | https://chatgpt.com/backend-api/codex |
claude |
Bearer setup/OAuth token | https://api.anthropic.com/v1 |
grok |
Bearer access token (auto-refresh) | https://api.x.ai/v1 |
providers:
chatgpt:
kind: openai_compat
base_url: "https://chatgpt.com/backend-api/codex"
auth: oauth2
oauth:
credentials: chatgpt
anthropic:
kind: anthropic
base_url: "https://api.anthropic.com/v1"
auth: oauth2
oauth:
credentials: claude
xai:
kind: openai_compat
base_url: "https://api.x.ai/v1"
auth: oauth2
oauth:
credentials: grokauth: oauth2 with a TokenSource always sends Authorization: Bearer, which is what subscription OAuth tokens expect (Claude OAuth is not x-api-key).
Optional edge auth so only your machine can call the gateway:
edge_auth:
enabled: true
keys: ["local-dev"]export KEY=local-dev
./examples/claude-code-multi.sh gpt+grokAPI keys instead of subscriptions
If you prefer Platform API keys (not consumer OAuth):
export OPENAI_API_KEY ANTHROPIC_API_KEY XAI_API_KEY
./llm-gateway -config examples/configs/claude-code-multi.yaml
KEY=local-dev ./examples/claude-code-multi.sh multiSame combo launcher and shell helpers work. See Getting started for generic key setup.
Troubleshooting
| Symptom | What to try |
|---|---|
ConnectionRefused / Unable to connect to API |
Gateway not running → cc-gateway-up or ./examples/claude-code-multi.sh gpt (auto-starts HTTPS) |
| TLS / certificate errors | ./examples/scripts/gen-localhost-tls.sh; prefer mkcert -install; helpers set NODE_EXTRA_CA_CERTS |
missing …/examples/scripts/gen-localhost-tls.sh |
Re-run llm-gateway helpers install (script is $HOME/.config/inja-gateway/scripts/). Or generate into the install certs dir: bash $REPO/examples/scripts/gen-localhost-tls.sh ~/.config/inja-gateway/certs |
cc-list: command not found: _inja_cc_list_profiles |
Re-source helpers (eval "$(llm-gateway helpers source)" or examples/shell/…) |
Empty cc-gateway-logs |
Rebuild/restart gateway after upgrade; only gateway-routed traffic logs (not Cursor built-in models) |
no credentials for chatgpt (or claude/grok) |
llm-gateway auth login <provider> or auth import … |
auth status shows expired |
Re-login; for Grok/ChatGPT refresh should renew access automatically if refresh token is present |
| Grok browser Invalid action | auth import grok from Grok CLI; avoid prefilled device URLs |
| Grok login works, inference 403 | xAI tier / entitlement — check SuperGrok plan or API key path |
| Claude 401 after import on macOS | Keychain isn’t read by import — use auth login claude / setup-token |
| ChatGPT 401 via gateway | Re-login Codex OAuth; confirm auth status has refresh; check base_url |
| Gateway healthz fails | Start ./llm-gateway -config examples/configs/claude-code-subscriptions.yaml |
| Model not found / 404 upstream | Fix alias target in YAML to an id your account can call |
| Translate stream looks empty early | Expected: usage often arrives on the final event only |
./llm-gateway auth status
./llm-gateway auth logout grok && ./llm-gateway auth import grok
curl -s http://localhost:8787/healthzArchitecture recap
- Claude Code always uses the Anthropic Messages wire format (
POST /v1/messages). - Gateway resolves
modelvia aliases →provider/model. - Same family as Anthropic → passthrough. Otherwise → canonical IR translate.
- Upstream auth comes from the subscription store (
oauth.credentials), not from Claude Code’s env (except the edge/client key). - Subscription headers — Claude OAuth betas +
X-App: cli; ChatGPT/Codex UA / Originator / account id. - TLS + body fidelity — Chrome-like TLS to Anthropic/ChatGPT; Claude OAuth tool rename, cloaking/
cch, multi-account pool on 429. GET /v1/models— credential-gated aliases + catalog (optional remote refresh).- Usage can be metered with
hooks.jsonl(defaultstdoutin the example config).
claude CLI ──ANTHROPIC_BASE_URL──► :8787
KEY (edge) │
├─ anthropic + Bearer + OAuth betas + utls + cloak
├─ chatgpt + Bearer + Codex headers + utls
└─ xai + Bearer (grok creds)File map
| Path | Role |
|---|---|
examples/configs/claude-code-subscriptions.yaml |
Subscription OAuth providers + aliases |
examples/configs/claude-code-multi.yaml |
API-key multi-provider recipe |
examples/claude-code-multi.sh |
Combo launcher for Claude Code |
examples/shell/claude-code-helpers.sh |
Same scripts embedded in the binary (llm-gateway helpers install) |
~/.config/inja-gateway/shell/ |
Install target after helpers install / load-helpers |
examples/shell/claude-code-profiles.sh |
Profile/combo resolver |
examples/claude-code-settings.json.example |
settings.json snippets |
subauth/ |
OAuth login + credential store |
cmd/gateway/auth_cmd.go |
llm-gateway auth CLI |
Related docs
- Claude Code checklist — release regression for Anthropic ingress
- OAuth & upstream auth — all auth modes
- xAI (Grok) — openai_compat notes
- Getting started
- Compatibility matrix
- External: Claude Code auth · Codex / ChatGPT auth · Claude Code LLM gateways