Skip to content

Playwright MCP: What It Is and How to Use It in Claude Code

ILIA KARPENKO7 min readSupport the author

Playwright MCP is Microsoft's official Model Context Protocol server for Playwright: it lets an AI agent such as Claude Code, Cursor, or GitHub Copilot open a real browser, click, type, and read the page through Playwright. It works on structured accessibility snapshots rather than screenshots, so the agent reads the page as a tree of roles and names, picks an element reference out of it, and acts on that reference. No vision model sits in the loop.

That design decision is the reason it behaves differently from screenshot-driven browser agents. A snapshot gives the model an exact handle for every interactive element, so a click lands on the element it named instead of on coordinates it estimated. It also means the agent works in the same vocabulary Playwright locators use, which matters the moment you want the session to end in code you can keep.

How to add Playwright MCP to Claude Code

You need Node.js (the Playwright docs ask for version 20 or newer) and the Claude Code CLI. Then it is one command:

claude mcp add playwright npx @playwright/mcp@latest

Start a new Claude Code session and run /mcp. You should see playwright listed as connected, with its browser tools available. Ask for something concrete to check it works: "Open https://demo.playwright.dev/todomvc, add two todos, and tell me what the counter says."

Three variations come up often:

GoalCommand
Pass server flags, such as headless modeclaude mcp add playwright -- npx @playwright/mcp@latest --headless
Share the server with everyone on the repoclaude mcp add playwright --scope project npx @playwright/mcp@latest
Pin a version instead of tracking latestclaude mcp add playwright npx @playwright/mcp@0.0.83

The -- matters in the first row. Without it, Claude Code reads --headless as its own option instead of passing it to the server. The project scope writes the server into a .mcp.json file at the repo root, so teammates get the same browser tools after they approve it.

Cursor, VS Code, Windsurf, and Claude Desktop use the same server through a JSON config instead of a command:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}
Free and open sourceCasely writes these cases for youAttach a spec and one file of your team's existing test cases in Claude. Casely copies your columns, names the gaps it found in the spec, and exports a single Excel file your tracker imports in one pass.Read the install docs

What the server exposes

The default tool set covers the whole interaction surface: browser_navigate, browser_click, browser_type, browser_fill_form, browser_select_option, browser_hover, browser_drag, browser_press_key, browser_file_upload, browser_handle_dialog, browser_wait_for, and browser_snapshot for reading the page back. Inspection comes with it: browser_console_messages, browser_network_requests, browser_evaluate, browser_find.

Everything else is opt in through --caps, which keeps the tool schema small until you need more.

CapabilityTools it addsWhen it earns its place
testingbrowser_generate_locator, browser_verify_element_visible, browser_verify_text_visible, browser_verify_value, browser_verify_list_visibleTurning an exploratory walk into assertions and locators you can paste into a spec
storageCookie, localStorage, and sessionStorage tools plus browser_storage_stateLogged-in flows, and saving auth state so the next run skips the login form
networkbrowser_route, browser_unroute, browser_route_list, browser_network_state_setMocking a backend response or taking the page offline to test an error path
devtoolsbrowser_start_recording, browser_stop_recording, tracing, video, browser_highlightRecording a flow you perform by hand and getting Playwright code back
visionbrowser_mouse_click_xy and the other coordinate toolsCanvas, maps, drag handles: anything with no accessibility node to target
pdfbrowser_pdf_saveChecking a generated document rather than a page

browser_start_recording deserves a callout. You demonstrate a flow in the browser yourself, then browser_stop_recording hands back what you did as Playwright code. That is the shortest path from a manual reproduction to something a runner can execute.

Configuration is CLI flags. --browser picks chrome, msedge, firefox, or webkit. --device "iPhone 15" or --mobile emulates a phone, and the README notes mobile pages are usually lighter, which saves tokens. --test-id-attribute changes what generated locators anchor to, defaulting to data-testid. --codegen sets the language for generated code: TypeScript by default, with Python, Java, and C# available.

How this differs from writing Playwright tests

Both end in the same place, which is why the distinction gets missed. The difference is what each one guarantees.

Playwright Test is the enforcement layer. It has fixtures, retries, sharding across machines, a trace per retry, an HTML report, and a CI exit code. Run it twice on the same commit and it does the same thing twice.

