Every AI coding agent has the same blind spot: it can write code that looks correct but cannot see whether the result actually renders, behaves, or passes a test in the browser. You either add a manual verification step — defeating the point of agent-driven development — or you trust the agent's static analysis and ship bugs. Playwright MCP closes that gap by giving Claude Code a live browser it can drive itself.
This guide walks through setting up the Playwright MCP server with Claude Code, shows the exact agent workflow for verifying a UI change, and covers how to combine browser automation with AppHandoff MCP for end-to-end contract verification.
What is Playwright MCP?
Playwright MCP is an open-source MCP server published by Microsoft as @playwright/mcp. It wraps Playwright — the browser automation library — and exposes its capabilities as standard MCP tools. Any MCP-capable client, including Claude Code, can connect to it and direct a real browser: Chromium, Firefox, or WebKit.
The server exposes tools like browser_navigate, browser_click, browser_fill, browser_take_screenshot, browser_snapshot, and more. From Claude Code's perspective, these are just tool calls — the same mechanism it uses to read files, run commands, or call APIs. The agent issues a browser_navigate call, the MCP server launches a browser (or reuses one), and the result comes back as structured text or a screenshot. No human needs to open a tab.
If you want the broader context on what MCP is and why it matters for AI development, see our MCP developer guide.
Step 1: Install and Connect Playwright MCP to Claude Code
Claude Code ships with the claude mcp add command that handles both local (stdio) and remote (HTTP) MCP servers. For Playwright MCP, you use the stdio variant — it spawns a local Node process running the server:
claude mcp add playwright -- npx @playwright/mcpThis registers the server globally in your Claude Code configuration. The next time you open a session, Claude Code will automatically connect to it. You can verify it is registered with:
claude mcp listIf you want the server scoped to a specific project rather than globally, use the project-level approach: add an mcpServers block to .claude/settings.json in your repo root:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp"]
}
}
}Commit that file and every teammate's Claude Code session picks up the same Playwright tooling automatically — no individual setup required.
Step 2: Let Your Agent Verify a UI Change
Here is the canonical agent loop that Playwright MCP enables. The agent edits a React component, then uses Playwright to confirm the change renders correctly — all in the same session, no human in the loop.
Suppose you ask Claude Code to update a button label. Without browser automation, the agent edits the file, runs a TypeScript type-check, and calls it done. With Playwright MCP, the loop looks like this:
# Agent edits the component
# Then verifies it without leaving the session:
1. browser_navigate → http://localhost:3000/dashboard
2. browser_snapshot → captures the DOM tree
3. browser_find → locates the button by selector
4. browser_take_screenshot → visual confirmation
5. (optional) browser_click → tests the interactionThe agent can read the snapshot output, identify whether the updated label appears, and report back with certainty rather than inference. If the change did not render — a missing import, a conditional that short-circuits — the agent sees it immediately and fixes it before you ever look at the browser.
For form flows, the loop extends further: browser_fill populates fields, browser_click submits, and browser_snapshot confirms the success state. The agent can verify a complete user journey without a human clicking through it manually.
What Your Agent Can Do with Playwright MCP
The full tool surface of @playwright/mcp covers the complete Playwright automation API:
Navigation: browser_navigate loads a URL in a real browser tab. browser_navigate_back and browser_navigate_forward move through history. browser_reload refreshes the page.
DOM interaction: browser_click clicks any element by CSS selector or text. browser_fill types into inputs. browser_select_option sets dropdown values. browser_press_key fires keyboard events. browser_drag handles drag-and-drop flows.
Observation: browser_snapshot returns a structured accessibility tree — richer than raw HTML and easier for the agent to parse. browser_take_screenshot returns a base64 PNG the agent can embed in its reasoning or attach to a ticket. browser_console_messages surfaces JavaScript errors from the page.
Network: browser_network_requests lists the XHR and fetch calls the page made — useful for verifying that an API endpoint was hit with the right payload.
Tabs: browser_tabs lists open tabs; the agent can open new ones or switch between them for multi-page flows.
Playwright MCP vs. Running Tests Manually
The usual Playwright workflow is: developer writes a test file, runs npx playwright test, reads the output, and edits code until it passes. That loop requires a human at the keyboard for every iteration.
With Playwright MCP, the agent is the developer and the test-runner simultaneously. It can:
1. Make a code change
2. Start the dev server (via a shell tool call)
3. Navigate the browser to the affected page
4. Assert the expected state using browser_snapshot or browser_find
5. If the assertion fails, read the error, fix the code, and repeat from step 3
That entire loop runs inside a single Claude Code session with no human involvement. The practical result is that agents catch visual and interaction regressions before you see them — not after.
The tradeoff is that Playwright MCP is optimized for on-demand, agent-driven verification rather than CI test suites. For a persistent test suite that runs in CI on every push, you still want playwright test with spec files. Playwright MCP fills the gap between "code written" and "CI ran" — the in-session verification step that manual dev workflows skip.
Combining Playwright MCP with AppHandoff
Browser verification is most valuable when you know what to verify. That is where AppHandoff MCP comes in.
AppHandoff continuously scans your frontend and backend repos and tracks API contracts. When a backend endpoint changes its response shape, AppHandoff flags the mismatch against every frontend component that calls it. With both MCP servers connected, an agent can:
# 1. AppHandoff MCP: find what changed
get_mismatches → [ { endpoint: "/api/projects", field: "status", change: "string → enum" } ]
# 2. Fix the frontend component to handle the new enum
# 3. Playwright MCP: verify the fix renders correctly
browser_navigate → /projects
browser_snapshot → confirms status badge uses new enum values
browser_take_screenshot → attached to the handoff ticket
# 4. AppHandoff MCP: close the handoff ticket with browser evidence
update_handoff_request → resolved, screenshot attachedThe combination gives you a closed loop: AppHandoff tells the agent what broke at the API layer, Playwright confirms the fix works at the UI layer, and both feed back into the handoff ticket so the next agent or human reviewer sees the full picture — not just "I edited a file."
Common Use Cases
Verify a component renders after refactoring. After an agent migrates a class component to a hook-based one, Playwright navigates to the affected route and snapshots it. If the DOM structure matches expectations, the agent commits. If not, it debugs before you know anything happened.
Test auth flows end to end. The agent fills the login form, submits it, and verifies the redirect lands on the dashboard. This catches auth edge cases — wrong redirect URIs, missing session cookies, CORS issues — that unit tests cannot surface.
Screenshot-driven QA tickets. Before closing a UI handoff ticket, the agent takes a before/after screenshot pair with browser_take_screenshot and attaches both to the ticket. Reviewers get visual evidence without spinning up a local environment.
# Agent captures before/after evidence
browser_navigate → http://localhost:3000/settings
browser_take_screenshot → settings-before.png
# ... apply the change ...
browser_navigate → http://localhost:3000/settings
browser_take_screenshot → settings-after.pngNetwork payload inspection. After updating a fetch call, the agent uses browser_network_requests to confirm the request body includes the right fields and the response is 200, not 422. This is faster than adding logging and checking the terminal.
Catch console errors on deploy. After deploying to a staging URL, the agent navigates key routes and reads browser_console_messages to surface any JavaScript errors that slipped through build-time checks.
For more MCP server patterns, see MCP server examples and the best MCP servers for Claude Code roundup.
Getting Started Checklist
1. Install: claude mcp add playwright -- npx @playwright/mcp
2. Verify: claude mcp list — confirm playwright appears
3. Start your dev server in a separate terminal (or let the agent start it via a shell tool)
4. Ask Claude Code to navigate to a route and take a screenshot — confirm the browser launches
5. Add to team config by committing .claude/settings.json with the server block so every teammate gets it automatically
Once the basic setup is working, add AppHandoff MCP alongside it. The combination of contract awareness (AppHandoff) and browser verification (Playwright) gives Claude Code the context it needs to make changes confidently and confirm they worked — without a human standing by.