MJ-skill/codex-account-switching/SKILL.md
Multi-account Codex isolation via per-account CODEX_HOME. Works for both direct codex CLI invocation (`CODEX_HOME=~/.codex-b codex exec ...`) and MCP server setup (Claude Desktop / Claude CLI MCP entries). Use when more than one OpenAI account / API key needs to coexist on the same machine.
npx skillsauth add develata/deve-skills codex-account-switchingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
codex login.CODEX_HOME=<path> codex ... for a single command is enough — no skill needed.One CODEX_HOME per account. Each home holds its own auth.json, config.toml, session cache. Two ways to route a call to a specific account:
CODEX_HOME=~/.codex-b codex exec .... No MCP setup required; the home dir + codex login is enough.mcp__codex-main__codex / mcp__codex-b__codex), so prompts can pick the account by tool name. Required if Claude Desktop / Claude CLI delegates via MCP rather than Bash.| Account role | CODEX_HOME | MCP server name |
|---|---|---|
| Primary | ~/.codex | codex-main |
| Secondary | ~/.codex-b | codex-b |
| Tertiary | ~/.codex-c | codex-c |
Force cli_auth_credentials_store="file" on every instance so credentials stay inside the home dir instead of mixing through the system keychain.
mkdir -p ~/.codex-b
Verified-mandatory:
codex loginaborts withCODEX_HOME points to "<path>", but that path does not existif the home dir is missing. Tested 2026-04-10 againstcodex-cli 0.118.0.
CODEX_HOME=~/.codex-b codex -c 'cli_auth_credentials_store="file"' login
# completes in browser
printenv OPENAI_API_KEY_B | CODEX_HOME=~/.codex-b codex -c 'cli_auth_credentials_store="file"' login --with-api-key
Never write API keys directly into Claude config files.
CODEX_HOME=~/.codex codex -c 'cli_auth_credentials_store="file"' login status
CODEX_HOME=~/.codex-b codex -c 'cli_auth_credentials_store="file"' login status
ls -la ~/.codex/auth.json ~/.codex-b/auth.json
Expectations:
auth.json is a real file (not a symlink to the same target)config.toml (or empty if not customized)# Locate the codex binary (adapt if installed differently)
CODEX_BIN="$(which codex)" # e.g. /opt/homebrew/bin/codex on macOS arm64
# Remove the ambiguous bare entry first to prevent accidental fall-through
claude mcp remove codex -s user
# Add explicit per-account entries
claude mcp add codex-main "$CODEX_BIN" mcp-server -s user -e CODEX_HOME=$HOME/.codex
claude mcp add codex-b "$CODEX_BIN" mcp-server -s user -e CODEX_HOME=$HOME/.codex-b
# Verify
claude mcp list
claude mcp get codex-main
claude mcp get codex-b
All entries should report ✓ Connected.
Edit ~/Library/Application Support/Claude/claude_desktop_config.json. Replace the single codex entry with one entry per account:
{
"mcpServers": {
"codex-main": {
"command": "<CODEX_BIN_PATH>",
"args": ["mcp-server"],
"env": { "CODEX_HOME": "<HOME_DIR>/.codex" }
},
"codex-b": {
"command": "<CODEX_BIN_PATH>",
"args": ["mcp-server"],
"env": { "CODEX_HOME": "<HOME_DIR>/.codex-b" }
}
}
}
Replace <CODEX_BIN_PATH> with the output of which codex (e.g., /opt/homebrew/bin/codex on macOS arm64) and <HOME_DIR> with your home directory (e.g., /Users/yourname).
Then fully restart Claude Desktop (Quit, not just close window).
Assumption-dependent: Claude Desktop honoring the
env.CODEX_HOMEfield is the standard stdio-MCP pattern but cannot be verified without a Desktop restart. After restart, each Codex server should report its own account identity in the first invocation. If a server reports the wrong account, the env injection failed and the entry needs review.
When dispatching a Codex job, route to a specific MCP server explicitly:
"Use
codex-bto investigate the legacy module loader."
Never just say "use codex" once the migration is complete. The ambiguity is what the multi-account isolation exists to eliminate.
The skill is the source of truth for these helpers. The user installs them once into a PATH directory (commonly ~/.local/bin/ or ~/bin/), then re-runs the install whenever the skill is updated. This avoids drift between docs and shell while keeping helpers usable as real executables.
# Pick whichever PATH directory you already use:
echo "$PATH" | tr ':' '\n' | grep -E "$HOME/bin|$HOME/.local/bin"
# Common targets:
# ~/.local/bin (already in PATH on most modern setups)
# ~/bin (older convention; may need to be added to PATH)
Then create the three helper files below in your chosen directory, e.g.:
INSTALL_DIR="$HOME/.local/bin" # or "$HOME/bin"
mkdir -p "$INSTALL_DIR"
# (paste each script body to its own file under $INSTALL_DIR)
chmod +x "$INSTALL_DIR/codex-account-login" \
"$INSTALL_DIR/codex-account-status" \
"$INSTALL_DIR/codex-account-relogin"
which codex-account-login codex-account-status codex-account-relogin
After every edit to the skill that touches the helper sections, repeat the install to refresh the on-disk copies.
~/bin/codex-account-login#!/usr/bin/env bash
# Usage: codex-account-login <name> e.g. codex-account-login b
# Logs into a per-account CODEX_HOME using file-based credential storage.
set -euo pipefail
name="${1:-}"
if [[ -z "$name" ]]; then
echo "usage: codex-account-login <name>" >&2; exit 2
fi
if [[ "$name" == "main" ]]; then
home="$HOME/.codex"
else
home="$HOME/.codex-$name"
fi
mkdir -p "$home"
echo "==> CODEX_HOME=$home"
CODEX_HOME="$home" codex -c 'cli_auth_credentials_store="file"' login
echo "==> Verifying..."
CODEX_HOME="$home" codex -c 'cli_auth_credentials_store="file"' login status
ls -la "$home/auth.json" 2>/dev/null || echo "WARNING: $home/auth.json missing"
~/bin/codex-account-status#!/usr/bin/env bash
# Usage: codex-account-status
# Reports login state for every ~/.codex* home dir.
set -uo pipefail
shopt -s nullglob
for h in "$HOME/.codex" "$HOME"/.codex-*; do
[[ -d "$h" ]] || continue
printf '%-30s ' "$h"
CODEX_HOME="$h" codex -c 'cli_auth_credentials_store="file"' login status 2>&1 || echo "(error)"
done
~/bin/codex-account-relogin#!/usr/bin/env bash
# Usage: codex-account-relogin <name>
# Logs out then logs into a single account home without touching others.
set -euo pipefail
name="${1:-}"
if [[ -z "$name" ]]; then
echo "usage: codex-account-relogin <name>" >&2; exit 2
fi
if [[ "$name" == "main" ]]; then
home="$HOME/.codex"
else
home="$HOME/.codex-$name"
fi
mkdir -p "$home"
CODEX_HOME="$home" codex -c 'cli_auth_credentials_store="file"' logout || true
CODEX_HOME="$home" codex -c 'cli_auth_credentials_store="file"' login
CODEX_HOME="$home" codex -c 'cli_auth_credentials_store="file"' login status
ls -la ~/bin/codex-account-login ~/bin/codex-account-status ~/bin/codex-account-relogin
file ~/bin/codex-account-* | grep -i 'shell script'
codex-account-status
This skill follows the verification discipline defined in the dual-agent-original-request-review skill. Specifically:
Verified facts (tested 2026-04-10 against codex-cli 0.118.0 on macOS arm64):
cli_auth_credentials_store="file" is accepted as a valid -c config overrideCODEX_HOME=<path> env var isolates login state across home dirsCODEX_HOME path must exist before codex login runs (otherwise hard error)claude mcp add -s user supports per-server -e KEY=VALUE env injectionclaude mcp list and claude mcp get <name> report MCP server connection state/opt/homebrew/bin/codex is the cask install symlink targetAssumption-dependent:
cli_auth_credentials_store="file" runtime semantics — verified the flag is accepted, but did NOT verify it actually bypasses the system keychain on a fresh login (the test machine already had ~/.codex/auth.json). Verify on first new-account login by checking <CODEX_HOME>/auth.json was created and the OS did not prompt for keychain access.env.CODEX_HOME — standard stdio-MCP pattern; verify after Desktop restart.Failure mode: if any of the above breaks, fall back to a single-account codex entry and document the failure in this skill's notes section.
| Symptom | Likely cause | Fix |
|---|---|---|
| CODEX_HOME points to ... but that path does not exist | Forgot mkdir -p | mkdir -p $CODEX_HOME and retry |
| Wrong account replies via MCP | env injection failed in Claude config | claude mcp get codex-<name> should show CODEX_HOME env; if missing, re-add with -e CODEX_HOME=... |
| Stale Desktop after JSON edit | Desktop process not fully restarted | Quit Desktop entirely (Cmd+Q), wait, relaunch |
| OS keychain prompts during login | cli_auth_credentials_store="file" flag was not applied | Confirm the -c flag is on the command (helper scripts always include it) |
| Two homes share the same credentials | One home is a symlink instead of a real dir | ls -la ~/.codex* / and replace symlinks with real dirs |
| claude mcp list still shows bare codex after migration | Entry was project-scoped, not user-scoped | claude mcp remove codex -s project or -s local |
To remove a secondary account cleanly:
# 1. Remove the MCP entry
claude mcp remove codex-b -s user
# 2. (Optional) Delete the home directory
rm -rf ~/.codex-b
# 3. If using Claude Desktop, remove the entry from claude_desktop_config.json and restart
Do not remove the primary account (codex-main) unless you are migrating back to single-account mode. In that case, re-add a bare codex MCP entry pointing to ~/.codex.
When upgrading Codex CLI (e.g., brew upgrade codex):
auth.json and config.toml live in CODEX_HOME dirs, not the binary install path.which codex still matches the path in your MCP server configs. If it changed, update the MCP entries.codex-account-relogin <name> to refresh credentials.codex-account-status should report all accounts as logged in.gpt-5.5) that requires CLI ≥ 0.122. Symptom: codex-main returns model 'gpt-5.5' requires a newer version of Codex. Account tier (Pro/Team/etc.) is irrelevant — the blocker is CLI version, not subscription.brew upgrade: Claude Code spawns codex MCP servers at startup and keeps the subprocess alive. brew upgrade --cask codex updates which codex immediately, but the running MCP still uses the old path. Claude Code full restart required before the new binary takes effect; /mcp reconnect alone is insufficient. Verify with mcp__codex-main__codex returning a normal response instead of the version error.model: "gpt-5.2-codex" returns not supported when using Codex with a ChatGPT account. Do not fall back to codex-specialized model IDs. The only fallbacks are (a) upgrade CLI, (b) switch to an API-key MCP (e.g., codex-b) that accepts the full model whitelist.codex MCP alongside codex-main "as backup" — accidental use defeats the isolationclaude_desktop_config.json — use codex login --with-api-key from a shell with the env var setcli_auth_credentials_store="file" is set — if you see the OS asking for keychain access, the file-store flag was not applied to that invocation~/.codex is the most common bug<CODEX_HOME>/auth.json exists post-login~/bin/ directly without updating this skill — drift makes the skill misleading; always edit the skill first, then reinstalltools
Collect and audit Codex token usage with a bundled Python CLI and optional Windows batch launchers. Use this skill when the user asks to check Codex token usage, generate daily token audit logs, calculate monthly CostUSD totals, review Codex spending, or run Codex token usage scripts on Windows, Bash, WSL, or Linux.
tools
Use when giving the user an INLINE reply that carries a trade-off, a decision, a verdict, or a non-trivial finding (decision brief / round verdict / failure root-cause). NOT for "done"/status confirmations, one-line answers, or pure data dumps. Forces a compact decision-brief shape and blocks internal tool-name / file-path bleed into user-facing text.
development
Use for cross-file or cross-chapter terminology audits and corpus-wide term unification in thesis/paper sources — extract candidate term drift, build a decision queue, classify each occurrence, apply accepted replacements safely, and verify counts/build. Trigger on "术语审计", "术语统一", "术语一致性", "逐词审", "这个词全文怎么用", "把 X 全文改成 Y", "terminology audit", or "unify term X". Do NOT use for ordinary prose drafting or a single known-location edit; use academic-writing for prose quality and claim-boundary judgment.
tools
Use for ANY codex CLI dispatch via dispatch wrapper (no time threshold; presence-of-risk triggers, not estimated wall — stdin-EOF stalls occur at <60s). Combines internal log-inactivity watchdog wrapper + external Claude-session cron probe + sentinel hook enforcement. Detects stalls in ≤60-270s vs hours-without-detection failure mode.