Browser automation typically means writing Playwright scripts by hand. Hunting for the right selectors, adding wait conditions, handling race conditions across browsers. It works. It's also slow and repetitive.
The Playwright MCP server takes a different approach. It lets Claude Code drive a real browser through natural language, skipping the scripting entirely.
Installation takes one command. From there, you can point Claude at your running app for self-QA, run exploratory tests in plain English, and debug flaky flows by having Claude reproduce them in a real browser.
This post walks through setup, practical workflows, and troubleshooting for the Playwright MCP server with Claude Code. It also covers the CLI vs MCP tradeoff so you know when each approach fits. If you're already familiar with MCP in Claude Code, you'll be up and running in minutes.
What is the Playwright MCP server?
The Playwright MCP server is Microsoft's official package (@playwright/mcp) that gives coding agents like Claude Code direct browser control through the Model Context Protocol. It uses the browser's accessibility tree for interactions, making them faster and more token-efficient than screenshot-based approaches.
The Model Context Protocol is the bridge. Claude Code acts as the MCP client, sending requests to the Playwright server, which controls the browser and returns results.

The server exposes 34 tools across categories like core automation, tab management, vision-based interactions, and test assertions. Examples include browser_navigate, browser_click, browser_type, browser_take_screenshot, and browser_snapshot. When Claude needs to interact with a web page, it calls these MCP tools directly.
The key difference from screenshot-based browser automation is the accessibility tree. Playwright MCP reads structured accessibility snapshots (the same ARIA tree that screen readers use) and sends that structured data to Claude. The interaction is purely text-based.
A snapshot looks like this:
- heading "Dashboard" [level=1]
- navigation "Main"
- link "Settings" [href="/settings"]
- link "Profile" [href="/profile"]
- button "Save Changes" [disabled]Accessibility snapshots are faster to parse, cheaper in tokens, and more reliable than sending a screenshot and asking Claude to figure out where the buttons are. Claude can reference elements by their role and name ("click the Save Changes button"), which is more precise than interpreting pixel coordinates from an image.

This also makes interactions more stable. Screenshots break when the page layout shifts even slightly. Accessibility snapshots remain consistent as long as the underlying element structure stays the same.
By default, the server runs locally as a process on your machine using stdio transport. Claude Code communicates with it through standard input/output, so all browser interactions happen on your local network. For remote setups or Docker containers, you can run the server in HTTP mode by passing the --port flag.
One thing to watch out for. If you search for "Playwright MCP server," you'll find ExecuteAutomation's @executeautomation/playwright-mcp-server in the results. That's a separate community project with a different API surface. Microsoft's official package is @playwright/mcp, and that's what this guide covers.
How do you set up Playwright MCP with Claude Code?
Run claude mcp add playwright npx @playwright/mcp@latest before starting a Claude Code session. This registers the Playwright MCP server and persists the configuration in ~/.claude.json. Use --scope project to share the setup with your team via version control, or --scope user for personal use across all projects.
The setup takes three steps. The entire process is under five minutes if you already have Node.js installed.
First, confirm you have Node.js 18+ installed. Playwright MCP won't work on older versions (you'll get a "performance is not defined" error on Node 16). Run node --version to check.
Second, register the MCP server.
claude mcp add playwright npx @playwright/mcp@latestPin to a specific version for shared or CI configs to avoid intermittent tool failures from beta releases. For team setups, add the --scope flag:
# Personal use across all projects
claude mcp add --scope user playwright npx @playwright/mcp@latest
# Shared via .mcp.json in version control
claude mcp add --scope project playwright npx @playwright/mcp@latestThird, install browser binaries if you haven't already:
npx playwright installOn Linux or Docker, you'll also need system libraries. Run npx playwright install-deps to grab those.
To verify the setup, start Claude Code and ask it to navigate to a URL. Try this first message. "Use Playwright MCP to open https://example.com and describe what you see."
Simon Willison (Django, Datasette) flagged a gotcha worth knowing. Explicitly say "Playwright MCP" in your first message. Claude sometimes defaults to running Playwright through Bash commands, especially if you don't mention MCP by name.
After adding the server, you can check that it's registered by running claude mcp list or using the /mcp command inside Claude Code to see all available tools. The Claude Code MCP documentation covers additional configuration options.
For Claude Desktop users, the setup path is different. You'll edit claude_desktop_config.json directly and add a mcpServers entry with the command and args. Restart Claude Desktop after saving the config for the changes to take effect.
What can you do with Playwright MCP in Claude Code?
Start with self-QA by telling Claude to open your running app on localhost and verify that its code changes work. Beyond self-QA, Playwright MCP enables exploratory testing through natural language, authenticated session management via storage state, and test code generation from browser exploration sessions.
Self-QA during development
This is the use case that clicks first. You make changes to your app, then ask Claude to open localhost and verify the UI matches what you intended.

