Skip to main content
Glama
bothuany
by bothuany

jev-browser-mcp

A browser for your agent that keeps the page out of its context.

Your model says what it wants. A tiny typed-decision model clicks, a cheap model reads, and only the answer comes back — never the DOM.

License: MIT Node 20+ MCP Playwright

94× less context than Playwright MCP when reading · $0 replays · self-healing recipes · exports plain Playwright tests


claude mcp add --scope user jev-browser -- npx -y jev-browser-mcp

Then ask Claude something like "on the Ada Lovelace Wikipedia page, when and where was she born?". Claude gets back 266 tokens. The same question through Playwright MCP costs 108,726.

Why

Browser MCP servers hand the page to your model. A real page is 10k–100k tokens, and whatever lands in the conversation is paid for again on every later message. Twenty steps on a real site and the context is mostly DOM.

This server splits the work between three models, and the expensive one does the least:

flowchart LR
    A["🧠 Your model<br/>(Claude, GPT…)"] -- "intent:<br/>'find the price'" --> S["jev-browser-mcp"]
    S -- "answer · 300 tokens" --> A
    S -- "compressed state" --> J["⚡ Jev<br/>which element? which op?<br/>~$0.04 / 1M tokens"]
    S -- "page text" --> F["📖 Gemini Flash<br/>reads the page,<br/>writes field values"]
    S <--> P["🌐 Chrome<br/>(Playwright)"]

who

job

sees the page?

your model

states the intent, reads the result

no

Jev

decides each step: which element, which operation, is it done

a compressed state

Gemini Flash

answers questions about the page, writes values into fields

yes, on the server

Related MCP server: Cloudflare Playwright MCP

What it's good at

📖 Knowing something without reading the page

browse_ask reads the page on the server and returns the answer, optionally as JSON. Measured on four live pages, all answers correct:

page

Playwright MCP

jev-browser

Wikipedia · Ada Lovelace

108,726 tokens

266

409×

GitHub · microsoft/playwright

14,531

399

36×

MDN · Array.prototype.at

13,918

519

27×

Hacker News · top 3 as JSON

13,478

418

32×

total

150,653

1,603

94×

Each read costs $0.0004–$0.003 in Flash tokens.

🔁 Record once, replay for free, heal when the site changes

browse_goal  saveAs=checkout.json     → Jev drives it once       ~$0.0005
browse_replay checkout.json           → no model at all          $0 · ~2 s
  … the site is redesigned: ids renamed, labels changed …
browse_replay checkout.json heal=true → only the broken step     ~$0.0001
browse_replay checkout.json           → free again               $0
browse_replay export=playwright       → a plain @playwright/test spec

Each step is recorded with several locators, strongest first: role and name, label, field name, id, and the stable tail of a framework-generated id. When every locator misses, only that step goes to Jev, and the repaired step is written back into the recipe.

Measured on six hard cases (calendar, autocomplete, dependent dropdown, ordered form, delayed dialog, form inside an iframe): each page was redesigned so every recorded locator missed. The old recipe broke, healed 6/6, and the exported specs pass on plain Playwright with this server not running.

🏢 Enterprise screens that break other tools

It was hardened against a live JSF/PrimeFaces admin console, not only demo pages:

  • generated j_idt… ids

  • ViewState fields that must never be touched

  • buttons drawn as <span>s

  • disabled state expressed only as a CSS class

  • iframes

  • modals that appear seconds late

A three-step search recorded there replays in 4.4–4.9 s at $0. The replay passed 3/3 even when the session started with a different search already in the box.

🪶 Cheap actions too

task

Playwright MCP, used well

browse_act

browse_goal

4-field form + submit

360 tokens · 4 calls

252 · 3

527 · 1

dependent dropdown

321 · 4

208 · 2

340 · 1

Wikipedia search, live

18,875 · 3

405 · 3

456 · 1

On a toy page there is nothing to save. The saving grows with the size of the page.

What it is not

IMPORTANT

This is not an autonomous open-web agent. Left alone on 30 live WebVoyager tasks, it completes 30%. Agents where a large model reasons about every step report far more. Jev picks the right control on the screen; it does not reason across ten criteria on a page. That reasoning is your model's job.

It is built to be the hands under a strong model, and that is how it is measured.

How it compares

All results below were measured live and are reproducible. Methodology, raw results and grading reasons are in docs/BENCHMARKS.md.

vs jev-ultrafast: both run autonomously, 30 WebVoyager tasks, same text model.

passed

median time

cost / task

jev-browser

9 / 30

18 s

$0.0009

jev-ultrafast

6 / 30

16 s

$0.0046

About 5× cheaper on every task. The success difference is not significant (McNemar p = 0.51). ultrafast passes Google Flights; this server does not.

vs Playwright MCP, with the same GPT-5 driver on both. Four tasks, so this is an observation, not a statistic:

passed

driver tokens

list price

Playwright MCP 0.0.82

1 / 4

1.15 M

$1.54

jev-browser

1 / 4 verified + 2 unverified¹

0.76 M

$1.15

On the Apple task the driver made 1 browse_goal call and 1 browse_ask call: 3 steps and 11k tokens, against 16 steps and 88k through Playwright MCP.

¹ A harness bug left the final page unread. Those runs were graded on the driver's answer alone, so they are not counted as passes.

NOTE

