Docs

Jev Browser Control has two parts: a Chrome extension that reads and operates pages, and an MCP server that lets Claude talk to it. Jev, TypeSafe's decision model, chooses the actions when you hand it a task.

Install the extension

  1. Download the extension (.zip, version 0.2.0) and unzip it.
  2. Open chrome://extensions and switch on Developer mode (top right).
  3. Click Load unpacked and choose the unzipped folder.
  4. Pin the orange cursor icon. Clicking it opens the side panel; the settings page opens by itself the first time.

It works in Chrome, Edge, Brave and other Chromium browsers, version 120 or newer. A Chrome Web Store listing is on its way; until then Chrome keeps the unpacked extension installed, it just won't update itself.

Choose a provider

Every browser step is one Jev call. Typing a value costs one call to a small text model. The extension's settings decide who is billed:

ProviderYou needYou pay
CreditsA jbc_ key from your dashboard5× what OpenRouter charges, from prepaid credits
Your OpenRouter keyA key from openrouter.aiOpenRouter's price, directly. Free software, MIT license
CustomAny endpoint with the same request shapeWhatever that endpoint charges

For TypeSafe direct, choose Custom, set the decisions URL to https://api.typesafe.ai/v1/systemone with your TypeSafe key, and set the Jev model to jev-latest. Keep an OpenRouter key in the chat key field for the text helper.

Press Test connection in the settings to make one tiny Jev call.

Connect Claude

The MCP server runs on your computer when Claude starts. It opens a bridge on 127.0.0.1:10522, and the extension connects to it. It needs Node.js 22 or newer and has no other dependencies.

Claude Code

claude mcp add jev-browser -- npx -y https://jevbrowsercontrol.com/downloads/jev-browser-control-mcp-0.2.0.tgz

Claude Desktop

Settings → Developer → Edit Config, add this, and restart Claude Desktop:

{
  "mcpServers": {
    "jev-browser": {
      "command": "npx",
      "args": ["-y", "https://jevbrowsercontrol.com/downloads/jev-browser-control-mcp-0.2.0.tgz"]
    }
  }
}

From source

git clone https://github.com/nexibeo/jev-browser-control
claude mcp add jev-browser -- node /path/to/jev-browser-control/mcp/server.mjs

Ask Claude “check the browser status”. It should report the extension as connected. The side panel shows Claude connected too.

Several Claude sessions can share one browser: the first MCP server owns the port and the others join it. If one exits, another takes over.

Grok Bot, ChatGPT and other remote AI apps

Apps that run in the cloud can't start a program on your computer. For them, jevbrowsercontrol.com runs the same tools as a remote MCP server, and passes each call to your extension.

  1. Get a key in your dashboard. Remote control itself is free; Jev's calls are billed to the provider you chose in the extension.
  2. In the extension's settings, under Remote AI apps, switch on “Let remote AI apps control this browser”. It uses your credits key, or a separate key you paste there. The side panel shows Remote on once it is connected.
  3. In the app, add a custom connector (MCP server):
URL:           https://jevbrowsercontrol.com/mcp
Authorization: Bearer jbc_…your key…

For Grok Bot there is a ready-made template, Jev Browser Operator, that sets this up and knows how to use the tools.

Anyone with the key can control your browser while remote control is on. Keep it secret, revoke it in the dashboard if it leaks, and switch remote control off when you don't need it. Clicks that buy, pay, send, post or delete always wait for your OK in the Jev side panel, and a remote app can't skip that.

Each remote call adds a round trip through the relay (about 0.3 seconds), and a single jev_task stops after 85 seconds, so split longer work into several tasks.

Use it

From the side panel

Click the toolbar icon, type a goal such as “Find the cheapest one-way flight from Zürich to London on 20 October”, and press Run. Each step shows what Jev chose, how sure it was and how long it took. Stop ends the task at once.

From Claude

Ask in plain words: “Use the browser to find the opening hours of the Rijksmuseum,” or “Fill in the contact form on example.com with my details: …”. Claude decides when to drive the browser itself and when to hand a sub-task to Jev with jev_task. Put every value that has to be typed into your request; Jev's text helper never makes up personal details.

Tools

