Playwright MCP¶
Browser automation via Playwright accessibility tree. No vision or screenshots required — Playwright represents pages as a structured accessibility snapshot that Claude can navigate directly.
Source: microsoft/playwright-mcp
Enabling¶
The server is included in servers.yaml with enabled: false. To activate it permanently:
Or enable for the current session only:
Server Config¶
Options¶
Add to the args array to customise behaviour:
| Option | Description |
|---|---|
--headless |
Run without a visible browser window |
--browser=firefox |
Use Firefox or WebKit instead of Chromium |
--viewport=WxH |
Set viewport size (e.g., 1280x720) |
Tools¶
- Navigation:
browser_navigate,browser_back,browser_forward,browser_wait - Interaction:
browser_click,browser_type,browser_select_option,browser_press_key - State:
browser_snapshot,browser_screenshot,browser_evaluate - Tabs:
browser_tab_list,browser_tab_new,browser_tab_select,browser_tab_close
Element Annotations (play_util)¶
The play_util pack adds visual annotation tools on top of this server — highlight elements, guide users through workflows, and let users point Claude to elements with Ctrl+I.
See play_util reference for the full API.
Usage Patterns¶
- Prefer
browser_snapshotoverbrowser_screenshot— it's faster and doesn't require vision - Standard flow:
browser_navigate→browser_snapshot→browser_click/type→browser_snapshot - Use
browser_evaluatefor custom JS execution - Use
browser_screenshotonly for visual verification when the accessibility tree is insufficient
Verification Checklist¶
Use these checks after enabling the server:
ot.servers(pattern="playwright", info="full")
ot.packs(pattern="play")
ot.tool_info(pattern="playwright.")
Examples¶
1. Read a page without vision¶
Use the accessibility snapshot to understand page structure without a screenshot.
playwright.browser_navigate(url="https://en.wikipedia.org/wiki/Anthropic")
playwright.browser_snapshot()
# Returns structured YAML accessibility tree — headings, links, buttons, text
2. Extract all headings from a page¶
Pull structured content with JavaScript — no selectors library needed.
playwright.browser_navigate(url="https://en.wikipedia.org/wiki/Anthropic")
playwright.browser_evaluate(
function="() => Array.from(document.querySelectorAll('h2')).map(h => h.textContent.trim())"
)
# Returns: ["Contents", "History", "Business structure", "Product", ...]
3. Fill and submit a login form¶
Automate authentication flows end-to-end.
playwright.browser_navigate(url="https://myapp.com/login")
playwright.browser_snapshot() # Check form field names first
playwright.browser_fill_form(fields=[
{"selector": "input[name='email']", "value": "user@myapp.com"},
{"selector": "input[name='password']", "value": "secure123"},
])
playwright.browser_click(element="Submit button", ref="...")
playwright.browser_snapshot() # Verify logged in
4. Scrape a data table¶
Extract all rows from an HTML table as a list of records.
playwright.browser_navigate(url="https://myapp.com/pricing")
playwright.browser_evaluate(
function="""() => {
const rows = Array.from(document.querySelectorAll('table tr'));
return rows.map(r => Array.from(r.querySelectorAll('td,th')).map(c => c.textContent.trim()));
}"""
)
5. Test a multi-step checkout flow¶
Walk through a user journey and verify state at each step.
playwright.browser_navigate(url="https://shop.myapp.com/product/1")
playwright.browser_snapshot()
playwright.browser_click(element="Add to cart button")
playwright.browser_snapshot() # Verify cart updated
playwright.browser_navigate(url="https://shop.myapp.com/cart")
playwright.browser_snapshot() # Verify item in cart
playwright.browser_take_screenshot()
6. Test mobile viewport rendering¶
Check how a page looks at phone dimensions.
playwright.browser_navigate(url="https://myapp.com")
playwright.browser_resize(width=390, height=844) # iPhone 14
playwright.browser_snapshot()
playwright.browser_take_screenshot()
playwright.browser_resize(width=1280, height=720) # Reset to desktop
7. Highlight page elements for user guidance¶
Use the annotation overlay to visually guide a user through a workflow.
playwright.browser_navigate(url="https://myapp.com/settings")
play_util.inject_annotations()
play_util.guide_user(
task="Update your profile",
steps=[
{"selector": "input[name='display_name']", "label": "1. Edit name"},
{"selector": "input[name='email']", "label": "2. Confirm email"},
{"selector": "button[type='submit']", "label": "3. Save", "color": "green"},
],
)
playwright.browser_take_screenshot()
8. Monitor console errors during navigation¶
Detect JavaScript errors thrown during page load.
playwright.browser_navigate(url="https://myapp.com")
playwright.browser_console_messages()
# Look for level="error" entries — useful for regression checks
Common Mistakes to Avoid¶
- Don't assume elements exist — use
browser_snapshotfirst - Don't skip snapshots between actions
- Don't use
browser_screenshotwhenbrowser_snapshotis sufficient