| name | playwriter-mcp |
| description | ONLY apply when user EXPLICITLY mentions "Playwriter". Default browser automation is ms-playwright-mcp. |
Playwriter MCP Guide
ACTIVATION: Only use when user explicitly says "Playwriter". Default browser MCP is ms-playwright-mcp by Microsoft.
Rules and usage for Playwriter - Chrome extension + CLI/MCP for real browser automation.
Table of Contents
Core
Workflows
Reference
When to Use Playwriter (vs Playwright MCP)
Use Playwriter when:
- Need existing logged-in sessions (bank, email, social media)
- Want to use your ad blockers, password managers, extensions
- Avoiding automation/bot detection
- Collaborating with AI in real-time (you see what it does)
Use Playwright MCP when:
- Need clean, isolated sessions
- Testing without user state
- Standard automation without auth requirements
Intent Lookup
User wants to...
- Check bank account / pay bills -> Existing session, visual labels,
snapshot({ page })
- Read email / send messages -> Existing Gmail/Outlook session, no re-auth
- Post to social media -> Bypass bot detection, use existing cookies
- Fill government forms -> Use saved passwords, extensions
- Scrape authenticated content -> No login needed, existing cookies
- Debug web app ->
getCDPSession, createDebugger, breakpoints
- Record demo/tutorial ->
startRecording / stopRecording
- Collaborate with AI -> Real-time visibility, can intervene
Technical tasks...
- Get element refs ->
snapshot({ page }) or screenshotWithAccessibilityLabels({ page })
- Take screenshot ->
page.screenshot({ path: '...', type: 'jpeg' })
- Click by ref ->
page.locator('aria-ref=e5').click()
- Persist data ->
state.varName = ...
- Intercept API ->
page.on('response', ...)
- Record session ->
startRecording / stopRecording
MUST-NOT-FORGET
- Install Chrome extension FIRST (from Chrome Web Store)
- Click extension icon on tab to enable control (icon turns green)
- Use single quotes for
-e to prevent bash interpretation
- Never call
browser.close() - it closes YOUR Chrome
- Use
state.varName to persist data between calls
- Green icon = connected, gray = not controlled
- TIMEOUTS: ALWAYS pass timeout (default 20000ms is too long!). Use
1500 for simple ops, 3000 for screenshots.
- NO waitForTimeout inside code - causes stalls. Use proper waits like
waitForSelector instead.
- goto() stalls on SPAs - default
waitUntil: 'load' never fires on SharePoint/dynamic sites. Use { waitUntil: 'domcontentloaded' }.
- click() can stall - if element triggers animation/loading that blocks. Don't click multiple elements in one call.
- After any cancellation - always check connection before proceeding with more operations.
- If stalled, reset won't work - user must restart Chrome or click extension icon again.
Quick Start
npm i -g playwriter
playwriter session new
playwriter -s 1 -e 'await page.goto("https://example.com")'
playwriter -s 1 -e 'console.log(await snapshot({ page }))'
playwriter -s 1 -e 'await page.locator("aria-ref=e5").click()'
CLI Commands
Session Management
playwriter session new
playwriter session list
playwriter session reset <id>
Execute Code
playwriter -s <id> -e '<code>'
Variables in scope: page, context, state, require
Common Workflows
Navigate and Screenshot
playwriter -s 1 -e 'await page.goto("https://example.com")'
playwriter -s 1 -e 'await page.screenshot({ path: "screenshot.png" })'
Screenshot with Visual Labels
playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
playwriter -s 1 -e 'await page.locator("aria-ref=e5").click()'
Persist Data Between Calls
playwriter -s 1 -e "state.users = await page.$$eval('.user', els => els.map(e => e.textContent))"
playwriter -s 1 -e "console.log(state.users)"
Create Isolated Page
playwriter -s 1 -e 'state.myPage = await context.newPage(); await state.myPage.goto("https://example.com")'
Intercept Network Requests
playwriter -s 1 -e "state.requests = []; page.on('response', r => { if (r.url().includes('/api/')) state.requests.push(r.url()) })"
playwriter -s 1 -e "await Promise.all([page.waitForResponse(r => r.url().includes('/api/')), page.click('button')])"
playwriter -s 1 -e "console.log(state.requests)"
Screenshots
playwriter -s 1 -e 'await page.screenshot({ path: "screenshot.png" })'
playwriter -s 1 -e 'await page.screenshot({ path: "full.png", fullPage: true })'
playwriter -s 1 -e 'await page.screenshot({ path: "shot.jpg", type: "jpeg", quality: 80 })'
Visual Labels
Vimium-style labels for AI element identification:
playwriter -s 1 -e 'await screenshotWithAccessibilityLabels({ page })'
playwriter -s 1 -e 'await page.locator("aria-ref=e5").click()'
Color coding:
- Yellow = links
- Orange = buttons
- Coral = inputs
- Pink = checkboxes
- Peach = sliders
- Salmon = menus
- Amber = tabs
Accessibility Snapshot (No Screenshot)
playwriter -s 1 -e 'console.log(await snapshot({ page }))'
Screen Recording [ASSUMED]
playwriter -s 1 -e 'await startRecording({ page, outputPath: "./recording.mp4", frameRate: 30 })'
playwriter -s 1 -e 'await page.click("a")'
playwriter -s 1 -e 'await stopRecording({ page })'
Recording survives page navigation (uses chrome.tabCapture).
MCP Configuration
Skill-based (recommended):
npx -y skills add remorses/playwriter
Direct MCP config:
{
"mcpServers": {
"playwriter": {
"command": "npx",
"args": ["playwriter@latest"]
}
}
}
Troubleshooting
View Logs
playwriter logfile
All Pages Return about:blank
Restart Chrome (known Chrome bug in chrome.debugger API).
Extension Icon Not Turning Green
- Ensure extension installed from Chrome Web Store
- Click directly on extension icon (not right-click menu)
- Try
playwriter session reset <id>
Connection Issues
playwriter session reset <id>
Security
- WebSocket binds to
localhost:19988 only (any local process can connect; use --token for auth)
- Only tabs where you clicked extension icon are controlled
- Chrome shows automation banner on controlled tabs
- Malicious websites cannot connect
Requirements
- Chrome/Chromium browser
- Node.js 18+ with npm
- Playwriter Chrome extension (from Chrome Web Store)
See SETUP.md for installation details.