ToolArgumentsWhat it does
jev_taskgoal, details, url, newTab, maxSteps, maxSeconds, allowIrreversibleRuns a task with Jev. Returns the status, every step, the cost and the final page's text.
jev_finddescriptionThe visible element that best matches a description, with probabilities.
jev_checkstatementThe probability that a statement about the page is true.
jev_stopStops running Jev tasks.
browser_snapshotfullNumbered elements and visible text. full lists the whole page.
browser_clickrefClicks element [ref].
browser_typeref, text, submitReplaces a field's text; submit presses Enter.
browser_selectref, optionChooses a dropdown option by its label.
browser_press_keykey, refEnter, Tab, Escape, arrows, or combos like Control+A.
browser_scrolldirection, amountScrolls about one screen.
browser_navigateurl, newTabOpens a URL. New tabs join the orange “Jev” group.
browser_tabsaction, tabIdLists, selects or closes tabs.
browser_backforwardHistory back or forward.
browser_readformat, offset, limitThe whole page as markdown, text or links.
browser_screenshotqualityA JPEG of the visible page.
browser_waittext, secondsWaits for text to appear.
browser_statusConnection, current tab, provider and limits.

How a jev_task ends

StatusMeaning
doneJev chose DONE and its separate goal check agreed.
done_unconfirmedJev chose DONE but the goal check disagreed. Look at the page.
needs_confirmationThe next click may buy, pay, send, post or delete. It was not clicked.
needs_inputA field needs a value the goal doesn't give. Nothing was made up.
blocked / stuckNo useful action left, or three actions in a row changed nothing.
budgetA limit on actions, seconds or cost was reached.

Safety

  • Jev only chooses among options the extension offered. Its answer is an element number that code maps to a real element; it never becomes a selector, coordinates or a script.
  • Password and file-upload fields are never offered, to Jev or to Claude.
  • Clicks that buy, pay, send, post or delete stop for confirmation (setting: on by default).
  • Blocked sites: neither Jev nor Claude acts on domains you list.
  • Page text is sent to Jev as untrusted data. Prompt injection on a web page can still mislead a model, so keep limits on and check results.
  • The bridge listens on 127.0.0.1 only, accepts only Chrome extensions (web pages can't connect), and other Claude sessions need a local token.
  • The agent acts in your normal Chrome profile with your logins. For risky work, use a separate Chrome profile.

Settings

SettingDefault
ProviderCredits
Jev model~typesafe/jev-latest (always the newest; the tilde is required)
Text modelinception/mercury-2.5
Limits per task30 actions, 120 seconds, $0.10
Ask before irreversible clicksOn
InputTrusted (Chrome shows “started debugging this browser” while Jev acts). Synthetic events avoid the bar, but some sites ignore them.
Claude bridge port10522 (set JBC_PORT for the MCP server too if you change it)

Keys are stored in Chrome's local extension storage on this computer and are sent only to the provider you chose.

Credits API

With a credits key you can call Jev from your own code. The requests and responses match OpenRouter's, so an OpenRouter client only needs a new base URL and key.

EndpointUse
POST /api/v1/decisionsJev decisions: {model, state, questions}. Also at /api/alpha/decisions.
POST /api/v1/chat/completionsThe small text models (no streaming).
GET /api/v1/balanceYour remaining credits.
GET /api/v1/modelsAllowed models and their price here.
curl https://jevbrowsercontrol.com/api/v1/decisions \
  -H "Authorization: Bearer $JBC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "~typesafe/jev-latest",
    "state": { "page": "Checkout: 2 items, total $31.50" },
    "questions": {
      "has_items": { "type": "noul", "instructions": "Does the cart in `page` contain items?" }
    }
  }'

Each response's usage.cost is what you were charged (5× OpenRouter's cost for that call), and usage.credits_remaining is your balance after it. Failed calls are free. Errors use OpenRouter's shape: 401 bad key, 402 out of credits, 429 too many requests per minute.

Troubleshooting

Claude says the extension is not connected

Keep Chrome open and click the Jev toolbar icon; that wakes the extension, and it connects within a second. Check that “Let Claude control this browser” is on in the settings, and that nothing else uses port 10522.

“This page can't be controlled by extensions”

Chrome doesn't let extensions script chrome:// pages, the Chrome Web Store or other extensions. Open a normal website first.

Clicks do nothing while DevTools is open

Only one debugger can attach to a tab. With DevTools open the extension falls back to synthetic events, which some sites ignore. Close DevTools.

Jev picked the wrong thing

Jev can be confidently wrong between look-alikes (“Cold Email” and “Cold Outreach”). Name the target precisely in the goal, and verify the result with jev_check or a snapshot.

Open source

The extension and MCP server are MIT-licensed at github.com/nexibeo/jev-browser-control. The loop's design (one request for the operation plus a target for every operation, freshness checks before input) comes from Browser Use's Jev Ultrafast, also MIT. Issues and pull requests are welcome.