Skip to content
PEN Docs

Tool Reference

PEN ships with 31 tools in 10 categories. Every tool follows MCP conventions: auto-generated inputSchema from Go structs, text output, and isError: true on failure.

Workflow (1 tool)

pen_workflow

Run a guided PEN workflow without manually chaining the underlying tools.

ParamTypeDefaultDescription
namestringWorkflow name: slow-page-triage, js-bloat-check, or accessibility-pass
urlstringcurrent pageOptional URL to navigate to before the workflow runs
waitMsint3000Milliseconds to wait for settling and vitals collection
durationint5Optional CPU profiling duration in seconds for performance workflows
selectorstringOptional selector used by accessibility-pass

pen_workflow reuses typed helpers from network capture, JS coverage, Web Vitals, CPU profiling, and accessibility scanning. It returns a workflow verdict, key findings, workflow notes when some evidence could not be collected, and recommended next steps.


Memory (4 tools)

pen_heap_snapshot

Take a V8 heap snapshot. Streamed to disk, so even massive heaps won't blow up memory.

ParamTypeDefaultDescription
forceGCbooltrueForce GC before snapshot
includeDOMboolfalseInclude detached DOM node analysis
maxDepthint3Retained size analysis depth (1–10)

CDP: HeapProfiler.takeHeapSnapshot, addHeapSnapshotChunk events. Exclusive lock. Rate limit: 10s cooldown. Hard cap: 2 GB — snapshots exceeding this limit are aborted with a suggestion to use pen_heap_sampling.

pen_heap_diff

Compare two snapshots to spot memory growth. Shows size delta, percentage change, and a qualitative assessment (minimal / moderate / significant / large growth — likely a memory leak).

ParamTypeRequiredDescription
snapshotAstringyesID of first snapshot
snapshotBstringyesID of second snapshot

pen_heap_track

Toggle heap allocation tracking for leak detection over time.

ParamTypeDefaultDescription
actionstring"start" or "stop"
trackAllocationsbooltrueTrack allocation stacks

CDP: HeapProfiler.startTrackingHeapObjects / stopTrackingHeapObjects.

pen_heap_sampling

Toggle sampling-based heap profiling. Lower overhead than full snapshots.

ParamTypeDefaultDescription
actionstring"start" or "stop"
samplingIntervalint32768Bytes between samples

CDP: HeapProfiler.startSampling / stopSampling / getSamplingProfile.


CPU (3 tools)

pen_cpu_profile

Record a CPU profile and surface the hottest functions.

ParamTypeDefaultDescription
durationint5Seconds to profile (1–30)
sampleRateint100Sampling interval in microseconds (min 10)
topNint20Number of top hotspot functions

CDP: Profiler.start / stop. Exclusive lock.

pen_capture_trace

Grab a Chrome trace (DevTools Timeline). Streamed to disk via IO.read.

ParamTypeDefaultDescription
durationint5Seconds to trace (1–30)
categories[]stringChrome trace categories

Default categories: devtools.timeline, v8.execute, blink.user_timing, loading, latencyInfo, disabled-by-default-devtools.timeline. Exclusive lock. Rate limit: 5s cooldown. Hard cap: 500 MB — traces exceeding this limit are aborted.

pen_trace_insights

Crunch a previously captured trace file. Pulls out long tasks (>50ms), CLS, LCP, slowest resources, and frame timing.

ParamTypeDefaultDescription
filestringPath to trace JSON file (from pen_capture_trace)
topNint10Number of top items per category

Max file size: 100 MB. Supports both {"traceEvents":[...]} wrapper and plain array formats.


Network (4 tools)

pen_network_enable

Start capturing network requests.

ParamTypeDefaultDescription
disableCachebooltrueDisable browser cache
clearFirstbooltrueClear previously captured data

CDP: Network.enable.

pen_network_waterfall

Show captured network requests as a waterfall table.

ParamTypeDefaultDescription
sortBystring"time"Sort: time, size, status, duration
filterstringFilter by MIME type prefix
statusFilterstringFilter by status: 4xx, 5xx, error (all failures), or exact code like 404
urlFilterstringFilter by URL substring (case-insensitive)
limitint50Max entries

Large assets flagged at 100 KB threshold.

pen_network_request

Get details of a specific captured network request.

ParamTypeDescription
urlPatternstringURL substring to match
requestIDstringExact request ID from waterfall

pen_network_blocking

Identify render-blocking resources. No parameters. Returns synchronous scripts and blocking stylesheets.


Coverage (2 tools)

pen_js_coverage

Collect JavaScript code coverage: per-function byte ranges, used vs unused percentages.

ParamTypeDefaultDescription
callCountbooltrueInclude per-function call counts
detailedboolfalseBlock-level coverage granularity
navigatestringURL to navigate to before collecting
topNint20Top N scripts by unused bytes

CDP: Profiler.startPreciseCoverage / stopPreciseCoverage.

pen_css_coverage

Collect CSS rule usage: which rules were applied vs unused.

ParamTypeDefaultDescription
navigatestringURL to navigate to for full-page CSS
topNint20Top N stylesheets by unused rules

CDP: CSS.startRuleUsageTracking / stopRuleUsageTracking.


Audit (3 tools)

pen_performance_metrics

Grab real-time performance counters (instant, no profiling needed). No parameters.

CDP: Performance.getMetrics. Returns JSHeapUsedSize, Nodes, LayoutCount, RecalcStyleCount, ScriptDuration, TaskDuration, etc.

pen_web_vitals

Capture Core Web Vitals (LCP, CLS, INP estimate).

ParamTypeDefaultDescription
waitMsint3000Milliseconds to wait for metric collection to stabilize

