{"slug": "claude-code-router-v3-what-changed-and-how-i-set-it-up-now", "title": "Claude Code Router v3: What Changed and How I Set It Up Now", "summary": "A developer documented the v3 rewrite of Claude Code Router (CCR), now a local model gateway and control plane for coding agents, in a first-person setup guide. The v3.1.1 release moves configuration into a SQLite database at ~/.claude-code-router, replaces base-URL proxying with Agent Config profiles launched via `ccr \"<profile>\"`, and adds credential pools, per-rule fallback chains, and request logs. The tool now supports agents beyond Claude Code, including Codex, Grok CLI, Kimi CLI, Kilo Code, OpenCode, and others.", "body_md": "I went back to Claude Code Router this week to point a side project at a cheaper model. My notes from the last time I used it were useless. CCR isn't a small proxy you start and forget anymore. The README now calls it \"a local model gateway and control plane for coding agents\", and the recommended install is a desktop app.\n\nMost of what ranks for \"claude code router\" still describes the older shape: run a proxy, aim Claude Code's base URL at it, sort traffic into background, thinking and long-context buckets. The core idea holds. The way you set it up and route traffic doesn't. This is what I worked out from the v3 README and docs. The latest release is v3.1.1, published September 16, 2026, and the repo is around 37.6k stars.\n\n(For context, the side project is a landing page plus a small browser extension. I'm testing [Begin](https://begin.sh/?utm_source=devto&utm_medium=ugc&utm_campaign=zaramenon&utm_content=claude-code-router-intro) for that part, since it builds websites and Chrome extensions from the same prompt. Claude Code and CCR are for the backend code I still write by hand.)\n\nThe short version: CCR runs on your machine and gives your coding agents one stable endpoint. Behind that endpoint you manage providers, models, credentials, routing rules and logs.\n\nThree things surprised me:\n\n**It's not just for Claude Code.** The supported list now includes Claude Code (CLI and app), Claude Design, Codex, Grok CLI, Kimi CLI, Kilo Code, OpenCode, Pi, ZCode and WorkBuddy. The name stuck. The scope didn't.\n\n**Config moved into the app.** The settings live in `config.sqlite` in `~/.claude-code-router` (or `%APPDATA%\\claude-code-router` on Windows). The docs warn against editing or copying the live SQLite file while CCR runs. Use **Settings → Export data**, or stop CCR before a file-level backup. If your muscle memory is \"open the config and edit JSON\", unlearn it.\n\n**You launch the agent through CCR.** You don't just set a base URL. You create an \"Agent Config\" profile, then start Claude Code from CCR. Open Claude Code the normal way and it skips CCR entirely, unless the profile's scope is set to \"System default\".\n\nHere's how the old mental model maps to v3, as far as I can tell from the docs:\n\n| What I used to think about | Where it lives in v3 | \n|---|---|\n| Point Claude Code's API base URL at the proxy | An Agent Config profile, launched with `ccr \"<profile name>\"` or from the desktop card | \n| A default model plus task buckets | A profile default model, plus separate Fable / Opus / Sonnet / Haiku tier overrides | \n| Special-case routing | Custom rules on request headers or body, or a Node.js script rule | \n| Hoping a provider stays up | Per-rule or default fallback: `retry` or an ordered`model-chain` | \n| One API key per provider | Credential pools with priority, weight and limits | \n| Guessing what happened | Request logs showing request model, resolved provider and resolved model | \n\nI'm on a headless Linux box most of the time, so I used the npm CLI rather than the Electron app. Both read the same config directory, but the commands differ. The desktop app writes launchers named `ccr-app`. The npm package gives you `ccr`. Don't mix them up when copying commands from a profile card.\n\n```\nnode --version                     # the CLI needs Node.js 22 or newer\nnpm install -g @musistudio/claude-code-router\nccr ui --no-open                   # background service, no browser on SSH\n```\n\n`ccr ui` prints a management URL. Two ports matter. The management UI defaults to `127.0.0.1:3458` and the model gateway to `127.0.0.1:3456`. If 3458 is taken, CCR moves to the next free port, so trust the printed URL. That URL contains a `ccr_web_token` query parameter. The docs say to treat it like a password. Don't paste it in a ticket or a screenshot.\n\nThen, in the UI, in the order the docs suggest:\n\nThen launch it:\n\n```\nccr \"Claude Code - Work\"\nccr \"Claude Code - Work\" cli -- --model sonnet   # args after -- go to the agent\nccr stop                                          # stops the background service\n```\n\nInside Claude Code, `/model` lists the models CCR exposes. That's the quickest way to confirm you're going through the gateway. The other is the request log.\n\nFor a server where something else supervises the process, the docs recommend `ccr serve --no-open` in the foreground, with a fixed `CCR_WEB_AUTH_TOKEN`. Don't also run a background `ccr start` next to it, or you get two processes fighting over one config.\n\nThe tier overrides were the biggest change in how I think about routing. Claude Code picks a model per tier, and a CCR profile lets you override each tier separately. A strong provider model on Opus, a cheap one on Haiku, everything else on the default. Leave a tier empty and Claude Code picks for itself. The value has to be a valid `Provider/model` (the docs use `Moonshot/kimi-k3` as an example) or a Fusion model.\n\nSubagents get their own mechanism. If you add a **Description** to models on the Models page, CCR injects that list into Claude Code's Agent/Task tool descriptions. When Claude Code spawns a subagent, it starts the prompt with a tag like `<CCR-SUBAGENT-MODEL>provider/model</CCR-SUBAGENT-MODEL>`. CCR strips the tag and routes that request to the tagged model. No descriptions means no injection, so the Description field doubles as the on/off switch. When it works, the request log shows `builtin:claude-code-subagent`.\n\nCustom rules come after that. They match on `request.header` or `request.body`, run top to bottom, and the first enabled match wins. Most of my \"it went to the wrong model\" moments came down to rule order.\n\nWhen one condition isn't enough, there's a **Node.js script rule**. The file is an async function *body*, not a module. You get a read-only `input` object and return a decision. This is the one I use to send oversized requests to a long-context model:\n\n```\n// long-context.js: CCR script rule (function body, no imports/exports)\nif (input.summary.hasImage) {\n  return null; // not mine, let the next rule decide\n}\n\nif (input.tokenCount > 120000) {\n  return {\n    model: \"Moonshot/kimi-k3\",\n    fallback: {\n      mode: \"model-chain\",\n      models: [\"Provider/backup-model\"],\n      retryCount: 0\n    }\n  };\n}\n\nreturn null; // no match, continue down the list\n```\n\nSome details from the docs worth knowing. `input.tokenCount` is CCR's estimate and is `0` when unavailable. The timeout is configurable from 10 to 30000 ms. CCR re-reads the file on every run, so edits apply without re-saving the rule. Scripts are **fail-open**: an exception, timeout or invalid result logs a diagnostic and moves on to the next rule. That's the right default for availability. It also means a broken script fails quietly, so check the logs after any edit.\n\nRouting doesn't change model quality. A cheaper model behind Claude Code's interface is still the cheaper model. The interface makes it more pleasant, not smarter.\n\nThe surface area has also grown a lot. Fusion, ToolHub, browser automation, Chrome login-state import, AgentClaw bots relaying through Slack, Discord, Telegram and more. All optional, but there's much more to secure than a single proxy port. Upstream provider keys sit in the local data directory, and the docs say to protect it and its backups as sensitive data. If you bind the management service to `0.0.0.0`, they ask for a fixed strong token, a firewall or private network, and TLS from a reverse proxy.\n\nFinally, the routing is easy to bypass by accident. If Claude Code isn't launched from CCR and the profile isn't \"System default\", your requests go straight to Anthropic. The troubleshooting page leads with that question for a reason.\n\n**Does Claude Code Router still work with the npm CLI, or only the desktop app?**\n\nBoth. `npm install -g @musistudio/claude-code-router` gives you `ccr`, which runs the same gateway and a browser-based UI without Electron. You need Node.js 22+.\n\n**What port does Claude Code Router use?**\n\nThe model gateway defaults to `http://127.0.0.1:3456` and the management UI to `http://127.0.0.1:3458`. The UI moves to the next free port if 3458 is busy.\n\n**Why aren't my Claude Code requests going through CCR?**\n\nCheck three things: the CCR service is running, Claude Code was launched from CCR (not opened directly), and the Agent Config profile is enabled with a scope that covers how you're launching it.\n\n**How do I fix \"model not found\" with Claude Code Router?**\n\nThe model name has to match in three places: the provider's model list, the model in your routing config, and the model in the Agent Config. Compare all three.\n\nClaude Code Router grew from a clever hack into real infrastructure. I'd rather have the request logs, credential pools and explicit fallbacks than the old setup. It just takes an afternoon to relearn. The [repo README](https://github.com/musistudio/claude-code-router) links to the full docs once you need more than the basics.\n\nAs for the side project: the backend goes through Claude Code on a routed model. The marketing site and the extension shell go through [Begin](https://begin.sh/?utm_source=devto&utm_medium=ugc&utm_campaign=zaramenon&utm_content=claude-code-router-outro), which comes with hosting, sign-in and Stripe payments already connected.", "url": "https://wpnews.pro/news/claude-code-router-v3-what-changed-and-how-i-set-it-up-now", "canonical_source": "https://dev.to/zaramenon/claude-code-router-v3-what-changed-and-how-i-set-it-up-now-mj7", "published_at": "2026-10-07 03:14:09+00:00", "updated_at": "2026-10-07 03:17:52.002770+00:00", "lang": "en", "topics": ["ai-agents", "ai-tools", "developer-tools", "ai-infrastructure"], "entities": ["Claude Code Router", "Claude Code", "Codex", "Grok CLI", "Kimi CLI", "Kilo Code", "OpenCode", "Node.js"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/claude-code-router-v3-what-changed-and-how-i-set-it-up-now", "markdown": "https://wpnews.pro/news/claude-code-router-v3-what-changed-and-how-i-set-it-up-now.md", "text": "https://wpnews.pro/news/claude-code-router-v3-what-changed-and-how-i-set-it-up-now.txt", "jsonld": "https://wpnews.pro/news/claude-code-router-v3-what-changed-and-how-i-set-it-up-now.jsonld"}}