Skip to content

Getting started

browxai is an MCP server that gives an AI agent a curated browser-control surface. It runs over stdio and is driven by any MCP client.

You need Node 22 or newer (node --version tells you). browxai drives the Google Chrome you already have installed, so a machine with Chrome needs no browser download.

Terminal window
npm install -g browxai
browxai doctor

browxai doctor checks the environment and prints one line per area, with a tick or a cross and the next step under anything that fails. browxai doctor --verbose prints every check. On a machine with no Google Chrome it fails until you add a browser: install Chrome, or fetch the bundled Chromium (about 150 MB).

Terminal window
npx playwright-core@1.64.1 install chromium

A bare Linux image also lacks the system libraries Chromium needs. Add --with-deps to that command to install them (it needs root).

Firefox and WebKit sessions use their own Playwright builds (npx playwright-core@1.64.1 install firefox webkit).

A global install puts the browxai binary on your PATH, so an MCP client can launch it by name (command: "browxai"). The binary is the MCP server on the stdio transport. Run by hand in a terminal it just waits for a client, so use browxai doctor to check the machine instead: it reports the Node version, the browser, the workspace and your configuration.

On Linux and macOS, npm install -g can fail with EACCES when npm’s global prefix sits in a root-owned directory. Don’t reach for sudo. Either skip the global install and use npx -y browxai as the client’s command (how to wire it into a client), or give npm a prefix in your home directory:

Terminal window
npm config set prefix ~/.npm-global

Then add ~/.npm-global/bin to your PATH and run the install again.

browxai launches the Google Chrome already installed on the machine, on one default profile per workspace (<workspace>/profile), so logins carry over between sessions. It looks for Google Chrome at its default install path on each OS, so a distro Chromium package is not picked up. When there is no Chrome it falls back to Playwright’s bundled Chromium. browxai doctor fails only when neither browser is present.

The quickest way is one command, run in your project:

Terminal window
browxai init .

It writes a .mcp.json in that directory, finds the MCP clients on your machine (Claude Code, Cursor, Codex and Claude Desktop) and prints the exact command or snippet for each one. It also adds browxai to the user-level config of each of Cursor, Codex and Claude Desktop it finds, for example ~/.cursor/mcp.json. It prints the change first. A file that exists is merged, and the old copy is kept as <config>.browxai-bak. Pass --no-write-user-config to leave those files alone, or --no-write to print everything and write nothing. An older --write-user-config still works and does nothing extra. A file init will not edit (not plain JSON, or one that already has a browxai entry) is left as it is. A read or write error on a config makes init exit with code 1, after it tried every client. At the end it opens a headless private session on a blank page, takes a snapshot and closes it, then prints ok: first snapshot in N ms. If that fails, init says what to fix and exits with code 1. Add --no-smoke to skip that check.

To do it by hand instead, add browxai to your client’s MCP server config. In Claude Code, one command does it:

Terminal window
claude mcp add browxai -- browxai

Restart the client after any config change, then check that browxai shows as connected (in Claude Code, run /mcp).

Every client below runs the same command, browxai. Without a global install, use npx -y browxai instead (claude mcp add browxai -- npx -y browxai).

Add this to ~/.codex/config.toml, or to .codex/config.toml in a project. Or run codex mcp add browxai -- browxai.

[mcp_servers.browxai]
command = "browxai"
startup_timeout_sec = 30
tool_timeout_sec = 120

The longer startup timeout helps when the client launches browxai through npx -y, which can take a while on first run. Options go in an env table: env = { BROWX_HEADLESS = "1" }.

Add this to ~/.cursor/mcp.json for all projects, or .cursor/mcp.json for one:

{
"mcpServers": {
"browxai": {
"command": "browxai"
}
}
}

Each client keeps its list of servers under its own key in its own file.

  • Claude Desktop: key mcpServers. macOS ~/Library/Application Support/Claude/claude_desktop_config.json, Windows %APPDATA%\Claude\claude_desktop_config.json.
  • VS Code: key servers, in .vscode/mcp.json.
  • Windsurf: key mcpServers, in ~/.codeium/windsurf/mcp_config.json.
  • Zed: key context_servers, in settings.json. Its entry has a different shape, so copy it from Zed’s MCP docs.

For the three JSON clients, the entry is "browxai": { "command": "browxai" } under that key, as in the Cursor example.

By default the server launches a managed Chrome on the workspace’s default profile, headed, with the default capability set (read, navigation, action, human). That is the installed Google Chrome, or the bundled Chromium with a logged warning when Chrome is absent. Every capability outside that set is opt-in.

A headed browser needs a display. On a machine without one, such as a Linux server or a container, the first session fails to open until you set BROWX_HEADLESS=1 in the server’s environment. In a JSON config that is an env entry next to command: "env": { "BROWX_HEADLESS": "1" }. With Claude Code, add --env BROWX_HEADLESS=1 to claude mcp add.

VariablePurpose
BROWX_WORKSPACEWhere all transient state lives (default ~/.browxai/). Never cwd.
BROWX_HEADLESS1 or true launches headless.
BROWX_CAPABILITIESThe full comma-separated capability set. It replaces the default, so keep read,navigation,action,human and add eval, network-body, clipboard, or file-io to opt into gated tools.
BROWX_ENGINEDefault engine, chromium unless set. Also --engine <kind>. The values are in the FAQ.
BROWX_ATTACH_CDPLoopback CDP endpoint to attach to an existing Chrome (BYOB). Needs byob-attach in BROWX_CAPABILITIES too: read,navigation,action,human,byob-attach.

See the tool reference for the full configuration surface, and note that capabilities are resolved once at server start: changing them means restarting the server.

A typical agent loop:

  1. navigate to a URL.
  2. snapshot to get the accessibility tree plus DOM-walk; every node has a stable [ref=eN].
  3. find to describe the target in natural language; get ranked candidates with a stability flag, an actionable verdict, and a visible-rect bbox.
  4. click / fill / … to act by ref; each returns a structured ActionResult describing what navigated, what structure changed, and a console/network slice.

For verification use text_search, inspect, and the read tools; for flaky or transient UI use wait_for, sample, and act_and_sample.

Try it with a prompt such as “open https://example.com, snapshot it and tell me what the page says”. The agent calls navigate and snapshot. The paragraph text comes back on its row, and the heading and link come back as refs it can click. A Chrome window opens on a machine with a display. Headless runs show no window.

Run browxai doctor. For an error string, see Troubleshooting.

  • Tool reference is every tool, its inputs and outputs, example calls, the configuration and session model, and the stability policy.
  • Agent guidance is the reach-for-this-not-that map: the footguns agents hit and the curated tool that avoids each one.
  • Configuration and Recipes cover config layers and copy-adaptable flows.
  • Security and threat model is the capability model, what browxai defends against, and what it explicitly does not.