even-better-playwright-mcp
An advanced Playwright MCP server that enables efficient browser automation through compressed accessibility snapshots, sandboxed code execution, and visual element labeling. It features 90% DOM compression and integrated DevTools for deep web inspection and interaction.
README
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
executetool - šļø 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:
compress(boolean, default: true) - Enable smart compression (~90% token reduction)
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 pagecontext- Browser contextstate- Persistent object across calls$('e5')- Shorthand forpage.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 reffullPage(boolean) - Capture entire scrollable areawithLabels(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 forignoreCase(boolean, default: false) - Case-insensitive matchinglineLimit(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:
- better-playwright-mcp - Intelligent DOM compression
- playwriter - Code execution and DevTools
- playwright-mcp - Microsoft's official MCP
License
MIT
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.