TL;DR: The Playwright MCP server connects Claude Code to a real browser through the Model Context Protocol. Claude navigates pages, reads the DOM through the accessibility tree, inspects response headers, and tests authenticated flows. You write the prompt; Claude issues the browser steps. This post sets it up in one command and walks three security workflows: recon and entry-point mapping, authenticated access-control testing, and security header checks.
Assumed audience: You work in security engineering or web app pentesting. You know what a DOM, a session cookie, and an MCP server are. You have Claude Code installed. Test only systems you own or hold written authorization to assess.
Why This Matters
Browser-based security checks need a real browser. curl and basic HTTP scrapers miss JavaScript-rendered content, client-side routing, and session state. Screenshot-based computer use is slow and misreads elements.
The Playwright MCP server gives Claude Code structured access to the DOM, network requests, and page state. Claude issues tool calls against a live browser, reads the result of each action, and decides the next step. You describe the test in plain language; Claude drives the browser.
What this gets you:
Recon that executes JavaScript: single-page apps, lazy-loaded forms, and client-rendered endpoints show up.
Authenticated testing: log in once, then run checks across a held session.
Deterministic reads: the accessibility tree is structured text, not pixels, so results are repeatable and cheaper in tokens than screenshots.
How the Playwright MCP Server Works
Playwright's MCP server is the bridge between Claude Code and the browser. It exposes browser control as roughly two dozen tools Claude can call: navigate, snapshot the accessibility tree, click, type, read network requests, read console messages, and take screenshots.

Two packages exist:
@playwright/mcp: the official server maintained by Microsoft. Use this one.playwright-mcp: an earlier community build. The official package covers its functionality.
@playwright/mcp defaults to the accessibility tree, so you get element roles, names, and attributes as text. That output is precise to assert against and does not cost image tokens.
Prerequisites
Before starting, confirm you have:
Claude Code installed and working (Anthropic API key or a Claude subscription)
Node.js 18 or newer on your machine
npx available in your terminal
Written authorization to test the target, and a defined scope
Check Node:
Command: Send below command to terminal
node --version
# Expect: v18.x.x or higherStep-by-Step Setup
Step 1: Add the Playwright MCP Server to Claude Code
One command registers the server. The --scope project flag keeps it to the current engagement directory instead of all your projects.
Command: Send below command to terminal
claude mcp add playwright --scope project -- npx @playwright/mcp@latestThe -- separator matters. Everything after it is the launch command passed straight to the server. Flags placed before -- get read by Claude Code instead of Playwright.
On first run, Playwright installs the browser binaries it needs (Chromium by default).
Note: The older approach of hand-editing an mcp_servers.json file is not how current Claude Code registers servers. Use claude mcp add. Verified against Claude Code and Microsoft Playwright MCP docs, October 2026.
Step 2: Add Flags for Isolated, Headless Runs
For security testing, run each session with a throwaway profile so logins and cookies do not leak between tests. The --isolated flag keeps the browser profile in memory and discards it on close. --headless runs without a visible window.
Remove the server first if you added it without flags:
Command: Send below command to terminal
claude mcp remove playwright
claude mcp add playwright --scope project -- npx @playwright/mcp@latest --isolated --headlessSupported browsers: chromium, firefox, webkit. Pass --browser firefox to switch.
Step 3: Verify the Connection
Start Claude Code in your engagement directory:
Command: Send below command to terminal
claudeConfirm the server is listed with its tools:
Prompt: Send below prompt to Claude Code
/mcpThe playwright server should appear with its browser tools. If it shows as failed, run npx @playwright/mcp@latest directly in the terminal to see the actual error, usually a Node version mismatch or a network issue during the binary download.
Step 4: Run a First Browser Read
Point Claude at a page you own and ask for a structured read:
Prompt: Send below prompt to Claude Code
Role: web app recon assistant.
Task: open https://your-authorized-target.example, snapshot the page, and list every form, input field, and visible link.
Constraint: do not submit any form or click any destructive control.
Output: a markdown table with columns [element type, name/id, action/href].Claude navigates, reads the accessibility tree, and returns the table. From here you build toward real workflows.

Use Case 1: Recon and Entry-Point Mapping
Mapping the app's exposed footprint comes first. Playwright renders JavaScript, so client-side routes and forms injected after load show up that an HTTP scraper never sees.
Ask Claude to enumerate the testable entry points:
Prompt: Send below prompt to Claude Code
Role: web app recon assistant.
Task: crawl https://app.authorized-target.example starting from the home page. Follow in-scope internal links up to depth 2.
For each page, record: URL, forms (with method and action), input fields (name, type), file upload fields, and external script sources.
Constraint: stay on the app.authorized-target.example host. Do not submit forms. Stop after 25 pages.
Output: write results to recon-map.json as an array of page objects.Claude tracks visited URLs, follows in-scope links, extracts the elements, and writes the file. No selector hunting on your part.
What to do with recon-map.json:
Feed file upload fields and input names into targeted fuzzing.
Flag external script sources for supply-chain review.
Sort forms by method to find state-changing
POSTendpoints worth testing first.
Keep Token Cost Down
Reading full page HTML repeatedly burns tokens fast. Keep prompts specific about what to extract, and ask Claude to read the accessibility snapshot or a named DOM section rather than the whole page. Set a page cap so a crawl does not run forever.
Use Case 2: Authenticated Access-Control Testing
Playwright holds browser state (cookies and local storage) across tasks in a session. Claude logs in once and runs checks against that held session.
Broken access control ranks first on the OWASP Top 10. Test it by comparing what two roles can reach

