
Claude Code expects Anthropic-style configuration. Conductor can run Codex directly, but if you want to use Conductor’s Claude Code runner with a Codex subscription, CLIProxyAPI can sit in the middle and expose a local Anthropic-compatible endpoint while routing requests to Codex-backed OpenAI models.
The setup is:
- Claude Code points at CLIProxyAPI
- Conductor’s Claude Code runner uses that Claude Code config
- CLIProxyAPI maps Claude-looking model names to Codex-backed models
So the chain becomes:
This post is the version that finally worked.
The annoying part was not Claude Code itself. The standalone Claude CLI worked quickly. The annoying part was Conductor continuing to send Claude-looking model IDs even after the UI/config said GPT. The proxy had to handle that. Conductor wasn’t respecting the ANTHROPIC_DEFAULT_OPUS_MODEL type envs.
Install and log in to CLIProxyAPI
On macOS:
brew install cliproxyapi
brew services start cliproxyapiThen log in with the Codex/OpenAI account you want to use:
cliproxyapi -codex-loginCLIProxyAPI stores auth files under:
~/.cli-proxy-api/The proxy config is usually:
/opt/homebrew/etc/cliproxyapi.confThe local API server listens on:
http://localhost:8317Check that it is alive:
brew services info cliproxyapi
lsof -nP -iTCP:8317 -sTCP:LISTENConfirm the proxy model list
Do not copy random model names from old docs. Query your local proxy.
Get one of your local proxy API keys from cliproxyapi.conf, then:
curl -sS \
-H "Authorization: Bearer YOUR_LOCAL_PROXY_KEY" \
http://localhost:8317/v1/models | jq -r '.data[]?.id'In my case, the useful Codex-backed models included:
gpt-5.5
gpt-5.4
gpt-5.4-miniThe older gpt-5-codex(...) examples were stale for this setup.
Configure Claude Code directly
Conductor exposes this in its UI as:
Claude Code executable path
Claude settings
~/.claude/settings.jsonSo the most reliable place to configure the Anthropic-compatible proxy is Claude Code’s own settings file.
Edit:
~/.claude/settings.jsonUse this shape:
{
"theme": "dark",
"model": "gpt-5.5",
"env": {
"ANTHROPIC_AUTH_TOKEN": "YOUR_LOCAL_PROXY_KEY",
"ANTHROPIC_BASE_URL": "http://localhost:8317",
"API_TIMEOUT_MS": "3000000",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "gpt-5.5",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "gpt-5.5",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "gpt-5.4",
"ANTHROPIC_MODEL": "gpt-5.5",
"ANTHROPIC_SMALL_FAST_MODEL": "gpt-5.4"
}
}Because this file contains a key, lock it down:
chmod 600 ~/.claude/settings.jsonThen test Claude Code without relying on your shell environment:
env \
-u ANTHROPIC_AUTH_TOKEN \
-u ANTHROPIC_API_KEY \
-u ANTHROPIC_BASE_URL \
-u ANTHROPIC_MODEL \
-u ANTHROPIC_SMALL_FAST_MODEL \
-u ANTHROPIC_DEFAULT_OPUS_MODEL \
-u ANTHROPIC_DEFAULT_SONNET_MODEL \
-u ANTHROPIC_DEFAULT_HAIKU_MODEL \
claude -p "Reply exactly: ok" \
--output-format text \
--no-session-persistenceExpected:
okIf that works, Claude Code itself is fine.
Mirror the env in Conductor if needed
Conductor also has Environment settings. In my case, putting the values only in ~/.claude/settings.json was not enough for every Conductor run, so I mirrored the provider env values into Conductor’s local environment store.
From the UI, add local/shared env vars equivalent to:
ANTHROPIC_BASE_URL=http://localhost:8317
ANTHROPIC_AUTH_TOKEN=YOUR_LOCAL_PROXY_KEY
ANTHROPIC_API_KEY=YOUR_LOCAL_PROXY_KEY
API_TIMEOUT_MS=3000000
ANTHROPIC_DEFAULT_OPUS_MODEL=gpt-5.5
ANTHROPIC_DEFAULT_SONNET_MODEL=gpt-5.5
ANTHROPIC_DEFAULT_HAIKU_MODEL=gpt-5.4
ANTHROPIC_MODEL=gpt-5.5
ANTHROPIC_SMALL_FAST_MODEL=gpt-5.4I kept the model names plain here. Reasoning/effort can be controlled by Conductor or CLIProxyAPI, but the first goal is to make routing boring.
Configure Conductor’s defaults
Conductor’s settings file lives at:
~/.conductor/settings.tomlMine ended up like this:
"$schema" = "https://conductor.build/schemas/settings.schema.json"
claude_provider = "anthropic"
codex_provider = "default"
[git]
branch_prefix_type = "github_username"
[models]
default = "gpt-5.5"
review = "gpt-5.5"
[models.claude_code]
default_effort_level = "medium"
review_effort_level = "xhigh"
[models.codex]
default_thinking_level = "high"
review_thinking_level = "high"This handles the Conductor side of the UI. But it was not the final fix.
The real gotcha: Conductor still sent Claude model IDs
Even after changing the settings above, Conductor kept sending requests like:
{
"model": "claude-opus-4-8"
}CLIProxyAPI then did the reasonable thing:
providers=claude, model=claude-opus-4-8But I had only logged in with Codex/OpenAI, not Claude. So CLIProxyAPI returned:
503 auth_unavailable: no auth availableThis is the point where the architecture becomes clearer:
- Conductor may keep insisting on Claude-looking model IDs.
- Claude Code may accept those IDs.
- CLIProxyAPI routes by model name.
- If the model name starts with
claude-*, CLIProxyAPI tries Claude auth unless told otherwise.
So the proxy itself needs to translate those Claude-looking names into Codex-backed models.
Add CLIProxyAPI aliases for Conductor
Edit:
/opt/homebrew/etc/cliproxyapi.confAdd:
# Route Claude Code / Conductor Claude model IDs to Codex OAuth models.
# Conductor may still send claude-* IDs even when configured for GPT models.
oauth-model-alias:
codex:
- name: "gpt-5.5"
alias: "claude-opus-4-8"
fork: true
- name: "gpt-5.5"
alias: "claude-opus-4-8-1m"
fork: true
- name: "gpt-5.5"
alias: "claude-opus-4-7"
fork: true
- name: "gpt-5.5"
alias: "claude-opus-4-7-1m"
fork: true
- name: "gpt-5.5"
alias: "claude-opus-4-6"
fork: true
- name: "gpt-5.5"
alias: "claude-opus-4-6-1m"
fork: true
- name: "gpt-5.5"
alias: "claude-sonnet-4-6"
fork: true
- name: "gpt-5.5"
alias: "claude-sonnet-4-6-1m"
fork: true
- name: "gpt-5.4"
alias: "claude-haiku-4-5-20251001"
fork: true
oauth-excluded-models:
claude:
- "claude-*"Then restart the proxy:
brew services restart cliproxyapiIf Homebrew gets stuck stopping the service, run the restart outside a sandboxed shell or restart the LaunchAgent from your normal terminal.
Test the exact model Conductor sends
This was the important test:
curl -sS \
-H "Authorization: Bearer YOUR_LOCAL_PROXY_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
http://localhost:8317/v1/messages \
-d '{
"model": "claude-opus-4-8",
"max_tokens": 24,
"messages": [
{
"role": "user",
"content": "reply ok"
}
]
}'Once this returned 200, Conductor worked.
I also tested the other names Conductor might send:
claude-opus-4-8
claude-opus-4-8-1m
claude-sonnet-4-6
claude-sonnet-4-6-1m
claude-haiku-4-5-20251001All returned 200 after the alias config.
Keep your shell clean
I initially put the Anthropic env vars in ~/.zshrc. That worked for a normal terminal, but it is cleaner to keep this setup in ~/.claude/settings.json and Conductor’s own environment settings.
That way shell startup does not secretly override unrelated tools.
Debug checklist
If this setup fails, check in this order.
1. Does CLIProxyAPI run?
brew services info cliproxyapi
lsof -nP -iTCP:8317 -sTCP:LISTEN2. Does the local key work?
curl -sS \
-H "Authorization: Bearer YOUR_LOCAL_PROXY_KEY" \
http://localhost:8317/v1/modelsYou should get 200.
3. Does Claude Code read ~/.claude/settings.json?
env \
-u ANTHROPIC_AUTH_TOKEN \
-u ANTHROPIC_API_KEY \
-u ANTHROPIC_BASE_URL \
claude -p "Reply exactly: ok" \
--output-format text \
--no-session-persistence4. What model is Conductor actually sending?
Look at CLIProxyAPI logs:
ls -lt ~/.cli-proxy-api/logs | headOpen the newest error-v1-messages-*.log and search for:
"model":If you see claude-opus-4-8, your Conductor settings are not the deciding layer. Add a proxy alias.
5. Test that exact model directly
curl -sS \
-H "Authorization: Bearer YOUR_LOCAL_PROXY_KEY" \
-H "Content-Type: application/json" \
-H "anthropic-version: 2023-06-01" \
http://localhost:8317/v1/messages \
-d '{"model":"claude-opus-4-8","max_tokens":24,"messages":[{"role":"user","content":"reply ok"}]}'If this returns 200, the proxy side is fixed.
Final shape
Once the aliases are in place, the Claude Code runner path in Conductor can use the same local proxy path:
The main trick is not the Claude Code env. It is making sure the proxy translates the Claude model IDs that Conductor actually sends.
Related Articles
Using Factory Droid with Claude Max & OpenAI Codex Subscriptions via CLIProxyAPI
Connect Factory Droid to your Claude Max and OpenAI Codex subscriptions using CLIProxyAPI as a local OAuth-to-API-key proxy. Covers installation, latest model configuration, and troubleshooting for Claude Opus 4.7, Sonnet 4.6, GPT-5.5, and more.
macoshappymode: a tiny macOS menu bar app that keeps Dark Mode on schedule
A behind-the-scenes look at happymode: a native macOS menu bar utility that switches system appearance using sunrise/sunset (no external APIs) or custom daily times, with a weekly preview and permission-aware UX.