npm.io
0.1.12 • Published 5d agoCLI

@morphllm/morphrouter

Licence
MIT
Version
0.1.12
Deps
2
Size
115 kB
Vulns
0
Weekly
0

@morphllm/morphrouter

Morph-powered model routing for Claude Code.

You stay signed into Claude Code with your normal Claude account. This wrapper runs the real Claude Code TUI, classifies each prompt with Morph (difficulty / ambiguity / domain), and switches the live session between haiku, sonnet, and opus by injecting /model. It can also inject /effort low|medium|high|xhigh|max. The default matrix routes difficulty to model (easy -> haiku, medium -> sonnet, hard -> opus) and ambiguity to effort (low -> low, medium -> medium, high -> high).

No Anthropic API key, OpenRouter key, or per-user provider key is required for this mode.

Install

npm install -g @morphllm/morphrouter
# or run without installing:
npx @morphllm/morphrouter chat

Requires Node.js >= 20 and an installed, logged-in Claude Code.

Quick start

export MORPH_API_KEY=...           # your Morph key
morphrouter init                   # write a starter config
morphrouter chat "fix the parser bug"

Running morphrouter with no subcommand is the same as morphrouter chat. chat (alias enterprise-chat) launches the native Claude Code TUI. When you submit a normal prompt it: clears the draft line, calls Morph, sends /model <selected-model> if the model changed, auto-confirms Claude Code's switch prompt, sends /effort <selected-effort> if needed, waits for it to settle, then resends your prompt.

The Morph status bar is part of normal chat startup. When Claude Code does not already have a custom statusLine, morphrouter wires the bar automatically.

Slash commands (/status, /model opus, /exit, …) pass through unchanged.

Works with all Claude Code flags

Any flag you pass is forwarded straight to the underlying claude process, so subagents, MCP, sessions, and permission modes all work as normal:

# boolean flags can be passed directly:
morphrouter chat --dangerously-skip-permissions

# expose the local routed session through Claude Code Remote Control:
morphrouter chat -- --remote-control

# use `--` before value-flags so they aren't read as prompt text:
morphrouter chat "refactor auth" -- --add-dir ../shared --resume
morphrouter chat -- --mcp-config ./mcp.json --permission-mode plan

Notes:

  • The router owns --model, so a --model you pass is ignored.
  • Subagents and remote control work because this drives the real TUI — the wrapper only touches the top-level input line and /model switching.
  • In the SDK fallback (chat-sdk), --dangerously-skip-permissions and --add-dir are translated to SDK options; other flags are TUI-only.

Config

The subscription route is just the Claude Code model alias. Thinking effort is configured beside it:

{
  "routing": {
    "defaultRoute": "sonnet",
    "defaultEffort": "medium",
    "matrix": [
      { "difficulty": "easy", "ambiguity": "low",  "domain": "*", "route": "haiku", "effort": "low" },
      { "difficulty": "easy", "ambiguity": "high", "domain": "*", "route": "haiku", "effort": "high" },
      { "difficulty": "hard", "ambiguity": "low", "domain": "*", "route": "opus", "effort": "low" },
      { "difficulty": "hard", "ambiguity": "high", "domain": "*", "route": "opus", "effort": "high" }
    ]
  }
}
Stop switching on long context (KV cache)

Switching models mid-conversation busts the upstream KV/prefix cache. Set a token ceiling past which the router pins the current model instead of re-routing:

{ "routing": { "contextLock": { "enabled": true, "maxTokens": 60000 } } }

In the gateway this counts the full request (system + tools + messages); in native chat it counts the rendered output the router can observe, so it is approximate and errs toward locking a little early.

Tuning for native /model switching lives under claudeCodeSubscription (switchIdleMs, switchConfirmTimeoutMs, autoConfirmModelSwitch, autoConfirmEffortSwitch, …). See config.example.json in the repo for the full set.

Debug trace:

MORPH_NATIVE_TRACE=/tmp/morph-native-trace.jsonl morphrouter chat

Commands

morphrouter                 # same as morphrouter chat
morphrouter chat            # route each turn in native Claude Code via /model
morphrouter enterprise-chat # alias for chat
morphrouter chat-sdk        # Claude Agent SDK wrapper (non-TTY fallback)
morphrouter plan-chat "..." # route once at startup, then hand off to claude
morphrouter statusline      # print latest Morph decision for statusLine
morphrouter doctor          # diagnose the setup
morphrouter config          # open the config file in your editor (alias: edit-config)

Develop

npm ci
npm test

This package is published by the landing repo's morphcli-publish-mcp.yml workflow.

License

MIT