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.
Desktop app only. This works in the Codex desktop app on your own computer. It does not work in ChatGPT on the web, the phone app, or Codex cloud tasks.
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 01).
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.
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
Claude found these by reading Codex's files. Without them, any AI you ask to build this 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 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 old tasks keep using the old provider. After any change, start a new task.
Before you start
What you need
The Codex desktop app on a Mac, signed in with your ChatGPT account. On Windows, read the Windows section first. The web version of ChatGPT will not work: the router runs on your computer, and only the desktop app can reach it.
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. Codex can run the same prompt instead (see Step 03).
Python, which the AI will check for you.
Codex fully quit while its settings change.
Step 01
Back up your Codex config
Your way back if anything goes wrong. Open Terminal and run this.
Check it worked: a file called config.toml.backup now sits in your ~/.codex folder.
To undo everything later, quit Codex and run cp ~/.codex/config.toml.backup ~/.codex/config.toml.
Step 02
Put your OpenRouter key in the Keychain
Run this yourself, not through an AI. The key goes into the macOS Keychain, so it never sits in a file or a chat log.
Run in Terminal (Mac)
security add-generic-password -s codex-router -a OPENROUTER_API_KEY -w
Check it worked: it asked for a password, you pasted your key and pressed Return, and it finished without an error. Nothing shows as you paste. That is normal.
Step 03
Run the build 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 the AI does not rediscover them by breaking your Codex first.
Build prompt
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.
- While a custom provider is active, Codex stops refreshing its own copy of the ChatGPT model list, so new OpenAI models never appear. The router must fetch the live list itself.
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: the live ChatGPT model list 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. Refresh the ChatGPT list whenever the Codex app updates.
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.
Prefer to stay in Codex? Paste the same prompt into a new Codex task and Codex can build it for you, no Claude Code needed. I built mine with Claude Code, so the Codex route is untested, but it should work. Back up first (Step 01), because Codex is editing its own settings, and quit and reopen Codex when it finishes.
Check it worked: the AI reports three test files created on disk, one per model, with a cost for each request.
Read what the AI does before you approve it. Whichever tool you use, 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 04
Test it in Codex
Start small. One new task, one cheap model, one file.
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.
Switch to a GPT model in another new task and do the same.
Check it worked: both files exist, and your GPT models are still at the top of the picker.
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. A long answer with several tool calls can also take a couple of minutes, so check before assuming it is stuck.
On Windows
Untested. Use these steps instead.
The Codex app runs on Windows and the router is plain Python, so it should work. Nobody has run these steps yet. Expect the AI 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, follow the Mac steps inside WSL instead, because WSL keeps its own Codex folder.
Step 03 on Windows: paste this first, then the build prompt
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 04 as normal.
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.
A new OpenAI model is missing after an update
Codex stops refreshing its own model list while the router is on.
The router fetches the live list. Restart Codex, and restart once more if the model still hides.
It worked yesterday, not today
A Codex update changed something the router depends on.
Switch to ChatGPT only, then ask the AI to read the router log.
Doing a live demo or a client call? Switch to ChatGPT only first, so the picker looks standard. Switch back afterwards.
Cost
What a request cost in my test
Measured on my setup with a large tool list (~165k tokens per request, uncached). Yours will differ. 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.
Who built 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.
Your next step
Build with a community behind you.
Join the AI Lead Builder community for practical support putting AI to work in your business.
Your membership brings together weekly coaching with Muhammad, training and call replays, business software, and the Agency OS plugin.
Learn and get help
Weekly coaching, training, and a community of business owners.
Build and put it to use
Agency OS plus software for your CRM, funnels, and follow-up.
Hear from Jerry Relth
AI Lead Builder member · Healthcare software, USA
The weekly calls "absolutely changed the way that I do business."
Jerry Relth · AI Lead Builder member, healthcare software, USA
"Agency OS gave me the system, the community gave me the momentum."
Paul Meyers · Agency owner, Canada
"The system is excellent, but the community is why it sticks."