jev-browser

September 17, 2026 · View on GitHub

A Jev‑powered browser MCP server for LLM agents. Jev (TypeSafe AI's decision model) picks the next browser action in ~300 ms with no LLM tokens; the driving agent only steps in on escalations.

Measured against Playwright MCP with the same driver model: 1.5× faster, 1.6× cheaper, same accuracy on a 12-task suite — and the autonomous Jev loop alone runs at ~1.8 s and $0.0005 per task with 97% success. Full numbers: RESULTS.md.

How it works

snapshot (one page.evaluate, 2–25 ms)
      │  compact candidate list, ranked locally by goal-token overlap,
      │  stable refs, input values, viewport flags

one Jev call (parallel questions, ~300 ms, no LLM tokens)
      │  action · element · key · field↔text binding
      │  prev_ok (verify last step) · goal_achieved (done detection)

act (trusted input via CDP)  →  deterministic state diff (url/text/inputs)

      ├─ confident + verified  → next step
      └─ low confidence / stuck / loop → escalate to the driving LLM

Key design points:

  • One Jev call per step. Verification, done-detection and the next decision are folded into the same parallel call.
  • Joint field+text choice. Jev cannot generate strings, so when typing is needed it picks from a ref|text joint choice — binding value to field in one pass.
  • Deterministic verification overrides weak signals. URL/text/input diffs decide; Jev's prev_ok is only a tie-breaker.
  • Typed refs, no hallucinated actions. Jev can only choose declared options; invalid action/element combos get one corrective re-ask.
  • Escalation contract. status: "escalate" / needs_agent: true returns page state, ranked candidates and reasons so the agent can fix and continue.

Requirements

  • Node.js ≥ 20 (tested on 26)
  • A TypeSafe API key with Jev early access
  • Chromium via Playwright (npx playwright install chromium)

Install

git clone https://github.com/MahmoudAdelbghany/jev-browser.git
cd jev-browser
npm install
npx playwright install chromium

cp .env.example .env      # then put your key in .env

.env:

TYPESAFE_API_KEY=apikey_...
JEV_MODEL=jev-latest

Use as an MCP server

opencode (~/.config/opencode/opencode.jsonc)

{
  "mcp": {
    "jev-browser": {
      "type": "local",
      "command": ["node", "/absolute/path/to/jev-browser/src/server.mjs"],
      "enabled": true,
      "environment": { "TYPESAFE_API_KEY": "apikey_..." }
    }
  }
}

Claude Code

claude mcp add jev-browser --env TYPESAFE_API_KEY=apikey_... -- node /absolute/path/to/jev-browser/src/server.mjs

Tools

ToolPurpose
jev_goalFastest path. Autonomous Jev loop toward a goal (~0.3–0.9 s/step). Returns a trace; on needs_agent the caller fixes the blocker and re-invokes.
jev_stepOne decision+action cycle when you want control between steps.
jev_observeCompact page state (url, title, text sample, ranked elements with refs) for LLM reasoning.
jev_actDirect deterministic action (click/type/press/scroll/back/wait/goto) — override/escape hatch.
jev_askBatch many typed questions (choice/score/noul) against the current page in ONE parallel Jev call: extraction, routing, verification.
jev_openOpen a URL (launches the shared headless browser once, fires a warmup call).
jev_statusUsage stats: calls, p50/p95 decision latency, tokens, estimated cost.

Notes: Jev cannot generate text — pass literal strings via texts for typing. Choice options cap at 255; pages are budgeted to ~32K tokens.

Benchmark

node bench/compare.mjs --stacks jev-only,claude-playwright,claude-jev --tasks all --timeout 300
node bench/compare.mjs --stacks jev-only --tasks all --repeat 3   # variance
node bench/mcp-smoke.mjs                                          # MCP wiring check

The harness serves a local deterministic site whose tasks end in per-session random codes (unguessable → no LLM judge needed) plus two live Wikipedia tasks. Results and methodology: RESULTS.md.

Security

jev-browser executes an LLM's decisions in a real browser. Run it with headless Chromium on non-sensitive sites; it is not a security boundary.