Switch between OpenAI Codex CLI provider configurations (official ChatGPT login, third-party relays, multiple API keys). CLI + Alfred workflow.
Project description
codex-profile-switcher
One-key switch between OpenAI Codex CLI configurations — official ChatGPT login, third-party relays, multiple API keys, whatever. CLI + optional Alfred workflow.
Each profile owns the provider slice of ~/.codex/config.toml (model, [model_providers.*], auth method) plus its own auth.json. Your local state (trusted projects, plugins, marketplaces, MCP servers, TUI prefs) is left untouched on every switch.
Install
Requires uv.
uv tool install codex-profile-switcher
This puts codex-switch on $PATH (default ~/.local/bin/). Run uv tool update-shell once if your shell can't find it.
Upgrade later with uv tool upgrade codex-profile-switcher; uninstall with uv tool uninstall codex-profile-switcher.
No-install (one-off)
uvx --from codex-profile-switcher codex-switch ls
uvx resolves and caches an ephemeral environment per invocation. Convenient for trying it out, slower for hot paths like Alfred — use uv tool install if you want the workflow to feel snappy.
Development version
Install directly from GitHub when you want the latest commit before it is released to PyPI:
uv tool install git+https://github.com/kadaliao/codex-profile-switcher.git
Alfred (optional)
After uv tool install, double-click alfred/codex-profile-switcher.alfredworkflow. Trigger with keyword cx.
The workflow calls $HOME/.local/bin/codex-switch; if uv tool install put the binary elsewhere (uv tool dir --bin to check), edit the two script blocks in the workflow's plist accordingly.
CLI
codex-switch # interactive picker (↑/↓, enter to switch, q to cancel)
codex-switch ls # list profiles, ★ marks the active one
codex-switch current # print the active profile
codex-switch official # switch back to official OpenAI ChatGPT login
codex-switch openai # alias of `official`
codex-switch use [name] # load <name>; omit for the picker
codex-switch save <name> # snapshot the current ~/.codex state as <name>
codex-switch show <name> # print <name>'s provider.toml + auth.json key names
codex-switch state <name> # show/set the session-state scope for a profile
codex-switch merge-history --dry-run
# preview history metadata changes without writing files
codex-switch doctor-history
# inspect current history provider/model state read-only
codex-switch rm <name> # delete profile (the active one is protected)
codex-switch alfred-list # JSON for Alfred Script Filter
The picker auto-falls back to a numeric menu when stdin/stdout aren't TTYs (pipes, scripts).
Official OpenAI shortcut
codex-switch official is the one-step way back to the official OpenAI ChatGPT login.
- The tool keeps a hidden
~/.codex/profiles/.official/snapshot for the official config/auth. - The first time you switch away from an official OpenAI session, that snapshot is refreshed automatically.
codex-switch openaiis an alias if you prefer typing the provider name directly.
Shared history by default
After every use / official switch, codex-switch automatically aligns local Codex history metadata to the active provider and model identity.
- You no longer need to remember
merge-historyduring normal profile switching. - This keeps session history visible when moving between relay profiles and the official OpenAI login, including surfaces that filter by model id.
merge-history --keep-modelsstill exists if you want a provider-only repair and need to preserve historical per-thread model ids.merge-history --dry-runreports rollout files/lines, SQLite rows, and the backup path it would create without writing anything.doctor-historyis read-only and summarizes the active profile, current provider/model, session-state mode, SQLitethreadsdistribution, recent threads, planned alignment counts, and provider/model drift.
Profile format
~/.codex/profiles/
├── .active # plaintext: name of the active profile
├── chatgpt-official/
│ ├── auth.json # full file copied into ~/.codex/auth.json
│ └── provider.toml # empty = use ChatGPT login
└── myrelay/
├── auth.json # {"OPENAI_API_KEY": "sk-..."}
└── provider.toml # only provider-related keys (see examples/)
The following top-level keys + tables are owned by a profile (swapped on use); everything else in ~/.codex/config.toml is preserved:
model,model_provider,model_reasoning_effort,model_reasoning_summary,model_verbositywire_api,disable_response_storage,preferred_auth_method[model_providers.*]
Adding a relay profile
- Configure the relay normally in
~/.codex/{config.toml,auth.json}and verifycodexworks. codex-switch save <name>— snapshots the provider slice + auth.json into a new profile.cxin Alfred (orcodex-switch use <name>) to switch anytime.
Or build the files by hand — see examples/relay-profile/.
Env overrides
| Var | Default | Purpose |
|---|---|---|
CODEX_PROFILE_ROOT |
~/.codex/profiles |
where profiles live |
CODEX_HOME |
~/.codex |
the codex config dir to write |
Releasing
Packages are published on PyPI as codex-profile-switcher.
Automated releases use GitHub Actions with the PYPI_API_TOKEN repository secret.
-
Update
versioninpyproject.toml. -
Run
uv run python -m unittest tests.test_clianduv build. -
Commit the version bump and push
main. -
Create and push a matching tag:
git tag vX.Y.Z git push origin vX.Y.Z
The Publish to PyPI workflow verifies that the tag version matches pyproject.toml, runs tests, builds the wheel and sdist, checks the distributions, and publishes them to PyPI. Manual local publishing is still possible with uvx twine upload dist/* when needed.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file codex_profile_switcher-0.5.1.tar.gz.
File metadata
- Download URL: codex_profile_switcher-0.5.1.tar.gz
- Upload date:
- Size: 147.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
766e597721a9e051041f9f4563dc6640fa820f5e915ff8493c64a282f9a18bf1
|
|
| MD5 |
0cddff88aef949f177cd07ac383c2557
|
|
| BLAKE2b-256 |
2742f074f38edfca86007af3cafd156c40f3c86ba1789cabb247155207fd4fe3
|
File details
Details for the file codex_profile_switcher-0.5.1-py3-none-any.whl.
File metadata
- Download URL: codex_profile_switcher-0.5.1-py3-none-any.whl
- Upload date:
- Size: 16.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
92b1de2f41671f4f3a790081c9abc318f515a665ba83ed1f6dc3b304fe0f7575
|
|
| MD5 |
5f690fab8147e959c8a7e12c4b4d63cc
|
|
| BLAKE2b-256 |
590b9801eb074f93a91d896168f5646f42dd04c910374b54b4ebbfe09a84231d
|