BrowserPilot

August 21, 2026 · View on GitHub

CI npm License: MIT

English | 简体中文

BrowserPilot is a local browser-control bridge for AI agents. It combines a Chrome extension, Native Messaging Bridge, local daemon, and stdio MCP server so that Codex, Claude Code, Antigravity, VS Code/Copilot, Cline, and other MCP clients can safely operate a real Chrome browser.

Browser content, screenshots, tasks, and approval records remain on the local machine by default. The daemon listens on 127.0.0.1 by default; WSL, container, or LAN access requires revocable Tokens.

Contents

Capabilities

CapabilityWhat it does
Real Chrome controlNavigate, click, type, scroll, capture, and manage tabs in the user's logged-in browser.
Observable interactionInspect visible DOM, snapshots, content, and screenshots before acting.
Multi-agent MCP accessConnect Codex, Claude Code, Antigravity, VS Code/Copilot, Cline, and other stdio MCP clients.
Scheduled browser automationStore trusted JavaScript jobs locally; run them on Cron schedules, manually trigger or cancel them, and inspect logs.
Local dashboardInspect connections, tasks, next run times, logs, approvals, and policy settings.
Enforced permissionsWrite actions, page JavaScript, downloads, and uploads are governed by executable policies with deny-by-default timeouts.
Remote/WSL supportConnect an MCP adapter in WSL or another trusted environment to a Windows daemon using revocable Tokens.

Quick start (production use)

This is the recommended production path. It requires Node.js 18+ and Google Chrome.

1. Install and register the local bridge

npm install -g @puxora/browserpilot
browserpilot install

To migrate from the former package, run npm uninstall -g @pulab/browserpilot before installing @puxora/browserpilot. Changing the npm package name does not remove local configuration or task data under ~/.browserpilot.

The command registers the Native Messaging Host for the current user. Open chrome://extensions, enable Developer mode, select Load unpacked, and choose the chrome-extension directory printed by the CLI.

Uninstall

npm does not automatically remove the Chrome registry entries and Native Messaging configuration created by the CLI. Clean up the local bridge before removing the npm package:

browserpilot uninstall
npm uninstall -g @puxora/browserpilot

browserpilot uninstall retains configuration, Tokens, tasks, and logs under ~/.browserpilot. To permanently delete that local data too, explicitly run browserpilot uninstall --purge. Remove the Chrome extension separately from chrome://extensions.

2. Start the local service

browserpilot start

start launches the daemon, Web UI, and scheduler in the background by default and returns the shell immediately. The dashboard is available at http://127.0.0.1:9876. Opening it from a local browser creates a loopback-only authentication cookie.

Common lifecycle commands:

browserpilot status
browserpilot stop
browserpilot restart

To keep logs attached to the current terminal, run:

browserpilot start --foreground

3. Connect an MCP client

Any stdio MCP client can start with this configuration:

{
  "mcpServers": {
    "browserpilot": {
      "command": "npx",
      "args": ["-y", "@puxora/browserpilot", "mcp"]
    }
  }
}

Use system_status and browser_list_tabs first to verify the daemon and extension connection.

Remote and WSL

Local clients do not need a manually supplied Token. For WSL, containers, or another host, create a revocable Token on the machine that runs the Windows daemon:

browserpilot token create --name wsl-agent

The complete Token is shown only once. Keep it in the client's secure secret store or environment; never commit it, put it in a URL, or add it to task source.

browserpilot token list
browserpilot token revoke --id <token-id>

Generate a generic client configuration in the remote environment:

browserpilot mcp config --client generic \
  --daemon-api http://<windows-host-ip>:9876/api \
  --token <token>

The Windows daemon must explicitly opt into non-loopback access and intentionally restrict hosts, origins, and firewall rules:

$env:CA_API_TOKEN = "<daemon-bootstrap-secret>"
$env:CA_TRUSTED_HOSTS = "<windows-host-ip>"
$env:CA_TRUSTED_ORIGINS = "http://<windows-host-ip>:9876"
browserpilot start --listen-host 0.0.0.0

Use this mode only on a trusted network. The daemon bootstrap secret and client Tokens should be stored separately.

MCP clients

BrowserPilot is a stdio MCP server: the client starts browserpilot mcp, which forwards calls to the local or selected daemon API.

Codex

codex mcp add browserpilot -- npx -y @puxora/browserpilot mcp

For WSL, add the following to ~/.codex/config.toml:

[mcp_servers.browserpilot]
command = "npx"
args = ["-y", "@puxora/browserpilot", "mcp", "--daemon-api", "http://<windows-host-ip>:9876/api"]

[mcp_servers.browserpilot.env]
CA_API_TOKEN = "bp_..."

Restart Codex and use /mcp or codex mcp list. See the Codex MCP guide.

Claude Code