Exploratory testing
Describe what you want tested in plain English. "Navigate to the checkout flow, add two items, and check that the cart total updates correctly." Claude handles the selectors, waits, and assertions. You get a step-by-step report of what it found.
For responsive testing, be explicit about viewports. Claude defaults to desktop. Try "Test the navigation menu at 375px, 768px, and 1440px width."
Authenticated testing with storage state
If your app requires login, you can authenticate once and reuse that session.
- Run the Playwright MCP server in headed mode (the default) so a visible browser opens.
- Log in to your app manually through the browser.
- Export the session state. Playwright saves cookies and localStorage to a JSON file. You can use
browser_save_storage_statevia MCP or runnpx playwright codegen --save-storage=auth-state.jsonfrom the terminal. - Configure the MCP server to load that file on startup.
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--storage-state", "./auth-state.json"]
}
}
}Every subsequent session loads the cookies and localStorage from auth-state.json, bypassing the login flow entirely. For MFA-protected apps, the recommended workflow is to log in manually once, export the state, and reuse it until the session expires.
Debugging flaky tests
Paste failing test logs into Claude Code, then ask it to reproduce the flow via Playwright MCP. Claude can navigate the same steps, observe the timing, and diagnose whether the issue is a race condition, a missing wait, or a stale selector. Faster than adding console.log statements and re-running.
Test code generation
Pass --codegen typescript to the MCP server args, and Playwright generates test code as Claude navigates. Explore the flow with natural language, get a working Playwright test file at the end.
A good way to bootstrap your test suite. Let MCP discover the flow, then run the generated tests through the CLI for repeated execution.
A note on privacy. Everything Claude sees through Playwright MCP (page content, console output, form data) gets sent to Anthropic's API. Stick to development environments with test data.
When should you use Playwright MCP vs the CLI?
MCP gives Claude persistent browser state and real-time adaptation. The CLI is more token-efficient because results go to disk as file paths. Use MCP for exploratory testing and self-QA. Use the CLI for repeatable test flows in CI/CD pipelines.
The key architectural difference is that MCP returns accessibility trees inline in the response, while the CLI saves snapshots and screenshots to files. With Tool Search enabled, MCP's upfront schema overhead disappears, but per-call data still consumes more context than file paths.
The hybrid approach works well. Use MCP for exploration and test discovery, then generate Playwright test files via --codegen for repeated execution.
How do you troubleshoot common Playwright MCP issues?
The most common issue is "no tools detected," which usually stems from invalid JSON config, version mismatches between Playwright and the MCP package, or outdated Node.js. Pin your MCP version instead of using @latest, make sure Node.js 18+ is active, and run npx playwright install to sync browser binaries.
The top five issues.
1. Tools disappear mid-session
The MCP server becomes unresponsive or tools return "No such tool available" errors. This often happens with @latest pulling unstable or beta versions. Pin to a specific version (e.g., @playwright/mcp@0.0.23) and restart Claude Code.
2. Node.js version mismatch
Requires Node.js 18+. If you see "performance is not defined" or similar runtime errors, check your active Node version with node --version. If you use nvm or another version manager, make sure the correct version is active when you add the MCP server.
3. Missing browser binaries
Run npx playwright install after setting up the MCP server. On Linux and Docker, also run npx playwright install-deps for system-level libraries that Chromium needs.
4. Version conflicts between Playwright and MCP
When the MCP package and Playwright browser binaries are out of sync, tools behave inconsistently. Pin @playwright/mcp to a specific version and run npx playwright install --force to resync binaries.
5. Docker and CI failures
Always pass --headless for container environments. Install all dependencies explicitly in your Dockerfile. Watch for session management issues in HTTP transport mode. Only the first request may succeed while subsequent requests fail with "Session not found" due to premature session cleanup.
Most of these trace back to version pinning. If you take away one thing from this section, pin your @playwright/mcp version to a specific release.
How do you give your whole team browser testing without the setup?
This guide walks through Playwright MCP from a developer's perspective. Node.js, npm, browser binaries, config flags. That works for your engineering team.
Designers verifying layout changes, PMs checking acceptance criteria, content teams previewing copy updates. They all need to see the app in a real browser. Playwright MCP only reaches developers who work in the terminal.
Builder.io is an agentic development platform where browser preview is built into every agent session. Each of the 20+ parallel agents runs in its own cloud container with a full dev environment and live browser preview. No Playwright setup, no browser binary installs, no MCP configuration.
- Designers open a visual canvas connected to your real components, verify spacing and layout changes in the browser, and commit directly to the branch
- PMs check acceptance criteria against live previews without asking engineering for a staging URL
- Content and marketing teams update copy, preview changes in a real browser, and send validated PRs to your queue
- You review architecture and merge clean code
See how Builder.io gives your whole team browser preview and testing.
FAQ
Q: Does Playwright MCP work in headless mode for CI environments?
A: Yes. Pass --headless to the MCP server args. In your configuration, that looks like "args": ["@playwright/mcp@latest", "--headless"]. All browser interactions, including screenshots and accessibility snapshots, work identically in headless mode.
Q: Can Claude handle login flows that require multi-factor authentication?
A: Claude can step through MFA flows when guided explicitly, but for CI pipelines, use storage state instead. Export cookies and localStorage to a JSON file after a manual login, then configure --storage-state to load that file on startup. This bypasses the entire login flow.
Q: What is the difference between @playwright/mcp and @modelcontextprotocol/server-playwright?
A: The @modelcontextprotocol/server-playwright package is the old name. Microsoft's current official package is @playwright/mcp. If you see the old name in tutorials or LLM-generated instructions, use @playwright/mcp instead. The API and tool names are the same.
Start with self-QA
The Playwright MCP server gives Claude Code direct browser control through structured accessibility snapshots. Exploratory testing and self-QA become conversational. The key decision is knowing when MCP's persistent state and real-time adaptation justify its higher token cost over the CLI.
Start with claude mcp add playwright npx @playwright/mcp@latest, point Claude at your running app on localhost, and ask it to verify your latest changes. That first self-QA loop is where you'll see the value immediately. From there, you can explore authenticated testing with storage state, generate Playwright test code from MCP sessions, and build the hybrid workflow that keeps both MCP and CLI in your toolkit. If you're using other MCP integrations, our Figma MCP Server guide covers the design-to-code workflow.
Builder.io visually edits code, uses your design system, and sends pull requests.
Builder.io visually edits code, uses your design system, and sends pull requests.
