explain-modelmuxlisted
Install: claude install-skill armenr/modelmux
# How modelmux works
Explain the mental model, adapting depth to the audience. The whole system is
small and readable — point people at the actual files.
## The constraint
Claude Code picks its upstream from **one global** environment variable,
`ANTHROPIC_BASE_URL`. There's no per-subagent model setting on the client side.
So if you want *some* agents on Claude and *others* on a different model, the
decision has to happen **outside** the client — in a proxy that every request
flows through.
## The proxy
`src/server.ts` is a `Bun.serve` reverse proxy. For each request it:
1. Extracts routing **signals** (`src/signals.ts`).
2. Picks a target via a first-match **cascade** (`src/route.ts` + `routes.toml`).
3. Rewrites auth for the chosen upstream (`src/upstreams.ts`) and forwards it.
SSE streams pass straight through.
Two upstreams: **Anthropic** (`api.anthropic.com`, "passthrough" = keep the
model Claude Code asked for) and **OpenRouter** (its Anthropic-compatible
endpoint, so no request translation is needed).
## The signals (why it routes by header, not model name)
From each request (`src/signals.ts`):
- **`x-claude-code-agent-id`** — present *only* on subagent requests, so it marks
`isSubagent`. This is the key signal, and routing on it sidesteps a Claude Code
bug where a subagent's requested model can silently fall back to the parent's.
- **`x-app`** — `cli` for foreground, `cli-bg` for background work.
- **`<<route:alias>>`** — an explicit tag placed in an