The first version lost this comparison. The driver ignored browse_goal and browse_ask, went step by step, and spent more tokens than Playwright MCP (486k vs 340k). The advantage only exists when the model uses the tools that keep the page out of its context. Two changes fixed it: action results got smaller, and the server now sends MCP instructions that tell the model when to use those tools.

When to use it

use it for

use something else for

✅ self-healing regression tests: record, replay free, export to Playwright

❌ "go do anything on the internet" with no model on top

✅ repetitive work in internal tools and admin panels

❌ single clicks on small pages: no saving there

✅ reading big pages without blowing up your context

❌ bot-protected consumer sites like Google Flights

✅ legacy JSF / PrimeFaces / iframe-heavy apps

✅ capturing a legacy screen's behaviour and checking the rewrite against it

Tools

Thirteen tools cover Playwright MCP's capabilities (20/20 probes, checked on the page: node bench/coverage.mjs). Their definitions take about 3.8k tokens; Playwright MCP's defaults take about 5.6k.

tool

what it does

browse_goal

drive toward a plain-language goal; optionally record it (saveAs)

browse_ask

a question about the page, answered on the server, optionally as JSON

browse_replay

replay a recipe with no model; heal broken steps; export=playwright

browse_act

click · type · fill (a whole form by label) · select · hover · drag · upload · key · scroll · wait

browse_verify

exact checks in code (free), or a plain-language claim judged by Jev

browse_navigate · browse_observe

open a URL · the compressed element list, with find

browse_tabs · browse_dialog_policy

tabs · decide alert/confirm before they block

browse_eval · browse_console · browse_screenshot

look under the hood

browse_page

pdf · resize · media · network requests · tracing · save session · close

A run ends as done, blocked, escalate or max_steps. escalate is a normal outcome: Jev would not commit, so the final page comes back and your model takes the next step itself.

Setup

Requirements:

  • Node 20+

  • Chromium: npx playwright install chromium, or attach to your own Chrome

  • one Vercel AI Gateway key, which reaches both Jev and Gemini

The server reads the key from AI_GATEWAY_API_KEY, JEV_KEY_FILE, or ~/.config/jev/key. Keep it out of the MCP registration so it never lands in shell history. On the free tier, Flash allows 5 requests a minute; the server retries through that limit instead of failing.

A profile directory alone is not enough. Server-rendered logins issue session cookies with no Expires, and Chrome drops those when it closes. Sign in by hand once and capture the live session:

npx jev-browser-login https://example.com/login   # sign in, then press ENTER
export JEV_BROWSER_STORAGE=~/.config/jev/session.json

For a session that never expires, run ./chrome-cdp.sh <url> from a checkout and set JEV_BROWSER_CDP=http://localhost:9222. You can watch every step and take the window back at any time.

You type your own password into your own window. The server never reads, stores or forwards it, and it refuses to type into password fields unless JEV_ALLOW_SECURE_FIELDS=1. A web page cannot set that variable.

variable

effect

JEV_BROWSER_STORAGE

session captured from a manual login

JEV_BROWSER_PROFILE

persistent profile directory

JEV_BROWSER_CDP

attach to your own Chrome, e.g. http://localhost:9222

JEV_BROWSER_HEADED

show the window

JEV_BROWSER_IGNORE_HTTPS_ERRORS

accept a corporate TLS interception certificate

JEV_ALLOW_SECURE_FIELDS

allow typing into password fields (off by default)

JEV_TEXT_MODEL

text model (default google/gemini-2.5-flash)

JEV_TEXT_THINKING

its thinking budget (default 0; thinking was 90% of the cost)

JEV_OBSERVE_LIMIT

elements per observation (default 120)

JEV_DONE_BAR

how sure the completion check must be (default 0.7)

JEV_IFRAMES=0

do not walk embedded documents

JEV_OUTPUT_DIR

downloads, PDFs, traces, large response bodies

JEV_VIEWPORT_WIDTH / _HEIGHT

default 1600×900 (admin consoles hide controls at 1280)

JEV_REPLAY_WAIT_MS

wait before a replay step is healed (default 8000)

JEV_SETTLE_MS / JEV_SETTLE_QUIET_MS

settle budgets for parsing (15 s) and restless (4 s) pages

JEV_DEBUG=1

print every offered operation, page class and field value

Known limits

  • Google Flights fails, and fails differently each time.

  • 30% autonomous success on the open web. See What it is not.

  • Borderline completion: one SPA case lands done or escalate depending on the run.

  • Tested on macOS only. No CI; the benchmarks cost real money, so they are run by hand.

Under the hood

docs/ENGINEERING.md explains why the loop owns progress, waiting, click correction and the completion check, and how a decision went from 7,226 tokens to ~1,500. It also lists the four fixes a real JSF console forced. Almost every rule in it exists because the simpler version failed on a real page first.

npm test                                   # 14 capability probes
node bench/hard/run.mjs                    # 6 hard cases
node bench/heal.mjs                        # record → replay → redesign → heal → exported specs
node bench/context.mjs                     # reading cost vs Playwright MCP, live pages
node bench/competitors/webvoyager.mjs A    # vs jev-ultrafast on WebVoyager

License

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to control a browser through a set of tools, allowing them to perform web automation tasks like navigation, typing, clicking, and taking screenshots.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to control a browser through a set of tools, allowing them to perform web automation tasks like navigation, typing, clicking, and taking screenshots.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI assistants to control a browser through a set of tools, allowing them to perform web automation tasks like navigation, typing, clicking, and taking screenshots.
    -