Skip to main content
Glama
SJMakin

even-better-playwright-mcp

by SJMakin

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:

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

  1. Get page structure

    Use: snapshot tool β†’ See all interactive elements with refs
  2. Interact with elements

    Use: execute tool Code: await $('e5').click()
  3. After navigation, refresh refs

    Use: snapshot tool again β†’ Refs are stale after navigation

Visual Automation

  1. Take labeled screenshot

    Use: screenshot tool with withLabels: true β†’ See visual labels overlaid on elements
  2. Identify element from image

    Label shows: "e5" on a button
  3. 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

-
security - not tested
F
license - not found
-
quality - not tested

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/SJMakin/even-better-playwright-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server