Skip to content
MrJev

JevRouter

Routes each agent step to a model, subagent, Skill, MCP tool, or CLI with one Jev Choice, requiring confirmation for risky capabilities and keeping decision receipts.

View on GitHub →

Hands-on review

Routes a request across models, subagents, skills, MCP tools and CLIs with one Jev call. Its quickstart shape silently drops a candidate's risk level.

Good for

  • Picking among tools, subagents, skills and models with one typed question
  • Agents that should propose an action rather than take it: decision-only by default
  • A readable decision record: every routing choice is written out with its inputs

Watch out for

  • Candidates in the quickstart's short form are forced to risk=low, confirmation off
  • Decision files keep your request and context in plain text under .jevrouter/
  • Two days old, not on npm, and discovery runs third-party commands to find them

Tested Sep 20, 2026 at 3c558a78edf5 · Node 24 in Docker, offline, using the project's own demo provider; 69 tests run with no network

How we reviewed this: we built it in Docker on Node 24, ran its test suite offline, and drove its route command with the bundled demo provider — no Jev calls needed to see how the policy layer behaves. We did not run agent start, which launches a host CLI, or the live provider.

What it does

JevRouter, by BillionsBobby, treats every capability an agent has — models, subagents, skills, MCP tools, CLIs — as options in one Choice question:

Which single capability should handle this request? Choose only from the supplied options.

Jev returns probabilities; local policy does the rest. Availability, permissions, risk level and confirmation requirements are all applied in code, and by default the router only decides: mode: decision_only, execution not started. There are two-stage and hierarchical paths for more than 32 candidates, a plan mode that batches every step’s question into one request, and a decompose mode that asks per sub-goal.

Its test suite — 69 tests — passed offline with no network and no key. The demo provider makes the whole flow runnable before you spend anything, which is the right thing to ship.

The quickstart shape drops your risk metadata

A candidate can be given in full manifest form, or in the short form the quickstart uses: a name and a description. In src/manifest.ts, anything with a name and no id is turned into a manifest with hard-coded values:

risk: { level: "low", categories: ["agent_tool"] },
availability: { available: true },
...

A risk or policy block you supplied in that shape is dropped, silently, and no warning is printed. We fed it a single candidate declaring the opposite:

{ "name": "drop_production_database",
  "description": "Permanently delete the production database and all backups",
  "risk": { "level": "critical", "categories": ["data_loss"] },
  "policy": { "requires_confirmation": true } }

and the decision came back:

status: selected | selected: drop_production_database
input declared: risk=critical, policy.requires_confirmation=true
router used:    risk_level=low, requires_confirmation=false

The README’s own summary says medium, high and critical capabilities require confirmation. They do — if the candidate reaches the router as a full manifest. In the shape the quickstart teaches, every candidate is low risk. One of the cookbooks mentions this in a footnote; the README does not.

Nothing here executes by default, so this is not a “it deleted my database” bug. It is a bug in the layer you would rely on before wiring execution, which is where a router of this kind earns its place. Listing capabilities with id and a full risk block avoids it entirely. We’ve reported it upstream.

What it sends, and what it writes down

  • The request goes out as you wrote it. The state is the request string, or {request, actor, context} when you supply those, with no redaction and no truncation. Candidate descriptions become the Choice criteria; the router deliberately does not forward the help_excerpt it captures when discovering CLIs, which is a good instinct.
  • Or it goes to OpenRouter instead. --provider openrouter posts to OpenRouter’s decisions endpoint rather than TypeSafe. Worth knowing which key you are spending and whose logs your request lands in.
  • Decisions are written to disk. .jevrouter/decisions/<id>.json holds the request, the context and the raw model answer, in plain text, with default permissions. agent setup does not add .jevrouter/ to your project’s .gitignore, so a routine git add . can commit your prompts.
  • Keys come only from the environment. Interactive entry doesn’t echo, and MCP configs are written with a "${KEY}" placeholder rather than the value. The README’s claim that keys are never written to manifests or decision files held up.
  • Discovery runs things. discover --cli executes <command> --help, and discover --mcp spawns the servers in your config with your full environment to enumerate their tools. Documented, and reasonable for a discovery step, but it means “finding capabilities” starts processes with your keys in their environment.

A few smaller edges: the cache key doesn’t include the model, so switching models can serve a previous model’s answer; serve binds to localhost with no authentication, so any local process can spend your quota; and JEV_API_URL isn’t checked for a scheme, so a mistyped http:// would send a bearer token in clear text.

Maintenance

61 commits in two days, MIT licensed, three open issues, several outside contributors, and version 0.1.0 with no npm release — installation is npx github:BillionsBobby/JevRouter. The README carries a benchmark of its own routing on an agent benchmark; those are the author’s numbers, and the raw data is in an issue rather than the repository.

Verdict

The idea is right, and the shape is right: one question over every capability you have, probabilities from the model, and every filter — availability, permissions, risk, confirmation — applied in code afterwards. Decision-only by default is the correct posture for something this young.

Give your candidates full manifests with explicit risk blocks rather than the quickstart’s short form, add .jevrouter/ to your .gitignore, and treat the decision files as prompt logs, because that is what they are.

For per-turn model routing instead of capability routing, see jev-router and Jev Codex Router. Our Best Jev Tools roundup compares what each tool sends.

See how it compares with other tools in Best Jev tools, tested hands-on.

Review updated Sep 20, 2026. Numbers quoted from the project are its author's own; we don't publish our own measurements of Jev.

More in Model Routing

jev-router

★ 560▲ 66

gargpratyush/jev-router

Per-turn model routing for Claude Code and Codex. Simple work goes to the fast tier and difficult work to the strong tier.

JavaScriptReviewed

Astra-Ares

★ 300▲ 7

miuuyy/Astra-Ares

Adjusts a Codex task's reasoning effort mid-run by asking Jev how hard the next step looks. Runs a patched Codex CLI and says it is a reference implementation rather than an app.

JavaScriptReviewed

jev-gateway

★ 300▲ 36

vinilana/jev-gateway

Local gateway for Codex and Claude Code that asks Jev which tool to call next and passes everything else to your usual model.

TypeScriptReviewed

Get new Jev projects every week

New Jev releases, pricing changes, and the best new projects, once a week. No spam; unsubscribe anytime.

Powered by Buttondown. See our privacy policy.