Prompt: Send below prompt to Claude Code
Role: access-control tester.
Task: log into https://app.authorized-target.example.
Use username: [email protected] and password from the env var LOWPRIV_PASS.
Once logged in, navigate directly to each URL in admin-urls.txt.
For each URL, record the HTTP status, the final URL after any redirect, and whether admin-only content rendered.
Constraint: read only. Do not change any data. Do not log the password value.
Output: write a markdown table to idor-results.md with columns [tested URL, status, redirected to, admin content visible (yes/no)].Claude handles the login, requests each admin URL as the low-privilege user, and reports where the app served content it should have blocked. A yes in the last column on an admin-only page is a broken-access-control finding.
Store Credentials in Environment Variables
Never place passwords in the prompt text. Claude includes whatever you type in its tool calls and session logs. Reference an environment variable instead:
Command: Send below command to terminal
export LOWPRIV_PASS='use-a-dedicated-test-account'Use dedicated test accounts with limited permissions. Do not run these flows against production accounts you cannot afford to lock out.
Handling Multi-Factor Prompts
TOTP and SMS codes need you in the loop. The workflow:
Run the login prompt.
Claude pauses at the MFA prompt.
You supply the code.
Claude continues the test.
Run these in headed mode when a step needs manual input.
Reuse Session State Across Runs
Playwright saves browser context (cookies and storage) to a file and reloads it later. Log in once, save, and reuse the session across runs without re-authenticating:
Prompt: Send below prompt to Claude Code
After logging in, save the browser session state to ./auth-state.jsonPrompt: Send below prompt to Claude Code
Load the saved session from ./auth-state.json, then navigate to the account settings page and list every action available to this role.Treat auth-state.json as a live credential. It holds a valid session. Add it to .gitignore, store it outside the repo, and delete it when the engagement ends.
Use Case 3: Security Header and Cookie Checks
Pair Playwright's network read with Claude's reasoning to audit transport and cookie posture across a route list in one pass.
Prompt: Send below prompt to Claude Code
Role: security header auditor.
Task: for each URL in routes.txt, navigate to it and read the main document response headers and all Set-Cookie headers.
Check for: Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, Referrer-Policy.
For each cookie, record whether Secure, HttpOnly, and SameSite are set.
Constraint: in scope hosts only. Read only.
Output: write header-audit.md with one section per URL. Mark each missing header and each cookie missing a flag.Claude reads the network response for each route and reports gaps. Missing HttpOnly on a session cookie, no Content-Security-Policy, or a missing Strict-Transport-Security all land in the report with the exact route.
Run It After Every Deploy
Wire this into a scheduled check so a config change that drops a security header gets flagged on the next run instead of at the next audit. Keep the route list in version control next to the test prompt.
Running Checks in Parallel
Claude runs several browser tasks at once with some setup. Each parallel agent needs its own browser context to avoid session collisions.
Rules that hold up:
Do not share browser contexts between agents. Use
--isolatedper instance.Share output through the filesystem: write to separate result files, merge after.
Set explicit stop conditions so agents do not duplicate work or loop.
Spin up multiple Claude Code instances, each with its own Playwright connection, and coordinate through a shared task list or output directory.
Headless vs. Headed Mode
Headed mode (visible window) fits:
Developing and debugging a test, where you watch what Claude does
Targets that serve different content to headless browsers
MFA flows needing manual input
Headless mode fits:
Scheduled checks where no one is watching
Server and CI environments
Faster runs where a visual is not needed
Switch by adding or dropping --headless in the claude mcp add command, then re-add the server.
Common Problems and How to Fix Them
Target Blocks Playwright
Symptom: The site serves a CAPTCHA, a bot-detection page, or empty content.
Fix: Switch from headless to headed mode. Many detection systems treat headless browsers differently. Slow the action sequence and set a realistic user agent. For authorized tests, coordinate with the app owner to allowlist your test origin.
Claude Loops Without Progress
Symptom: Claude keeps clicking or navigating and makes no headway.
Fix: Add a stop condition to the prompt: "If you stay on the same page for 3 attempts without progress, stop and report what you see." Clear exit criteria are the most effective control against runaway agent runs.
Browser-driving tools touch real systems with real credentials. Follow these rules:
Authorization first. Test only systems you own or hold written scope to assess. Keep the scope document next to the engagement files.
Credentials in env vars, never in prompts. Claude logs tool-call inputs. A password in a prompt ends up in session output.
Isolate profiles. Run with
--isolatedso one test's session does not bleed into another.Treat saved state as secret.
auth-state.jsonand cookies are live access. Keep them out of version control and delete them at the end.Do not paste session logs. Terminal output can contain cookie values and tokens. Redact before sharing.
Conclusion
The Playwright MCP server turns Claude Code into a browser-driving security assistant with structured DOM and network access. Setup is one command. The three workflows that pay off first: recon and entry-point mapping, authenticated access-control testing, and security header checks.
Next steps:
Add the server with
--isolated --scope project.Run the recon prompt against an authorized target and review
recon-map.json.Move to authenticated access-control testing with a dedicated low-privilege account.
Codify the checks that find real issues into scripted Playwright tests.
Further Reading
Ready to apply AI to your Security Engineering?
Subscribe to Secengai Newsletter for weekly actionable content on AI for security engineers.
