SemanticRouter.NET
Send every prompt to the cheapest model capable of answering it, across local models, your own subscription CLIs, and paid APIs, behind one OpenAI- and Anthropic-compatible endpoint.
Most agentic setups send every prompt to the same model. A greeting, a session title, and an architecture trade-off all spend the same frontier quota, and when that quota runs out, the session stops. SemanticRouter.NET decides per request: it works out what each prompt needs, sends it to the cheapest model that qualifies, and when a subscription hits its usage limit, cools that model down and moves on to the next-best one.
Cheapest capable model
Routes declare the tier and capabilities (code, tools, vision) an intent needs, and models declare what they provide. The default strategy picks the cheapest model that qualifies, so free local models answer whatever they are good enough for.
Your tools, unchanged
Three front doors: OpenAI chat completions, the Anthropic Messages API, and the OpenAI Responses API. Claude Code and Codex CLI keep their own model names and agentic loop, and the router picks the backend for each turn.
Failover and quota cooldowns
A failing model is skipped for 30 s, and one that reports a usage limit for 15 min. An account-wide limit cools down every model on that account at once.
A local-only rail
Routes marked LocalOnly are served only by models marked IsLocal, even on failover. Subscription CLI connectors refuse requests from other machines by default.
See what you share
Point it at an Obsidian vault, Claude Code's memory, or an MCP memory graph. For every request, the memory map shows which notes went in and whether a local or cloud model received them.
Decisions you can inspect
The X-Prompt-Route-* headers carry the reason, tier, similarity, complexity, and chosen model, the logs record every decision, and the diagnostics endpoint returns each route's similarity and the full ranked model list. The dashboard shows decisions live and applies configuration edits without a restart.

How it works
- Classify the prompt. Embedding similarity against your intent clusters, plus cheap complexity heuristics (length, code, structure, and reasoning phrases), produce a required tier, capabilities, and an optional local-only constraint. Automatic classification never lowers a requirement: you can ask for less with a callout such as
@tier1, and model trials can move a route to a cheaper model when feedback holds. - Rank the catalog. Eligible models are ordered by strategy: cheapest capable (the default), most capable, fastest, balanced, or your own priority. Clients can choose per request with
auto:cheapest,auto:best,auto:fastest, and more. - Dispatch with failover. The router tries the candidates in order and fails over when a model is down or out of quota, as long as no output has reached the client yet. In Annotate mode it only attaches the plan, and your own endpoint makes the call.
With the repo's sample LM Studio + Claude Code catalog:
prompt needs → served by
"hello, how are you today?" tier 1 → lmstudio-small (free, local)
"write a unit test for this function: …" tier 2 + code → lmstudio-coder (free, local)
"compare event sourcing and CRUD trade-offs" tier 4 → claude-code (your subscription)
"look up the customer record for account 4471" tier 1, local only → lmstudio-small (never leaves the machine)
… Claude session limit reached … tier 4 → lmstudio-coder (best available; Claude cools down)The dashboard at /router shows live decisions and cooldowns, has a prompt tester, and edits routes, models, connectors, and tiers on the running router.

Works with
- Claude Code
- Codex CLI
- GitHub Copilot CLI
- OpenAI SDKs
- LM Studio
- Ollama
- vLLM
- OpenAI
- Anthropic
- Gemini
- Azure OpenAI
- OpenRouter
Try it
Install the semantic-router .NET tool, which needs the .NET 9 SDK:
dotnet tool install -g SemanticRouter.Host
semantic-router init # finds LM Studio / Ollama models and the claude, codex and copilot CLIs
semantic-router doctor # checks every connector without calling a model
semantic-router # http://localhost:5080, dashboard at /router
# then, in another terminal, point Claude Code at it:
ANTHROPIC_BASE_URL=http://localhost:5080 ANTHROPIC_AUTH_TOKEN=semantic-router claudeOr download a desktop installer for Windows, macOS, or Linux from the latest release. It is self-contained, runs the router from the tray, and updates itself. The installers are not signed yet, so SmartScreen or Gatekeeper asks you to confirm the first launch.
Get involved
SemanticRouter.NET is free and open source under the MIT license, and it is still in testing. The repo's sample catalog can't stand in for your own mix of local models, subscription CLIs, and APIs, so the most useful help is running the router against that mix on real work. The desktop app has so far only been exercised on Linux (X11), so reports from Windows and macOS on the tray, the window and start at sign-in are especially useful. Report the prompts it routed to the wrong tier (a trivial request that spent frontier quota, or a hard one that landed on a model past its capability ceiling), with the reason and tier it recorded and the embedding model you used, since similarity thresholds differ between embedding models. Reports go in the repo's issues; leave out secrets and private prompt text.
Signing up creates a free siebe41.com membership tagged for this project. That is how testers hear about new builds.