ultimate-playwright-mcp
Provides browser automation capabilities for Google Chrome, enabling control of tabs, navigation, clicks, form filling, and checkpoint captures through a shared Chrome instance with multi-agent tab isolation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@ultimate-playwright-mcp open a new tab and navigate to example.com"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Ultimate Playwright MCP
Multi-agent Playwright MCP server with tab isolation via targetId. Allows multiple Claude instances (or other MCP clients) to share a single Chrome browser while maintaining isolated tab groups.
Why Ultimate Playwright?
The official @playwright/mcp gives you browser control for a single agent. But what if you have multiple agents sharing one browser?
Ultimate Playwright MCP solves this with tab group isolation:
š Multi-agent tab groups ā Each agent creates a
groupIdand only sees its own tabsšŖ Shared cookies & sessions ā All agents share the same BrowserContext (log in once, everyone's authenticated)
šØ Visual Chrome tab groups ā Companion extension organizes tabs into color-coded Chrome tab groups
š¾ Persistent registry ā Tab groups survive MCP server restarts (
~/.ultimate-playwright-mcp/tab-groups.json)š Connect to existing Chrome ā Uses CDP to attach to your running Chrome (keeps your profile, extensions, bookmarks)
Comparison
Feature | ultimate-playwright-mcp | @playwright/mcp | browser-use-mcp |
Multi-agent tab isolation | ā
Tab groups with | ā Single session | ā Single session |
Shared cookies across agents | ā Same BrowserContext | N/A | N/A |
Connect to existing Chrome | ā CDP | ā Launches new browser | ā Launches new browser |
Visual tab groups in Chrome | ā Extension | ā | ā |
Persistent tab registry | ā Survives restarts | ā | ā |
Accessibility tree snapshots | ā Element refs (e1, e2ā¦) | ā | ā Screenshot-based |
Open source | ā MIT | ā Apache-2.0 | ā MIT |
Related MCP server: playwright-mcp-orchestrator
Features
ā Tab Isolation - Each agent gets its own tabs via unique
targetIdā Shared Cookies - All agents share the same BrowserContext (cookies, sessions, localStorage)
ā Parallel Execution - Multiple agents can operate simultaneously without interference
ā CDP Connection - Connects to existing Chrome via Chrome DevTools Protocol
ā Native Page Checkpoints - Capture structured artifacts and generate reports per
targetIdā Battle-Tested - Extracted from OpenClaw (MIT licensed)
Installation
npm install -g ultimate-playwright-mcpOr run directly with npx:
npx ultimate-playwright-mcp --cdp-endpoint http://localhost:9222Quick Start
1. Launch Chrome with Remote Debugging
# macOS
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome \
--remote-debugging-port=9222 \
--user-data-dir=/tmp/chrome-debug
# Linux
google-chrome --remote-debugging-port=9222 --user-data-dir=/tmp/chrome-debug
# Windows
"C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe" ^
--remote-debugging-port=9222 ^
--user-data-dir=C:\\temp\\chrome-debug2. Configure Claude Desktop
Add to ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"ultimate-playwright": {
"command": "npx",
"args": [
"ultimate-playwright-mcp",
"--cdp-endpoint",
"http://localhost:9222"
]
}
}
}3. Restart Claude Desktop
Claude will now have access to browser control tools with tab isolation.
Usage Example
User: Open two tabs and navigate them independently
Claude: I'll create two tabs with separate targetIds:
1. browser_tabs({ action: "new" })
ā **targetId: ABC123...**
2. browser_tabs({ action: "new" })
ā **targetId: XYZ789...**
3. browser_navigate({ targetId: "ABC123...", url: "https://github.com" })
4. browser_navigate({ targetId: "XYZ789...", url: "https://google.com" })
Both tabs are now navigated independently!Available Tools
Tool | Description | Key Parameters |
| Create/list/delete tab groups for isolation |
|
| List, create, close, or select tabs |
|
| Navigate to a URL |
|
| Capture accessibility tree with refs |
|
| Click an element |
|
| Type text into an element |
|
| Hover over an element |
|
| Press a keyboard key |
|
| Fill multiple form fields |
|
| Wait for conditions |
|
| Capture a structured checkpoint for a tab |
|
| Generate reports from stored checkpoints |
|
Checkpoints
Use browser_checkpoint when you want a persisted capture of the current page for later review or report generation.
Checkpoints are scoped to the resolved
targetId, so they work with this server's tab isolation model.Artifacts and manifests are written under
~/.ultimate-playwright-mcp/checkpointsby default.Generated reports are written under
~/.ultimate-playwright-mcp/checkpoints/report.
Example:
1. browser_checkpoint({ targetId: "ABC123", name: "after-login" })
2. browser_checkpoint_report({ format: "html" })Tab Groups (Multi-User Isolation)
When multiple users or agents share one browser instance, tab groups keep everyone's tabs isolated. Each session creates its own group, and all tab operations are scoped to that group.
User: Research product pricing
Claude: I'll create a tab group first, then open tabs within it.
1. browser_tab_group({ action: "create", name: "pricing-research", color: "blue" })
ā **groupId: g_a1b2c3d4e5f6**
2. browser_tabs({ action: "new", groupId: "g_a1b2c3d4e5f6", url: "https://example.com/pricing" })
ā **targetId: ABC123...**
3. browser_tabs({ action: "list", groupId: "g_a1b2c3d4e5f6" })
ā Only shows tabs in this group (not other users' tabs)Meanwhile, another user on the same server:
1. browser_tab_group({ action: "create", name: "docs-review", color: "green" })
ā **groupId: g_x9y8z7w6v5u4**
2. browser_tabs({ action: "new", groupId: "g_x9y8z7w6v5u4", url: "https://docs.example.com" })
ā **targetId: XYZ789...**Both users share the same cookies/sessions but only see their own tabs!
Tab Group Lifecycle
Create a group at the start of your session
Open tabs within the group using
groupIdWork with tabs using
targetIdas beforeDelete the group when done (optionally closes all tabs)
Group state is persisted to ~/.ultimate-playwright-mcp/tab-groups.json so it
survives MCP server restarts.
Architecture
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Single Chrome Process ā
ā (--remote-debugging-port=9222) ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
ā ā Single BrowserContext ā ā
ā ā (shared cookies, storage) ā ā
ā ā ā ā
ā ā Group: alice (blue) ā ā
ā ā āāāāāāā āāāāāāā ā ā
ā ā ā Tab ā ā Tab ā ā ā
ā ā ā A ā ā B ā ā ā
ā ā āāāāāāā āāāāāāā ā ā
ā ā ā ā
ā ā Group: bob (green) ā ā
ā ā āāāāāāā āāāāāāā āāāāāāā ā ā
ā ā ā Tab ā ā Tab ā ā Tab ā ā ā
ā ā ā C ā ā D ā ā E ā ā ā
ā ā āāāāāāā āāāāāāā āāāāāāā ā ā
ā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā
CDP Connection
ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ultimate-playwright-mcp (MCP Server) ā
ā - Tab routing via targetId ā
ā - Tab groups via groupId ā
ā - Shared ownership registry (JSON file) ā
ā - Stdio transport ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā ā
āāāāāāāāāāā āāāāāāāāāāā āāāāāāāāāāā
ā Alice ā ā Bob ā ā Charlie ā
ā (Claude)ā ā (Claude)ā ā (Cursor)ā
āāāāāāāāāāā āāāāāāāāāāā āāāāāāāāāāāMCP Configuration
Cursor / Windsurf / Generic MCP Client
{
"mcpServers": {
"ultimate-playwright": {
"command": "npx",
"args": ["ultimate-playwright-mcp", "--cdp-endpoint", "http://localhost:9222"]
}
}
}With Environment Variable
{
"mcpServers": {
"ultimate-playwright": {
"command": "npx",
"args": ["ultimate-playwright-mcp"],
"env": {
"CDP_ENDPOINT": "http://localhost:9222"
}
}
}
}CLI Options
ultimate-playwright-mcp [options]
Options:
--cdp-endpoint <url> CDP endpoint URL (e.g., http://localhost:9222)
Can also use CDP_ENDPOINT env var.
If omitted, daemon-managed Chrome is started lazily on first tool call.
--agent-id <id> Optional agent ID for logging/debugging
Can also use AGENT_ID env var
--keep-alive Auto-restart daemon-managed Chrome if it exits
Use --no-keep-alive for testing workflows where you want Chrome to stay down after kill
Default: disabled (no auto-restart)
Can also use KEEP_ALIVE env var (set to "false" to disable)
--checkpoint-output-dir <path>
Root directory for checkpoint manifests, artifacts, and reports
Can also use CHECKPOINT_OUTPUT_DIR env var
-V, --version Output version number
-h, --help Display helpMulti-Agent Setup
Running Multiple Claude Code Instances
Each instance connects to the same MCP server and gets isolated tabs:
Terminal 1:
claude-code --mcp-config ./mcp-config.json
# Agent A creates tabs with targetIds starting from ABC...Terminal 2:
claude-code --mcp-config ./mcp-config.json
# Agent B creates tabs with targetIds starting from XYZ...Both agents share cookies and sessions but operate on different tabs!
Persistent Chrome Setup (macOS)
For a Chrome instance that auto-starts with debug port:
Create ~/Library/LaunchAgents/com.user.chrome-debug.plist:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.user.chrome-debug</string>
<key>ProgramArguments</key>
<array>
<string>/Applications/Google Chrome.app/Contents/MacOS/Google Chrome</string>
<string>--remote-debugging-port=9222</string>
<string>--user-data-dir=/Users/YOUR_USERNAME/chrome-debug-profile</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<true/>
</dict>
</plist>Load with:
launchctl load ~/Library/LaunchAgents/com.user.chrome-debug.plistDevelopment
# Install dependencies
npm install
# Build
npm run build
# Type check
npm run type-check
# Lint
npm run lint
# Watch mode
npm run watchLicense
MIT
Attribution
This project extracts browser control code from OpenClaw (MIT licensed), which provides battle-tested tab isolation and Playwright integration.
Key extracted components:
CDP session management (
pw-session.ts)Browser operations (
pw-tools-*.ts)Role-based element refs (
pw-role-snapshot.ts)
Links
OpenClaw - Source of browser control code
MCP Specification - Model Context Protocol
Playwright - Browser automation library
Available Tools
14 toolsbrowser_checkpointC
Capture a structured checkpoint for the current page or a specific tab. Stores checkpoint artifacts and a manifest under the server-managed checkpoint directory.
Inputs: name (required), targetId, description, highlightSelector, +2 more.
browser_checkpoint_reportA
Generate an HTML, Markdown, or MDX report from stored MCP checkpoint manifests.
Inputs: format, resultsDir.
browser_clickB
Click an element by its ref (e1, e2, etc. from snapshot)
Inputs: ref (required), targetId, button, doubleClick.
browser_evaluateA
Execute JavaScript in the page context via Playwright's page.evaluate(). Use for interacting with elements not in the accessibility snapshot (portal divs, framework overlays, shadow DOM). Can run arbitrary JS ā click hidden elements, extract data, manipulate the DOM. Optionally scope to a specific element via ref.
Inputs: expression (required), ref, targetId.
browser_fill_formA
Fill multiple form fields at once
Inputs: fields (required), targetId.
browser_hoverC
Hover over an element
Inputs: ref (required), targetId.
browser_press_keyC
Press a keyboard key
Inputs: key (required), targetId.
browser_screenshotA
Take a screenshot of the current page or a specific element. By default saves to file and returns the path (saves context window tokens). Use ref to screenshot a specific element (from snapshot refs like e1, e2), or element for a CSS selector. Omit both for a full page screenshot.
Inputs: targetId, ref, element, fullPage, +5 more.
browser_snapshotA
Capture accessibility tree snapshot of the current page. Returns element references (e1, e2, etc.) that can be used with other browser tools like click, type, etc.
Inputs: targetId, maxChars, compact, interactive, +1 more.
browser_tab_groupA
Manage tab groups for session isolation. Multiple users/agents sharing one browser MUST create a tab group first, then pass the groupId to browser_tabs and other tools. This ensures each session only sees and controls its own tabs.
Actions:
'create': Create a new tab group. Returns a groupId to use with all other browser tools.
'list': List all tab groups with tab counts.
'delete': Delete a tab group and optionally close its tabs.
ā” IMPORTANT: Always create a tab group before opening tabs with browser_tabs.
Inputs: action (required), name, color, groupId, +1 more.
browser_tabsA
Manage browser tabs. When using tab groups (recommended for multi-user), pass groupId to scope operations to your group's tabs only.
Actions:
'list': Show tabs. With groupId ā only your group's tabs. Without ā all tabs.
'new': Create a tab. If groupId is provided, the tab is added to that group.
'close': Close a tab by index or targetId.
'select': Focus a tab by index or targetId.
ā” IMPORTANT: Create a tab group first for multi-user isolation. Ungrouped tabs remain available as a fallback for local manual testing.
Inputs: action (required), groupId, url, index, +1 more.
browser_typeC
Type text into an element
Inputs: ref (required), text (required), targetId, submit.
browser_wait_forB
Wait for a condition (text, selector, load state, time, etc.)
Inputs: text, textGone, selector, url, +3 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelogā¦
TDQS
Scored across 14 tools
Each tool serves a distinct browser automation action (e.g., click, type, navigate, snapshot). Potential overlaps like browser_click vs. browser_hover are clearly differentiated by operation type, and browser_evaluate handles cases outside the snapshot tree.
All tools follow a consistent 'browser_verb_noun' pattern using snake_case. For example, browser_click, browser_navigate, browser_tab_group. No mixing of conventions.
With 14 tools, the server covers core browser automation tasks without being bloated. The count feels well-scoped for its purpose.
The tool set covers essential browser actions (navigation, interaction, snapshot, screenshots, tabs, checkpoints). Minor gaps exist, such as no explicit scroll or file upload, but these are advanced and not critical for most automation workflows.
Maintenance
Related MCP Connectors
Official Browserless MCP server: browser automation, scraping, screenshots and PDFs for AI agents.
Hosted Web Crawler MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Web scraping, browser automation, screenshots and AI data extraction for AI agents via MCP.
MCP server for building and testing AI agents with multi-model experimentation and insights.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceA Playwright-based MCP server that exposes a live browser as a traceable, inspectable, debuggable and controllable execution environment for AI agents.5,213 npm57-
- AlicenseNot gradedqualityDmaintenanceA multi-agent orchestrator that enables multiple AI agents to share a single Chrome browser instance with tab isolation and shared state. It preserves local browser data like cookies and logins while allowing concurrent agent sessions through the official Playwright MCP.10MIT
- AlicenseNot gradedqualityDmaintenanceMCP server enabling AI agents to control and inspect Chrome/Arc browsers via DevTools, with Arc-specific tab reuse.12 npm1Apache 2.0
- AlicenseAqualityCmaintenanceAn MCP server that runs concurrent, session-isolated Playwright browser contexts, so many agents can each drive their own browser at the same time without colliding.2311 npm5MIT