claude mcp add-json browserpilot '{"type":"stdio","command":"npx","args":["-y","@puxora/browserpilot","mcp"],"env":{}}'

For WSL, append --daemon-api to args and define CA_API_TOKEN in env. Verify with claude mcp. See Claude Code MCP.

Google has transitioned individual Gemini CLI users to Antigravity CLI. Use /mcp to open its MCP Manager, or edit global ~/.gemini/config/mcp_config.json; project-local configuration is .agents/mcp_config.json.

{
  "mcpServers": {
    "browserpilot": {
      "command": "npx",
      "args": ["-y", "@puxora/browserpilot", "mcp"],
      "env": {}
    }
  }
}

For WSL, use:

{
  "mcpServers": {
    "browserpilot": {
      "command": "npx",
      "args": ["-y", "@puxora/browserpilot", "mcp", "--daemon-api", "http://<windows-host-ip>:9876/api"],
      "env": { "CA_API_TOKEN": "bp_..." }
    }
  }
}

Run /mcp to inspect connection status and logs. Antigravity can migrate legacy Gemini CLI MCP configuration; review the result to ensure Tokens are not written into a project file. See Antigravity MCP and its Gemini CLI migration guide.

Gemini CLI (legacy compatibility)

Since 2026-06-18, free, Google AI Pro, and Google AI Ultra users should use Antigravity CLI. Gemini CLI remains relevant for enterprise Gemini Code Assist, Google Cloud, and certain paid API-key scenarios. If your organization still uses it:

gemini mcp add --scope user browserpilot npx -y @puxora/browserpilot mcp

Follow the official transition announcement for current eligibility.

VS Code and GitHub Copilot Chat

Create .vscode/mcp.json or use MCP: Add Server. Do not commit a real Token in project configuration:

{
  "servers": {
    "browserpilot": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@puxora/browserpilot", "mcp"],
      "env": { "CA_API_TOKEN": "${input:browserpilot-token}" }
    }
  },
  "inputs": [{
    "id": "browserpilot-token",
    "type": "promptString",
    "description": "BrowserPilot Token",
    "password": true
  }]
}

Remove env for local use. Run MCP: List Servers to verify. See the VS Code reference and Copilot MCP guide.

Cline and generic stdio clients

Cline commonly stores global settings in ~/.cline/data/settings/cline_mcp_settings.json, with .cline/mcp.json for project configuration. Other stdio MCP clients use the same shape:

{
  "mcpServers": {
    "browserpilot": {
      "command": "npx",
      "args": ["-y", "@puxora/browserpilot", "mcp"],
      "env": { "CA_API_TOKEN": "bp_..." }
    }
  }
}

Remove env for local use and keep the client's own tool approval enabled. See Cline configuration.

Scheduled automation

Tasks are useful for status checks, periodic collection, and workflows that may later require an upload/download approval. A task is a trusted local ES module with a name, Cron schedule, enabled flag, and run(ctx) function. Create it from the dashboard or MCP.

export default {
  name: 'Daily status check',
  description: 'Inspect the dashboard every morning',
  schedule: '0 9 * * *',
  enabled: true,
  async run(ctx) {
    await ctx.navigate('https://example.com/dashboard');
    await ctx.waitForLoad();
  },
};
WorkflowHow it works
Create/updateSubmit a complete module with task_create or task_update. The module and Cron are validated; a failed update keeps the previous version.
Enable/disableenabled: false stops scheduling. Restoring it to true reloads the job. Deleting a task or using task_delete stops it.
Run nowtask_run executes once without changing the Cron schedule.
Canceltask_cancel aborts a currently running job.
Observetask_list and task_get show state and next run; task_logs provides start, result, and failure records.
Overlap/concurrencyA job is not started again while its previous run is active; daemon concurrency limits also apply.

Cron expressions use five fields, such as 0 9 * * * (09:00 daily) and */30 * * * * (every 30 minutes). Validate a job manually before enabling its schedule. Task source can control the browser: only run code you trust. Clicks, page JavaScript, uploads, and downloads are still constrained by BrowserPilot's active policy.

CLI

CommandDescription
browserpilot --version / browserpilot -v / browserpilot versionShow the current CLI version.
browserpilot installRegister the Chrome Native Messaging Host for the current user.
browserpilot uninstallStop the daemon and remove BrowserPilot-created Native Messaging manifests, Chrome registry entries, and bridge files while retaining local data.
browserpilot uninstall --purgePermanently remove configuration, Tokens, tasks, and logs under ~/.browserpilot after the standard cleanup.
browserpilot startStart the daemon, dashboard, and scheduler in the background on 127.0.0.1:9876 by default.
browserpilot start --foregroundStart the daemon in the current terminal for debugging or live logs.
browserpilot start --listen-host <ip> --port <port>Set the HTTP listener and port; non-loopback use requires explicit security configuration.
browserpilot stopStop the background daemon.
browserpilot restartRestart the background daemon.
browserpilot statusShow the daemon PID, Web UI URL, and log path.
browserpilot mcpStart the stdio MCP server; starts the local daemon if it is absent.
browserpilot mcp --daemon-api <url> --token <token>Connect to a selected daemon; CA_API_TOKEN is also supported.
browserpilot mcp config --client <name> [--wsl] [--daemon-api <url>] [--token <token>]Print a reusable generic MCP JSON configuration.
browserpilot token create --name <name>Create a revocable remote MCP Token and show its plaintext once.
browserpilot token listList Token IDs, names, and creation dates without plaintext.
browserpilot token revoke --id <id>Revoke a Token immediately.

