Use any model with Claude Code. Add your own providers and API keys, switch instantly, and run multi-model tmux orchestration — no restart needed.
A lightweight local proxy that sits between Claude Code and any OpenAI-compatible or Anthropic-compatible API.
One-liner:
curl -fsSL https://raw.githubusercontent.com/codejunkie99/claude-model-switch/main/install.sh | shOr download directly:
| Platform | Download |
|---|---|
| macOS Apple Silicon | claude-model-switch-aarch64-apple-darwin.tar.gz |
| macOS Intel | claude-model-switch-x86_64-apple-darwin.tar.gz |
| Linux x64 | claude-model-switch-x86_64-unknown-linux-gnu.tar.gz |
| Linux ARM64 | claude-model-switch-aarch64-unknown-linux-gnu.tar.gz |
Extract and move to your PATH:
tar xzf claude-model-switch-*.tar.gz
mv claude-model-switch ~/.local/bin/cargo install claude-model-switchgit clone https://github.com/codejunkie99/claude-model-switch.git
cd claude-model-switch
cargo install --path .# 1. Point Claude Code at the local proxy
claude-model-switch init
# 2. One command: add provider + save key (preset base URL)
claude-model-switch add glm sk-xxx
# 3. Start the proxy
claude-model-switch start
# 4. Switch to it
claude-model-switch use glm
# 5. Switch back anytime
claude-model-switch use claudeThat's it. Claude Code now routes through your chosen provider.
Add any API endpoint that speaks the Anthropic or OpenAI messages format:
claude-model-switch add <name> \
<api-url> \
<api-key>
# or set credentials later:
claude-model-switch setup <name> --api-key <your-key>By default this creates an Anthropic passthrough provider: whatever model ID Claude sends is forwarded as-is to an upstream that already speaks the Anthropic Messages API.
For an OpenAI-compatible upstream (OpenRouter, z.ai, vLLM, LM Studio, …), add
--format openai. The proxy then translates each request into an OpenAI
chat/completions call and translates the streaming response — tool calls
included — back into Anthropic events, so Claude Code works unchanged:
claude-model-switch add my-llm https://api.example.com/v1 sk-xxx \
--format openai \
--haiku small-model --sonnet mid-model --opus big-modelBuilt-in provider presets let users skip --base-url — the preset knows each
provider's base URL, wire format, and a sensible default model mapping:
claude-model-switch add glm sk-xxx # z.ai GLM 5.2
claude-model-switch add openai sk-xxx # OpenAI
claude-model-switch add deepseek sk-xxx # DeepSeek
claude-model-switch add gemini xxx # Google Gemini| Preset (+aliases) | Base URL | Format | Default tiers (haiku/sonnet/opus) |
|---|---|---|---|
claude / anthropic |
api.anthropic.com | anthropic | passthrough |
glm / zai |
api.z.ai/api/paas/v4 | openai | glm-4.5-air / glm-5.2 / glm-5.2 |
openai |
api.openai.com/v1 | openai | gpt-4o-mini / gpt-4o / gpt-4o |
deepseek |
api.deepseek.com | openai | deepseek-chat / chat / reasoner |
mistral |
api.mistral.ai/v1 | openai | small / medium / large -latest |
groq |
api.groq.com/openai/v1 | openai | llama-3.1-8b / 3.3-70b / 3.3-70b |
gemini / google |
…googleapis.com/v1beta/openai | openai | gemini-1.5-flash / pro / pro |
minimax |
api.minimax.io/anthropic/v1 | anthropic | (set your own) |
openrouter |
openrouter.ai/api/v1 | openai | (set your own) |
xai / grok |
api.x.ai/v1 | openai | (set your own) |
together |
api.together.xyz/v1 | openai | (set your own) |
fireworks |
api.fireworks.ai/inference/v1 | openai | (set your own) |
moonshot / kimi |
api.moonshot.ai/v1 | openai | (set your own) |
Default model ids are best-effort and can drift — override any tier with
--haiku / --sonnet / --opus. For unknown base URLs the format is inferred
(an /anthropic path ⇒ native Anthropic), otherwise pass --format openai.
If a provider already exists, you can update only the key and it reuses the saved base URL:
# First time
claude-model-switch add acme https://api.acme.ai/v1 sk-old
# Later key rotation (base URL reused automatically)
claude-model-switch add acme sk-newFlag-based syntax still works if you prefer it:
claude-model-switch add <name> --base-url <api-url> --api-key <your-key>If you want Claude-tier rewriting, pass all three mapping flags:
claude-model-switch add <name> \
--base-url <api-url> \
--haiku <fast-model> \
--sonnet <balanced-model> \
--opus <best-model>Claude Code uses three model tiers internally. Tier mapping lets you map each tier to whatever model your provider offers:
- haiku — fast/cheap tier (used for quick tasks)
- sonnet — balanced tier (used for most coding)
- opus — best tier (used for complex reasoning)
# GLM via z.ai (OpenAI format)
claude-model-switch add glm \
--base-url https://api.z.ai/api/paas/v4 \
--format openai \
--haiku glm-4.5-air \
--sonnet glm-5.2 \
--opus glm-5.2
claude-model-switch setup glm --api-key sk-xxx
# MiniMax (native Anthropic endpoint)
claude-model-switch add minimax \
--base-url https://api.minimax.io/anthropic/v1 \
--haiku MiniMax-M2 \
--sonnet MiniMax-M2.5 \
--opus MiniMax-M2.5
claude-model-switch setup minimax --api-key xxx
# OpenRouter (OpenAI format)
claude-model-switch add openrouter \
--base-url https://openrouter.ai/api/v1 \
--format openai \
--haiku google/gemini-2.5-flash \
--sonnet anthropic/claude-sonnet-4 \
--opus deepseek/deepseek-r1
claude-model-switch setup openrouter --api-key sk-or-xxx
# Any custom OpenAI-compatible endpoint
claude-model-switch add my-llm \
--base-url https://api.example.com/v1 \
--format openai \
--haiku small-model \
--sonnet medium-model \
--opus large-model
claude-model-switch setup my-llm --api-key xxxInstall as a Claude Code plugin for the smoothest experience. The plugin auto-installs the binary, starts the proxy, and gives you interactive slash commands.
Copy or symlink the plugin/ directory into your Claude Code plugins:
# Option 1: symlink
ln -s /path/to/claude-model-switch/plugin ~/.claude/plugins/claude-model-switch
# Option 2: copy
cp -r /path/to/claude-model-switch/plugin ~/.claude/plugins/claude-model-switch| Command | What it does |
|---|---|
/cms-setup |
Interactive provider credential setup |
/cms-use |
Switch provider (shows picker if no arg) |
/cms-add |
Walk through adding a custom provider |
/cms-list |
List all available providers |
/cms-status |
Show current provider, models, proxy state |
/cms-orchestrate |
Launch multi-model tmux session |
/cms-start |
Start the proxy |
/cms-stop |
Stop the proxy |
/cms-remove |
Remove a provider |
The plugin's SessionStart hook automatically:
- Downloads and installs the binary if missing
- Starts the proxy if not running
- Runs first-time init if needed
Run multiple Claude Code instances in tmux, each using a different provider. Useful for parallel workstreams where different models have different strengths.
# Trio: 3 panes using your first 3 configured providers
claude-model-switch orchestrate start --preset trio
# Duo: 2 panes using your first 2 configured providers
claude-model-switch orchestrate start --preset duo
# Attach to see all panes
tmux attach -t cms-swarmPresets automatically assign roles to your configured providers (sorted alphabetically):
- trio — requires 3+ providers: planner (1st/sonnet), coder (2nd/opus), reviewer (3rd/sonnet)
- duo — requires 2+ providers: planner (1st/sonnet), coder (2nd/opus)
# Check status
claude-model-switch orchestrate status
# Send a prompt to a specific role
claude-model-switch orchestrate send planner "Break this into 3 milestones"
claude-model-switch orchestrate send coder "Implement milestone 1"
# See what a role is outputting
claude-model-switch orchestrate capture reviewer
# Switch a role to a different provider mid-session
claude-model-switch orchestrate switch coder openrouter --model sonnet
# Tear it down
claude-model-switch orchestrate stopClaude Code
|
v
http://localhost:4000/v1 (local proxy)
|
+-- Rewrites model name (claude-sonnet-4 -> your-model)
+-- Sets auth headers for the active provider
+-- If --format openai: translates request + streaming response
| (Anthropic Messages <-> OpenAI chat/completions, tool calls included)
|
v
https://api.your-provider.com/v1 (wherever you point it)
Responses stream straight through, so tokens reach Claude Code as they are generated — including when translating an OpenAI-format upstream.
The proxy runs on localhost:4000 and supports two routing modes:
- Global mode:
http://localhost:4000/v1routes to the active provider (set viause) - Per-process mode:
http://localhost:4000/p/<provider>/v1routes to a specific provider (used by orchestration)
Switching providers sends SIGHUP to the proxy — it reloads config without dropping connections.
| Command | Description |
|---|---|
init |
First-time setup — sets ANTHROPIC_BASE_URL in Claude Code settings |
start [--port N] |
Start the proxy (default port 4000) |
stop |
Stop the proxy |
use <provider> |
Switch the active provider |
setup <provider> --api-key <key> |
Register API credentials |
setup <provider> --auth-token <token> |
Register bearer token auth |
add <name> [<base-url>] [<api-key>] [--haiku <m> --sonnet <m> --opus <m>] |
Add/update provider (for presets, add <name> <api-key> works) |
remove <name> |
Remove a provider |
list |
List all providers |
status |
Show current config and proxy state |
orchestrate start --preset <name> |
Start multi-model tmux session |
orchestrate status |
Show tmux pane status |
orchestrate send <role> "<prompt>" |
Send prompt to a role |
orchestrate capture <role> |
Capture role output |
orchestrate switch <role> <provider> |
Switch a role's provider |
orchestrate stop [--stop-proxy] |
Stop tmux session |
Config lives at ~/.claude/model-profiles.json. You can edit it directly or use the CLI commands.
{
"active": "openrouter",
"providers": {
"claude": {
"base_url": "https://api.anthropic.com"
},
"openrouter": {
"base_url": "https://openrouter.ai/api/v1",
"api_key": "sk-or-xxx",
"models": {
"haiku": "google/gemini-2.5-flash",
"sonnet": "anthropic/claude-sonnet-4",
"opus": "deepseek/deepseek-r1"
}
}
}
}The binary isn't on your PATH. Either:
- Add
~/.local/binto your PATH:export PATH="$HOME/.local/bin:$PATH"(add to~/.bashrcor~/.zshrc) - Or move the binary somewhere already on your PATH:
mv claude-model-switch /usr/local/bin/
# Check if something is using port 4000
lsof -i :4000
# Stop any existing proxy
claude-model-switch stop
# Start on a different port
claude-model-switch start --port 4001If you change the port, also update ~/.claude/settings.json to match:
{ "env": { "ANTHROPIC_BASE_URL": "http://localhost:4001/v1" } }- Make sure
initwas run:claude-model-switch init - Check
~/.claude/settings.jsonhasANTHROPIC_BASE_URLset tohttp://localhost:4000/v1 - Make sure the proxy is running:
claude-model-switch status - Restart Claude Code after running
initfor the first time
- Verify your API key:
claude-model-switch statusshows the active provider config - Check that the base URL is correct (some providers need
/v1at the end, some don't) - Make sure the model names match what your provider expects exactly
Install tmux:
- macOS:
brew install tmux - Ubuntu/Debian:
sudo apt install tmux - Fedora:
sudo dnf install tmux
If the proxy crashed but the PID file remains:
rm ~/.claude/model-switch-proxy.pid
claude-model-switch startContributions welcome. Here's how:
- Fork the repo
- Create a branch:
git checkout -b my-feature - Make your changes
- Run tests:
cargo test - Commit and push
- Open a PR
git clone https://github.com/codejunkie99/claude-model-switch.git
cd claude-model-switch
cargo build
cargo testThe project uses rustls (no OpenSSL dependency), so cross-compilation works with cargo-zigbuild:
cargo install cargo-zigbuild
cargo zigbuild --release --target x86_64-unknown-linux-gnu
cargo zigbuild --release --target aarch64-unknown-linux-gnu- macOS or Linux
tmux(only for orchestration)
MIT