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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。