Playwright MCP is an authoring and exploration layer. The agent decides which tool to call next, so the route through the page varies between runs. It has no retries, no sharding, and no report. What it produces is a session, plus whatever locators, assertions, and code you extract from that session before it ends.

Use MCP to find out how the page behaves and to draft the spec. Use the test runner to hold the line afterward. A team that stops at the MCP session has an agent that browsed the app, not a regression suite.

The Playwright team is direct about a related tradeoff: for coding agents, they now point at playwright-cli with skills instead, because CLI invocations avoid loading large tool schemas and verbose accessibility trees into the model's context. MCP stays the better fit for agentic loops that need persistent browser state and iterative reasoning over page structure, such as exploratory automation or self-healing tests. The Playwright CLI vs MCP comparison walks through when each one wins. If you want Playwright to plan, write, and repair whole test files on its own, the built-in Playwright Test Agents are the third option.

Playwright MCP or Chrome DevTools MCP

Playwright MCPChrome DevTools MCP
BrowsersChrome, Edge, Firefox, WebKitChrome and Chrome for Testing
Strongest atDriving flows, mocking network, saving auth state, producing locators and codePerformance traces, Lighthouse audits, heap snapshots, deep protocol-level inspection
Output you keepPlaywright code, locators, storage stateA diagnosis of what the page did
Parallel sessionsSupported with --isolated or separate profilesOne browser per server instance

The split is clean enough to state in one line each. Reach for Playwright MCP when the goal is a test that will exist tomorrow. Reach for Chrome DevTools MCP when the goal is understanding why a page is slow, leaking, or throwing today, and cross-browser coverage is not part of the question.

Running both is reasonable. They are separate servers with separate tool namespaces, and the cost is context, not conflict.

Where it fails

It is not a security boundary. The project says so directly, and adds that the origin allowlist and blocklist are not security boundaries either and do not affect redirects. File access is restricted to workspace roots unless you pass --allow-unrestricted-file-access, and that flag deserves more thought than it usually gets.

Persistent profiles collide. The default profile is persistent and only one browser instance can hold it at a time, so two MCP clients in the same workspace conflict. Give each one --isolated or its own --user-data-dir.

Generated locators inherit whatever the page gives them. On a UI with no test ids, the agent falls back to roles and accessible names, and those move when someone rewrites a label, and unstable locators are a leading cause of flaky tests. Setting data-testid attributes before an agent starts generating locators is the cheapest stability you will buy all quarter.

Snapshots of heavy pages cost real context. A dense DOM produces a long tree on every action. --mobile and a narrower starting page help. So does turning off capability groups you are not using.

The Docker image runs headless Chromium only. Containerized setups lose the cross-browser advantage that is otherwise the main reason to pick this server over the DevTools one.

Nothing here reviews the test. An agent that walked a flow successfully will happily assert that the flow it just walked works. Assertions written from observed behavior encode the current behavior, bug included, which is the failure mode worth watching for in every AI-authored suite.

What is worth automating

The mechanical half is a good handoff: exploring an unfamiliar screen, finding stable locators, capturing auth state once instead of logging in on every run, and converting a manual reproduction into a first draft spec.

Browser tests sit at the top of the test pyramid, so keep the count small and put most checks lower. Deciding what the assertion should be stays a human call. A generated test tells you the page still does what it did the day it was recorded. Whether that is what the requirement asked for is a separate question, and it is answered upstream, in the test cases, not in the browser.

Frequently asked questions

Is Playwright MCP free? Yes. The server is open source under the Apache 2.0 license and runs locally through npx. You pay only for the model tokens your agent spends reading page snapshots.

Does Playwright MCP need screenshots or a vision model? No. It reads the page as an accessibility tree, so any text model can use it. The vision capability adds coordinate-based tools for canvas-style pages that have no accessibility nodes.

What is the difference between Playwright MCP and Playwright? Playwright is the browser automation library and test runner. Playwright MCP wraps that library as tools an AI agent can call. The tests you keep still run on Playwright Test.

Why does Playwright MCP use so many tokens? Every action returns a fresh snapshot of the page, and dense pages produce long snapshots. Use --mobile, keep capability groups off until you need them, or switch coding-agent work to playwright-cli, which writes snapshots to disk instead of into the model's context.

Open sourceThe skill lives on GitHubMIT licensed, no account, nothing to install on your machine. Star it if it saves you an afternoon.View the repository