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
- Download the extension (.zip, version 0.2.0) and unzip it.
- Open
chrome://extensionsand switch on Developer mode (top right). - Click Load unpacked and choose the unzipped folder.
- 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:
| Provider | You need | You pay |
|---|---|---|
| Credits | A jbc_ key from your dashboard | 5× what OpenRouter charges, from prepaid credits |
| Your OpenRouter key | A key from openrouter.ai | OpenRouter's price, directly. Free software, MIT license |
| Custom | Any endpoint with the same request shape | Whatever 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.
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.
- Get a key in your dashboard. Remote control itself is free; Jev's calls are billed to the provider you chose in the extension.
- 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.
- 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.
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
| Tool | Arguments | What it does |
|---|---|---|
jev_task | goal, details, url, newTab, maxSteps, maxSeconds, allowIrreversible | Runs a task with Jev. Returns the status, every step, the cost and the final page's text. |
jev_find | description | The visible element that best matches a description, with probabilities. |
jev_check | statement | The probability that a statement about the page is true. |
jev_stop | Stops running Jev tasks. | |
browser_snapshot | full | Numbered elements and visible text. full lists the whole page. |
browser_click | ref | Clicks element [ref]. |
browser_type | ref, text, submit | Replaces a field's text; submit presses Enter. |
browser_select | ref, option | Chooses a dropdown option by its label. |
browser_press_key | key, ref | Enter, Tab, Escape, arrows, or combos like Control+A. |
browser_scroll | direction, amount | Scrolls about one screen. |
browser_navigate | url, newTab | Opens a URL. New tabs join the orange “Jev” group. |
browser_tabs | action, tabId | Lists, selects or closes tabs. |
browser_back | forward | History back or forward. |
browser_read | format, offset, limit | The whole page as markdown, text or links. |
browser_screenshot | quality | A JPEG of the visible page. |
browser_wait | text, seconds | Waits for text to appear. |
browser_status | Connection, current tab, provider and limits. |
How a jev_task ends
| Status | Meaning |
|---|---|
done | Jev chose DONE and its separate goal check agreed. |
done_unconfirmed | Jev chose DONE but the goal check disagreed. Look at the page. |
needs_confirmation | The next click may buy, pay, send, post or delete. It was not clicked. |
needs_input | A field needs a value the goal doesn't give. Nothing was made up. |
blocked / stuck | No useful action left, or three actions in a row changed nothing. |
budget | A 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
| Setting | Default |
|---|---|
| Provider | Credits |
| Jev model | ~typesafe/jev-latest (always the newest; the tilde is required) |
| Text model | inception/mercury-2.5 |
| Limits per task | 30 actions, 120 seconds, $0.10 |
| Ask before irreversible clicks | On |
| Input | Trusted (Chrome shows “started debugging this browser” while Jev acts). Synthetic events avoid the bar, but some sites ignore them. |
| Claude bridge port | 10522 (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.
| Endpoint | Use |
|---|---|
POST /api/v1/decisions | Jev decisions: {model, state, questions}. Also at /api/alpha/decisions. |
POST /api/v1/chat/completions | The small text models (no streaming). |
GET /api/v1/balance | Your remaining credits. |
GET /api/v1/models | Allowed 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.