Do this at your own risk.This is what I did on my own Mac. Windows steps are included but untested. It is not a supported product, and you accept these risks by continuing.
Unofficial. It uses the same OpenAI endpoint as the Codex app. It can break or be blocked at any time.
Your account, your call. Read OpenAI's and OpenRouter's terms yourself.
It can break Codex. Back up your config first (Step 1).
It costs money. OpenRouter bills every request. Set a spending limit.
Keys stay in the Keychain (Mac) or Credential Manager (Windows). Never in chat or config files.
Not affiliated with OpenAI, Anthropic or OpenRouter. Tested on the Codex Mac app, September 2026.
Codex + OpenRouter
GPT and OpenRouter models in one Codex picker
What broke, why it broke, and the exact prompt to give Claude Code to build the fix. When my Codex limits run out, I switch to a cheaper model without leaving the app.
What happened
Codex broke its own picker
The idea
I kept hitting my Codex limits. So I asked Codex to add OpenRouter models to its own model picker, so I could keep working on something cheaper.
Codex
It built it. The picker filled up with OpenRouter models, and every GPT model disappeared. Then every model, old and new, failed with the same error.
Claude Code
I showed Claude Code the screenshots. It read Codex's own config, logs and task database, found the cause, and got my GPT models back. Then it built a small router so both sets of models live in one picker.
This is the error every model threw:
The 'deepseek/deepseek-v4.1-flash' model is not supported when using Codex with a ChatGPT account.
Why it broke
Three facts about Codex nobody tells you
These are what Claude found by reading Codex's files. If you ask any AI to build this without them, it will probably break Codex the same way.
A custom model list replaces the whole list.Codex's model_catalog_json setting does not add models. It swaps out the entire catalog, so your GPT models vanish unless you put them back in yourself.
A model list has no provider per model.Codex sends every model in the picker to the same provider. Your ChatGPT sign-in only accepts OpenAI's own model names, so it rejects deepseek/..., and a pure OpenRouter setup has no access to your ChatGPT plan.
Each task remembers its provider.The provider is saved when a task is created. Change the setup and your old tasks still use the old provider and keep failing. After any change, start a new task.
The fix
A small router on your own computer
Codex talks to one provider: a tiny program running on your computer. That program looks at the model name and sends the request to the right place.
Codex appone picker, all models
→
Local routerruns only on your computer
ChatGPT plannames with no slashgpt-5.5
OpenRouternames with a slashdeepseek/deepseek-v4.1-flash
Your GPT models keep using your ChatGPT plan. Everything else is billed to your OpenRouter credit. You pick either from the same list.
Before you start
What you need
The Codex desktop app on a Mac, signed in with your ChatGPT account. On Windows, see the Windows section below first.
An OpenRouter account with credit and an API key (set a spending limit on the key)
Claude Code set to Claude Opus 5.5, to do the build
Python, which Claude will check for you
Codex fully quit while the config changes
Step 1
Back up your Codex config (Mac)
Open Terminal and run this. It is your way back if anything goes wrong.
Run this yourself, not through an AI. It asks for the key and stores it in the macOS Keychain, so it never sits in a file or a chat log.
security add-generic-password -s codex-router -a OPENROUTER_API_KEY -w
Paste your key when it asks for a password, then press Return. Nothing shows as you paste. That is normal.
Step 3
Give Claude Code this prompt
Make an empty folder, open Claude Code in it, switch the model to Claude Opus 5.5, and paste the whole prompt. It carries every lesson from my build, so Claude does not have to rediscover them by breaking your Codex first.
I use the Codex desktop app on macOS, signed in with my ChatGPT account. I want my ChatGPT models AND OpenRouter models in the same Codex model picker, both working. Build this in the current folder. Test every piece before you tell me it works.
FACTS ABOUT CODEX YOU MUST WORK WITH
- model_catalog_json replaces Codex's entire model list. There is no per-model provider setting.
- The provider is saved per task when the task is created. After any change, only NEW tasks pick it up.
- A ChatGPT-login provider rejects any model name it does not recognise.
RULES
- I have already backed up ~/.codex/config.toml. Make your own timestamped copy too before changing it, and give me a one-command restore.
- My OpenRouter key is in the macOS Keychain: service "codex-router", account "OPENROUTER_API_KEY". Read it from there at runtime. Never write it to disk, never print it, never put it in config.toml.
- Do not print the contents of ~/.codex/auth.json or any token.
- Tell me before you change anything in ~/.codex.
BUILD
1. A small local router in Python (standard library only) on localhost, protected by a random local token.
- Model names WITHOUT a slash (gpt-...) go to the ChatGPT Codex backend, using the login Codex already stores in ~/.codex/auth.json, refreshing the token when it expires.
- Model names WITH a slash (deepseek/..., google/..., z-ai/...) go to OpenRouter's Responses API with my key.
2. A merged model catalog: Codex's own models first, then OpenRouter models that support tool calling. Put the vendor and version in each display name so I can tell models apart, and put the price in the description. Hide models without tool support.
3. A custom provider in config.toml that points Codex at the router, with an auth command that also starts the router if it is not running. Keep every change inside clearly marked BEGIN and END comments so it can be removed cleanly.
4. Three switch scripts I can double-click: mixed (GPT + OpenRouter), ChatGPT only (restores my original config), OpenRouter only.
FOR OPENROUTER REQUESTS THE ROUTER MUST
- remove Codex's built-in web_search tool (OpenRouter rejects it)
- drop the reasoning field when effort is "none" or missing (reasoning models reject it), and offer low, medium and high effort for models that support reasoning
- remove empty enum values and empty anyOf or oneOf lists from tool schemas (Google models reject them)
- cap google/* models at 512 tool functions, dropping the largest MCP servers first
- let me list MCP servers to leave out of OpenRouter requests, to keep cost down
- log model name, status code and the upstream error text, never request bodies or keys
TEST
Using my real Codex config (not a stripped-down test config, it hides tool-list errors), run a throwaway Codex session and have one GPT model and two cheap OpenRouter models each create a file on disk. Confirm the files exist. Tell me what each request cost, then tell me to restart Codex and open a NEW task.
Read what Claude does before you approve it. It will ask to edit files in ~/.codex. Approve only changes you understand, and say no to anything that prints or copies a key.
Step 4
Test it in Codex
Quit Codex completely and reopen it.
Start a new task. Old tasks will not switch over.
Pick a cheap OpenRouter model and ask it to create a file called hello.txt.
Check the file exists. Then switch to a GPT model in another new task and do the same.
The first message in a new task can sit for a while before anything happens. That is Codex starting your MCP servers, not the router. If one of your servers is broken, Codex waits for it to time out.
Windows
On Windows: untested, use these steps instead
I have not run this on Windows. The Codex app does run on Windows, and the router is plain Python, so it should work. But nobody has tested these steps. Expect Claude to need a few rounds of fixes.
These steps assume Codex runs natively on Windows, which is the default. If you switched Codex to WSL in its settings, use the Mac steps inside WSL instead, because WSL keeps its own separate Codex folder.
Paste this block first, then the main prompt from Step 3 above. Where the two disagree, this block wins.
I am on Windows, running the Codex desktop app natively (not in WSL). Adjust everything below for Windows:
- My Codex folder is %USERPROFILE%\.codex, not ~/.codex.
- My OpenRouter key is NOT in a macOS Keychain. It is a generic credential in Windows Credential Manager, target "codex-router". Read it at runtime with Python's ctypes (CredReadW). Never write it to a file or print it.
- Make the switch scripts .bat files I can double-click.
- Use the full path to python.exe in the config's auth command, and start the router in the background without leaving a console window open.
- If you find Codex is set to run in WSL, stop and tell me before building anything.
Then follow Step 4 as normal: restart Codex, open a new task, test with a cheap model.
Troubleshooting
Every error I hit, and the fix
What you see
Why
Fix
"not supported when using Codex with a ChatGPT account"
The model list was replaced, or the task was created under the old provider.
Use the router, then start a new task.
OpenRouter model: nothing happens
Codex is still starting MCP servers on the first message of a new task.
Wait, or remove MCP servers that fail to start.
Error mentioning web_search
OpenRouter does not accept Codex's built-in web search tool.
The router strips it.
"Reasoning is mandatory"
Codex sent reasoning effort "none" to a model that must reason.
Drop the field, offer low, medium and high.
Gemini: an enum "cannot be empty"
Some MCP tool schemas contain an empty option. Google rejects it.
Clean the schemas in the router.
Gemini: too many functions
Google caps function declarations per request at 512. Codex can send far more.
Cap google/* models at 512.
"Provider returned error" or big bills
Codex sends every tool from every MCP server with each request.
Leave your biggest MCP servers out of OpenRouter requests.
It worked yesterday, not today
A Codex update changed something the router depends on.
Switch to ChatGPT only, then ask Claude to read the router log.
Cost
What a request cost in my test
Measured on my setup with a large tool list (~165k tokens per request, uncached). Yours will be different. Fewer MCP servers means cheaper requests.
DeepSeek V4.1 Flash
$0.025
Gemini Flash Lite
$0.049
Gemini Flash
$0.25
Kimi K3
$0.50
GPT-5.5 via OpenRouter
$0.83
Claude Fable 5.1
$1.65
My whole test run cost about $1.19 in OpenRouter credit. GPT models in the picker keep using your ChatGPT plan, not OpenRouter credit.
Credit
Who did what
Codex wrote the first version, the one that broke. Claude Code fixed it, in two parts:
Claude Fable 5.1Read Codex's logs and config, found why every model failed, restored the GPT models and built the router.
Claude Opus 5.5Got the OpenRouter models actually answering: the tool-schema fixes, the Gemini limit, the cost cuts and a readable picker.