
Windsurf’s Cascade agent can now open a browser, click through the feature it just wrote, read the console errors, and fix them before you ever hit refresh. That’s the practical payoff of a Windsurf Playwright MCP setup — native MCP server configuration in the IDE plus Browser Preview, wired to Microsoft’s official Playwright MCP server. The gap between devs who have this configured and devs who don’t is measured in hours of manual smoke-testing per sprint. Here’s the copy-paste build, the config file, the prompts that work, and the honest failure modes.
What’s new in the Windsurf Playwright MCP setup
Two things converged. First, Windsurf shipped first-class Model Context Protocol support inside Cascade — a plugin store with one-click installs, plus a raw mcp_config.json escape hatch for anything not in the store. You get an MCP toggle in the Cascade panel, per-server enable/disable, and tool-level visibility so you can see exactly which tools the agent has been handed. That last part matters more than it sounds: Cascade has a working tool budget, and Playwright MCP alone exposes roughly two dozen tools. Without per-tool control you burn context on browser plumbing before the agent reads a single file.
Second, Microsoft’s Playwright MCP server matured past the demo phase. The key design decision: it drives the browser through Playwright’s accessibility tree, not screenshots. The agent receives a structured, labeled snapshot of the page — roles, names, states, and stable element references — instead of pixels it has to squint at with a vision model. No screenshot tokens, no coordinate guessing, deterministic element targeting. It’s faster, cheaper, and dramatically more reliable than vision-driven clicking, and it’s why a Playwright MCP server loop can run twenty steps without drifting.
Combine those with Browser Preview — Windsurf’s in-IDE browser that pipes console logs, network errors, and DOM selections straight back into Cascade’s context — and you have a closed loop. Cascade writes code, launches it, drives it, reads what broke, and patches it. The manual step you used to do between “it compiles” and “ship it” is now something the agent does to itself. That’s the whole AI browser testing workflow in one sentence.
Why it matters
- Smoke tests stop being a human chore. “Log in, add to cart, check out, confirm the order number renders” is a prompt now, not a fifteen-minute click-through you skip when you’re in a hurry.
- The feedback loop closes inside the IDE. No copy-pasting console errors into chat. Cascade reads the failure and the source file in the same context window, which is where most of the accuracy gain comes from.
- Accessibility-tree targeting kills flaky selectors. The agent works from roles and accessible names, so the tests it generates lean on
getByRoleandgetByLabelinstead of brittle CSS chains — the same thing Playwright’s own docs have been begging teams to do for years. - You get real test files, not just a passing vibe. Ask Cascade to persist the successful run as a
.spec.tsand you’ve converted an exploratory session into CI coverage. The exploration pays for itself twice. - It surfaces accessibility bugs for free. If the agent can’t find your button because it has no accessible name, neither can a screen reader. Broken a11y becomes a hard blocker instead of a backlog ticket.
- Reproducing user bug reports gets cheap. Paste the steps from the ticket, let the agent walk them, and get a stack trace plus a failing test in one pass.
How to use it today: the copy-paste Windsurf Playwright MCP setup
Budget ten minutes. You need Node 18+ and Windsurf updated to a build with the MCP panel (Cascade → the hammer/plugin icon in the input toolbar).
-
Confirm the server runs standalone first. Never debug two things at once. Run it in your terminal and watch for a clean start:
npx @playwright/mcp@latest --helpIf that hangs or 404s, fix your npm registry access before touching Windsurf. Install the browser binaries once:
npx playwright install chrome -
Open the Cascade MCP config. In Cascade, click the plugin icon, then Configure (or edit the file directly). Paths:
# macOS / Linux ~/.codeium/windsurf/mcp_config.json # Windows %USERPROFILE%\.codeium\windsurf\mcp_config.json -
Add the server. This is the minimal working mcp_config.json Windsurf block — the whole file, not a fragment:
{ "mcpServers": { "playwright": { "command": "npx", "args": ["-y", "@playwright/mcp@latest"] } } }On Windows, if the IDE’s environment doesn’t resolve
npx, use the shell wrapper form:{ "mcpServers": { "playwright": { "command": "cmd", "args": ["/c", "npx", "-y", "@playwright/mcp@latest"] } } } -
Tune the flags for real work. The defaults are conservative. This is the config I actually run — isolated profile so sessions don’t inherit cookies, a fixed viewport for reproducibility, and a save directory for traces:
{ "mcpServers": { "playwright": { "command": "npx", "args": [ "-y", "@playwright/mcp@latest", "--browser", "chrome", "--isolated", "--viewport-size", "1280,800", "--save-trace", "--output-dir", "./.playwright-mcp" ] } } }Add
./.playwright-mcpto your.gitignore. Traces are large and contain whatever was on screen. -
Restart Cascade and verify the tools loaded. Hit refresh in the MCP panel. You should see the
playwrightserver green with its tool list —browser_navigate,browser_snapshot,browser_click,browser_type,browser_console_messages, and friends. If it’s red, the error is almost always the command path, not the config schema. -
Disable the tools you don’t need. Everyone skips this step and then complains about context bloat. Turn off PDF, tab management, and file-upload tools unless your flow uses them. Fewer tools, sharper agent.
-
Run your dev server, then give Cascade a QA prompt. Be specific about the assertion, not just the steps — a vague prompt gets you a vague “looks good.” This is the shape that works:
Using the Playwright MCP tools, QA the signup flow at http://localhost:3000. 1. Navigate to /signup 2. Take a snapshot and list every form field by its accessible name 3. Submit the form empty — confirm each required field shows an inline error 4. Fill valid data (use qa+{timestamp}@example.com), submit 5. Confirm redirect to /welcome and that an h1 containing the user's first name is present 6. Read the browser console and report any errors or warnings Do not fix anything yet. Report findings as a numbered list with the exact element refs and console output. Then wait for my go-ahead.The “do not fix anything yet” line is load-bearing. Without it, Cascade starts editing files midway through the run and you lose the clean diagnostic.
-
Convert the successful run into a permanent test. Once the flow passes, cash it in:
Write that exact flow as a Playwright test at tests/e2e/signup.spec.ts. Use getByRole and getByLabel locators only — no CSS or XPath selectors. Use web-first assertions (expect(locator).toBeVisible()), no manual waits or timeouts. Then run it and paste the output.Then verify it yourself outside the agent:
npx playwright test tests/e2e/signup.spec.ts --reporter=list -
Wire it into CI. The agent-authored spec is worthless if it only runs when you remember. Minimal GitHub Actions step:
- name: E2E run: | npm ci npx playwright install --with-deps chromium npx playwright test --reporter=github
One rule to save you a bad afternoon: point the agent at localhost and staging, never production. An agent with click-and-type authority over a live admin panel is a destructive tool wearing a helpful hat. Use --isolated, use throwaway credentials, and keep production out of the loop.
How it compares
| Approach | How it sees the page | Setup cost | Best for | Main drawback |
|---|---|---|---|---|
| Windsurf Cascade + Playwright MCP | Accessibility tree (structured) | ~10 min, one JSON file | In-IDE QA loop on code you just wrote | Tool count eats context if untrimmed |
| Cursor + Playwright MCP | Accessibility tree | Comparable; same server, different config path | Teams already standardized on Cursor | No equivalent of Browser Preview’s console piping |
| Windsurf Browser Preview alone | Console, network, DOM selection | Zero — built in | Reading errors from a page you drive yourself | You do the clicking; no scripted multi-step runs |
| Browser-use / vision agents | Screenshots + coordinates | Moderate, Python-side | Sites where the DOM is hostile or canvas-based | Slower, pricier, less deterministic |
| Hand-written Playwright specs | Your selectors | High per flow | Stable regression suites in CI | Nobody writes them for exploratory QA |
The honest read: these aren’t competitors so much as stages. Use the Cascade browser preview plus MCP loop for exploration and fast feedback, then graduate the flows that matter into committed spec files. Vision agents are a fallback for the ten percent of pages where the accessibility tree is genuinely useless.
What’s next
The obvious near-term direction is persistence and parallelism. Each QA session is ephemeral today — the agent drives, reports, and the browser state evaporates. Expect richer session reuse (authenticated storage state handed to the agent so it doesn’t re-login on every run) and multi-context runs so a single prompt can check desktop and mobile viewports side by side. The --storage-state and --save-session flags on the Playwright MCP server are already the seed of this.
The second thing to watch is where the loop runs. An automated QA with AI agent workflow that only fires when a developer types a prompt leaves most of its value on the table. The natural end state is the same MCP-driven agent running headless in CI against a preview deployment, triaging its own failures and opening a PR with the fix — the human reviews a diff instead of a video. Cascade already has the file-editing half; the missing pieces are cost control and a trust boundary that stops an agent from “fixing” a test by deleting the assertion.
Third: watch for MCP security hardening. Giving a language model a browser makes prompt injection a live attack surface — a malicious page can contain text aimed at your agent, and the agent will read it as instructions. Expect origin allowlists, tool-call confirmation prompts, and read-only browser modes to become standard config. If you’re rolling this out to a team, treat the browser tool set the way you’d treat shell access: scoped, logged, and never pointed at anything you can’t afford to have clicked.
Frequently Asked Questions
Do I need to install Playwright in my project to use the MCP server?
No. The Playwright MCP server runs via npx @playwright/mcp@latest as its own process with its own browser binaries. You only need Playwright as a project dependency when you start committing generated .spec.ts files and running them in CI — which you should, but it’s a separate step.
Why does Cascade say the server failed to start?
Ninety percent of the time it’s the command path. Windsurf spawns the server with the IDE’s environment, not your shell’s, so a Node installed via nvm or fnm may not be on PATH. Fix it with the absolute path to npx, or on Windows by wrapping with cmd /c as shown above. Check the MCP panel’s error output — it prints the actual spawn error, and it’s rarely a JSON problem.
How is this different from just using Browser Preview?
Browser Preview is a viewer that feeds console output and DOM selections back to Cascade — you still do the navigating. The Windsurf Cascade MCP config route gives the agent actuation: it navigates, clicks, types, waits, and reads results on its own across many steps. In practice you run both, because Browser Preview’s console piping is the fastest way to hand the agent a runtime error you noticed yourself.
Can it test flows behind a login?
Yes, two ways. Let the agent log in with throwaway credentials as step one of the flow, or pre-authenticate once and pass the saved session with --storage-state ./auth.json so every run starts logged in. The second is faster and avoids hammering your auth endpoint. Never put real credentials in the config file or the prompt — use a dedicated QA account.
Does this replace writing Playwright tests?
It replaces writing the first draft and it replaces manual smoke-testing. It does not replace a curated regression suite. Agent-generated specs need review — they tend toward over-asserting on incidental text and under-asserting on the thing that actually matters. Read the diff, tighten the assertions, commit it.
What’s the biggest mistake people make with this setup?
Leaving every browser tool enabled and then wondering why the agent is slow and forgetful. Trim the tool list to navigate, snapshot, click, type, wait, and console. The second biggest mistake is writing prompts that describe steps without stating the expected outcome — “click through checkout” gets you a confident “done!” while “confirm the order confirmation page shows an order number matching /^ORD-\d{6}$/” gets you an actual verdict.
Go deeper than this article
This article covers the essentials. Our Technical & Coding eguide collection gives you the full step-by-step playbooks — prompts, workflows, and copy-paste recipes built for exactly this work.