CDP: Runtime.evaluate with PerformanceObserver entries.

pen_accessibility_check

Quick accessibility sweep: missing alt text, unlabeled inputs, contrast problems, ARIA violations.

ParamTypeDescription
selectorstringCSS selector to scope (default: entire page)

CDP: DOM, Runtime.


Source (3 tools)

pen_list_sources

List every parsed JS source in the page.

ParamTypeDefaultDescription
refreshboolfalseRe-enable debugger for fresh list
filterstringFilter by URL substring

CDP: Debugger.enable, scriptParsed events. Reports source map URLs as metadata (does not fetch or parse source maps).

pen_source_content

Fetch the source of a specific script.

ParamTypeDefaultDescription
scriptIDstringScript ID from pen_list_sources
urlPatternstringURL substring (first match)
maxLinesint200Truncate after N lines

CDP: Debugger.getScriptSource. You get the code as V8 sees it — bundled or minified if that's what's loaded.

pen_search_source

Search across all loaded scripts for a string or regex pattern.

ParamTypeDefaultDescription
querystringSearch query (required)
isRegexboolfalseTreat query as regex
caseSensitiveboolfalseCase-sensitive search
maxResultsint50Max results across scripts

CDP: Debugger.searchInContent.


Console (2 tools)

pen_console_enable

Start capturing console output and exceptions. Call this before pen_console_messages.

ParamTypeDefaultDescription
clearFirstboolfalseClear existing messages before starting

CDP: Runtime.enable. Registers listeners for Runtime.consoleAPICalled and Runtime.exceptionThrown events. Idempotent — safe to call multiple times (uses consoleListenerOnce).

pen_console_messages

List captured console messages with level, text, source URL, and timestamp.

ParamTypeDefaultDescription
levelstringFilter: error, warning, log, info, debug
textFilterstringFilter by case-insensitive substring match on message text
lastintallReturn only the N most recent messages (max 200)
clearboolfalseClear messages after reading

Buffers up to 1,000 messages. When full, the oldest 100 entries are evicted. Text truncated at 2,000 characters. Stack traces included for errors.


Lighthouse (1 tool)

pen_lighthouse

Run a full Lighthouse audit. Needs the Lighthouse CLI (npm install -g lighthouse).

ParamTypeDefaultDescription
categories[]string["performance","accessibility","best-practices","seo"]Categories to audit
urlstringcurrent pageURL to audit

Allowed categories: performance, accessibility, best-practices, seo, pwa. Lighthouse connects to Chrome through the same CDP port PEN uses — no extra browser.


Utility (8 tools)

pen_status

Show PEN server status. No parameters. Returns connection state, version, active target, config, runtime memory stats, and currently active operations (which tools hold domain locks and for how long).

pen_list_pages

List all open browser tabs with URLs, titles, and target IDs. No parameters.

pen_select_page

Point PEN at a different tab.

ParamTypeDescription
targetIdstringTarget ID from pen_list_pages
urlPatternstringURL substring to match

pen_navigate

Navigate the current page: go to a URL, back, forward, or reload.

ParamTypeDefaultDescription
actionstringgoto, back, forward, or reload (required)
urlstringURL (required when action is goto)
waitint2Seconds to wait after navigation (0–30)

URL validation blocks dangerous schemes (javascript:, data:, file:, chrome:, about:, ftp:, ws:, wss:, blob:, vbscript:). Only HTTP and HTTPS get through. Forward navigation uses Page.getNavigationHistory + Page.navigateToHistoryEntry.

pen_collect_garbage

Force V8 garbage collection. No parameters. Rate limit: 5s cooldown.

pen_screenshot

Snap a screenshot of the current page or a specific element.

ParamTypeDefaultDescription
selectorstringCSS selector for element capture
fullPageboolfalseFull page capture
formatstring"png"png, jpeg, or webp
qualityint0–100 for jpeg/webp

Returns base64-encoded image in mcp.ImageContent.

pen_emulate

Set device emulation: CPU throttling, network throttling, viewport presets.

ParamTypeDescription
devicestringPreset: iPhone 14, Pixel 7, iPad
cpuThrottlingfloat64CPU slowdown factor (e.g., 4 = 4x slower)
networkThrottlingstringslow-3g, 3G, 4G, WiFi, or offline

Network presets: slow-3G (2000ms latency, 50KB/s), 3G (563ms latency, 188KB/s), 4G (170ms, 500KB/s), WiFi (2ms, 3.75MB/s), offline (no connectivity). Settings persist until browser restart — affects all subsequent measurements.

pen_evaluate

Run JavaScript in the page context. Requires the --allow-eval flag.

ParamTypeDefaultDescription
expressionstringJS expression (required)
returnByValuebooltrueReturn result by value

Gated by --allow-eval flag and an expression blocklist. See Security.


Rate Limits

ToolCooldownReason
pen_heap_snapshot10sHeavy GC + disk I/O
pen_capture_trace5sExclusive Tracing domain
pen_collect_garbage5sV8 GC is expensive

All other tools: no cooldown.

Tool Chaining

Tools produce IDs consumed by downstream tools:

ProducerConsumerID Type
pen_heap_snapshotpen_heap_diffSnapshot ID
pen_list_pagespen_select_pageTarget ID
pen_network_waterfallpen_network_requestRequest ID
pen_list_sourcespen_source_content, pen_search_sourceScript ID
pen_capture_tracepen_trace_insightsTrace File Path
pen_console_enablepen_console_messages— (implicit)

IDs stay valid until PEN restarts or the underlying thing goes away (tab closed, page navigated, etc.).