Skip to content

Repository files navigation

CodexMulti

English · 한국어 · 日本語 · 简体中文 · Español

CodexMulti — one Mac, many Codex accounts, with automatic failover

When one Codex account hits its limit, keep going with the next.

CodexMulti puts your Codex accounts in one macOS menu-bar app. Track each account’s usage and reset times, choose their order, and let automatic failover handle confirmed usage-limit errors.

Download · Changelog · Security · Contributing

Latest release CI

  • See your whole pool. Account usage, reset times and failover states are together in one window. The menu bar keeps the pool summary close by; Accounts… opens the full list in one click.
  • Set the order once. Drag accounts into your preferred order. When an eligible request hits a confirmed usage limit, the proxy tries the next available account.
  • Choose automatic participants. Turn off Include in automatic switching in an account menu to make it Manual only. You can still select it yourself; automatic failover and pool capacity exclude it. The setting survives restarts.
  • Turn on one switch. Failover setup includes the local proxy and its Node runtime. Added or reconnected accounts are picked up automatically while the app is open.
  • Keep credentials local. Each account has its own Codex directory and Keychain backup. There is no CodexMulti account to create or hosted service to connect to.

CodexMulti menu with pooled capacity, account usage, reset times and the active account, using demo accounts

Light · Dark

Your pool, account usage and reset times — one click from the menu bar. Demo accounts shown.

What is Failover, and why use it?

A coding task can stop when one Codex account reaches its usage limit, even if another account still has capacity. Without automatic switching, you have to choose another account and retry the request yourself.

Failover automatically tries the next available account when the current one returns a confirmed usage-limit error. Add your accounts, put them in your preferred order, and turn on Use Failover. CodexMulti routes eligible Codex requests through a local proxy on your Mac.

For example, if account A reaches its limit before a response starts, the proxy retries that request with account B. If B is also at its limit, it tries the next eligible account. You can keep working without manually changing the account for each limit error.

The accounts keep their own subscriptions and limits; Failover makes their available capacity easier to use. It does not replay a response that has already started or retry every kind of error. See when account switching happens for the exact conditions.

Install

You need an Apple Silicon Mac running macOS 26 or later, Codex CLI 0.146.0 or later with ChatGPT sign-in, and at least two accounts for failover to be useful.

brew install --cask moonsunkim/tap/codexmulti

Or use the latest release. Releases from 0.2.1 onward are Developer ID signed and notarized by Apple.

Script installer or manual installation
curl -fsSL https://raw.githubusercontent.com/moonsunkim/codexmulti/main/install.sh | bash

The installer checks the release's published SHA-256, preserves an existing app as CodexMulti.app.previous, installs to /Applications, and opens the app in the background. It preserves Gatekeeper quarantine attributes.

For manual installation, download CodexMulti-<version>.zip and the matching .sha256 file. Put both in one directory, then verify the archive before expanding it:

shasum -a 256 -c CodexMulti-<version>.zip.sha256

Move the verified CodexMulti.app into /Applications and open it.

For an existing installation, use Settings → Software update → Check for updates for normal upgrades. If Set up safe updates appears, close Codex clients and complete that one-time setup first. Checks and installation are started by you; see in-app updates.

Two steps to get going

  1. Add your accounts. Click +, give the account a name, and complete the official browser sign-in. Repeat for the accounts you want in the pool.
  2. Turn on Use Failover. Open Settings. The app prepares its bundled proxy, checks that it is working, and connects Codex to it.

Use Codex as usual. If an account returns a confirmed usage-limit error before a response starts, the same request can continue through the next eligible account. Paused, invalid and cooling accounts are skipped.

Account additions, reconnections and order changes are applied automatically while the app is open. Changes that need a proxy reload wait for active requests to finish. Closing the menu-bar app leaves a healthy proxy running; turning Failover off restores direct Codex connections after active requests finish.

Open Accounts… from the menu bar to see your full pool. In an account's … menu, Use in failover… selects that account for new requests. Pause in failover excludes it from receiving new requests; Resume in failover includes it again. Requests already in flight continue on their current account.

Account rows show used capacity for the displayed period: 100% means that limit is exhausted. Pool shows the average weekly capacity remaining across included accounts with reported weekly usage. Paused and invalid accounts are excluded; cooling accounts still contribute to this average. It is not a combined token allowance or a count of accounts ready to accept a request.

