
Playwright E2E MCP
io.github.trajectiq-aiv0.1.0Updated Oct 5, 2026
Run and debug Playwright E2E tests: failure analysis, DOM inspection, visual diffs, flaky diagnosis.
Overview
Lets an assistant run, debug, and inspect Playwright end-to-end tests, with structured failure diagnostics, live DOM inspection, and visual diffs.
- What it does
- Exposes eight tools around Playwright: run-test runs specs and returns pass/fail stats plus classified failures and fix hints; get-failure digs into one failure with stack, expected/actual, the DOM snapshot from the trace, failed network requests, and console errors; list-tests enumerates specs. It also inspects live pages headlessly, validates CSS selectors, scaffolds tests from real selectors, compares visual state against a baseline, and re-runs a failing test 2-10 times to decide whether it is flaky or consistently broken.
- When to use it
- Useful when a project already has Playwright end-to-end tests and you want an assistant to run them, explain failures, fix broken selectors, catch visual regressions, or judge whether a failure is flaky. Less relevant if you have no Playwright suite or only need unit tests.
- Requirements
- Local process via npx or a local checkout. Needs Node.js 20 or newer, a project with @playwright/test installed, and Playwright browsers (for example npx playwright install chromium). Optional environment variables PW_MCP_PROJECT_ROOT, LOG_LEVEL, and LOG_FORMAT. A running dev server is needed for tests that hit the app.
Installation
In SourceWeft
- Open Playwright E2E MCP in the dashboard and add it to a workspace.
- Enable the server for the chats that should use its tools.
Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.
Other MCP clients
Follow the launch instructions in the repository.
README
playwright-e2e-mcp
An MCP server that lets AI agents run, debug, and inspect Playwright end-to-end tests — with structured results, actionable failure diagnostics, and live DOM inspection.
Instead of handing an agent raw Playwright output, this server turns every run into
machinable results: pass/fail stats, per-failure messages with file:line, a failure
kind (assertion, timeout, browser crash, syntax error, dead dev server, full disk…),
and a concrete "how to fix" hint. When a test fails because a selector no longer
matches, the agent can open the live page in a headless browser, see the real DOM
with unique CSS selectors, and validate the replacement selector before re-running.
Tools
run-test
Flakiness handling: by default the server injects --retries=1 (unless the config
already sets retries), so a test that passes on the retry is reported as flaky,
not failed. Traces are captured automatically (--trace=retain-on-failure) so
get-failure can show the DOM at the moment of failure.
Example result:
get-failure
Returns the message/code frame, expected vs actual, stack, failure kind with a
diagnosis, the test's console output, the DOM snapshot from the Playwright trace
(plus the failed action, its selector, and the action log leading up to it),
the network requests that failed (4xx/5xx, dead endpoints, no-response — with
method, URL, status and resource type), the console errors/warnings the page
logged before the failure, and
numbered next steps (re-run this single test by file:line, headed/debug mode,
validate-selector when the message mentions a locator, …).
inspect-page
Returns each element's unique CSS selector, tag, visibility, bounding box, text and attributes, plus captured console messages (errors first).
list-tests
Uses playwright test --list when Playwright works, and falls back to a source scan
(keeping the reason) when the install or a spec file is broken.
validate-selector
Verdicts: ✅ VALID — N matches (with a sample of matches), ✅ VALID — 0 matches
(with debugging advice), ❌ INVALID (parse error + fix), or a warning when the input
uses a Playwright-only engine (text=, xpath=, >>, :has-text()), which is not
plain CSS.
generate-e2e-test
Reads the agent's recent changes (git status, falling back to git diff HEAD~1,
then recent mtimes), extracts the locators those files actually declare
(data-testid, getByRole, aria-label, placeholder, id, name, element text),
ranks verified-live selectors first, writes a spec built from them, and reports each
selector with its source file:line.
compare-visual-state
The first call saves a baseline under .pw-mcp/visual/ (add that to .gitignore, or
commit it for CI comparisons). Later calls report changed-pixel counts, merged
regions ((x, y) 120×40 — 1,200 px), the average color shift ("blue → red"),
and write a red-highlighted diff image for review.
diagnose-flaky
Every run executes with --retries=0 and auto-retry disabled, so each result is
honest evidence. The response contains a per-run table (status, duration, first
failure), the count of distinct normalized error signatures, and one of:
- ❌ CONSISTENTLY FAILING — failed every run (same error → reproducible bug, different errors → still broken, just noisy). Fix it; it is not flaky.
- ⚠️ FLAKY — some runs passed. Includes
N of Mcounts and whether the failures share one signature (real intermittent bug) or vary (timing/environment instability). - ✅ NOT REPRODUCING — passed every re-run; the original failure was one-off.
The last run is stored, so get-failure can analyze it immediately afterwards.
Installation
Requirements:
- Node.js ≥ 20 (the server is built on MCP SDK v2 — the
2026-07-28spec line) - A project with
@playwright/testinstalled and browsers available (npx playwright install chromium)
No npm account needed — install straight from GitHub (the prepare script
builds dist/ automatically on install):
Or grab the packaged tarball from the repo's GitHub Releases page and install it locally:
Listed in the official MCP Registry as
io.github.trajectiq-ai/E2E — registry-aware clients discover it there, and every
v* release tag republishes the entry from CI via server.json.
MCP client configuration
Claude Code / generic (project-scoped):
Claude Desktop / Cursor / Windsurf: add the same block to their MCP config file.
The server uses its working directory as the project root; set PW_MCP_PROJECT_ROOT
when the client launches it somewhere else (e.g. your home directory).
Codex / VS Code / Copilot CLIs:
Claude Desktop (one-click): download and double-click the .mcpb Desktop
Extension attached to the latest release —
the bundle ships its own dependencies, so no Node setup is required.
Claude Code:
Gemini CLI / Qwen Code: paste the mcpServers block above into
.gemini/settings.json (Qwen Code: .qwen/settings.json) — both speak the same
MCP settings format.
All tools ship MCP tool annotations (readOnlyHint, destructiveHint,
idempotentHint, openWorldHint), so clients can show accurate safety prompts
before running anything.
From a local checkout:
Configuration
Logs always go to stderr — stdout is reserved for the MCP protocol.
Typical workflow
generate-e2e-test{ "description": "checkout with a saved card" }— scaffolds a spec from your real selectors (skipped if you write the test yourself).list-tests— see what exists (tests/checkout.spec.ts:5 checkout › pays with card).run-test{ "testFiles": ["tests/checkout.spec.ts"] }— run it; get stats + failures (flaky tests are auto-retried once before being called failures).get-failure{ "index": 1 }— read the code frame, expected/actual, the DOM snapshot at failure from the trace, the failed network requests, the page's console errors, and next steps.- If it looks selector-related:
inspect-page{ "url": "http://localhost:3000/checkout" }to see the real DOM, thenvalidate-selectorto prove the replacement selector works. - After changing CSS/components:
compare-visual-state{ "url": "…", "name": "checkout" }to catch unintended visual regressions. - If a failure looks intermittent:
diagnose-flaky{ "runs": 3 }— get the evidence verdict (flaky vs consistently broken) before deciding what to fix. - Fix the spec or the app, then re-run only what failed:
run-test{ "lastFailed": true }, and repeat until green.
Edge cases handled
Security notes
- No shell: Playwright is spawned as
node <playwright/cli.js> …with an argument array — no command interpolation. - Path sandbox: user paths are resolved lexically and must stay inside the project root.
- Cleanup: temp report/script files are written to the OS temp dir and removed; child processes are tracked and killed on shutdown.
Development
Built on @modelcontextprotocol/server v2 (the 2026-07-28 MCP spec line) with
Zod v4 standard schemas; every tool declares spec tool annotations.
Tests cover the report parser (sample Playwright JSON, trace attachments), path utils
(Windows and macOS paths, sandboxing), the project detector (temp-dir fixtures: config
discovery, multiple configs, missing install, test-file scanning), the shared tool
helpers, the trace reader (synthetic trace.zip: error, failed action, DOM snapshot,
*.network failed-request parsing, console error/warning events), the image diff
(PNG round-trip, regions, color shift, dimension changes), the change analyzer
(selector extraction, git + mtime paths) and the flaky verdict logic
(failure signatures, CONSISTENTLY FAILING / FLAKY / NOT REPRODUCING / NO TESTS RAN).
Integration suite (npm run e2e)
Unit tests prove the logic; the integration suite proves the loop. It boots the real
server over stdio against a live fixture app and a Playwright project under
e2e/fixture/, then drives it exactly like an MCP client and asserts ~40 behaviours
that only appear end-to-end:
- initialize handshake, 8 tools, spec tool annotations and object input schemas,
- live DOM inspection, CSS selector validation (matches, zero matches, engine syntax, parse errors), dead-server detection,
- visual regression: baseline → unchanged compare →
blue → reddiff detection, run-testpass/fail/lastFailedstats and meta lines,get-failuretrace diagnostics: DOM at failure, the 404 network request, theconsole.errormessage, diagnosis and next steps,- auto-retry turning a first-run failure into
PASSED (1 flaky), diagnose-flakyverdict FLAKY (2 of 3 runs) with retries disabled,generate-e2e-testwriting its scaffold, plus error paths (missing test path, unknown tool, unreachable server).
First run needs the browser once: npx playwright install chromium.
CI runs the suite on Ubuntu and Windows (see .github/workflows/ci.yml).
Try the example
With Playwright installed in your project:
or ask your agent to call run-test with
"testFiles": ["examples/sample-test.spec.ts"] — it hits the public
example.com page, so it verifies browsers, network and the MCP
pipeline in one shot.
License
MIT
Source: README.md at commit 7b3a543
Tools
0Version history
1- v0.1.0LatestOct 5, 2026


