English | 中文
A CLI tool for managing multiple Claude / Codex configurations and automatically switching between them. Cross-platform: Linux, macOS, Windows (x86_64 + ARM64).
⚡ Zero background processes: cc-switch flips configurations, launches Claude / Codex, then exits immediately — no daemon, no listening port, no resident footprint.
📘 Codex users: full configuration management docs live in docs/codex_EN.md.
- 🚀 Zero background — exits as soon as Claude / Codex starts; never resident
- 🛡️ Bypass permissions on by default — cc-switch launches Claude with
--dangerously-skip-permissions, so tool calls don't prompt each time (details below) - 🧩 Multi-config switching — interactive TUI plus a fast
usecommand - ⌨️ Native Vim keybindings —
j/kto move,n/pto page through configs; built for Vim geeks - 🎯 StatusLine integration — shows the active alias in Claude Code's status bar (see StatusLine integration)
- ⚡ Completion in every shell — Fish / Zsh / Bash / PowerShell / Elvish all get full completion; Fish adds live alias completion on top
- 📂 Codex support — manage Claude and OpenAI Codex auth from one tool
- 🌍 Cross-platform — macOS / Linux / Windows (x86_64 + ARM64); transparently handles npm-installed
claude.cmd/codex.cmdshims on Windows
🛡️ About the default bypass-permissions behavior
Both
cc-switch use <name>and interactive selection launch Claude with--dangerously-skip-permissionsautomatically applied — file reads/writes, Bash calls, and other tool actions no longer prompt one by one. This is the opinionated default for geek / power users.
Every example in this README uses these aliases. Add them once to your shell config — one paste — and the commands below stay short.
| Alias | Expands to | Purpose |
|---|---|---|
cs |
cc-switch |
short form of the main command (typing cs drops you into interactive mode) |
cx |
cc-switch codex |
short form of the Codex subcommand |
co |
cc-switch omp |
short form of the OMP subcommand |
Fish:
echo "alias cs='cc-switch'" >> ~/.config/fish/config.fish
echo "alias cx='cc-switch codex'" >> ~/.config/fish/config.fish
echo "alias co='cc-switch omp'" >> ~/.config/fish/config.fishZsh:
cat >> ~/.zshrc <<'EOF'
alias cs='cc-switch'
alias cx='cc-switch codex'
alias co='cc-switch omp'
EOFBash:
cat >> ~/.bashrc <<'EOF'
alias cs='cc-switch'
alias cx='cc-switch codex'
alias co='cc-switch omp'
EOFPowerShell:
Set-Alias -Name cs -Value cc-switch
function cx { cc-switch codex @args }
function co { cc-switch omp @args }After adding, restart your terminal (or
sourcethe config), then all examples below work withcs/cx/codirectly.
# Install
cargo install cc-switch
# ===== Claude configurations =====
cs add work sk-ant-work-xxx https://api.anthropic.com
cs # interactive menu, pick 'work'
cs use work # or switch + launch Claude (cs then exits)
# ===== Codex configurations ===== (full docs: docs/codex_EN.md)
cx add work --from-file # imports from ~/.codex/auth.json
cx use work # switch + launch Codex
# List all configurations
cs list # Claude
cx list # CodexOption 1 — Homebrew (recommended):
brew install Linuxdazhao/cc-switch/cc-switch
# Equivalent explicit form:
# brew tap Linuxdazhao/cc-switch && brew install cc-switchOption 2 — Cargo:
cargo install cc-switchOption 3 — Pre-built binaries: download the matching .tar.gz from Releases and put cc-switch on your PATH.
Option 1 — Scoop (recommended, v0.1.18+):
scoop bucket add cc-switch https://github.com/Linuxdazhao/scoop-cc-switch
scoop install cc-switchOption 2 — Cargo:
cargo install cc-switchOption 3 — Pre-built binaries: download the matching .zip from Releases and put cc-switch.exe on your PATH.
| Command | What it does |
|---|---|
cc-switch add <name> |
Add new configuration |
cc-switch list |
Show all configurations (JSON or plain text) |
cc-switch remove <name...> |
Delete one or more configurations |
cc-switch use <name> |
Switch and launch Claude (cc-switch then exits) |
cc-switch |
Enter interactive mode |
| Command | What it does |
|---|---|
cc-switch codex add <name> |
Add new configuration |
cc-switch codex list |
Show all configurations |
cc-switch codex remove <name...> |
Delete configurations |
cc-switch codex use <name> |
Switch and launch Codex |
cc-switch codex |
Enter interactive mode |
Full documentation: docs/codex_EN.md.
| Command | What it does |
|---|---|
cc-switch statusline install |
Install the Claude Code statusLine wrapper (shows current alias) |
cc-switch statusline uninstall |
Remove the statusLine wrapper |
cc-switch completion <shell> |
Generate shell completion scripts |
cc-switch is a one-shot command:
- You run
cs use work - cc-switch updates
~/.claude/settings.json(or writes~/.codex/auth.json) - cc-switch
execsclaude --dangerously-skip-permissions(orcodex) with the right env vars - The cc-switch process exits immediately — everything that follows is Claude / Codex itself
Which means:
- ✅ No long-lived process, no port, no PID lockfile
- ✅ No
cs start/cs stopceremony - ✅ Close Claude and the environment ends with it — no leftover state
- ✅ Once it exits, nothing of cc-switch is visible on the system except its config file
- 🛡️ The launched Claude has bypass-permissions enabled by default (see Highlights above)
# Claude interactive mode
cs
# Codex interactive mode
cx
# Navigation (arrows AND Vim-style keys both work):
# - ↑↓ or k/j: move up / down
# - 1-9: jump straight to that configuration
# - N/PageDown: next page (when >9 configs)
# - P/PageUp: previous page
# - R: reset to default Claude (Claude mode only)
# - E: edit configuration
# - Q: quit# Switch to a configuration and launch Claude
cs use work
# Switch and send a prompt
cs use work "Write a Python script for me"
# Switch and resume a previous session
cs use work --resume c8439f36-44a9-4d85-9e88-de35e004fdd4
cs use work -r c8439f36-44a9-4d85-9e88-de35e004fdd4
# Switch and continue the most recent session
cs use work --continue
cs use work -c# Every option at once
cs add work -t sk-ant-xxx -u https://api.anthropic.com \
-m claude-3-5-sonnet-20241022 \
--small-fast-model claude-3-haiku-20240307 \
--max-thinking-tokens 8192 \
--api-timeout-ms 300000 \
--disable-nonessential-traffic 1 \
--default-sonnet-model claude-3-5-sonnet-20241022 \
--default-opus-model claude-3-opus-20240229 \
--default-haiku-model claude-3-haiku-20240307
# Force overwrite
cs add work -t sk-ant-xxx -u https://api.anthropic.com -f
# Interactive add
cs add work -i
# Import from JSON file (alias required)
cs add work --from-file # import from ~/.claude/settings.json
cs add work --from-file config.json # import from a specific file
⚠️ If you run multiple Claude instances at once, useenvmode (the default).
envmode (default, recommended): writes to theenvfield ofsettings.json. Claude reads these into the process environment at launch and does not watch the file afterward. Each window / session is fully isolated.configmode: writes to root-level camelCase config fields insettings.json. Claude hot-reads these at runtime — so flipping cc-switch once will silently switch every Claude instance already running onto the new configuration. Avoid this unless you have exactly one window open and want the change to apply live.
cs --store env # Write to env field (default, safe with multiple instances)
cs --store config # Write root-level camelCase (mutates live instances)cs list # JSON format (default)
cs list -p # Plain text formatcs remove work
cs remove work personal test-config# Migrate from old path (~/.cc_auto_switch/) to the new one
cs --migratecc-switch can show the current configuration alias at the start of Claude Code's status bar so you can tell at a glance which API set you're on.
# Install (run after first install or after upgrading cc-switch)
cs statusline install
# Uninstall
cs statusline uninstallHow it works:
- cc-switch writes a shell wrapper to
~/.claude/cc_auto_switch_statusline.sh - It auto-detects
ccstatusline(prefersbunx, falls back tonpx) and uses it as the underlying statusLine command - The status bar gains an
[alias]prefix, e.g.[work] /Users/you/project | claude-sonnet-4-6 | $0.12 - If you already have a statusLine command in
settings.json, it is wrapped, not replaced - Uninstall restores the original command
Requires bun or npm on PATH (to run ccstatusline).
Re-generate completion scripts after upgrading to pick up new subcommands (
codex,statusline).
# Fish (recommended — the only shell with dynamic alias completion)
cc-switch completion fish > ~/.config/fish/completions/cc-switch.fish
# Zsh
cc-switch completion zsh > ~/.zsh/completions/_cc-switch
echo 'fpath=(~/.zsh/completions $fpath)' >> ~/.zshrc
# Bash (incl. Git Bash on Windows)
cc-switch completion bash > ~/.bash_completion.d/cc-switch
echo 'source ~/.bash_completion.d/cc-switch' >> ~/.bashrc
# Elvish also supported
cc-switch completion elvishDon't redirect the completion script directly into $PROFILE — that overwrites your existing aliases, modules, and theme. Write it to a dedicated file and dot-source it:
$completionDir = Split-Path -Parent $PROFILE
if (-not (Test-Path $completionDir)) { New-Item -ItemType Directory -Path $completionDir | Out-Null }
$completionPath = Join-Path $completionDir 'cc-switch.completion.ps1'
cc-switch completion powershell | Out-File -Encoding utf8 $completionPath
$line = ". '$completionPath'"
if (-not ((Test-Path $PROFILE) -and (Select-String -Path $PROFILE -Pattern ([regex]::Escape($line)) -Quiet))) {
Add-Content -Path $PROFILE -Value $line
}The snippet is idempotent — safe to re-run.
CMD has no completion mechanism; just use the commands directly.
Fish / Zsh / Bash / PowerShell / Elvish all get full completion for subcommands, args, and flags. Dynamic alias completion — pressing <Tab> to enumerate every config name live — is available in every shell: Fish ships it out-of-the-box; the others just need the snippets below.
| Shell | Static (commands / args / flags) | Dynamic alias completion (use <Tab> lists configs) |
|---|---|---|
| Fish | ✅ auto | ✅ auto (Claude + Codex) |
| Zsh | ✅ auto | ⚙️ snippet needed (see below) |
| Bash | ✅ auto | ⚙️ snippet needed (see below) |
| PowerShell | ✅ auto | ⚙️ snippet needed (see below) |
| Elvish | ✅ auto | ⚙️ build your own with edit:completion:arg-completer |
Mechanism:
cc-switch --list-aliasesandcc-switch --list-codex-aliasesprint every configured alias and are shell-agnostic. Fish's generated script already wires them into completion; for the other shells you just append a few lines.
All snippets below are additive — paste them after the script produced by
cc-switch completion <shell>. Static completion keeps working.
Append to ~/.zshrc (after the completion script is sourced and compinit has run):
_cc_switch_dynamic_aliases() {
local -a aliases
local words_count=$#words
local cmd1=$words[2]
local cmd2=$words[3]
# cc-switch codex use|remove <TAB>
if [[ "$cmd1" == "codex" && ("$cmd2" == "use" || "$cmd2" == "remove") && $words_count -ge 4 ]]; then
aliases=("${(@f)$(cc-switch --list-codex-aliases 2>/dev/null)}")
compadd -a aliases
return 0
fi
# cc-switch use|switch|remove <TAB>
if [[ ("$cmd1" == "use" || "$cmd1" == "switch" || "$cmd1" == "remove") && $words_count -ge 3 ]]; then
aliases=("${(@f)$(cc-switch --list-aliases 2>/dev/null)}")
compadd -a aliases
return 0
fi
}
# Override the clap-generated _cc-switch with the dynamic version
compdef _cc_switch_dynamic_aliases cc-switchAppend to ~/.bashrc (after source ~/.bash_completion.d/cc-switch):
_cc_switch_with_aliases() {
# First run the clap-generated completion (handles subcommands, flags, etc.)
_cc-switch "$@"
# Then override COMPREPLY at alias positions
local cur="${COMP_WORDS[COMP_CWORD]}"
local prev="${COMP_WORDS[COMP_CWORD-1]}"
local cmd1="${COMP_WORDS[1]:-}"
case "$prev" in
use|switch|remove)
if [[ "$cmd1" == "codex" ]]; then
COMPREPLY=($(compgen -W "$(cc-switch --list-codex-aliases 2>/dev/null)" -- "$cur"))
else
COMPREPLY=($(compgen -W "$(cc-switch --list-aliases 2>/dev/null)" -- "$cur"))
fi
;;
esac
}
complete -F _cc_switch_with_aliases -o nosort cc-switchPowerShell's Register-ArgumentCompleter composes with existing completion — no replacement needed. Append to your PowerShell $PROFILE (or to the cc-switch.completion.ps1 file from earlier):
Register-ArgumentCompleter -CommandName cc-switch -Native -ScriptBlock {
param($wordToComplete, $commandAst, $cursorPosition)
$tokens = $commandAst.CommandElements | ForEach-Object { $_.ToString() }
$count = $tokens.Count
if ($count -lt 2) { return }
$cmd1 = $tokens[1]
$cmd2 = if ($count -ge 3) { $tokens[2] } else { '' }
# cc-switch codex use|remove <TAB>
if ($cmd1 -eq 'codex' -and ($cmd2 -eq 'use' -or $cmd2 -eq 'remove')) {
cc-switch --list-codex-aliases 2>$null | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
return
}
# cc-switch use|switch|remove <TAB>
if ($cmd1 -in 'use', 'switch', 'remove') {
cc-switch --list-aliases 2>$null | Where-Object { $_ -like "$wordToComplete*" } | ForEach-Object {
[System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_)
}
}
}Aliases were introduced at the top of this README (jump back). Reprinting here for convenience:
# Fish
echo "alias cs='cc-switch'" >> ~/.config/fish/config.fish
echo "alias cx='cc-switch codex'" >> ~/.config/fish/config.fish
# Zsh / Bash
echo "alias cs='cc-switch'" >> ~/.zshrc # or ~/.bashrc
echo "alias cx='cc-switch codex'" >> ~/.zshrc
# PowerShell
Set-Alias -Name cs -Value cc-switch
function cx { cc-switch codex @args }💡 Fish tip: dynamic completion still works through the
csalias — Fish expands the alias before completing.
# Provide an explicit alias before --from-file
cs add my-work --from-file my-work-config.json
# Expected JSON format:
# {
# "env": {
# "ANTHROPIC_AUTH_TOKEN": "sk-ant-xxx",
# "ANTHROPIC_BASE_URL": "https://api.anthropic.com",
# "ANTHROPIC_MODEL": "claude-3-5-sonnet-20241022"
# }
# }cx add work --from-file # default ~/.codex/auth.jsonFull documentation: docs/codex_EN.md.
cc-switch stores configurations in ~/.claude/cc_auto_switch_setting.json:
- Claude configurations: update Claude's
settings.jsonwith the right environment variables - Codex configurations: write
~/.codex/auth.json, which the Codex CLI reads for auth
Which means:
- ✅ No global configuration changes
- ✅ Complete isolation between configurations
- ✅ Safe and secure API key management
- ✅ Works with any Claude / Codex installation
- ✅ Preserves other settings
- ✅ Supports a custom settings directory
cc-switch sets the following when switching configuration:
ANTHROPIC_AUTH_TOKEN- your API tokenANTHROPIC_BASE_URL- API endpoint URLANTHROPIC_MODEL- custom model (optional)ANTHROPIC_SMALL_FAST_MODEL- fast model for background tasks (optional)ANTHROPIC_MAX_THINKING_TOKENS- maximum thinking tokens (optional)API_TIMEOUT_MS- API timeout in ms (optional)CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC- disable non-essential traffic (optional)ANTHROPIC_DEFAULT_SONNET_MODEL- default Sonnet model (optional)ANTHROPIC_DEFAULT_OPUS_MODEL- default Opus model (optional)ANTHROPIC_DEFAULT_HAIKU_MODEL- default Haiku model (optional)CLAUDE_CODE_SUBAGENT_MODEL- subagent model (optional)CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK- disable non-streaming fallback (optional)CLAUDE_CODE_EFFORT_LEVEL- effort level (optional, e.g. 'max')CC_SWITCH_CURRENT_ALIAS- current alias (injected by cc-switch for the statusLine wrapper)
Codex configurations live in ~/.codex/auth.json and support two auth modes:
chatgpt (OAuth): id_token, access_token, refresh_token, account_id
apikey: OPENAI_API_KEY
Full documentation: docs/codex_EN.md.
# Clone
git clone https://github.com/Linuxdazhao/cc_auto_switch.git
cd cc-switch
# Build
cargo build --release
# Test
cargo testMIT License — see LICENSE.
Made with ❤️ by Linuxdazhao