Usage is a saved snapshot. Refresh one account from its … menu, or use Refresh All Accounts. Scheduled refresh is Off by default; Settings offers 15 min, 30 min or 1 hour. Refresh also updates the local proxy status. Rename… changes the name displayed in CodexMulti, not the account’s OpenAI email.

CodexMulti light and dark appearance showcase based on demo account screenshots

Original screenshots: Light · Dark

Refresh, appearance, language, usage-window and Failover settings in CodexMulti

Light · Dark

Choose your usage refresh interval, preferred usage window and theme. The language menu supports System, English, 한국어, 日本語, 简体中文 and Español. Simplified Chinese uses zh-Hans; Spanish uses the shared es catalog. System mode recognizes Simplified Chinese and regional Spanish preferences; Traditional Chinese is not translated yet. See i18n maintenance to add or update translations.

Take a closer look at an account

Expand an account to see its usage windows, authentication and failover status, last refresh, and reported reset credits.

When the provider reports an available credit, the account menu can offer Use one reset…. A fresh preflight and two confirmations are required before spending one existing credit. Clear cooldown… is a separate action for a limit already reset elsewhere; it does not redeem a credit.

Expanded account details showing usage, token status, refresh time and available reset credits

Light · Dark

All screenshots use synthetic accounts.

When will it switch accounts?

Only after a confirmed usage-limit response: a pre-stream HTTP 429 with error type usage_limit_reached, that same response during a WebSocket handshake, or a usage_limit_reached error inside a Responses WebSocket before any response event reaches the client. Each eligible account is tried at most once for the request.

Manual switching applies to the next request even when Codex reuses an existing WebSocket. Responses already running finish on their original account. Conversation context is carried forward when an account changes; independent streams can continue without being interrupted. If the complete continuation is no longer cached, the client must resend full context; the proxy does not silently omit conversation history.

Network failures, 5xx, interrupted streams, plan mismatches, usage_not_included and unrecognized 429 responses stop the request. A response that has already started is not replayed on another account. If no eligible account remains, the request fails rather than retrying indefinitely.

The app does not increase an account's limits or change its subscription. Proxy compatibility tracks the Codex CLI; see the release notes before upgrading.

Your accounts stay on your Mac

There is no telemetry, analytics or CodexMulti-hosted control plane. Authentication, usage checks and inference contact provider services directly. The proxy listens on loopback and its control API uses a private per-user capability.

Each account uses an isolated Codex home. Credentials remain local, with a Keychain backup; your personal ~/.codex/auth.json is not replaced. Enabling Failover edits only the two managed base-URL entries in ~/.codex/config.toml and leaves a timestamped backup. Turning it off restores direct routing.

See Security and proxy security for the trust boundary and log-handling details.

Build from source

You need Zig 0.16.0 on PATH, Xcode (or the Command Line Tools) with Swift 6 and the macOS 26 SDK, and macOS 26 on Apple Silicon.

./app/scripts/fetch-node.sh                                        # pinned Node, SHA-256 verified
./app/scripts/build-app.sh                                         # → app/dist/staging/CodexMulti.app
./app/scripts/screenshots.sh
./app/scripts/verify-provenance.sh app/dist/staging/CodexMulti.app
./app/scripts/verify-bundled-proxy.sh app/dist/staging/CodexMulti.app

The build compiles the core as an aarch64-macos object, links it into the Swift executable, and assembles the bundle with the pinned Node binary and the proxy source. Provenance markers record the core source digest, the bridge schema, the proxy commit, a digest of the bundled proxy tree, and the Node hashes; verify-provenance.sh recomputes them rather than trusting the text.

Tests:

(cd core && zig build test && zig build test-bridge)
(cd app && CODEXMULTI_TEST_HEADLESS=1 swift test)   # never plain `swift test`: it opens windows
(cd proxy && npm test)
(cd updater && CODEXMULTI_TEST_HEADLESS=1 swift test)

CI checks the Zig core, Node proxy, SwiftUI shell and distribution scripts on macOS. The SwiftUI shell job runs with the macOS 26 SDK.

Signing and release packaging are separate from the ordinary build: app/scripts/package-signed-macos.sh audits the local signing identity, signs the bundled Node and then the app inside-out, and refuses a bundle whose provenance or designated requirement does not match.

How it is built

