Automatic model switching for Claude Code based on prompt complexity
npx claudepluginhub tzachbon/claude-model-router-hookAutomatic model switching for Claude Code based on prompt complexity. No API calls.
Share bugs, ideas, or general feedback.
A Claude Code hook system that classifies every prompt by task complexity and switches your active model automatically. Sub-agent model rules are injected into every session so spawned agents also use the right tier.
settings.json (action: "autoswitch")SessionStart~ to bypass classification and keep the current model~/.claude/hooks/model-router-hook.logTwo hook scripts run inside Claude Code:
session-init.sh (SessionStart) injects a systemMessage into every session that enforces these sub-agent rules:
| Tier | Use for |
|---|---|
haiku | Git ops, renames, formatting, file lookups, quick reads |
sonnet | Feature work, debugging, writing/editing code, planning |
opus | Architecture, deep multi-file analysis, complex refactors |

model-router-hook.sh (UserPromptSubmit) classifies the incoming prompt and compares the recommended tier against the current model in settings.json. By default it warns with a recommendation; set "action": "autoswitch" in your config to switch automatically.
claude plugin marketplace add tzachbon/claude-model-router-hook
claude plugin install claude-model-router-hook@claude-model-router-hook
Hooks are registered automatically. Restart Claude Code to activate.
curl -fsSL https://raw.githubusercontent.com/tzachbon/claude-model-router-hook/main/install.sh | bash
git clone https://github.com/tzachbon/claude-model-router-hook.git
cd claude-model-router-hook
./install.sh
Or copy manually:
mkdir -p ~/.claude/hooks
cp hooks/session-init.sh hooks/model-router-hook.sh ~/.claude/hooks/
chmod +x ~/.claude/hooks/session-init.sh ~/.claude/hooks/model-router-hook.sh
Then add hooks to ~/.claude/settings.json (use the full absolute path from echo $HOME):
Under SessionStart:
{
"type": "command",
"command": "/home/yourname/.claude/hooks/session-init.sh",
"timeout": 2
}
Under UserPromptSubmit:
"UserPromptSubmit": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "/home/yourname/.claude/hooks/model-router-hook.sh",
"timeout": 2
}
]
}
]
Then restart Claude Code.
Prefix any prompt with ~ to skip classification entirely and keep the current model active.
Routing behavior is controlled by ~/.claude/model-router.json (global) or .claude/model-router.json (project-level, takes priority).
| Key | Values | Default | Description |
|---|---|---|---|
action | "warn", "autoswitch" | "warn" | warn shows a recommendation; autoswitch changes settings.json automatically |
See the schema for all options (thresholds, per-tier keywords/patterns, etc.).
Activity is written to ~/.claude/hooks/model-router-hook.log:
[2026-03-07 12:00:00] model=sonnet rec=opus action=WARN->opus prompt="analyze the entire..."
[2026-03-07 12:01:00] model=opus rec=match action=ALLOW prompt="git commit changes"
[2026-03-07 12:02:00] OVERRIDE prompt="~ keep opus for this..."
Copy and paste this into any Claude Code session to install the hooks automatically.
Set up the model-matchmaker hook system in my global Claude Code config. Do exactly the following steps:
────────────────────────────────────────────────────────────
STEP 1 — Create the hooks directory
────────────────────────────────────────────────────────────
Run: mkdir -p ~/.claude/hooks
────────────────────────────────────────────────────────────
STEP 2 — Create ~/.claude/hooks/session-init.sh
────────────────────────────────────────────────────────────
Write this exact content to the file, then run: chmod +x ~/.claude/hooks/session-init.sh
#!/bin/bash
# Session init hook: injects model-tier guidance into every conversation,
# including mandatory rules for sub-agent model selection.
# Adapted from model-matchmaker (https://github.com/coyvalyss1/model-matchmaker)
INPUT=$(cat)