even-better-playwright-mcp
The best of all worlds Playwright MCP server - combining intelligent DOM compression, code execution, visual labels, and advanced DevTools capabilities.
Features
π Full Playwright API - Execute any Playwright code via the execute tool
ποΈ 90%+ DOM Compression - SimHash-based list folding and wrapper removal
π Ref-Based Elements - Stable [ref=e1] identifiers with aria-ref selectors
π Regex Search - Find content in snapshots without re-fetching
π― Visual Labels - Vimium-style overlays for screenshot-based interaction
π§ Advanced DevTools - Debugger, live editor, styles inspection, React source finding
π Sandboxed Execution - Safe VM with scoped file system and module allowlist
Installation
npm install -g even-better-playwright-mcp
Or use directly with npx:
npx even-better-playwright-mcp
Configuration
Add to your MCP client settings (e.g., Claude Desktop's claude_desktop_config.json):
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["even-better-playwright-mcp"]
}
}
}
CLI Options
Usage: even-better-playwright-mcp [options]
Options:
--browser <browser> Browser to use: chromium, firefox, webkit (default: chromium)
--headless Run browser in headless mode (default: false)
--cdp-endpoint <url> Connect to existing browser via CDP endpoint
--user-data-dir <path> Use persistent browser profile directory
-h, --help Show help message
Examples
# Basic usage (launches Chromium in headed mode)
even-better-playwright-mcp
# Use Firefox in headless mode
even-better-playwright-mcp --browser firefox --headless
# Connect to existing Chrome instance
even-better-playwright-mcp --cdp-endpoint ws://localhost:9222
# Use persistent profile
even-better-playwright-mcp --user-data-dir ./browser-profile
Tools
1. snapshot - Get Page Structure
Get compressed accessibility snapshot with ref IDs for element targeting.
Returns: DOM tree with [ref=e1], [ref=e2] etc.
Use refs with execute tool: await $('e1').click()
Call again after navigation (refs become stale).
Options:
Example output:
### Page Info
- URL: https://example.com
- Title: Example Domain
### Accessibility Snapshot
- document [ref=e1]
- heading "Example Domain" [level=1] [ref=e2]
- paragraph [ref=e3]: This domain is for use in illustrative examples...
- link "More information..." [ref=e4]
2. browser_execute - Run Playwright Code
Execute any Playwright code with full API access. This is the main tool for browser automation.
Scope variables:
page - Current Playwright page
context - Browser context
state - Persistent object across calls
$('e5') - Shorthand for page.locator('aria-ref=e5')
accessibilitySnapshot() - Get current page snapshot
Common patterns:
// Navigate
await page.goto('https://example.com')
// Click by ref (from snapshot)
await $('e5').click()
// Fill input
await $('e12').fill('search query')
// Get text
const text = await $('e3').textContent()
// Wait for network
await page.waitForLoadState('networkidle')
// Screenshot
await page.screenshot({ path: 'screenshot.png' })
Advanced - DevTools access:
// Get CDP session for debugging
const cdp = await getCDPSession({ page })
const dbg = createDebugger({ cdp })
// Set breakpoint
await dbg.setBreakpoint({ file: 'app.js', line: 42 })
// Inspect styles
const styles = await getStylesForLocator({ locator: $('e5') })
// Find React component source
const source = await getReactSource({ locator: $('e5') })
// => { fileName: 'Button.tsx', lineNumber: 42 }
Safe modules via require():
path, url, crypto, buffer, util, assert, os, fs (sandboxed)
3. screenshot - Capture Page Image
Capture screenshots with optional visual ref labels.
Options:
ref (string) - Screenshot specific element by ref
fullPage (boolean) - Capture entire scrollable area
withLabels (boolean) - Show Vimium-style ref labels
Label colors by role:
Color | Role |
Yellow | links |
Orange | buttons |
Coral | text inputs |
Pink | checkboxes, radios |
Blue | images, videos |
4. browser_search_snapshot - Search Content
Search the last captured snapshot using regex patterns.
Options:
pattern (string) - Regex pattern to search for
ignoreCase (boolean, default: false) - Case-insensitive matching
lineLimit (number, default: 100) - Maximum lines to return
Example:
Pattern: "button|link"
Result:
- link "Contact Us" [ref=e15]
- button "Submit" [ref=e23]
- link "Privacy Policy" [ref=e31]
Workflow
Basic Automation
Get page structure
Use: snapshot tool
β See all interactive elements with refs
Interact with elements
Use: execute tool
Code: await $('e5').click()
After navigation, refresh refs
Use: snapshot tool again
β Refs are stale after navigation
Visual Automation
Take labeled screenshot
Use: screenshot tool with withLabels: true
β See visual labels overlaid on elements
Identify element from image
Label shows: "e5" on a button
Click using ref
Use: execute tool
Code: await $('e5').click()
Architecture
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β even-better-playwright-mcp β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β CORE β
β βββ aria-ref selector system ([ref=e1], [ref=e2], etc.) β
β βββ page._snapshotForAI() for accessibility snapshots β
β βββ Standard Playwright browser automation β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ENHANCED SNAPSHOT β
β βββ SimHash-based list folding (compress 48 items β 2 lines) β
β βββ Useless wrapper removal β
β βββ Regex-powered content search β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β CODE EXECUTION β
β βββ browser_execute tool (run Playwright code in VM sandbox) β
β βββ Sandboxed require (safe module allowlist) β
β βββ Scoped file system (cwd, /tmp only) β
β βββ Console log capture and forwarding β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β ADVANCED DEVTOOLS β
β βββ Debugger class (breakpoints, step, inspect variables) β
β βββ Editor class (live code editing without reload) β
β βββ Styles inspection (CSS like DevTools panel) β
β βββ React source finding (component file/line locations) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β VISUAL OVERLAYS β
β βββ Vimium-style labels on interactive elements β
β βββ Color-coded by role (links=yellow, buttons=orange, etc.) β
β βββ Screenshot with visible ref labels β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Ref System
All projects use the same ref system built into Playwright:
Snapshots generate refs like [ref=e1]
Selectors use page.locator('aria-ref=e1')
Shorthand $('e1') in execute tool
Important: Refs become stale after navigation. Always call snapshot again after page.goto() or clicking links that navigate.
Compression Algorithm
The snapshot compression achieves ~90% token reduction:
Original DOM (5000+ lines)
β removeUselessWrappers()
β truncateText(50 chars)
β detectSimilarPatterns(SimHash)
β foldLists()
Compressed (<500 lines)
Example:
Before:
- listitem [ref=e234]: Product 1 - Description...
- listitem [ref=e235]: Product 2 - Description...
- listitem [ref=e236]: Product 3 - Description...
... (48 items)
After:
- listitem [ref=e234]: Product 1 - Description...
- listitem (... and 47 more similar) [refs: e235, e236, ...]
Error Handling
The execute tool provides contextual hints:
Stale ref: "Page may have navigated. Refs are stale after navigation. Call snapshot tool to get fresh refs."
Timeout: "Operation timed out. Try increasing timeout or check if element exists/is visible."
Hidden element: "Element may be hidden or covered by another element. Try scrolling or closing overlays."
Connection lost: "Browser connection lost. The browser may have been closed - try again to relaunch."
Development
Building from Source
git clone https://github.com/your-repo/even-better-playwright-mcp
cd even-better-playwright-mcp
npm install
npm run build
Project Structure
even-better-playwright-mcp/
βββ bin/
β βββ cli.ts # CLI entry point with arg parsing
βββ src/
β βββ index.ts # MCP server setup
β βββ browser.ts # Browser/context management
β βββ vm-context.ts # VM sandbox setup
β βββ tools/
β β βββ snapshot.ts # Snapshot tool (compressed)
β β βββ execute.ts # Execute tool (main)
β β βββ screenshot.ts # Screenshot tool (with labels)
β β βββ search.ts # Search tool
β βββ utils/
β β βββ smart-outline.ts # DOM compression
β β βββ list-detector.ts # Pattern detection
β β βββ dom-simhash.ts # SimHash implementation
β β βββ scoped-fs.ts # Sandboxed file system
β β βββ search.ts # Regex search
β βββ devtools/
β β βββ cdp-session.ts # CDP connection
β β βββ debugger.ts # Debugger class
β β βββ editor.ts # Live editor
β β βββ styles.ts # CSS inspection
β β βββ react-source.ts # React locations
β βββ visual/
β βββ aria-labels.ts # Vimium-style overlays
βββ package.json
βββ tsconfig.json
βββ README.md
Acknowledgments
This project combines the best ideas from:
License
MIT