Jev Browser
Jev Browser
Fast and very cheap browser use using TypeSafe's Jev model.
Give jev-browser a task and a URL.
It drives a real headless browser through an MCP server, CLI, or library. TypeSafe's Jev model picks one action per step from the page's clickable, typeable, and selectable elements, and scores how likely it is that the goal is met or the run is stuck. Code owns the loop: budgets, recovery, stop gates. You get the final page, a step trace with confidences, console errors, and a screenshot.
Things it has done on real sites, not demos:
Navigated Wikipedia from the Coffee article to Espresso in about 4 seconds, for $0.0016.
Filled a contact form and stopped without submitting it.
Pulled the price off a live pricing page.
Returned a full guide page as markdown.
Produced an accessibility-tree breakdown of a WordPress site.
This is early software. Expect rough edges on harder sites. Issues and pull requests are welcome; see CONTRIBUTING.md.
Install
Requires Node.js 20 or newer, a TypeSafe API key from console.typesafe.ai/settings/keys, and optionally a key for a typing provider (see the typing model). Playwright's Chromium downloads automatically on install; set JEV_BROWSER_SKIP_BROWSER_DOWNLOAD=1 to opt out.
Let an agent install it for you
Paste this into your coding agent:
Install the Jev Browser MCP server for me. The package is @jkudish/jev-browser on npm and the server
command is `npx -y @jkudish/jev-browser`; register it as an MCP server with your client. Check whether
TYPESAFE_API_KEY is already set in the server environment; if not, walk me through setting it up without
pasting the key into the chat (I can create one at console.typesafe.ai/settings/keys). When it's
registered, ask if I'd like to run a first navigation task, and when we do, show me the step trace and cost.
Full instructions: https://github.com/jkudish/jev-browser#readmeFrom npm:
npx -y @jkudish/jev-browser --helpAmp
amp mcp add jev-browser -- npx -y @jkudish/jev-browserClaude Code
claude mcp add jev-browser -- npx -y @jkudish/jev-browserCodex (~/.codex/config.toml)
[mcp_servers.jev-browser]
command = "npx"
args = ["-y", "@jkudish/jev-browser"]OpenCode (opencode.json)
{
"mcp": {
"jev-browser": {
"type": "local",
"command": ["npx", "-y", "@jkudish/jev-browser"],
"environment": { "TYPESAFE_API_KEY": "ts_..." }
}
}
}Any other MCP client
{
"mcpServers": {
"jev-browser": {
"command": "npx",
"args": ["-y", "@jkudish/jev-browser"],
"env": { "TYPESAFE_API_KEY": "ts_..." }
}
}
}Some MCP clients filter the environment before spawning servers, which silently drops TYPESAFE_API_KEY. If the server reports a missing key, pass it explicitly as shown above.
Related MCP server: Web Bridge
The tool
Every run makes paid TypeSafe API calls, typically a fraction of a cent, plus one small LLM call per typed field when a typing provider is configured. The example below is a real run.
// arguments
{
"task": "Search Wikipedia for the espresso-based drink called Ristretto and stop when you are on that article",
"start_url": "https://en.wikipedia.org/wiki/Main_Page"
}// live result, abridged
{
"status": "done",
"final_url": "https://en.wikipedia.org/wiki/Ristretto",
"elapsed_ms": 5894,
"steps": [
{ "step": 1, "proposed_action": "click_e2", "executed_action": "click_e2", "detail": "a \"Search Wikipedia [f]\" -> /wiki/Special:Search", "confidence": 1.0 },
{ "step": 2, "proposed_action": "type_e1", "executed_action": "type_e1", "detail": "typed \"Ristretto\" via openrouter", "confidence": 0.99 },
{ "step": 3, "proposed_action": "done", "executed_action": null, "detail": "done proposed; not executed", "confidence": 1.0 }
],
"usage": { "jev_calls": 3, "input_tokens": 45810, "est_cost_usd": 0.0021 }
}Parameters: max_steps (default 24), max_seconds (default 180), allow_typing (default true), format (text, markdown, html, aria), max_chars (override the cap), screenshot (final, default, or none).
What you get back
The final page, in the format you ask for. Every payload reports truncated and true_length, and max_chars overrides any default.
Format | Default cap | Best for |
| 8,000 chars | Feeding the page to Jev or an LLM next; quick reads |
| 16,000 chars | Readable artifacts and notes; carries navigation chrome |
| 1 MB | Parsing the page yourself with your own selectors |
| 16,000 chars | The accessibility tree as YAML; what screen readers and agents see |
A final screenshot. A viewport JPEG that renders inline in MCP clients, or lands as a file with the CLI's --screenshot path.jpg. Pass screenshot: "none" to skip it.
A debug trace you can audit. One record per step: the proposed action versus the action actually executed, why a recovery fired, action errors, the Choice confidence, the top option's probability, and the goal and stuck probabilities for that step. Stop statuses say which gate fired. Alongside the trace: console errors, page errors, and failed network requests captured per step and tagged with the page they came from, up to 200 events, plus Jev call counts, token usage, and estimated cost. If the final payload or screenshot could not be extracted, the run still returns and lists the problem under extraction_problems.
How it decides
Each step makes one primary Jev call with three questions over the same state: an action Choice over the page's interactive elements plus scroll/back/done, a goal Noul, and a stuck Noul (fan-out pattern). The state includes a short excerpt of the page's visible text, so the goal judgment can see content, not just URLs and links. A select action adds one second-stage Choice for its option. Elements come from the DOM directly, not the accessibility tree, because accessibility trees under-report inputs; the agent found DuckDuckGo's search box only after this switch. Actions: click, type, select a native dropdown, scroll, back, done.
Stop conditions, in code, checked before executing the step's proposed action: the agent chooses done, goal probability > 0.85, stuck probability > 0.85, the step budget, or the time budget. A repeated action with no effect switches to the next-best option from the Choice distribution. There is deliberately no low-confidence override: split probability across several similar elements is usually several acceptable alternatives, not uncertainty.
Statuses: done (agent chose to stop), goal_achieved (the goal watcher fired), stuck, max_steps, timeout, error. done and goal_achieved are two independent judgments; agreement between them is what a trustworthy finish looks like, and the trace shows both at every step.
The typing model
Jev never generates text. It returns typed decisions only: which option, with what probabilities. So when a task needs a string, typing a search query or filling a field, that string comes from a small model you choose. This is the only place a second model is involved, and it runs at most once or twice per task, about 48 tokens per call.
Configuration is automatic when possible. The server picks the first provider whose key it recognizes, in this order:
Provider | Recognized by | Default model |
OpenAI |
|
|
OpenRouter |
|
|
Anthropic |
|
|
|
|
Overrides:
JEV_BROWSER_TYPE_MODELpicks any model the resolved provider offers, for exampleopenrouter:anthropic/claude-haiku-4.5style ids.JEV_BROWSER_TYPE_PROVIDERforces one ofopenai,openrouter,anthropic,google, skipping auto-detection.JEV_BROWSER_TYPE_BASE_URL(plusJEV_BROWSER_TYPE_API_KEYif it needs one) points at any OpenAI-compatible endpoint: Ollama, LM Studio, vLLM, a gateway. This wins over provider detection.
Local example, no cloud key at all:
JEV_BROWSER_TYPE_BASE_URL=http://localhost:11434/v1 JEV_BROWSER_TYPE_MODEL=qwen2.5:7b \
npx -y @jkudish/jev-browser run "Search Wikipedia for Ristretto and stop on the article" https://en.wikipedia.org/wiki/Main_PageWith no provider at all, typing falls back to a keyword heuristic built from the task text. It is labeled honestly in the trace (via keyword-heuristic), and it is meaningfully worse: in testing its queries buried a target article eight results pages deep. Give it a real model if your tasks type anything.
Limits
Up to 240 elements per step; Jev's Choice supports 255 options. Beyond that the list is truncated and the state says so, which can hide the needed element on very dense pages.
The markdown format converts the whole body, so it carries navigation chrome and can include inline script text; a readability pass is a candidate improvement, not a committed one.
Password and file inputs are never offered. Hover-revealed menus, keyboard actions (Escape, Enter on unstaged fields), multi-field form sequencing, shadow DOM, and iframes are out of scope for v0.1.
Thresholds (0.85 goal, 0.85 stuck, budgets) are starting points measured on Wikipedia and DuckDuckGo tasks. Tune them for your sites.
Jev is calibrated, not infallible. Treat the trace as evidence, not proof.
Configuration
Env var | Default | Purpose |
| none | TypeSafe direct. Default provider when set. |
| none | Powers both the Jev judgments (when |
|
| Force |
|
| Pin a Jev version, or |
| see above | Typing provider, model, and endpoint. |
| unset | Set to |
| unset | Set to |
OpenRouter
With only an OPENROUTER_API_KEY, both the Jev judgments and (with no other typing provider) the typing model run through OpenRouter: one key powers the whole package. The Jev endpoint there is alpha and adds a hop, and it serves pinned versions rather than a latest alias, so jev-latest maps to typesafe/jev-1.13. Direct TypeSafe remains the recommended default when you have both keys.
Also in the family
Need the judgments without the browser? Jev MCP exposes the same model as three tools your agent can call anywhere: verify claims against evidence, screen content before it enters context, and rank candidates by meaning. The npm package is @jkudish/jev-mcp.
Sponsoring
If you find Jev Browser useful, consider becoming a sponsor or donating.
Development
npm install
npm run build
npm test # unit tests, offline
npm run test:e2e # live navigation tests; requires TYPESAFE_API_KEYSee CONTRIBUTING.md. To report a vulnerability, see SECURITY.md.
License
Available Tools
1 toolTool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
v0.2.0- First observed
jev_navigate
TDQS
Scored across 1 tool
With only a single tool, there is no possibility of confusion between different tools. The tool's purpose is clear and distinct, and an agent can easily select it for any browser navigation task.
There is only one tool name, 'jev_navigate', which follows a clean verb_noun pattern. Since there are no other tools to compare against, naming is inherently consistent.
A single tool is on the thin side for a browser server, but the tool is comprehensive, handling navigation, tracing, error capture, and screenshot generation. It is borderline but acceptable for a focused high-level automation agent.
The tool covers the core navigation workflow and returns extensive diagnostic data, but it lacks granular browser operations like clicking, typing, or extracting specific elements. Agents requiring fine-grained control would need to rely entirely on this one high-level action, which is a notable gap.
Maintenance
Related MCP Connectors
Programmatic headless browser sessions: create, interact, browse, and extract - rendered in a real
Headless-browser-as-JSON with memorymarket cache economics. Real Chromium, crypto settlement.
Browser MCP for logged-in tasks. Uses your Chrome — credentials stay local. Zero-token replay.
Hosted browser for AI agents: screenshots, post-JS DOM, console, WCAG. No install, no API key.
Related MCP Servers
- AlicenseAqualityAmaintenanceMCP server + Chrome extension that drive the user's real, logged-in Chrome over a local WebSocket. 59 token-efficient web-dev tools: compact element refs instead of screenshots, server-side table filtering, visual regression, accessibility/SEO/security audits, network mocking. Also runs on ChromeOS/Crostini.59206 npm3MIT
- AlicenseAqualityBmaintenanceBrowser automation MCP server that uses a real browser to give agents eyes and hands—open pages, click, fill, screenshot, and run scripts via accessibility-tree snapshots.2230 npmMIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to call TypeSafe's JEV classifier and receive structured, typed judgments with probabilities for binary, choice, and scoring questions.MIT
- AlicenseNot gradedqualityBmaintenanceEnables natural-language interaction with TypeSafe's Jev decision API, supporting mixed question calls, batch evaluation, model listing, and confidence or composite-score gates over stdio.3MIT