← Architecture

Chrome extension

MV3 WebSocket proxy that routes Playwright commands into your real Chrome session.


What it does

The brow-use extension is a Manifest V3 Chrome extension that connects your real Chrome browser to the brow-use MCP server. It opens a persistent WebSocket connection to the server on port 3456 and listens for browser commands. When a command arrives, it executes it against your active Chrome tab using playwright-crx — a full Playwright API backed by chrome.debugger instead of a separate browser process.

This is what makes session mode possible: commands run inside your existing Chrome profile with your login state, cookies, and storage intact.


Permissions


Supported commands

CommandWhat it does
navigateNavigate the active tab to a URL, waits for domcontentloaded
clickClick an element by CSS selector
typeFill an input field by CSS selector
get_accessibility_treeReturn an ARIA snapshot of the page body
snapshotCapture a PNG screenshot, returned as base64
start_traceBegin a Playwright trace (screenshots, DOM snapshots, sources)
stop_traceStop the trace and send the .zip bytes back to the server
clear_sessionClear cookies, localStorage, and sessionStorage for the active tab

Connection lifecycle

The extension's service worker connects to ws://localhost:3456 on startup. If the connection drops — because the MCP server hasn't started yet or restarted — it retries automatically every 3 seconds. No manual reconnect is needed.

The popup shows connection status: Connected to brow-use server when the WebSocket handshake succeeds, or Server not running if the MCP server is not reachable.


Build and load

1 — Build

npm run build

Outputs the compiled extension to dist/extension/.

2 — Load in Chrome

  1. Open chrome://extensions
  2. Enable Developer mode (toggle, top-right)
  3. Click Load unpacked and select dist/extension/
This is a one-time step. Chrome remembers the extension across restarts.

Watch mode

Enable remote debugging so the watcher can trigger reloads over CDP:

npm run chrome

If Chrome is already open, quit it first — --remote-debugging-port is a startup flag and is ignored if Chrome is already running.

Then in a second terminal, start the watcher:

npm run dev:extension

On each .ts save in extension/, the watcher rebuilds and calls chrome.runtime.reload() via CDP — no manual refresh at chrome://extensions.