Part Responsibility
SwiftUI app Windows, menus, accessibility and macOS integration.
Zig core Accounts, background work, guarded routing changes, and all UI text.
Node proxy Local request forwarding and failover across eligible accounts.
Native updater Signed runtime staging, request admission fencing and crash recovery.

The app sends typed intents to the core and renders its returned state. The proxy runs independently as a per-user LaunchAgent, so requests can continue after the menu-bar app closes. Both the proxy and its pinned Node runtime are bundled in the app. After one-time update setup, the running proxy uses a verified immutable copy under ~/Library/Application Support/CodexMulti/runtimes/.

In-app updates

Open Settings and use Software update. The first setup asks you to close Codex clients because older installations do not have the atomic request admission fence. Later updates preserve the running proxy while the app is replaced. A changed proxy runtime waits until HTTP requests, WebSocket connections and credential refreshes have finished. A UI-only update keeps the current proxy process. New connections can fail briefly during a runtime switch; active requests are never forcefully cut or replayed.

Account changes pause during an update. Settings shows the pending update and offers cancellation before the stop is committed, or Turn off when requests finish. The update agent survives the menu-bar app closing. If the new runtime cannot start, it restores the previous compatible runtime. A live but unreachable process requires recovery rather than being forcibly stopped. Show previous app opens the retained signed app when app installation needs manual recovery.

Update checking is enabled in release builds with an HTTPS feed and pinned Sparkle public key. Local builds without an update feed show that distribution configuration is unavailable. See the update design and implementation constraints and release configuration.

Recovery, removal and manual routing repair

The app retries recovery while Failover is enabled. If a change must wait for active requests, its status explains the wait. Turn Failover off to restore direct Codex routing after those requests finish.

For an installation with safe updates configured, quit Codex clients and the CodexMulti menu-bar app, then run:

"/Applications/CodexMulti.app/Contents/Helpers/codexmulti-update-agent" prepare-removal \
  --app "/Applications/CodexMulti.app" \
  --config "$HOME/.config/codexmulti/proxy.json"
brew uninstall --cask codexmulti

Use your configured proxy config path if it differs. Preparation waits for requests to finish, restores only CodexMulti's routing entries, and removes its automatic-start registration. If it reports proxy_busy, the agent continues waiting; retry preparation after clients have finished. Account credentials, usage history and reset records remain available for reinstall.

The cask verifies explicit removal preparation before deleting the app. It is marked auto_updates; use the in-app updater for normal upgrades. Homebrew does not give its uninstall script a reliable upgrade-versus-removal signal, so unprepared --greedy upgrades and reinstalls stop before replacing the app. They do not silently turn Failover off. --zap additionally removes saved account data. For an older installation without the native update helper, keep using its bundled codexmulti-maintenance prepare-uninstall procedure before removal.

If the app or helper cannot run, open ~/.codex/config.toml in a text editor. Remove only these exact root-level entries when present, preserving all other settings:

chatgpt_base_url = "http://127.0.0.1:8787/backend-api/"
openai_base_url = "http://127.0.0.1:8787/backend-api/codex"

The following service-removal check is for legacy agents that launch Node directly. Managed-runtime installations use codexmulti-runtime-launcher; use the native helper or the recovery controls described above for those installations. Do not force-stop a managed runtime with active requests.

Then inspect launchctl print "gui/$(id -u)/dev.codexmulti.app.proxy". Only if its program arguments point to your CodexMulti app's Contents/Helpers/node, Contents/Resources/proxy/src/server.mjs, --config, and your proxy config, stop it with launchctl bootout "gui/$(id -u)/dev.codexmulti.app.proxy" and remove ~/Library/LaunchAgents/dev.codexmulti.app.proxy.plist. Restart Codex clients so they reread the direct-connection configuration. Do not replace the whole shared config with an old backup.

Proxy control requires a private per-user capability. Ordinary Codex proxy traffic is trusted at the local-machine level, so use it only on a Mac with trusted local users and processes. See proxy security.

License

MIT — see LICENSE. Bundled Node.js notices are included in THIRD_PARTY_NOTICES.md.

CodexMulti is an independent open-source project. It is not affiliated with or endorsed by OpenAI. Codex is a trademark of OpenAI.

About

A macOS menu-bar app that keeps several Codex accounts usable: bundled failover proxy, one .app to install.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages