Skip to main content
Glama
io.github.bdbais/routeai

io.github.bdbais/routeai

by bdbais

RouteAI

CI License: MIT Donate

A Claude Code plugin that routes small coding jobs to the AIs you already have — the Ollama machines on your network and the free tiers of providers like Gemini, Groq or OpenRouter — while Claude decides what to delegate and checks every result. Fewer Claude tokens, work in parallel, and free capacity used before paid.

Website, in 13 languages: https://routeai.bais.info

Claude Code ──(MCP, stdio)──► RouteAI ──► desktop with GPU     complex code, functions
   decides, briefs,             router        laptop (CPU)         tests, scripts, build, docs
   reviews, gives feedback      learned        Gemini / Groq free   docs, extraction, overflow
                                stats + cost   any paid API         only when you allow it

Why

Claude is the best engineer on the team, and the most expensive. Plenty of the work in a coding session is well defined and easy to check: unit tests for a module, a CLI script, docstrings, a CI workflow, a pyproject.toml, working out why a build failed, or the same mechanical edit on forty files. A 7–30B model running at home does these for free, while Claude keeps the design, the hard parts and the final review.

Related MCP server: claude-token-saver-mcp

What it does

  • Priority routing by machine power. Each task category prefers a tier. complex and code go to the fast GPU machine; tests, scripts, build and docs go to the slower machines. A task only moves to the other tier when the preferred machines are busy.

  • It learns as it goes. Among suitable candidates the router ranks by measured quality² ÷ expected time. Expected time includes prompt processing, generation, model load or swap, and queue wait. Quality comes from the benchmark and from Claude's feedback on real work.

  • A benchmark that grades itself, meant to be run from time to time until the fleet "knows" your hardware. There are 10 tasks, each checked automatically:

    • code is run against hidden unit tests;

    • generated tests are mutation-tested against 4 buggy variants;

    • scripts are run with sample input and their output compared;

    • config files are checked by parsing the TOML;

    • docstrings are checked with AST comparison;

    • log diagnoses are checked against a strict JSON schema.

    Probes also measure how much of each model sits in VRAM and how throughput scales with parallel requests. The result is a report with concrete suggestions for fleet.toml.

  • Claude never pastes files. The server reads project files itself (paths or globs), can write results straight to disk, and returns only a preview.

  • Parallel batches. One instruction runs over many files, spread across every machine.

  • Claude stays in charge. The benchmark only suggests configuration changes; Claude proposes them and you approve them.

  • No dependencies. It needs only Python 3.11+ and Ollama. No pip install and no SDK.

Adding another AI

Beyond local machines, RouteAI talks to any OpenAI-compatible provider — Gemini, Groq, OpenRouter, DeepSeek, Mistral, OpenAI, or your own vLLM/LM Studio endpoint:

/routeai:add-ai gemini gem1

Three rules keep it safe and cheap:

  • The key never touches the configuration or the chat. You put it in an environment variable (GEMINI_API_KEY, GROQ_API_KEY, …) and the node stores only that variable's name.

  • Your files stay home unless you say otherwise. A provider only receives project files when its node has send_files = true; without it, it is skipped for any task that includes files.

  • Free first, then paid, then nothing. Set [nodes.cost] (USD per million tokens, 0 for a free tier) and a [nodes.limits] cap: daily requests or tokens for free tiers, daily_cost_usd for paid ones. The router prefers free nodes, stops using a node when its limit is reached, and falls back to your own machines.

/routeai:usage then shows tokens, cost and remaining quota per node.

Requirements

  • Claude Code

  • Python 3.11 or newer. The launcher in bin/ finds it by itself: py -3 or python on Windows, python3.14…python3.11, python3 or python on macOS/Linux. Set ROUTEAI_PYTHON to force one. (The system python3 of macOS is 3.9: install a newer one, e.g. with Homebrew.)

  • One or more machines running Ollama. On machines other than the one running Claude Code, set OLLAMA_HOST=0.0.0.0 so Ollama listens on the LAN.

Tested end to end on Windows 11 with two Ollama machines; the unit tests run on Windows, macOS and Linux in CI.

Install

In Claude Code:

/plugin marketplace add bdbais/routeai
/plugin install routeai@bais

Trying it out to review it? REVIEWER-GUIDE.md is a 20-minute test plan: what to run, what to look for, the known limits, and what makes a bug report actionable.

Then, in a new session, describe your machines:

/routeai:setup gpu=http://192.168.1.13:11434 local=http://localhost:11434

Setup probes each Ollama server, picks the installed models per category (models are set per machine and per category, because the right model depends on each machine's power), lists recommended models that are missing with their size and hardware needs — and downloads them only if you say so — then writes ~/.routeai/fleet.toml. You can also edit that file by hand; see config/fleet.example.toml. With no config at all, the plugin uses the local Ollama only.

Let the fleet learn your hardware, then check routing and savings:

/routeai:bench
/routeai:status

Using it

Every finished task reports how many Claude tokens it saved (this task, session and all-time), and Claude tells you in one line. It is an estimate: the tokens of the files the worker read plus the tokens it generated, minus the brief Claude wrote and the result Claude read. Tiny tasks can come out negative — delegation pays off on substantial inputs/outputs and on batches, where one brief covers many files. Measured on the test fleet: pytest tests for a ~100-line module saved ~1,200 Claude tokens (15 s on the GPU box); Markdown references for two modules, as a batch split across both machines, saved ~4,800.

You don't have to do anything special. The delegate skill teaches Claude when a sub-task is worth delegating, how to write a self-contained brief, and how to verify the result. You can also ask directly: "use the fleet to write tests for every module in src/parsers/".

Tool

Purpose

fleet_status

Shows node health, loaded and missing models, where each category routes, tokens saved, and whether a benchmark or setup is due

fleet_setup

Probes your Ollama servers, picks models per category, suggests models to pull, writes fleet.toml

fleet_nodes

Adds, removes, enables or disables one machine, keeping the other machines' settings

fleet_usage

Ollama tokens processed per machine and model, with totals, plus the Claude tokens saved

fleet_queue

Queues work the fleet finishes on its own while Claude is paused; lists and clears it

fleet_delegate

Runs one task: instruction, category, files, context, output_path, json_schema

fleet_delegate_batch

Runs the same instruction on many files in parallel, e.g. output_pattern: "tests/test_{stem}.py"

fleet_job

Reports progress and results of a batch, a long task or a benchmark

fleet_feedback

Records good / fixed / rejected for a result, which trains the router

fleet_bench

Runs the self-learning benchmark (quick or full, explore, deep)

fleet_pull

Downloads a model onto a node

The same features are available from the command line (bin/routeai is also on the PATH of Claude's Bash tool while the plugin is enabled):

python run.py init --node gpu=http://192.168.1.13:11434   # same as /routeai:setup
python run.py status                         # health + routing preview + savings + bench advice
python run.py nodes add gpu2=http://192.168.1.20:11434   # also: list, remove, enable, disable
python run.py usage --days 7                 # Ollama tokens per machine + savings, last week
python run.py queue work                     # keep working the queue while Claude is paused
python run.py bench --mode quick --deep      # graded benchmark + parallel probe
python run.py bench --mode full --explore    # also try installed models you haven't configured

Stats, the task log and reports are kept in ~/.routeai/.

How often to benchmark

fleet_status tells you when a run is due:

  • While learning (a model/category pair has fewer than 5 samples, or its recent scores disagree): every 2–3 days, or after adding models.

  • Once stable: monthly, or after a hardware change.

Every real task also updates speed statistics, and every fleet_feedback updates quality. The benchmark is how new models and machines earn trust quickly.

Tips from real hardware

  • Pin num_ctx. Ollama's default context can push a model out of VRAM; on a 12 GB GPU, qwen2.5-coder:14b went from 7 to 49 tokens/s at num_ctx = 8192. Context is fixed per model on purpose, because changing it between requests forces a reload.

  • MoE models suit small GPUs. qwen3-coder:30b still produces about 28 tokens/s when half of it is offloaded to the CPU.

  • CPU-only laptops still help. Give them small coder models (3–7B) for scripts, tests and docs, and max_parallel = 1 so your own work stays responsive.

  • Rented or remote servers: reach them over SSH (below), not with port 11434 open. Ollama has no authentication of its own.

Remote machines over SSH

Ollama has no authentication, so a machine outside your LAN should never expose port 11434. RouteAI reaches it through the SSH access you already have: Ollama keeps listening only on 127.0.0.1 over there, and each request travels through a tunnel that RouteAI opens, keeps alive and reopens when it drops.

First time, in your own terminal (not through Claude: ssh asks for the password there):

python run.py ssh-setup linux-gpu you@your-server
1/5  reaching you@your-server         DNS, then the SSH port
2/5  key: created ~/.routeai/ssh/id_ed25519_linux-gpu
3/5  installing it on you@your-server  ssh shows the server fingerprint and asks for the password
4/5  opening the tunnel with the key alone
5/5  saving the node

The password is typed into ssh itself and used once, to install a dedicated key; RouteAI never sees or stores it. The key is installed restricted:

restrict,port-forwarding,permitopen="127.0.0.1:11434",command="/bin/false" ssh-ed25519 AAAA… routeai-linux-gpu

so it can open this one tunnel and nothing else - no shell, no other ports. A stolen copy reaches your Ollama, not your server. (--full-access installs it without restrictions; --remote-port if Ollama listens elsewhere.)

Already log in with a key? Skip all that: python run.py ssh-setup linux-gpu gpu-box --use-ssh-config, or add it from Claude with /routeai:nodes add linux-gpu=ssh://gpu-box. Your ~/.ssh/config, agent and known_hosts are used as they are.

In fleet.toml the node has ssh instead of url:

[[nodes]]
name = "linux-gpu"
ssh = "you@your-server"                       # or an ~/.ssh/config alias, or user@host:2222
ssh_key = "C:/Users/you/.routeai/ssh/id_ed25519_linux-gpu"

When something breaks, python run.py ssh-check linux-gpu tests DNS, the SSH port, authentication and Ollama one stage at a time and says what to do. The server's fingerprint is pinned at setup: if it ever changes the tunnel refuses to open; after a legitimate reinstall, python run.py ssh-forget linux-gpu and run ssh-setup again.

Tunnels use the system ssh client (OpenSSH, built into Windows 10+, macOS and Linux) with BatchMode, so they never wait for a prompt. They are closed when RouteAI exits; on Windows they die with it even if it is killed.

Sharing what you measured

The benchmark tells you what runs well on your machines. https://routeai.bais.info/community/ collects what people chose to share, so a newcomer can see what a 12 GB GPU or a CPU-only laptop really gets out of a given model and quantisation — something no public leaderboard measures.

Sending is manual, opt-in and one command:

python run.py send-stats            # prints everything it would send, then asks
python run.py send-stats --dry-run  # prints it and sends nothing
python run.py send-stats --delete   # removes your results from the site

What travels: model tag, quantisation, parameter size, context, a hardware bucket (cpu, gpu12, …), category, score, tokens per second, GPU offload ratio, run count, plugin version, operating system name. What never travels: machine names, addresses, file paths, prompts, instructions, project data. The payload is built field by field from a fixed list, so nothing can leak into it by accident later.

Two lists are kept apart. Certified results come from an installation signed in with GitHub (device flow, in your terminal: RouteAI receives the account id, stores it only as a keyed hash, and discards the token). Not certified results are anonymous — useful, but nothing stops one person from sending again from a fresh install. Either way the numbers are self-reported, results far out of scale are flagged and left out of the medians, and repeated abuse is blocked. IP addresses are never stored: they are counted for a day to limit floods.

Security

  • Provider keys are read from environment variables only: they are never written to fleet.toml, never logged, and requests never follow redirects, so a key cannot be forwarded elsewhere.

  • A remote provider receives project files only if you set send_files = true for it.

  • The server only reads and writes files inside the project, plus any allowed_roots you list (explicit paths; globs are relative to the project). Network (UNC) paths are refused before they are touched.

  • Worker output is written before Claude reviews it, so it is never written into .git/, .claude/, node_modules/, virtualenvs or editor folders, where a file could run code or change tool settings.

  • Globs skip dotfiles and secret-looking files (.env, *.pem, *.key, credentials…); list such a file explicitly only if you really want a local model to see it.

  • An answer cut off at max_output_tokens is reported as a failure and never written over a file.

  • Requests to nodes never follow redirects, so a node's bearer token cannot be forwarded elsewhere.

  • :cloud models, which run on ollama.com, are never used unless allow_cloud_models = true.

  • Nothing is ever sent to the internet unless you run send-stats yourself, and that command prints the whole payload and asks before sending.

  • SSH nodes: the password is only ever typed into ssh in your terminal; the dedicated key can open the tunnel to Ollama and nothing else; the host fingerprint is pinned; targets that could be read as ssh options (-o…, spaces, quotes) are refused; the local end of a tunnel listens on 127.0.0.1 only.

  • Traffic to nodes bypasses system HTTP proxies, so LAN requests are not sent through a corporate proxy.

  • The benchmark runs code written by your local models in a temporary folder with a timeout and a minimal environment. That is enough for its small, fixed prompts, but it is not a security sandbox.

  • Don't delegate secrets. The delegate skill tells Claude never to send .env or credential files.

Development

Install or refresh the plugin from a local checkout on Windows, including validation, tests, the fleet config and a server smoke test (run it again after every change; -Uninstall removes it):

powershell -ExecutionPolicy Bypass -File scripts\install.ps1
python -m unittest discover -s tests -v      # no Ollama needed (live tests are skipped)
ROUTEAI_LIVE=1 python -m unittest tests.test_live -v   # drives the real MCP server against your fleet
node site/build.mjs                          # showcase site; fails on any missing translation
claude --plugin-dir .                        # try the plugin from a checkout

The live test uses your fleet.toml but a temporary home and project, so your learned statistics stay untouched.

Support

If RouteAI saves you tokens, you can buy me a coffee on PayPal ☕ or star the repo.

Independent open-source project, not affiliated with Anthropic or Ollama. MIT licensed.

Available Tools

11 tools
fleet_benchA

Start the self-learning benchmark in the background: graded coding tasks per category on every node/model, plus optional resource probes. Returns a job_id; the finished job contains a report with recommendations for fleet.toml.

Inputs: deep, mode, nodes, models, +2 more.

fleet_delegateA

Delegate ONE small task to a local model and get the result. The server reads files itself. With output_path the answer is written to that file and only a preview comes back. Long tasks return a job_id to poll with fleet_job. complex/code → fast GPU node first; tests/scripts/build/docs → light nodes first (overflow to the other tier when busy); general → any; auto → keyword guess.

Inputs: instruction (required), node, files, model, +7 more.

fleet_delegate_batchA

Apply the same instruction to many files in parallel across all nodes (one task per file). Returns a job_id immediately; poll fleet_job. Use output_pattern with {path} {dir} {stem} {name} {ext}, e.g. 'tests/test_{stem}.py'. complex/code → fast GPU node first; tests/scripts/build/docs → light nodes first (overflow to the other tier when busy); general → any; auto → keyword guess.

Inputs: files (required), instruction (required), context, category, +4 more.

fleet_feedbackA

Tell the fleet how good a delegated result was, after you reviewed it. good = used as is, fixed = needed corrections, rejected = unusable. This trains the router.

Inputs: task_id (required), verdict (required), note.

fleet_jobC
Read-only

Progress and results of a background job (batch, long task, benchmark or pull).

Inputs: job_id (required), include_outputs.

fleet_nodesB

Add, remove, enable or disable ONE machine in the fleet configuration, keeping every other machine's settings and comments. 'add' probes the new server and picks its models per category; 'list' only shows the current machines. The previous file is kept as a backup.

Inputs: action (required), url, name, tier, +11 more.

fleet_pullA

Download a model onto a node (ollama pull). Downloads can be many GB and take minutes: only with the user's approval.

Inputs: node (required), model (required).

fleet_queueA

Queue work the fleet finishes on its own, so it keeps going while you are paused (usage limit reached, session closed) - slow but steady. Actions: 'add' (same fields as fleet_delegate; give an output_path so the result lands on disk), 'list' (queued, running and finished, with results to review), 'cancel' one by id, 'clear' (done | pending | all).

Inputs: action (required), id, note, what, +6 more.

fleet_setupA

Create or replace the fleet configuration by probing the user's Ollama servers: picks installed models per category and lists recommended models that are missing (with size and hardware). Without nodes it only probes the configured machines. Never pull models without the user's approval.

Inputs: nodes, overwrite.

fleet_statusA
Read-only

Nodes, health, loaded models, routing preview per category, token savings and whether a benchmark or the first setup is due.

Inputs: no named parameters.

fleet_usageA
Read-only

How much the fleet was used and what it saved: tokens processed per node (local machines and providers) and per model, cost in USD, today's quota use, Claude tokens saved, and a breakdown per category. This project by default; scope 'all' for every project, days for a period.

Inputs: days, scope.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.7/5.0

    Scored across 11 tools

    Disambiguation4/5

    Each tool has a mostly distinct purpose, with action and resource clearly separated. The main overlaps are fleet_status vs fleet_usage on usage/savings metrics and fleet_job vs fleet_queue on background work status, but the descriptions clarify the boundaries.

    Naming Consistency5/5

    All tools share the fleet_ prefix and use lowercase snake_case throughout. The verb/noun suffixes are intuitively matched to each operation, making the naming pattern highly predictable.

    Tool Count5/5

    With 11 tools, the set is well-scoped and covers the fleet lifecycle without redundancy or bloat. Each tool has a clear role, and the count is comfortably within the ideal range.

    Completeness4/5

    The core workflow is well covered: set up the fleet, manage nodes, delegate single/batch tasks, queue work, monitor jobs, provide feedback, benchmark, and track usage. Minor gaps include no way to cancel a running background job or remove a pulled model.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables Claude to delegate coding tasks to local Ollama models, reducing API token usage by up to 98.75% while leveraging local compute resources. Supports code generation, review, refactoring, and file analysis with Claude providing oversight and quality assurance.
      518 npm
      26
      AGPL 3.0
    • A
      license
      A
      quality
      D
      maintenance
      Enables Claude Code to offload routine code generation and text processing tasks to a local Ollama LLM, saving Cloud API tokens and costs with automatic model selection and security features.
      11
      867 npm
      3
      Apache 2.0