Skip to content
MrJev

jev-cli (tumf)

CLI and stdio MCP server for the three Jev primitives, with --value for shell scripts and structured stderr errors. auth set refuses a key as an argument, keeping it out of shell history.

View on GitHub →

Hands-on review

A CLI and stdio MCP server for the three Jev primitives, with structured errors and real exit codes on every failure path we could force.

Good for

  • `auth set` refuses a key as an argument, keeping it out of shell history
  • `--value` prints the bare number, so shell scripts can use it
  • The same install ships a working stdio MCP server

Watch out for

  • In plain mode a 200 with no answers is relayed through and exits 0
  • Twelve stars, one author; needs Python 3.13

Tested Sep 23, 2026 at 980cb98f5f52 · python:3.13-slim in Docker, `make check` (61 tests), then the CLI and the MCP server against a stand-in

How we reviewed this: we ran make check — its whole CI — then drove the CLI and the MCP server against a stand-in we controlled, using the custom provider. We made no Jev calls.

What it is

One install, two commands. jev asks Jev a typed question from the shell; jev-mcp exposes the same four tools to an MCP host over stdio.

$ jev noul -q "Is this urgent?" -s "My payment failed three days ago."
{"model":"jev-latest","answers":{"answer":{"type":"noul","noul":0.77}},"usage":{…}}

$ jev noul -q "Is this urgent?" -s "help" --value
0.77

That second form is the point of a CLI: a bare number a shell script can branch on, rather than JSON you have to pipe through jq.

jev run takes a request file or stdin and sends several questions together — we counted three questions in one request on the wire, which is the behaviour that makes Jev worth using from a script at all.

Four providers are built in: the official API, Vercel’s AI Gateway, OpenRouter, and custom for anything that speaks the same shape. That last one is how we reviewed it without spending.

The key handling

The README claims auth set will not take the key as an argument, “which keeps it out of process arguments and shell history”. We tried:

$ jev auth set --provider custom apikey_SHOULD_BE_REFUSED
jev: error: unrecognized arguments: apikey_SHOULD_BE_REFUSED

Refused. It is a small thing that takes one line to get wrong, and a key in ~/.bash_history or in ps output is a real way keys leak.

Errors, and the one that escapes

The README promises “structured stderr errors and meaningful exit codes”, and mostly delivers:

what the provider did exit stderr
HTTP 500 4 {"ok": false, "error": "API HTTP 500: …"}
connection refused 4 {"ok": false, "error": "API connection failed: …"}
no key stored 3 {"ok": false, "error": "custom API key is not stored; run: jev auth set …"}
empty answers, with --value 1 {"ok": false, "error": "unexpected API response: 'answer'"}
a non-JSON 200 4 {"ok": false, "error": "API returned invalid JSON: Expecting value: line 1 column 1 (char 0)"}

That last row used to be the gap: an HTML timeout page returned with a 200 — an ordinary thing to hit behind a gateway — produced a Python traceback ending in json.decoder.JSONDecodeError, on a tool whose whole design invites a script to parse stderr as JSON. Reported; fixed in v0.6.3 with a regression test that uses an HTML body and a 200. We re-ran the whole table against our stand-in at 72607dd and the row above is what comes back now.

One half of that report is still open, and it is the smaller half. In plain mode an empty answers object is relayed through untouched and exits 0:

$ jev noul -q 'Is this urgent?' -s 'Restore service today.'
{"model": "m", "answers": {}}
$ echo $?
0

With --value the same response exits 1 with unexpected API response: 'answer', so the strict path is strict and the pass-through path passes through. That is defensible for a tool whose plain mode is “show me what the API said”, but a caller piping plain mode into jq gets an empty object rather than an error.

Everything else is the shape you want: the failure says what happened and, where it can, the command that fixes it.

The MCP server

jev-mcp came up over stdio and listed its tools without complaint:

tool: noul
tool: choice
tool: score
tool: run

Included in the normal install with no extra to select, which is the right call — an MCP server that needs a separate package is an MCP server people do not find.

Engineering

MIT, Python 3.13+, one runtime dependency (mcp). make check is the whole CI: 60 tests, OK, followed by a clean uv build of both the sdist and the wheel. One of those tests checks that the shipped agent skill has portable frontmatter and a working reference, which is a nice thing to have automated.

Twelve stars, one author, version 0.6.2.

Verdict

An unfussy, well-mannered CLI. The --value flag and the real exit codes make it usable from a shell script rather than just from a terminal, and the auth handling shows somebody thought about where keys end up.

Fix the one traceback and the error contract is complete. Until then, if you are branching on this in CI, do not assume stderr is JSON.

Note the Python floor: 3.13, which is newer than most of this directory asks for.

For a semantic-search CLI with the same attention to exit codes, see jgrep; for bulk work rather than one question at a time, jev-ultralightspeed.

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

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

More in Command-Line Tools

jevgrep (dzhng)

★ 3.1k▲ 239

dzhng/jevgrep

Finds code by what it does rather than what it matches: a CLI for coding agents that asks which files and which regions are relevant to a description. Unrelated to the JevGrep above, which has the same name.

TypeScriptReviewed

webctl

★ 163▲ 1

dorkitude/webctl

Search CLI for agents: results from up to three backends are scored by Jev against your query and an explicit --goal, and only the relevant ones reach the agent's context. Its benchmark excludes an arm it could not observe.

GoReviewed

sys1grep

★ 150

uehaj/sys1grep

Greps by meaning rather than pattern, scoring every line against a description and combining meanings with AND, OR and NOT; a single dependency-free Node file. Japanese and English. Formerly jev-semgrep.

JavaScriptReviewed

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.