# cdpilot
> Zero-dependency browser automation from your terminal. One command, full control.
[](https://www.npmjs.com/package/cdpilot)
[](https://www.npmjs.com/package/cdpilot)
[](LICENSE)
[](https://nodejs.org)
[](https://modelcontextprotocol.io)
[](https://glama.ai/mcp/servers/mehmetnadir/cdpilot)
## Quick Start
```bash
npx cdpilot launch # Start browser with CDP
npx cdpilot go https://example.com
npx cdpilot shot # Take screenshot
```
No config files. No boilerplate. Just `npx` and go.
## Why cdpilot?
AI agents and developers need browser control that **just works**:
- **Zero config** — `npx cdpilot launch` starts an isolated browser session
- **Zero dependency** — No Puppeteer, no Playwright, no Selenium. Pure CDP over HTTP
- **70+ commands** — Navigate, click, type, screenshot, network, console, accessibility, video understanding, progressive anti-bot resilience, and more
- **AI-agent friendly** — Designed for Claude, GPT, Gemini, and any LLM tool-use workflow
- **Isolated sessions** — Your personal browser stays untouched. cdpilot runs in its own profile
- **Visual feedback** — Green glow overlay, cursor visualization, click ripples, and keystroke display keep you informed during automation
- **Multi-project isolation** — Each project gets its own browser instance and port automatically, no conflicts
- **AI control warning** — Red toast notification appears when you hover during active automation
- **Privacy-first** — Everything runs locally. No data leaves your machine
### Browser Selection (Workload-Aware Auto-Pick)
cdpilot picks the right browser for what you're doing. `auto` (default) is a
two-axis policy — extension workload × platform stability:
| Your workload | Auto-pick order |
|---|---|
| Has extensions registered (`ext-install`) | vivaldi → brave → edge → chromium → chrome (→ Chrome for Testing, if installed) |
| No extensions (pure automation) | chrome → vivaldi → edge → chromium → brave |
Override anytime:
```bash
cdpilot browser # show current pick + reason
cdpilot browser vivaldi # pin to Vivaldi
cdpilot browser chrome-for-testing # pin to Chrome for Testing (after installing it, below)
cdpilot browser auto # restore smart default
```
**Why the split?**
- **Chrome 137+ silently drops `--load-extension`** for unpacked extensions
(no error, no warning) — Google removed it from branded Chrome builds
([PSA](https://groups.google.com/a/chromium.org/g/chromium-extensions/c/1-g8EFx2BBY/m/S0ET5wPjCAAJ)).
Verified — `chrome://extensions` shows 0 items.
- **Vivaldi, Brave, Edge, Chromium and Chrome for Testing** honor `--load-extension` (tested).
- On **macOS 26 (Tahoe)** Brave 1.89 crashes deterministically at ~7min
uptime (SIGTRAP in ThreadPoolForegroundWorker). cdpilot detects the OS
and demotes Brave automatically until a fixed Brave release ships.
Each browser gets its own isolated profile (`~/.cdpilot/.../profile-vivaldi`
etc.) so switching never causes prefs corruption.
### Extension development: Chrome for Testing
If you develop an extension against Chrome itself, install
[Chrome for Testing](https://developer.chrome.com/blog/chrome-for-testing) (CfT) —
the Chrome team's versioned, non-auto-updating Chrome build for automation, which
still loads unpacked extensions:
```bash
cdpilot browser install chrome-for-testing # latest Stable
cdpilot browser install chrome-for-testing --channel beta # stable | beta | dev | canary
cdpilot browser install chrome-for-testing --version 154 # a milestone, or a full version (154.0.8037.57)
cdpilot ext-install ./my-extension/ # register your unpacked extension
cdpilot browser status # shows the CfT version and path
```
- **Download only on that command.** It is a one-time ~150-190 MB zip (mac-arm64 at
154.0.8037.57: 191,429,663 bytes); cdpilot never fetches it by itself. The build comes
from the official [CfT JSON endpoints](https://googlechromelabs.github.io/chrome-for-testing/)
(`last-known-good-versions-with-downloads.json`, per-version and per-milestone files).
Those list URLs only, no hash, so the download is checked against the server's
`Content-Length` and its `x-goog-hash` md5; the zip's SHA-256 is recorded.
- It is extracted to `$CDPILOT_HOME/browsers/chrome-for-testing//` (on macOS the
quarantine attribute is cleared on that directory only) and recorded in `installed.json`.
- **Used automatically for extension work:** while dev extensions are registered, a
branded Chrome pick (`cdpilot browser chrome`, or `auto` with Chrome the only
extension-capable choice) becomes Chrome for Testing, with one stderr line saying so.
Without CfT installed, `ext-install` on Chrome prints the install command and keeps
Vivaldi/Brave as the alternative. `cdpilot browser chrome-for-testing` selects it
always. An explicit `CHROME_BIN` is never replaced.
- It runs with cdpilot's usual per-project isolated profile (`profile-cft`).
- **It is for extension development and testing — not a stealth browser.** cdpilot
makes no anti-bot claims for it; use your regular browser setup for that.
- **Linux (Ubuntu 23.10+):** AppArmor blocks unprivileged user namespaces, and CfT
(unlike the distro's Chrome package) has no profile allowing them, so it exits at
start. cdpilot prints this hint; allow them with
`sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0`.
## Installation
```bash
# Use directly (no install needed)
npx cdpilot
# Or install globally
npm i -g cdpilot
```
**Requirements:** Node.js 18+, Python 3.10+, and one of: Brave Browser, Google Chrome, or Chromium. (The Python `websockets` module is auto-installed by the pre-flight wizard on first launch.)
### First-time setup
```bash
npx cdpilot setup # Auto-detect browser, create isolated profile
npx cdpilot launch # Start browser with CDP enabled
npx cdpilot status # Check connection
```
### Claude Code plugin marketplace
Install cdpilot's MCP server and its skill straight into Claude Code, no
`.mcp.json` editing required:
```bash
/plugin marketplace add mehmetnadir/cdpilot
/plugin install cdpilot@cdpilot
```
This registers the `cdpilot` MCP server (`npx cdpilot mcp`) and a short skill
that teaches Claude Code when and how to reach for cdpilot's commands. See
[`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json) and
[`plugins/cdpilot/`](plugins/cdpilot/).
### MCP Bundle (.mcpb)
For MCP clients that support one-click local server installation (Claude
Desktop and others), download the `.mcpb` file attached to the
[latest release](https://github.com/mehmetnadir/cdpilot/releases/latest) and
open it, or build it yourself:
```bash
npm run build:mcpb # writes cdpilot.mcpb at the repo root
```
The bundle still needs the same runtime on the machine that runs it: Node.js
18+, Python 3.10+, and Brave/Chrome/Chromium installed. See
[`manifest.json`](manifest.json) for the bundle's MCP Bundle manifest
([spec](https://github.com/modelcontextprotocol/mcpb)).
### Upgrading from 0.4.x → 0.5.0 — read this first
**One breaking change**, the rest is additive.
**Breaking — Visual feedback default flipped to OFF.** The green glow border,
animated fake cursor, click ripples, and keystroke display made cdpilot feel
like an amateur typing on every page. They are now opt-in:
```bash
cdpilot show on # restore the old visual feedback layer
cdpilot show off # default since 0.5.0
```
The MCP server's persistent-glow flow (`CDPILOT_MCP_SESSION=1`) is **unchanged**
— AI agents that rely on visible feedback during a session still see it
automatically. Only direct-CLI users see the difference.
**New in 0.5.0** (no migration needed):
- `cdpilot dismiss` — heuristic auto-click for "Stay signed out / No thanks"
buttons on LLM chat sign-up walls.
- `cdpilot adaptive on` — auto-escalate to stealth on CAPTCHA-protected
hosts, with persistent per-host memory.
- `cdpilot cookies save/load` — export/import cookies as JSON to replay
CF/DataDome clearance across runs.
- `cdpilot context create/list/close` + `CDPILOT_TARGET` — isolated browser
contexts for true parallel automation inside a single browser.
- `cdpilot fast` / `cdpilot show` — bundled timing + visual toggles.
- Pure performance: post-load sleep 1500ms → 300ms, `scrollIntoView` instant,
WebSocket connection pool, `/json` TTL cache.
See [CHANGELOG.md](CHANGELOG.md) for the full list with rationale.
## Commands
### Navigation & Content
```bash
cdpilot go # Navigate to URL (alias: open )
cdpilot content # Get page text content
cdpilot html # Get page HTML
cdpilot shot [file] # Take screenshot (PNG)
cdpilot pdf [file] # Save page as PDF
```
### Interaction
```bash
cdpilot click # Click element
cdpilot type # Type into input
cdpilot fill # Set input value (React-compatible)
cdpilot submit