Claude Code for Playwright MCP — Workflow Guide
The Setup
You are using the Playwright MCP server to give Claude Code the ability to interact with web browsers — navigating pages, clicking elements, filling forms, and taking screenshots. This turns Claude Code into a browser automation agent. The key challenge is configuring the MCP server correctly and structuring prompts so Claude Code interacts with the browser effectively.
What Claude Code Gets Wrong By Default
-
Writes Playwright test scripts instead of using MCP tools. Claude generates
test('should...', async ({ page }) => { })test files. With Playwright MCP, Claude Code uses the browser through MCP tool calls — no test files needed for interactive browser tasks. -
Uses CSS selectors for everything. Claude writes brittle
page.locator('.btn-primary')selectors. Playwright MCP exposes accessibility-based interactions — clicking by text content or role is more reliable and is the default for MCP actions. -
Ignores the snapshot-based interaction model. Claude tries to interact with elements by coordinates. Playwright MCP provides accessibility snapshots of the page and uses element references from those snapshots for interactions.
-
Opens browsers on the server. Claude launches headed browsers assuming a display is available. Playwright MCP handles browser lifecycle — it runs in the background and provides page content through the MCP protocol.
The CLAUDE.md Configuration
# Playwright MCP Browser Integration
## MCP Server
- Server: @playwright/mcp (Playwright MCP server)
- Config: in Claude Code MCP settings
- Mode: headless by default, headed for debugging
## Playwright MCP Rules
- Use MCP tools for browser interaction, not test scripts
- Navigate: browser_navigate to URL
- Snapshot: browser_snapshot for page accessibility tree
- Click: browser_click with element ref from snapshot
- Type: browser_type to fill input fields
- Screenshot: browser_screenshot for visual verification
- Wait for network idle before snapshots
- One browser context at a time
## Conventions
- Start with browser_navigate to the target URL
- Take snapshot to understand page structure before acting
- Use text-based element selection from snapshots
- Screenshot after key actions for verification
- Close tabs when done: browser_tab_close
- Handle auth by navigating to login, typing creds, submitting
- Console logs available via browser_console_messages
Workflow Example
You want Claude Code to test a signup flow on your staging environment. Prompt Claude Code:
“Go to staging.myapp.com/signup, fill in the registration form with test data, submit it, and verify the welcome page appears. Take a screenshot of each step.”
Claude Code should use browser_navigate to open the signup URL, browser_snapshot to find form fields, browser_type to fill email and password fields, browser_click to submit the form, wait for navigation, take a browser_screenshot to verify the welcome page, and report the results.
Common Pitfalls
-
Acting before page load completes. Claude tries to click elements immediately after navigation. Pages with JavaScript rendering need time to hydrate. Use
browser_snapshotwhich waits for the page to stabilize before returning the accessibility tree. -
Snapshot reference staleness. Claude stores element references from an old snapshot and tries to use them after page changes. After any navigation or significant DOM change, take a new
browser_snapshotto get fresh element references. -
Auth state not persisting. Claude logs in on every test flow because the browser context resets. Use the same browser tab for related flows, or set up auth state via cookies before starting the test sequence.