Skip to content

edbnme/pen

Repository files navigation

PEN

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.

Install

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 | iex

Then run the interactive setup wizard:

pen init

Package managers:

# macOS / Linux
brew install edbnme/tap/pen

# Windows
scoop bucket add pen https://github.com/edbnme/scoop-pen
scoop install pen

Other 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@latest

Verify it works:

pen --version

More install methods (from source, manual binary setup): docs/INSTALL.md

Quick Start

The fastest way to get going is the interactive setup wizard:

pen init

This 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.

Manual setup

If you prefer to configure things by hand:

1. Launch a debug browser — PEN can do this automatically:

pen --auto-launch

This 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-run

Windows (PowerShell):

& "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222 --user-data-dir="$env:TEMP\pen-debug-profile" --no-first-run

Linux:

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-dir forces a separate instance that works alongside your existing browser.

2. Add PEN to your IDE

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 Desktopconfig path:

{
  "mcpServers": {
    "pen": {
      "command": "pen",
      "args": ["--auto-launch", "--project-root", "/absolute/path/to/project"]
    }
  }
}

3. Use it

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.

Flags

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

Tools

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

Architecture

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).

Security

  • Localhost only — rejects remote CDP URLs
  • No browser launch — attaches to existing browser
  • Eval gatedpen_evaluate needs --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/ with 0600 perms
  • 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

Docs

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

About

MCP server that connects AI assistants to Chrome DevTools.

Resources

Stars

Watchers

Forks

Contributors