Playwright MCP: setup in Claude Code, Cursor and VS Code, flags, and safe use

Microsoft's Playwright MCP server (@playwright/mcp) lets an AI agent drive a real browser through accessibility snapshots. How to install it in Claude Code, Cursor, VS Code and Claude Desktop, the flags that matter, when to use Chrome DevTools MCP instead, and how to keep sessions and cookies safe.

Walma Engineering·Updated 5 October 2026·8 min read

Playwright MCP gives an AI agent a real browser. Claude, Cursor, Copilot in VS Code or any other MCP client can open a URL, read the page, click, type, fill forms, handle dialogs and check the result, using Microsoft's Playwright under the hood. This guide covers installation in the four common clients, how the snapshot approach works, the flags worth knowing, when Chrome DevTools MCP is the better choice, and the security points to settle before you point it at anything logged in. For the basics of MCP itself, see What is an MCP server?.

What it is

The official server lives at github.com/microsoft/playwright-mcp and ships on npm as @playwright/mcp. It runs locally over stdio, launches a browser on your machine and exposes tools such as browser_navigate, browser_snapshot, browser_click, browser_type, browser_fill_form, browser_select_option, browser_wait_for, browser_tabs and browser_take_screenshot. Requirements are short: Node.js 18 or newer and an MCP client.

One note from Microsoft's own README before you start: for coding agents, Microsoft now points to the separate Playwright CLI with skills as the more token-efficient option, because it avoids loading large tool schemas and accessibility trees into the context. MCP remains the better fit for agent loops that benefit from a persistent browser and iterative reasoning over page structure, such as exploratory testing or long-running workflows. If you are new to the skills idea, see Claude skills vs MCP.

Snapshots, not screenshots

Most browser agents look at a screenshot and guess where to click. Playwright MCP works differently. browser_snapshot returns the page's accessibility tree as structured text: roles, names, values and states, with a reference for each element. The model then calls browser_click or browser_type with that reference as the target.

This has three practical effects:

  • No vision model needed. Any text model that handles tool calls can drive it.
  • Deterministic actions. The click goes to an element, not a pixel coordinate, so a layout shift does not send it to the wrong button.
  • It rewards accessible markup. Buttons with labels, form fields with names and proper headings make the agent's job easy. Div soup makes it hard, which is a useful accessibility signal in itself.

Screenshots still exist. browser_take_screenshot is there for humans and for visual checks, but the tool description itself says you cannot act on a screenshot and should use the snapshot for actions. If you do need pixel-based control, for example on a canvas app, enable --caps=vision to get coordinate tools like browser_mouse_click_xy.

Installing it

Claude Code

claude mcp add playwright npx @playwright/mcp@latest

To pass flags, use the -- separator so Claude Code does not parse them as its own:

claude mcp add playwright -- npx @playwright/mcp@latest --headless --isolated

Add --scope project to write it to .mcp.json and share it with the team. The full set of options is in adding MCP servers to Claude Code.

Cursor

Open Cursor Settings, MCP, Add new MCP Server, choose the command type and enter npx @playwright/mcp@latest. Or add it to .cursor/mcp.json (project) or ~/.cursor/mcp.json (global):

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

More detail in adding MCP servers to Cursor.

VS Code

From the terminal, this adds it to your user profile:

code --add-mcp '{"name":"playwright","command":"npx","args":["@playwright/mcp@latest"]}'

For a workspace setup, VS Code's own format is .vscode/mcp.json with a top-level servers object (not mcpServers):

{
  "servers": {
    "playwright": {
      "command": "npx",
      "args": ["@playwright/mcp@latest"]
    }
  }
}

Claude Desktop

Open Settings, Developer, Edit Config, add the same mcpServers block shown for Cursor to claude_desktop_config.json and restart Claude. See adding MCP servers to Claude Desktop.

The flags that matter

All flags go in the args array after the package name, and each also has a PLAYWRIGHT_MCP_* environment variable.

FlagWhat it does
--headlessRuns without a visible window. The default is headed.
--browserchrome, firefox, webkit or msedge.
--isolatedKeeps the profile in memory. Nothing is saved to disk, and closing the browser drops all state.
--storage-state <path>Loads cookies and local storage from a file into an isolated session.
--user-data-dir <path>Uses a specific persistent profile directory.
--allowed-origins / --blocked-originsSemicolon-separated lists of origins the browser may or may not request.
--capsOpt-in tool groups: vision, pdf, devtools, among others.
--secrets <path>A dotenv file whose values are masked in tool responses.
--device / --viewport-sizeEmulate a device such as "iPhone 15" or set a fixed viewport.
--portServe over HTTP instead of stdio, for a headed browser on a machine with a display.

Profiles deserve a moment of thought. By default the server uses a persistent profile stored under ms-playwright/mcp-{channel}-{workspace-hash} in your cache directory (on macOS, ~/Library/Caches/ms-playwright/). Anything you log into stays logged in next time. That is convenient, and it is also a set of live sessions sitting on disk. A persistent profile can only be used by one browser at a time, so parallel clients in the same workspace need --isolated or separate --user-data-dir values.

For repeatable testing, the cleaner pattern is an isolated session seeded with a known login:

{
  "mcpServers": {
    "playwright": {
      "command": "npx",
      "args": [
        "@playwright/mcp@latest",
        "--isolated",
        "--storage-state=./auth/test-user.json"
      ]
    }
  }
}

The storage state file uses Playwright's standard format, so a file your existing Playwright test suite already produces will work.

