ccs — Claude Code Switcher
A fast, single-binary CLI launcher for Claude Code and Codex that lets you interactively select a model provider before each session — no more juggling shell aliases.
Select provider
[Recent] All ←/→ switch list, ↑/↓ move, Enter select, Esc cancel
TOOL PROVIDER MODEL
> claude DeepSeek deepseek-v4-pro
claude DeepSeek deepseek-v4-flash
claude Mimo mimo-v2.5-pro
Features
- Interactive three-column menu — tool / provider / model, with Recent / All lists switched by left and right arrows
- Direct selection via
-p <id>to skip the menu - Resume support —
-rmaps toclaude -rorcodex resumeautomatically - Dry-run mode —
-nprints the exact command and env vars without launching - Config-driven — add or remove providers by editing
~/.config/ccs/config.toml; no recompile needed - Remembers last choice — the previous selection is highlighted by default
- Zero runtime deps — single static binary, ~1 MB
Requirements
- macOS or Linux (uses
exec(2)— Unix only) claudeand/orcodexinPATH- Rust 1.70+ (for building from source)
Installation
From crates.io (recommended)
From source
⚠️ Do not install as
cc— that name is reserved for the system C compiler and will break your Rust/C toolchain.
Verify
Updating
With cargo-update (recommended):
# cargo install-update -a # or update all installed crates
Without extra tools:
Configuration
On first run, ccs generates a template config at ~/.config/ccs/config.toml.
Edit it to add your API keys and desired providers.
# ~/.config/ccs/config.toml
[[]]
= "deepseek-pro"
= "DeepSeek"
= "deepseek-v4-pro"
= "claude"
= true
= ["--dangerously-skip-permissions"]
[]
= "https://api.deepseek.com/anthropic"
= "YOUR_DEEPSEEK_API_KEY"
= "deepseek-v4-pro"
= "deepseek-v4-pro"
= "deepseek-v4-pro"
= "deepseek-v4-flash"
= "deepseek-v4-pro"
= "max"
Config fields
| Field | Type | Required | Description |
|---|---|---|---|
id |
string | ✅ | Unique identifier, used with -p |
provider |
string | ✅ | Service name shown in column 2 |
model |
string | ✅ | Model name shown in column 3 |
executable |
"claude" | "codex" |
✅ | Binary to launch |
supports_resume |
bool | — | Enable -r / resume (default: false) |
resume_as_subcommand |
bool | — | Use codex resume style instead of -r flag (default: false) |
base_args |
string[] | — | Args always prepended to the command |
[providers.env] |
table | — | Environment variables injected into the subprocess |
Resume behaviour
| Provider type | Config | Resulting command |
|---|---|---|
| claude | supports_resume = true |
claude … -r |
| codex | supports_resume = trueresume_as_subcommand = true |
codex resume … |
Usage
Usage: ccs [OPTIONS] [PASSTHROUGH]...
ccs <COMMAND>
Commands:
list List all configured providers
validate Validate config and check executables in PATH
edit Open the config file in $EDITOR (falls back to vi)
Arguments:
[PASSTHROUGH]... Arguments passed through to claude/codex
Options:
-r, --resume Resume the last session
-p, --provider <ID> Skip the menu and use a specific provider ID
-n, --dry-run Print the command that would run, without executing
--show-secrets Reveal masked secret values in dry-run / list output
-h, --help Print help
-V, --version Print version
Examples
# Interactive provider selection
# Resume last session with the same interactive selection
# Jump straight to a specific provider
# Resume with a specific provider
# Debug: see exactly what command would be executed
# Reveal the real API key in dry-run output (default is masked)
# Pass extra arguments to the underlying tool
# Inspect all configured providers
# Make sure every provider's executable is in PATH
# Edit your config in $EDITOR (falls back to vi)
Recent selections
ccs remembers the last 3 provider IDs you used and shows them in a
dedicated Recent list. The menu defaults to the most recent provider, and left
and right arrows switch between Recent and All providers. The list is stored as
plain lines (newest first) in ~/.config/ccs/recent.
Secret masking
By default, --dry-run and ccs list mask values whose env-key contains any of
token, key, secret, or password (case-insensitive). The output looks
like ***masked (len=42)*** so you can paste logs without leaking keys. Pass
--show-secrets to reveal the real value.
Dry-run output example
[dry-run] env:
ANTHROPIC_AUTH_TOKEN=***masked (len=19)***
ANTHROPIC_BASE_URL=https://api.deepseek.com/anthropic
...
[dry-run] cmd:
claude --dangerously-skip-permissions --print 'explain this code'
Adding a custom provider
Add a new [[providers]] block to ~/.config/ccs/config.toml:
[[]]
= "my-provider"
= "MyService"
= "my-model-v1"
= "claude"
= true
= ["--dangerously-skip-permissions"]
[]
= "https://api.myservice.com/v1"
= "sk-..."
No recompile needed — changes take effect immediately on the next run.
Project structure
ccs/
├── src/
│ ├── main.rs # All logic (~270 lines)
│ └── default_providers.toml # Template config embedded in the binary
├── Cargo.toml
├── Cargo.lock
├── LICENSE
├── README.md
└── CONTRIBUTING.md
Contributing
See CONTRIBUTING.md.