MCP server that connects AI assistants to Chrome DevTools. Ask your AI to profile a page, find a memory leak, or measure coverage — PEN runs the browser profiling and returns structured results.
Single Go binary. No Node.js. No browser launch. Attach to your dev browser and go.
Quick install (recommended):
# macOS / Linux
curl -fsSL https://raw.githubusercontent.com/edbnme/pen/main/install.sh | sh
# Windows (PowerShell)
irm https://raw.githubusercontent.com/edbnme/pen/main/install.ps1 | iexThen run the interactive setup wizard:
pen initPackage managers:
# macOS / Linux
brew install edbnme/tap/pen
# Windows
scoop bucket add pen https://github.com/edbnme/scoop-pen
scoop install penOther options:
# Download binary from GitHub Releases (all platforms)
# → https://github.com/edbnme/pen/releases/latest
# Or install with Go 1.23+
go install github.com/edbnme/pen/cmd/pen@latestVerify it works:
pen --versionMore install methods (from source, manual binary setup): docs/INSTALL.md
The fastest way to get going is the interactive setup wizard:
pen initThis auto-detects your environment, lets you pick your IDE and browser, generates the MCP config, and optionally launches your browser with debugging — all in one command.
If you prefer to configure things by hand:
1. Launch a debug browser — PEN can do this automatically:
pen --auto-launchThis detects an installed browser, launches it with a separate debug profile (your existing browser stays untouched), and connects via CDP. No need to close your browser or manage anything manually.
Prefer to launch Chrome yourself?
Use --user-data-dir so it doesn't conflict with your existing browser:
macOS:
open -a "Google Chrome" --args --remote-debugging-port=9222 --user-data-dir=/tmp/pen-debug-profile --no-first-runWindows (PowerShell):
& "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="$env:TEMP\pen-debug-profile" --no-first-runLinux:
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/pen-debug-profile --no-first-run &Verify the debug port is open — visit http://localhost:9222/json in a new tab. You should see a JSON array.
Why
--user-data-dir? Chrome's debug port flag is silently ignored when Chrome is already running.--user-data-dirforces a separate instance that works alongside your existing browser.
VS Code — create .vscode/mcp.json in your project:
{
"servers": {
"pen": {
"command": "pen",
"args": ["--auto-launch", "--project-root", "${workspaceFolder}"]
}
}
}Cursor — .cursor/mcp.json in your project (or ~/.cursor/mcp.json for global):
{
"mcpServers": {
"pen": {
"command": "pen",
"args": ["--auto-launch", "--project-root", "${workspaceFolder}"]
}
}
}Claude Desktop — config path:
{
"mcpServers": {
"pen": {
"command": "pen",
"args": ["--auto-launch", "--project-root", "/absolute/path/to/project"]
}
}
}Open a page in the debug browser, then ask your AI:
"Check the performance metrics of this page"
PEN connects to the browser, runs the profiling, and returns structured results.
| Flag | Default | Purpose |
|---|---|---|
--cdp-url |
http://localhost:9222 |
CDP endpoint |
--transport |
stdio |
stdio, http, or sse |
--addr |
localhost:6100 |
Bind address for HTTP/SSE |
--allow-eval |
false |
Enable pen_evaluate (runs JS in browser) |
--project-root |
. |
Sandbox for source file paths |
--stateless |
false |
Stateless HTTP mode (no session tracking) |
--log-level |
info |
debug / info / warn / error |
--version |
— | Print version and exit |
30 tools across 9 categories:
| Category | Tools |
|---|---|
| Performance | pen_performance_metrics · pen_web_vitals · pen_accessibility_check |
| Memory | pen_heap_snapshot · pen_heap_diff · pen_heap_track · pen_heap_sampling |
| CPU | pen_cpu_profile · pen_capture_trace · pen_trace_insights |
| Network | pen_network_enable · pen_network_waterfall · pen_network_request · pen_network_blocking |
| Coverage | pen_js_coverage · pen_css_coverage |
| Source | pen_list_sources · pen_source_content · pen_search_source |
| Console | pen_console_enable · pen_console_messages |
| Lighthouse | pen_lighthouse |
| Utility | pen_status · pen_list_pages · pen_select_page · pen_navigate · pen_collect_garbage · pen_screenshot · pen_emulate · pen_evaluate |
Full schemas: docs/spec/08-tool-catalog.md
AI Assistant ◄── stdio/JSON-RPC ──► PEN (Go) ── CDP/WebSocket ──► Chrome (localhost:9222)
cmd/pen/ Entry point, flags, signals
internal/
cdp/ CDP connection, target management
server/ MCP server, locking, progress
tools/ Tool handlers (one file per category)
format/ Output formatting
security/ Validation, rate limiting, temp files
New in this release: console.go (real-time console capture via Runtime CDP domain), lighthouse.go (Lighthouse CLI integration), pen_navigate in utility.go (browser navigation control), and pen_trace_insights in cpu.go (offline trace analysis engine).
- Localhost only — rejects remote CDP URLs
- No browser launch — attaches to existing browser
- Eval gated —
pen_evaluateneeds--allow-eval - Expression blocklist — blocks
fetch,document.cookie,eval, etc. even with eval on - Path sandboxing — source tools can't escape
--project-root - Temp isolation — snapshots/traces go to
$TMPDIR/pen/with0600perms - Rate limiting — cooldowns on heap snapshots, traces, and other heavy ops
- Size caps — 2 GB max heap snapshot, 500 MB max trace capture
- Graceful shutdown — 5-second grace period for in-progress operations on SIGINT/SIGTERM
| Doc | What's in it |
|---|---|
| Getting Started | Install, browser setup, IDE config |
| Running PEN | Usage, Docker, server deploys, troubleshooting |
| Tool Catalog | Every tool's params and output |
| Security Model | Threat model, defenses |
| System Architecture | Design and tech stack |