MCP tools

Run npm run check:tools for the complete list. Prefer an observe → act → verify flow and stable node_id or semantic targets over fragile CSS selectors.

CategoryRepresentative toolsUse
Tabsbrowser_list_tabs, browser_create_tab, browser_claim_tab, browser_release_tabInspect, create, and exclusively control tabs.
Navigationbrowser_navigate, browser_go_back, browser_reloadOpen pages and use browser history.
Observationbrowser_get_visible_dom, browser_get_dom_snapshot, browser_get_contentRead structure, visible content, and state.
Interactionbrowser_click_node, browser_type_node, browser_click_role, browser_type_by_labelClick and type by stable nodes or semantic targets.
Wait and imagesbrowser_wait_for_load, browser_wait_for_selector, browser_screenshot, browser_long_screenshotWait for state transitions and inspect results.
Sensitive actionsbrowser_execute, browser_close_tabRun page JavaScript or close a tab; both are gated by developer settings, approvals, and leases.
Taskstask_create, task_update, task_run, task_cancel, task_logsManage, schedule, cancel, and audit local jobs.
Statussystem_status, browser_controller_configInspect connection status and declare the current controller.

Ordinary target-tab tools claim control before the first operation and keep the control banner visible until browser_release_tab, browser_finalize_tabs, user cancellation, connection shutdown, or lease expiry. During navigation, the banner is restored as soon as the new document starts and checked again when loading completes. browser_navigate creates a new tab when tabId is omitted so it cannot replace the page hosting an agent or the user's current work; an existing tab is reused only when its tabId is explicit. Screenshots return native MCP image content by default instead of placing Base64 in text. Pass output: "file" or path to save a local file. path may be absolute or relative to the MCP adapter working directory, and existing files are overwritten only with overwrite: true. Full-page screenshots always use scroll stitching and never trigger Chrome's native debugging banner; legacy strategy: "debugger" input safely falls back to stitching.

Permissions and security

Every dashboard setting maps to browser execution:

  • Write-action approval gates clicks, typing, page JavaScript, and closing tabs. Site exceptions only change this approval and never relax transfer policy.
  • Page JavaScript developer permission rejects browser_execute when disabled; when enabled, write-action approval still applies.
  • Download policy applies only to downloads initiated by BrowserPilot-controlled tabs. always permits, ask waits for approval, and none cancels. Timeout cancels by default.
  • Upload policy runs before AI opens a file input. always, ask, and none determine whether the system file picker opens. The user still selects local files; timeout denies by default.
  • Remote authentication protects every /api endpoint with a Token. The Web UI receives an HttpOnly, SameSite cookie only on loopback; remote MCP uses Bearer Tokens.

The extension uses permissions including tabs, scripting, nativeMessaging, and downloads to control the real browser. Install only trusted builds, do not expose the daemon on an untrusted network, and never store passwords or Tokens in task source.

Architecture

MCP client
  -> BrowserPilot MCP Adapter (stdio)
  -> daemon API / Token / approval and policy
  -> loopback WebSocket
  -> Chrome extension
  -> real Chrome tabs

Dashboard -> daemon API
Scheduler -> local task store -> same policy and browser execution path

BrowserPilot is designed to be local-first, explicit about remote exposure, observable before action, guarded for sensitive operations, and isolated across controller sessions through tab leases.

Development deployment

Run from source:

git clone https://github.com/Puxora/BrowserPilot.git
cd BrowserPilot/orchestrator
npm ci
node bin/cli.js install
npm start

Load the repository-root chrome-extension in Chrome. During development run:

npm test
npm run test:coverage
npm run check:tools
npm audit --package-lock-only --audit-level=moderate
npm pack --dry-run

Contributing, releases, and changes

  • Read CONTRIBUTING.md for contribution flow and test expectations.
  • Report vulnerabilities through SECURITY.md, not public issues.
  • Follow CODE_OF_CONDUCT.md.
  • See CHANGELOG.md for released changes. Before publishing, run tests, audit, and npm pack --dry-run, then publish using semantic versioning.

Licensed under the MIT License.