# barq-mcp

> Fast browser hands for coding agents: the agent names an outcome, Jev (TypeSafe's decision model) picks each click in about 300 ms. MCP server, Claude Code plugin, library and CLI; works in a browser it launches or in your own Chrome or Edge.

Latest version **0.2.4** (published 2026-09-24) · MIT license · 0 weekly downloads

## Install

```sh
npm install barq-mcp
pnpm add barq-mcp
yarn add barq-mcp
bun add barq-mcp
```

Provides the commands `barq`, `barq-mcp`.

## Health

**Score 60/100 (C)** — status: active.

Positive: esm support; no vulnerabilities; recently updated; high maintenance score.

Warnings: low downloads; no types; pre 1.0.

## Facts

| | |
|---|---|
| Version | 0.2.4 |
| Published | 2026-09-24 |
| First published | 2026-09-23 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | none |
| Module format | ESM + CommonJS |
| Node | >=20.3 |
| Dependencies | 5 |
| Unpacked size | 383.7 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 0 |
| Author | Ibrahim Hajjaj |
| Maintainers | ibrahimwithi |
| Keywords | barq, jev, jev-browser, typesafe, system-one, mcp, mcp-server, claude, claude-code, claude-code-plugin, browser-automation, browser-agent, ai-agent, playwright, llm, agent |

## Links

- npm: https://www.npmjs.com/package/barq-mcp
- Repository: https://github.com/ibrahimhajjaj/barq
- Homepage: https://github.com/ibrahimhajjaj/barq#readme
- Issues: https://github.com/ibrahimhajjaj/barq/issues
- npm.io page: https://npm.io/package/barq-mcp

## Dependencies (5)

- [ws](https://npm.io/package/ws.md) ^8.21.3
- [zod](https://npm.io/package/zod.md) ^4.6.5
- [tldts](https://npm.io/package/tldts.md) ^7.4.13
- [playwright](https://npm.io/package/playwright.md) ^1.63.0
- [@modelcontextprotocol/sdk](https://npm.io/package/@modelcontextprotocol/sdk.md) >=1.30.0 <2.0.0

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 0.2.4 (latest) — 2026-09-24
- 0.2.3 — 2026-09-24
- 0.2.2 — 2026-09-23
- 0.2.1 — 2026-09-23

## README

# ⚡ Barq: TypeSafe Jev AI browser automation

Barq is fast AI browser automation for coding agents, powered by TypeSafe Jev and Playwright.
You name the outcome, Jev picks each click in about 300 ms, and your agent never reads page dumps.


https://github.com/user-attachments/assets/9a8db933-3275-4639-bd0f-46acdd042c28




```
browser_do("Log in", { username: "autofill", password: "autofill" })
  → { status: "done", url: "https://portal.example.com/home", actions: [...] }
```

It works inside the Chrome or Edge you already use, logged in as you, or in a clean Chromium it
starts itself. Not affiliated with TypeSafe; it calls their API with your key.

barq is Arabic for lightning (برق).

## Install

Node 20.3+, and a key from console.typesafe.ai.

In Claude Code:

```
/plugin marketplace add ibrahimhajjaj/barq
/plugin install barq@barq
```

It asks for the key (kept in the system keychain), which browser to use, and where its tabs go.
For its own browser, fetch Chromium once: `npx playwright install chromium`.

Any other MCP client:

```bash
claude mcp add barq -e TYPESAFE_API_KEY=your-key -- npx -y barq-mcp
```

Or from a clone:

```bash
git clone https://github.com/ibrahimhajjaj/barq && cd barq && npm install
claude mcp add barq -e TYPESAFE_API_KEY=your-key -- node "$PWD/bin/barq-mcp.mjs"
```

The key can live in the macOS keychain instead:
`security add-generic-password -s typesafe-api-key -a "$USER" -w`.

## Writing steps

One call, one outcome you could point at on the screen:

```
browser_open("https://shop.example.com/")
browser_do("Add the blue mug to the cart")
browser_do("Go to checkout")
browser_read("What does the order total come to?")  → "Total £24.00", p=0.98
browser_check("Does the cart show one blue mug?")   → 0.97
```

"Add two mugs, then check out" is two calls. Open-ended goals need a finish line: "scroll until at
least 3 new results are shown". Everything to type goes in `values` with a name Jev can match to a
field; Jev can't write text, it only chooses.

To find out what a page says, `browser_read` with a question beats everything else here: one Jev
call, the whole page rather than the part on screen, and you get back the passages that answer it
instead of the page. `browser_check` is for a yes/no you can act on, one thing per question, and on
a page that keeps its own history (a chat thread, a build log) it can answer "is it running now?"
from an older entry, so read the page there instead.

Statuses you get back: `done`, `likely_done` (verify it), `needs_confirmation` (the next click
pays, sends or deletes: ask the user, then call again with `allow_irreversible`), `needs_login`,
`error`, `ambiguous`, `stuck`, `max_actions`, `blocked` (captcha: with `wait_for_user_s` the tab is
put in front of you to solve it, then the step goes on), `timeout`.

## Your own browser

1. Open `chrome://inspect/#remote-debugging` (Edge: `edge://inspect/#remote-debugging`) and tick
   **Allow remote debugging for this browser instance**.
2. Set the browser to `edge` or `chrome` (plugin setting, or `BARQ_ATTACH=edge`).
3. The browser asks **Allow remote debugging?** once. Ticking the box in step 1 starts the
   browser's debugging server; it doesn't let anyone in, so each new connection is still announced.
   A small relay process keeps that one approved connection and shares it with every agent session,
   so you are asked once per browser run and not on each restart. It waits as long as you take to
   click, and holds the connection for eight idle hours (`BARQ_RELAY_IDLE_MIN`) because the browser
   only shows its "controlled by automated test software" bar while it is open, which is cheaper
   than finding the prompt again. While it runs, a program running as you that reads its token file
   (your account only) can drive the browser, as any approved debugging connection can;
   `BARQ_RELAY=0` turns the relay off and the prompt comes back every time.
4. Optional: load the `extension/` folder unpacked (Extensions → Developer mode → Load unpacked).
   Then barq's tabs live in one collapsed group named after your project instead of a separate
   window. Tabs it opens close when it is done, and your tab stays in front.

Your own tabs stay out of its sight: barq sees only the tabs it opened itself, so it can't read
yours, can't answer a dialog in one, and a tab the browser has put to sleep can't stall it.

### A browser of its own

`BARQ_ATTACH=own` uses a browser barq starts and keeps to itself, on a profile nothing else has
open. That browser never asks to be allowed, so there is no prompt and no relay to lose. It starts
with no logins, so sign in inside it once and they stay; it stays open between sessions, and the
next one finds it. `BARQ_BROWSER_PATH` picks which browser to start (Chrome, then Edge, then Brave,
then Chromium, then the driver's own), `BARQ_OWN_PROFILE` where to keep it.

## Logins

Never put a password in `values`. Pass a reference instead; it is read at the moment of typing and
never reaches Jev, the result or the trace:

| value | what happens |
|---|---|
| `"autofill"` | your password manager fills the field |
| `"autofill:work"` | picks the saved login whose name or username contains "work" |
| `"keychain:service[/account]"` | macOS keychain item |
| `"bw:item[/username\|/totp]"` | Bitwarden CLI (unlocked, `BW_SESSION` set) |
| `"env:NAME"` | environment variable of the server |

With several saved logins and none named, the step stops and lists them rather than guessing, even
if the browser pre-filled one. For Bitwarden's in-page menu, turn on "Show autofill suggestions on
form fields"; barq brings its tab to the front for the second the pick takes, then hands yours
back, and refuses any menu whose logins belong to another site.

## Reading a lot of pages

When you already know the URLs, skip the decision model entirely:

```bash
npx -p barq-mcp barq scan urls.txt --js "document.querySelector('h1').innerText" --out titles.jsonl
BARQ_ATTACH=edge npx -p barq-mcp barq scan jobs.json --selector li --click-until-gone "View more" --tabs 3
```

One JSON line per page, a rerun skips what is done, one retry per page, and everything stops if a
site answers with a captcha or "unusual traffic" page. Agents get the same through `browser_scan`,
which runs in the background and hands back counts and a sample, not the pages. A 1,600-page run in
a real browser took about 2 s a page and no model tokens per page.

## From Node

```js
import { Barq, scan, openBrowser } from "barq-mcp";

const b = await Barq.launch({ headed: true });
await b.open("https://www.saucedemo.com");
await b.do("Log in", { values: { username: "standard_user", password: "env:SAUCE_PASSWORD" } });
await b.do("Put the Sauce Labs Backpack in the cart");
console.log(await b.check("Does the cart badge show 1 item?"));   // 0..1
await b.close();

const browser = await openBrowser();                    // or { kind: "attach", spec: "edge" }
await scan(browser, urls, { tabs: 3, js: "document.title", checkpoint: "out.jsonl" });
await browser.dispose();
```

CLI: `npx -p barq-mcp barq do <url> "Log in" username=... password=env:PW`, and `npx -p barq-mcp barq run flow.json`.

## Where it is strong, where it is not

Good at: forms (a whole one in a round), dropdowns (including thousands of options), checkboxes
and radios, dynamic pages, modals, dialogs, drag and drop, uploads, iframes, shadow DOM, new tabs,
pages with 2,000 elements, and non-English interfaces. A canvas or a map has no elements to name:
`browser_screenshot` with `grid` and `browser_act` at a point cover it. Sessions can be kept to a
list of sites (`allowed_sites`) or given cookies of their own (`isolated`), in your browser too.

Not good at: judging many values at once ("is this table sorted?") comes back `likely_done` or
`stuck`, never a false `done`. A page whose own components are named for a state ("processing") can
also talk a check round, since that name is evidence too; `browser_read` answers from the words
instead, and tells you which headings a passage sat under. Counting works, because code counts rather than Jev. Captchas are
never solved by barq; they are handed to you. Sites that serve nothing to automated browsers need your own browser.

On the 66-task public benchmark: 66/66 correct in the latest two runs, 0 false "done", 300 to 400
ms a Jev call. Head to head with Playwright MCP, driven by the same model on the same 11 tasks: both
11/11, with barq 23% cheaper for the driver and 29% fewer tokens (4 times cheaper on Wikipedia).
[RESULTS.md](RESULTS.md) has the runs and the failures, [NOTES.md](NOTES.md) how it works and why.

## Development

```bash
git clone https://github.com/ibrahimhajjaj/barq && cd barq && npm install
npm test                                  # offline: fixtures and a local browser, no key
npm run test:e2e                          # the MCP server end to end (network + key)
npm run bench                             # the benchmark (network + key, about 6 minutes)
node bench/versus/run.mjs                 # head to head with Playwright MCP (claude CLI, about 5 minutes)
ln -s "$PWD" ~/.claude/skills/barq        # use this checkout as the Claude Code plugin
```

MIT licensed.

---
_Source: https://npm.io/package/barq-mcp · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
