Skip to content

Latest commit

 

History

209 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

pilot

CI E2E Smoke License GitHub Release npm version

A lightweight Node.js/TypeScript MCP server that gives AI agents DevTools-grade control over a running Chrome instance. Connects to Chrome via the Chrome DevTools Protocol (CDP) and exposes MCP tools for screenshots, navigation, clicks, typing, JavaScript evaluation, and live console/network event monitoring.

Use pilot to open a URL and watch for errors — from any AI agent that speaks MCP.

Prerequisites

  • Node.js: Use the version in .nvmrc. Supported: Node 22 (LTS) or 24 (Active LTS).
  • nvm (Node Version Manager)
  • pnpm package manager (managed via Corepack)
  • pre-commit for Git hooks (optional but recommended)

Install nvm

curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash

After installation, restart your shell (or source your shell profile) so the nvm command is available. See the nvm repository for the latest install script and platform-specific notes.

Install dependencies

nvm install   # installs the version from .nvmrc (Node 24)
nvm use

# Enable Corepack and activate the pnpm version pinned in package.json
corepack enable
corepack prepare --activate

pnpm install

# Optional: Install Git hooks
pre-commit install
pre-commit install --hook-type pre-push

Corepack ships with Node.js and uses the packageManager field in package.json to pin the pnpm version, so every contributor and CI run uses the same one.

Quick Start

# Build
pnpm run build

# Run as MCP server (stdio)
pnpm start

With Docker

To use the MCP server from a Docker container, pass -i so stdin stays open for stdio communication:

docker build -t pilot .
claude mcp add pilot -- docker run -i --rm pilot

Claude Code Integration

Add the MCP server to Claude Code:

# Via npx (no install required)
claude mcp add pilot -- npx @everydaydevopsio/pilot

# Or from a local build
claude mcp add pilot -- node /path/to/pilot/dist/mcp/index.js

Or add to .mcp.json in your project:

{
  "mcpServers": {
    "pilot": {
      "type": "stdio",
      "command": "npx",
      "args": ["@everydaydevopsio/pilot"]
    }
  }
}

MCP Tools

Browser Lifecycle:

Tool Description
browser_start Launch Chrome
browser_stop Stop Chrome

Browser Control:

Tool Description
browser_screenshot Capture viewport or full page screenshot
browser_navigate Navigate to URL and wait for load
browser_click Click element by CSS selector or coordinates
browser_type Type text into focused element or selector
browser_evaluate Execute JavaScript and return result
browser_wait Wait for selector, network idle, or fixed delay
browser_page_info Get current URL, title, and ready state
browser_viewport_resize Resize the viewport to new dimensions at runtime

Error Monitoring:

Tool Description
browser_get_console_logs Get buffered console messages with filters
browser_get_errors Get console errors (and optionally warnings)
browser_clear_errors Clear the console message buffer

Configuration

All configuration via environment variables.

Env var Default Description
PILOT_CDP_PORT 9222 CDP port when connecting to an existing Chrome (ignored when browser_start launches Chrome)
PILOT_CDP_HOST 127.0.0.1 CDP host when connecting to an existing Chrome (ignored when browser_start launches Chrome)
PILOT_LOG_LEVEL info Pino log level
PILOT_CHROME_PATH (auto) Path to Chrome executable
PILOT_HEADLESS false Run Chrome headless. Accepts true/1 or false/0.
PILOT_MCP_BUFFER_SIZE 1000 Console message buffer size
PILOT_PROFILE_NAME profile1 Persistent browser profile name. Profiles are stored under $XDG_DATA_HOME/pilot/<name> (default ~/.local/share/pilot/<name>).
PILOT_RESPONSIVE (preset) Responsive viewport mode. When true, the page uses real window dimensions and reflows on resize. Desktop presets default to true; mobile/tablet presets leave this unset (locked viewport). Set to false to lock the viewport with setDeviceMetricsOverride.
PILOT_CHROME_NO_SANDBOX (auto) Force --no-sandbox on/off. Accepts true/1 or false/0. When unset, the flag is auto-applied only when running as root on Linux. See Chrome sandbox below.

