browser-pilot
Give your AI agent control of your real browser β with your logins, cookies, and extensions intact. No extension needed.
npm install -g browser-pilot-cli
Agent Setup
1. Enable Chrome remote debugging (one-time)
Open chrome://inspect/#remote-debugging in Chrome (144+) and click Allow. No command-line flags, no restart needed.
Chrome 136 disabled the old --remote-debugging-port flag for security. Chrome 144 introduced this new UI toggle as the replacement β browser-pilot uses this.
2. Install the plugin for your agent
Claude Code:
/plugin marketplace add https://github.com/relixiaobo/browser-pilot.git
/plugin install browser-pilot@browser-pilot-marketplace
Codex CLI:
npx skills add relixiaobo/browser-pilot
OpenClaw:
cp -r plugin/skills/browser-pilot ~/.agents/skills/
Cursor / VS Code Copilot:
npx skills add relixiaobo/browser-pilot
3. Use it
Just tell your agent what you want to do:
- "Open GitHub and check my notifications"
- "Go to Hacker News and summarize the top 5 posts"
- "Fill out the form on this page"
The agent will use bp commands automatically. Your real login sessions are preserved β no need to re-authenticate.
Why browser-pilot?
- No extension required β Uses Chrome 144's native remote debugging toggle, not the Extension Debugger API
- Real login sessions β Operates your actual browser profile. Cookies, extensions, logins all intact
- CLI-native β Any agent with bash access can use it. No MCP protocol, no SDK integration needed
- Auto-snapshot β Every action returns page state with numbered
[ref] elements, so the agent always knows what's on screen
- Lightweight β 78KB npm package. No bundled Chromium (unlike Playwright's 400MB+)
Comparison
| Interface | CLI (bash) | MCP protocol | MCP protocol | Python SDK |
| Login session reuse | Yes | No | Depends | Yes |
| Extension required | No | No | No | No |
| Element refs | Numbered (accessibility tree) | Named refs (ARIA) | CSS selectors | Numbered (DOM) |
| Auto-snapshot after action | Yes | Yes | No | Yes |
| Network interception | Yes (block/mock/headers) | Yes | Yes | No |
| Multi-browser | Chromium-only | Chromium + Firefox + WebKit | Chromium-only | Chromium-only |
| Dialog auto-handling | Yes | Yes | No | Yes |
| JSON output | Default | MCP structured | MCP structured | Python objects |
| File upload | Auto-detect input | Yes | No | Yes |
How It Works
Agent (bash tool)
β bp open / bp click / bp eval ...
βΌ
CLI Process ββββ HTTP/Unix Socket ββββ Daemon Process (persistent)
β
β WebSocket (CDP)
βΌ
Chrome (your browser, your profile)
βββ Your windows (untouched)
βββ Pilot window (agent operates here)
The daemon maintains a single CDP WebSocket connection. A pulsing blue glow around the Pilot window indicates the agent is active.
Commands
Core Loop
bp open <url> | snapshot | Navigate to URL |
bp snapshot | snapshot | Get interactive elements |
bp click <ref> | snapshot | Click element by ref number |
bp type <ref> <text> | snapshot | Type into element (--clear, --submit) |
bp press <key> | snapshot | Press key (Enter, Escape, Control+a, Meta+c) |
bp eval [js] | value | Run JavaScript (escape hatch for anything) |
Utilities
bp screenshot [file] | Capture screenshot (--full, --selector) |
bp pdf [file] | Save page as PDF (--landscape) |
bp cookies [domain] | View cookies (includes HttpOnly) |
Edge Cases
bp upload <filepath> | Upload file (auto-finds <input type="file">) |
bp auth <user> <pass> | Set HTTP Basic Auth credentials (--clear) |
bp frame [index] | List or switch iframe context (0 = top) |
Dialogs (alert/confirm/prompt) are auto-handled by the daemon.
Popup windows (target="_blank", window.open) are auto-detected. Run bp tabs to see and switch to them.
Network
bp net | List recent requests (--url, --method, --status, --type) |
bp net show <id> | Full request/response details (--save <file>) |
bp net block <pattern> | Block requests matching URL pattern |
bp net mock <pattern> | Mock responses (--body, --file, --status) |
bp net headers <pattern> <header...> | Add/override request headers |
bp net rules | List active interception rules |
bp net remove [id] | Remove rule(s) (--all) |
bp net clear | Clear captured request log |
Session
bp connect | Connect to Chrome, create pilot window |
bp disconnect | Close pilot window, stop daemon |
bp tabs | List pilot tabs (auto-adopts popups) |
bp tab <n> | Switch tab |
bp close | Close current tab (--all) |
Refs
Action commands return a snapshot of interactive elements, each with a [ref] number:
[1] link "Home"
[2] textbox "Search"
[3] button "Submit"
Use the number in subsequent commands: bp click 1, bp type 2 "hello".
Refs are scoped to the current page β they refresh automatically after every action.
Output
JSON by default when piped (for LLM/script consumption). Human-readable when run in a terminal.
{"ok":true, "title":"Example", "url":"https://example.com", "elements":[{"ref":1, "role":"link", "name":"More info"}]}
Errors include hints:
{"ok":false, "error":"Ref [99] not found.", "hint":"Run 'bp snapshot' to refresh element refs."}
Force human output: bp --human open https://example.com
Eval
eval is the escape hatch β anything JavaScript can do:
bp eval "history.back()"
bp eval "history.forward()"
bp eval "location.reload()"
bp eval "window.scrollBy(0, 500)"
bp eval "document.querySelector('h1').textContent"
bp eval "document.querySelector('div').innerHTML"
bp eval "JSON.stringify(localStorage)"
echo 'complex js here' | bp eval
File Upload
bp upload auto-detects <input type="file"> on the page:
bp open https://images.google.com
bp click 5
bp upload ~/Downloads/photo.jpg
Network Interception
Monitor, block, and mock HTTP requests:
bp net
bp net --url "*api*" --method POST
bp net show 3
bp net block "*tracking*"
bp net block "*ads*"
bp net mock "*api/data*" --body '{"ok":true}'
bp net mock "*api/users*" --file mock.json --status 200
bp net headers "*api*" "Authorization:Bearer test123"
bp net rules
bp net remove 2
bp net remove --all
bp net clear
Requirements
- Chrome 144+ / Edge / Brave (any Chromium-based browser)
- Node.js >= 18
- Remote debugging enabled (
chrome://inspect/#remote-debugging)
License
MIT