PilotBLOCK
Chrome extension + MCP server — AI agents control a tab in your real browser, already logged in
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://www.npmjs.com/package/pilot-mcp) [](https://github.com/TacosyHorchata/Pilot/blob/main/LICENSE) [](https://github.com/TacosyHorchata/Pilot)
Native Playwright-backed browser sessions by default. No Chrome extension required for QA automation.
Pilot has two browser backends:
- Native mode (default): isolated Playwright browser contexts. This is the supported path for parallel QA automation and reliable screenshots.
- Extension mode (legacy/opt-in): connects to your real Chrome profile when you need existing cookies and logged-in sessions.
Native mode avoids chrome.tabs.captureVisibleTab() entirely, so screenshots do not depend on Chrome being foregrounded, a tab being visibly active, or the extension service worker being fresh.
How it works
AI Agent → MCP Server → Broker on 127.0.0.1:3131 → Native browser session (stdio) (first process owns broker) (Playwright context/page)
- Pilot runs as an MCP server — Claude Code, Cursor, or any MCP client connects via stdio
- The first Pilot process becomes the broker on localhost
- Later Pilot processes connect as broker clients
- Each session gets an isolated native browser context/page
- Screenshots come from Playwright, not the Chrome extension capture API
Quick Start
1. Add the MCP server
codex mcp add pilot \ --env PILOT_BROWSER_MODE=native \ --env PILOT_PROFILE=full \ -- npx -y pilot-mcp
For a local checkout:
npm install npm run build codex mcp add pilot \ --env PILOT_BROWSER_MODE=native \ --env PILOT_PROFILE=full \ -- node /absolute/path/to/pilot/dist/index.js
2. Use it
"Open https://example.com, take a screenshot, and su
33160f9f22eaOBSERVED · 2026-10-08Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control.
claude mcp add pilot-mcp -- npx -y [email protected]
{
"mcpServers": {
"pilot-mcp": {
"command": "npx",
"args": [
"-y",
"[email protected]"
]
}
}
}Exposed tools (69)
57 read · 8 write · 4 destructive. Blast radius: 4 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
pilot_act | read | Perform a high-level browser action by resolving a human target into the best available @ref, label, role, placeholder, text, or selector. Use when an agent knows the user |
pilot_annotated_screenshot | read | |
pilot_assert | read | |
pilot_auth | read | |
pilot_back | read | Navigate back to the previous page in browser history. Use when the user wants to go back to the prior page they visited. Parameters: (none) Returns: The URL of the page after navigating back. Errors: - |
pilot_block | read | |
pilot_cdp | read | Connect Pilot to a real Chrome browser already running on the user |
pilot_click | read | |
pilot_clipboard | write | Read from or write to the browser clipboard. Use when the user wants to read content that an app copied to clipboard (share links, API keys, generated tokens), or pre-populate clipboard with text for paste operations. Parameters: - action: |
pilot_close | read | Close the browser instance and release all associated resources. Use when the user wants to end the browsing session, clean up after completing a task, or start fresh with a new browser session. Parameters: (none) Returns: Confirmation that the browser was closed. Errors: - |
pilot_console | read | Retrieve browser console messages (console.log, console.warn, console.error) from a circular buffer. Use when the user wants to debug JavaScript errors, check application logs, inspect warnings, or see what the page is printing to the console. Parameters: - level: Filter messages by log level — |
pilot_cookies | read | |
pilot_dialog | read | |
pilot_doctor | read | |
pilot_drag | destructive | Drag one element and drop it onto another element on the page. Use when the user wants to move an element, reorder items in a drag-and-drop list, or interact with a drag-and-drop UI. Parameters: - start_ref: The source element reference from snapshot (e.g., |
pilot_element_state | read | Check the current state of an element — whether it is visible, hidden, enabled, disabled, checked, editable, or focused. Use when the user wants to verify an element |
pilot_evaluate | write | Execute a JavaScript expression or function in the browser page context and return the result. Use when the user wants to run custom JavaScript on the page, read or modify DOM elements, extract data, or perform calculations. Supports async/await — use |
pilot_evidence_export | read | Export the active evidence bundle to JSON, Markdown, or both. Use when the agent is done reproducing, validating, or debugging and needs durable artifacts the user or another agent can inspect without replaying the browser session. Parameters: - format: |
pilot_evidence_start | write | |
pilot_evidence_step | read | |
pilot_extension_status | read | Check if the Pilot Chrome extension is connected and routing commands through the user |
pilot_file_upload | write | Upload one or more files to a file input element on the page. Use when the user wants to attach files, upload images, or submit documents through a file input field. Parameters: - ref: The file input element reference from snapshot (e.g., |
pilot_fill | read | |
pilot_find | read | Find an element by visible text, label, placeholder, or role — without running a full snapshot. Use when you know what you want to click or fill but don |
pilot_forward | read | Navigate forward to the next page in browser history. Use when the user wants to go forward after using pilot_back. Parameters: (none) Returns: The URL of the page after navigating forward. Errors: - |
pilot_frame_reset | destructive | |
pilot_frame_select | read | |
pilot_frames | read | |
pilot_geolocation | destructive | Set or clear the browser |
pilot_get | read | Navigate to a URL and return its full readable content + interactive elements in one call. Use this as the primary tool for |
pilot_guide | read | Read short just-in-time Pilot guidance for a specific agent workflow topic. Use when an agent needs to know the right Pilot pattern, recovery path, browser mode, evidence flow, or ref behavior without loading the README or asking the user for instructions. Parameters: - topic: One of |
pilot_handle_dialog | read | |
pilot_handoff | read | |
pilot_hover | read | Hover the mouse over an element, triggering hover states, tooltips, and dropdown menus. Use when the user wants to reveal hidden content, trigger a CSS :hover effect, or inspect tooltip text. Parameters: - ref: Element reference from snapshot (e.g., |
pilot_import_cookies | write | Import cookies from a real Chromium browser (Chrome, Arc, Brave, Edge, Comet) by decrypting the browser |
pilot_intercept | read | |
pilot_navigate | read | Navigate the browser to a URL and wait for DOM content to load. Use when the user wants to go to a specific webpage, URL, or link. For read tasks ( |
pilot_network | read | |
pilot_page_attrs | read | Get all HTML attributes of a specific element as a JSON object. Use when the user wants to inspect an element |
pilot_page_css | read | |
pilot_page_diff | read | |
pilot_page_forms | read | |
pilot_page_html | read | Get innerHTML of a selector/ref, or full page HTML if none provided. |
pilot_page_links | read | Get all links on the page as text + href pairs. |
pilot_page_text | read | Extract clean text from the page (strips script/style/noscript/svg). |
pilot_pdf | read | |
pilot_perf | read | |
pilot_press_key | read | Press a keyboard key or key combination on the page. Use when the user wants to press Enter to submit a form, Tab to move between fields, Escape to close a modal, ArrowDown to navigate a list, or use any keyboard shortcut. Parameters: - key: Key name or combination (e.g., |
pilot_reload | read | |
pilot_reset | destructive | |
pilot_resize | read | |
pilot_responsive | read | |
pilot_resume | read | |
pilot_screenshot | read | Take a PNG screenshot of the current page or a specific element. Use when the user wants to capture what the page looks like visually, save a screenshot to disk, or capture a specific element |
pilot_scroll | read | |
pilot_select_option | read | |
pilot_set_cookie | write | Set a cookie on the current page |
pilot_set_header | write | |
pilot_set_useragent | write | |
pilot_snapshot | read | |
pilot_snapshot_diff | read | |
pilot_status | read | |
pilot_storage | read | |
pilot_tab_close | read | |
pilot_tab_new | read | Open a new browser tab, optionally navigating to a URL. Use when the user wants to open a link in a new tab, create a blank tab, or work with multiple pages simultaneously. Parameters: - url: Optional URL to navigate to in the new tab (omit for a blank about:blank tab) Returns: The new tab |
pilot_tab_select | read | |
pilot_tabs | read | |
pilot_type | read | |
pilot_wait | read |
Trust audit
BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (6 observation(s))
- Network
- declared (7 observation(s))
- Shell
- declared (2 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (12)
const result = eval(script);
'169.254.169.254',
'metadata.google.internal',
pilot_drag, pilot_frame_reset, pilot_geolocation, pilot_reset
console.log(` [Image data — base64 chars shown, not token-comparable to ARIA text]`);
const local = path.resolve(fileURLToPath(import.meta.url), '../../cli/SKILL.md');
const serverPath = path.resolve(fileURLToPath(import.meta.url), '../../dist/index.js');
const daemonBin = path.resolve(fileURLToPath(import.meta.url), '../../dist/cli/daemon.js');
const clientBin = path.resolve(fileURLToPath(import.meta.url), '../../dist/cli/client.js');
const jsonlPath = path.resolve(fileURLToPath(import.meta.url), '../../benchmark/results.jsonl');
@anthropic-ai/sdk, @modelcontextprotocol/sdk, @types/ws, better-sqlite3, diff, playwright, ws, zod
pilot-demo.gif
Gates applied: no_behavioural_pass.
33160f9f22eafull audit observations/trust-audit/mcp-server/tacosyhorchata__pilot-1.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-08 | 33160f9f22ea | BLOCK | D | 69 | first audit |
Questions
What is the Pilot MCP server?
Chrome extension + MCP server — AI agents control a tab in your real browser, already logged in
What tools does Pilot expose?
69 in total: 57 read-only, 8 that write, and 4 that can delete or overwrite (pilot_drag, pilot_frame_reset, pilot_geolocation, pilot_reset). Every one is listed on this page with its risk.
Is Pilot safe to connect to an agent?
No — not without reading the findings first. The audit graded it D (69/100) and found 3 critical or high issues in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 4 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Pilot need?
No credential environment variables were found in its source, so it appears to need none.
How does Pilot run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as pilot-mcp at 0.4.2.
How current is this page?
The grade is for one exact copy of the source (33160f9f22ea), read on 2026-10-08. The repository is watched and re-audited when it changes.