Tip — running headless: By default Chrome opens a visible browser window. To run headless (no visible window), set PILOT_HEADLESS=true or ask the AI agent: "set headless to true" (or "run Chrome headless"). The agent will set PILOT_HEADLESS=true before calling browser_start.

Responsive viewport mode

Desktop presets (desktop, desktop-small) default to responsive mode. In responsive mode, the page uses the real browser window dimensions and reflows naturally when the window is resized — just like a normal browser. This is useful for testing responsive websites where you want the layout to react to window changes.

Mobile and tablet presets use a locked viewport (via setDeviceMetricsOverride) to emulate exact device dimensions regardless of the actual window size.

To lock the viewport on desktop (the old behavior), set responsive: false in browser_start or PILOT_RESPONSIVE=false.

Resizing at runtime

Use browser_viewport_resize to change the viewport dimensions while the browser is running:

browser_viewport_resize({ width: 1024, height: 768 })

This sets both the window size and the rendering viewport, and disables responsive mode so the page stays locked at the specified dimensions. Useful for testing specific breakpoints or device sizes without restarting the browser.

Chrome sandbox

The Chrome renderer sandbox is the primary defense against a compromised page (or page content reaching the agent via prompt injection) running code with the privileges of this process. An AI agent that visits arbitrary URLs is precisely the case where the sandbox matters most, so the server keeps it enabled by default.

--no-sandbox is auto-applied only when the server is running as root on Linux — the most common case where Chrome's user-namespace sandbox fails to initialize. In every other case (non-root user, macOS, Windows, non-root inside a container) the sandbox stays on.

Override the auto-detection with PILOT_CHROME_NO_SANDBOX:

  • PILOT_CHROME_NO_SANDBOX=true — force the flag on (e.g. an environment where the sandbox cannot work and you have accepted the risk).
  • PILOT_CHROME_NO_SANDBOX=false — force the flag off, even when running as root.

When the flag is applied, the server emits a warn-level log on launch so operators can see that the agent is browsing without the renderer sandbox. The safest Docker setup is to run the container as a non-root user with a working Chrome sandbox helper, rather than relying on --no-sandbox.

Testing

# Unit tests
pnpm run test

# With coverage (50% threshold enforced)
pnpm run test:coverage

# MCP E2E tests (requires Chrome installed)
pnpm run test:e2e:mcp

# MCP E2E tests via Docker (no local Chrome needed)
pnpm run test:e2e:mcp:docker

Project Structure

src/
├── browser.ts         # CDP connection + reconnect logic
├── cli/               # CLI commands
│   ├── init.ts        # Init command (creates skill)
│   └── skill-template.ts  # SKILL.md template
├── commands/          # CDP command implementations
│   ├── screenshot.ts
│   ├── navigate.ts
│   ├── click.ts
│   ├── type.ts
│   ├── evaluate.ts
│   ├── wait.ts
│   └── page_info.ts
├── mcp/               # MCP server (sole entry point)
│   ├── index.ts       # Entry point (stdio)
│   ├── server.ts      # MCP server setup
│   ├── console-buffer.ts  # Console message buffer
│   └── tools/
│       ├── browser.ts # Browser control tools
│       └── errors.ts  # Error monitoring tools
└── util/
    ├── config.ts      # Configuration loading
    └── logger.ts      # Pino logger setup

Claude Code Skill

The init command creates a Claude Code skill in your project that automates the browser debugging workflow.

Initialize the Skill

# Using npx (no installation required)
npx @everydaydevopsio/pilot init

# If installed globally
pilot init

# Overwrite existing skill
pilot init --force

This creates .claude/skills/debug-browser/SKILL.md in your project.

Using the Skill

In Claude Code, say "debug in browser" or use /debug-browser. The skill will:

  1. Add the MCP server to your Claude Code session
  2. Call browser_start to launch Chrome
  3. Spawn a background sub-agent to watch for console errors

Error Watching Workflow

  1. Ask Claude: "Use pilot to open localhost:3000 and watch for errors"
  2. Claude clears the error buffer and tells you to proceed
  3. You interact with the app in Chrome
  4. Claude periodically checks for errors and can fix them in your source code

License

MIT License - see LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages