A lightweight local dashboard for managing Codex model settings, reasoning effort, service tier, and custom OpenAI-compatible API providers from a browser UI.
This project runs locally on your machine and updates your Codex configuration without requiring you to manually edit config.toml.
- Switch Codex models from a local web dashboard
- Change reasoning effort and service tier in real time
- Reasoning levels are read dynamically from the Codex model cache (e.g. low, medium, high, xhigh, max, ultra)
- Add and manage custom OpenAI-compatible API providers
- Route custom models through a local OpenAI-compatible proxy
- Show non-GPT models in the Codex App picker using native model aliases
- Automatically create configuration backups before changes
- Restore previous Codex configuration backups
- Mask local user paths in the UI for better privacy
- Keep API credentials local and out of Git
Codex Switcher starts a local Express server and serves a browser-based dashboard at:
http://localhost:3777
The app reads and updates your local Codex files:
C:\Users\XXXXX\.codex\config.toml
C:\Users\XXXXX\.codex\models_cache.json
C:\Users\XXXXX\.codex\auth.json
When passthrough is enabled, the config uses the native OpenAI transport and points it at the local proxy/catalog:
model_provider = "openai"
openai_base_url = "http://127.0.0.1:3777/v1"
model_catalog_json = "C:\\path\\to\\merged-models.json"
chatgpt_base_url = "https://chatgpt.com/backend-api/codex"The project does not require [model_providers.customProvider] or another
custom provider table. Requests are routed by the selected model.
Custom provider data is stored locally in:
providers.json
providers.jsonis intentionally ignored by Git because it may contain API keys.
- Windows
- Node.js 18 or newer
- npm
- Codex installed and configured locally
Clone the repository:
git clone https://github.com/airplanestar888/Codex-Switcher.git
cd Codex-SwitcherInstall dependencies:
npm installOptional: create a local provider config from the example file:
cp providers.example.json providers.jsonThen edit providers.json or add providers from the web dashboard.
Start the local server:
npm startOr:
node server.jsOpen the dashboard:
http://localhost:3777
On Windows, you can also run:
run swap.bat
The dashboard can read available models from your local Codex model cache and display them in the UI. Selecting a model updates your local Codex configuration.
The app updates values such as:
model = "..."
model_reasoning_effort = "..."
service_tier = "..."You can add custom OpenAI-compatible providers from the dashboard by entering:
- Provider name
- Base URL
- API key
- Model IDs
Example provider format:
{
"providers": [
{
"id": "example-provider",
"name": "Example Provider",
"baseUrl": "https://example.com/v1",
"apiKey": "YOUR_API_KEY_HERE",
"rateLimitPerMin": 120,
"rateBurst": 5,
"models": [
"example-model"
]
}
],
"activeProviderId": null,
"activeProviderModel": null
}rateLimitPerMin (optional) is the provider's request limit per minute. The proxy
paces outgoing requests with a token bucket so it never exceeds this rate, and
retries with backoff when a 429/5xx still slips through. When omitted (or set to
"auto"), the bucket runs in AUTO mode: it starts unthrottled and learns the
provider's real limit from 429 response headers (Retry-After / X-RateLimit-*),
so you never have to hardcode a limit per provider. rateBurst (optional) is how
many requests may fire instantly before pacing kicks in; when omitted it is
derived from the rate (or auto-detected in AUTO mode).
When passthrough is enabled, Codex Switcher routes requests through the local proxy:
http://127.0.0.1:3777/v1
Native Codex model slots are used as aliases because some Windows Codex App
versions hide namespaced external slugs such as provider/model from the
picker. For example:
gpt-5.6-terra -> bynara/gpt-5.6-luna
gpt-5.6-luna -> step-flash/step-3.7-flash
gpt-5.5 -> rift-ai/gpt-5.6-luna
gpt-5.4-mini -> bseten/deepseek-ai/DeepSeek-V4-Flash-0731
The mapping is stored in the local, generated native-aliases.json file. The
Codex App sees the native-looking slot, while the proxy translates it to the
actual external provider/model and injects the provider API key locally.
This alias behavior is intentional and is needed for Desktop builds that can
read model_catalog_json but still filter external models from the picker.
After changing providers, fully quit Codex (Ctrl+Q), ensure codex.exe has
exited, then reopen it so the catalog is reloaded.
Before modifying your Codex configuration, the app creates a backup in:
C:\Users\XXXXX\.codex\Backup
Only the most recent backups are kept automatically.
You can restore backups directly from the dashboard.
This project is designed to keep sensitive data local.
The following files are ignored by Git:
providers.json
.env
.env.*
node_modules/
Do not commit real API keys, tokens, or personal credentials.
Use providers.example.json as a safe template for sharing provider configuration format.
.
├── public/
│ ├── index.html # Web dashboard
│ └── style.css # Dashboard styles
├── server.js # Express server, API routes, local proxy
├── merged-models.json # Generated native + routed picker catalog
├── native-aliases.json # Generated native-slot to provider/model mapping
├── package.json # npm scripts and dependencies
├── providers.example.json
├── run swap.bat # Windows helper script
└── README.md
npm start
npm run devBoth scripts start the local server.
Make sure the server is running:
npm startThen open:
http://localhost:3777
Make sure Codex has already generated a local model cache at:
C:\Users\XXXXX\.codex\models_cache.json
If no cache exists, the dashboard falls back to a default model display.
For the Windows Codex App, the picker can hide namespaced external slugs even
when codex debug models and model_catalog_json contain them. Enable
passthrough to generate native aliases, then fully quit Codex with Ctrl+Q
and reopen it. Confirm that codex.exe is no longer running before reopening.
Check the generated files:
node -e "console.log(require('./native-aliases.json'))"
node -e "console.log(require('./merged-models.json').models.map(m => m.slug))"The active config should contain an absolute catalog path and no custom provider table:
model_provider = "openai"
model_catalog_json = "C:\\path\\to\\merged-models.json"Check that:
- The provider Base URL is correct
- The API key is valid
- The selected model ID exists on that provider
- The provider supports OpenAI-compatible chat completions
This repository does not currently include a license file. Add one before distributing or using it in production environments.