There is also a --extension mode that connects to your running Chrome or Edge through the Playwright extension, reusing your real tabs and logins. It is useful for one-off tasks, and it is the mode that needs the most caution (see security below).

What teams use it for

  • Testing your own app while you build it. Ask the agent to run the signup flow on localhost, fill the form with edge cases and report what broke. With --caps=testing it gets assertion tools such as browser_verify_text_visible and browser_generate_locator, and --codegen controls which language it generates Playwright code in, which helps when you turn an exploratory session into a real test.
  • QA by agents. Walk through a release candidate, check that pages render, forms validate and links work, and collect console errors with browser_console_messages. It does not replace a test suite, but it catches things nobody wrote a test for.
  • Extracting data from your own systems. Internal admin tools and legacy apps without an API can be read through the browser. Keep this to systems you own or are permitted to automate.
  • Reproducing bug reports. Give the agent the steps from a ticket and let it confirm the bug and capture a screenshot.

Playwright MCP vs Chrome DevTools MCP

Google's Chrome DevTools team publishes chrome-devtools-mcp, and the two get compared often. They overlap on basic automation and diverge after that.

Playwright MCPChrome DevTools MCP
MaintainerMicrosoftChrome DevTools team
Package@playwright/mcpchrome-devtools-mcp
BrowsersChromium, Chrome, Edge, Firefox, WebKitChrome and Chrome for Testing officially
Automation enginePlaywrightPuppeteer
StrengthFlows, forms, cross-browser checks, test generationPerformance traces, network analysis, console with source-mapped stack traces

A simple rule: use Playwright MCP when the agent needs to do things in a browser, and Chrome DevTools MCP when it needs to diagnose why a page is slow or broken. Running both is fine. One difference to know before rolling out Chrome DevTools MCP: its README says Google collects usage statistics by default (opt out with --no-usage-statistics), and its performance tools may send trace URLs to the CrUX API (disable with --no-performance-crux). For a wider shortlist, see best MCP servers.

Security

A browser is one of the most powerful tools you can hand an agent. Microsoft's README says it directly: Playwright MCP is not a security boundary. Four things follow from that.

Sessions and cookies. Whatever the browser is logged into, the agent can act as. The default persistent profile keeps those sessions between runs, and extension mode hands over your everyday browser. Use --isolated with a dedicated test account's storage state, and keep the agent away from your personal email, banking and admin consoles.

Prompt injection from web pages. Every snapshot puts page content into the model's context. A page, a comment field or a product review can contain text written to look like instructions. An agent that reads an attacker's page while holding a logged-in session and a form-filling tool is the classic injection setup. Our MCP security guide covers the pattern in depth.

Origin lists are not a fence. --allowed-origins and --blocked-origins are useful for keeping an agent focused, but the README notes that they do not serve as a security boundary and do not affect redirects. Real network restrictions belong at the network or proxy level.

Dangerous tools. browser_run_code_unsafe runs arbitrary JavaScript in the Playwright server process, and the README describes it as RCE-equivalent. browser_evaluate runs JavaScript in the page. File access is limited to workspace roots by default; leave --allow-unrestricted-file-access off. The --secrets option masks known values in responses, but the code comments call it a convenience, not a security feature.

Running it for a team

On one developer's laptop, these choices are personal. Once a team, or agents in CI, use browser automation against internal systems, you want the same answers for everyone: which servers are allowed, which flags are mandatory, which origins they may touch, and a log of what each agent did. That is the job of an MCP gateway. Walma runs one inside your own Azure tenant in an EU region, so connections like Playwright sit behind a shared policy and audit log, next to the models your team already uses. If you need a browser-driven agent built around a specific internal system, that is the kind of work we do under custom solutions.

Frequently asked questions

What is Playwright MCP?+

Playwright MCP is Microsoft's official MCP server for browser automation, published on npm as @playwright/mcp. It lets an AI client such as Claude Code, Cursor or VS Code open pages, click, type, fill forms and read the result, using Playwright's accessibility tree instead of screenshots.

How do I add Playwright MCP to Claude Code?+

Run claude mcp add playwright npx @playwright/mcp@latest. To pass flags, put them after the package name, for example claude mcp add playwright -- npx @playwright/mcp@latest --headless --isolated. You need Node.js 18 or newer.

Does Playwright MCP need screenshots or a vision model?+

No. By default it works from accessibility snapshots: a structured text version of the page where each element has a reference the model can click or type into. Screenshots are available for humans to look at, and coordinate-based clicking is an opt-in capability (--caps=vision).

What is the difference between Playwright MCP and Chrome DevTools MCP?+

Playwright MCP is built for automation across Chromium, Firefox and WebKit, driven by accessibility snapshots. Chrome DevTools MCP, from the Chrome DevTools team, targets Chrome only and adds DevTools-level debugging such as performance traces, network analysis and console messages with source-mapped stack traces. Use Playwright for flows and tests, Chrome DevTools for debugging and performance.

Is Playwright MCP safe to use with my logged-in accounts?+

Treat it with care. The README states plainly that Playwright MCP is not a security boundary, and --allowed-origins does not act as one either. The default persistent profile keeps cookies between sessions, and any page the agent reads can carry prompt injection. Use --isolated with a dedicated test account's storage state for anything that matters.

Walma AI Hub

The same tools, in your EU region, under your control

A 20-minute walkthrough with an engineer. We map it to your tools, your MCP servers and your budget model.

About AI Hub