EasyPlaywrightMCP
The EasyPlaywrightMCP server enables LLM-driven browser automation for automated testing and demo video creation.
Authentication: Login using password forms, HTTP Basic, OAuth, tokens, or manual headed windows. Handles restricted logins (Google, Microsoft, Apple, etc.) by injecting user-provided credentials. Saves reusable authentication profiles.
Session Management: Start headless or headed Chromium sessions, optionally recording WebM video with synthetic cursor, click highlights, and TTS narration (edge-tts). Query session state (URL, title, ARIA snapshot) to guide LLM decisions.
Action Orchestration: Execute ordered sequences of browser actions (click, type, navigate, scroll, hover, etc.). In demo mode, actions are paced to narration and logged with timing cues.
Video Recording & Compilation: End sessions to finalize recorded videos, trimming idle segments. Compile multiple clips and transition slates into a single narrated MP4 demo with frame interpolation (60fps) and voiceover synchronization.
Use Cases: Automated end-to-end testing with pass/fail reporting, generating narrated product demos from prompts, testing features behind complex OAuth flows, and recording walkthroughs of features or documentation.
Supports automated login with Auth0 OAuth for testing and demo recording, handling session management and restricted auth.
Enables automated authentication against Cloudflare-protected sites, including bot walls, for testing and demo videos.
Facilitates automated login with Discord OAuth, managing sessions for testing and demo recording.
Integrates with Google OAuth (including Sign in with Google) for automated login and session management in testing and demo workflows.
Supports automated login with Okta social authentication, managing sessions for testing and demo video creation.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@EasyPlaywrightMCP Make a demo video of my last PR"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
EasyPlaywrightMCP
LLM-driven Playwright MCP for automated testing and demo videos.
Capture: synthetic cursor + always-on click highlight, 1920×1080 @ deviceScaleFactor 2, WebM→H.264 60fps minterpolate, smooth rAF scroll.
Narration: Microsoft Edge neural TTS via edge-tts.
Install
Client | Guide |
Cursor | |
Cursor CLI | |
Claude Desktop | |
Claude CLI |
Example prompts
Using EasyPlaywrightMCP Make a demo video of the feature in my last PR
Using EasyPlaywrightMCP Connect my google oauth and test this feature in production. Report the success or failure reason for each operation
Using EasyPlaywrightMCP Create a demo video of the steps in this MD
Workflows
Automated testing
login→ saveprofileId(orset_session_authfor Google/bot-blocked OAuth)start_session(usually headless) withprofileIdLoop:
query_session→orchestrate_sessionend_sessionShort answer to the user (pass/fail + findings)
Demo videos
loginif auth is needed (orset_session_authfor restricted providers)start_sessionwithrecordVideoPath(demoMode / auto-narrate on by default)Loop:
query_session→orchestrate_session— put spoken lines indescription/narration; server TTS + holdsend_session(finalizes WebM, trims idle, writes/updates.cues.json)compile_demowith clipvideoPathonly (loads cues automatically)
Demo vs testing: Recording sessions conjoin speech and UI on the server. Testing sessions (no recordVideoPath) keep snappy startMs/endMs pacing.
Restricted auth: For Google OAuth / Sign in with Google (and Microsoft, Discord, Cloudflare bot walls, etc.), do not use headed login. Immediately give the user the login URL, Network → Cookie header steps, and the console snippet from MCP instructions; then set_session_auth with their paste → start_session({ profileId }).
Per-app cookie guides: LinkedIn · Google OAuth / Workspace
Related MCP server: screenwright
Tools & type examples
login
// LoginInput
{
siteUrl: "https://app.example.com",
authUrl: "https://app.example.com/login",
username?: "user@example.com",
password?: "secret",
oauth?: {
accessToken?: "eyJ...",
cookies?: [{ name: "sid", value: "x", domain: "app.example.com" }],
localStorage?: [{ name: "token", value: "eyJ..." }]
},
httpCredentials?: { username: "u", password: "p" },
tokens?: { bearer?: "eyJ...", cookies?: [], localStorage?: [] },
timeoutMs?: 120000,
profileId?: "prof_abc" // reuse
}
// LoginResult → { ok: true, profileId: "prof_…", strategy: "password" }Strategies: password · http_basic · token_inject · oauth_tokens · manual (headed OAuth/password window) · reuse_profile
set_session_auth
// SetSessionAuthInput
{
siteUrl: "https://app.example.com/dashboard",
credentialsJson: JSON.stringify({
origin: "https://app.example.com",
cookies: [{ name: "session", value: "abc", domain: "app.example.com", path: "/" }],
localStorage: [{ name: "token", value: "eyJ..." }],
sessionStorage: []
}),
sessionId?: "sess_…", // optional: also inject into a live session
authUrl?: "https://app.example.com/login"
}
// → { ok: true, profileId: "prof_…", strategy: "restricted_auth", sessionId?: "sess_…" }Use when the user must log in in their own browser. Always (Google OAuth / Sign in with Google, Microsoft, Apple, Discord, Cloudflare Turnstile, Okta/Auth0 social). Accepts Network Cookie-header snippet JSON or Playwright storageState. Always saves a reusable profileId.
start_session
{
startUrl?: "https://app.example.com/dashboard",
headed?: false,
recordVideoPath?: "C:/Videos/clip.webm", // omit = no record; set => demoMode
narrate?: true, // default true when recording; false = silent capture
voice?: "en-US-AndrewNeural",
rate?: "+10%",
profileId?: "prof_abc"
}
// → { sessionId: "sess_…", headed: false, recording: true, demoMode: true, startUrl?: "…" }query_sessions / query_session
// query_session
{ sessionId: "sess_…" }
// → { url, title, viewport, ariaSnapshot, interactive: [{ role, name, selectorHint, inputType? }] }orchestrate_session
{
sessionId: "sess_…",
recordStepsPath?: "C:/Videos/steps.md",
commands: [
{
action: "click", // move|click|tap|type|press|scroll|wait|navigate|select|hover|upload
description: "Open Settings from the sidebar", // also default VO text in demoMode
narration?: "Spoken override",
skipNarration?: false,
startMs: 0, // ignored for pacing while recording
endMs: 1000,
selector: "nav >> text=Settings",
speed: "fast", // fast (default) | slow | timed
fill?: false, // demos: false for live typing
files?: ["C:/path/to/file.pdf"], // upload action
useFileChooser?: false // upload: click + FileChooser instead of setInputFiles
}
]
}
// → { commands: [{ index, description, action, startMs, endMs, videoStartMs?, videoEndMs?, ok, reason? }] }
// Recording also writes C:/Videos/clip.cues.jsonend_session
{ sessionId: "sess_…" }
// → { ok: true, videoPath?: "C:/Videos/clip.webm" }compile_demo
{
outputPath: "C:/Videos/final-demo.mp4",
fast?: false, // skip minterpolate for quick check
content: [
{
kind: "slate",
eyebrow: "INTRO",
heading: "Product Demo",
body: "A quick walkthrough",
durationMs: 3000,
narration: [{ startMs: 0, endMs: 2800, text: "Welcome to the demo." }]
},
{
kind: "clip",
videoPath: "C:/Videos/clip.webm" // loads clip.cues.json automatically
}
]
}
// → { ok: true, outputPath: "C:/Videos/final-demo.mp4" }Prerequisites
Node 20+
ffmpeg/ffprobeon PATH (Gyan build:winget install Gyan.FFmpeg)python -m pip install edge-ttsChromium via
npx playwright install chromium(runs onnpm install)
Install
Hey Siri, install https://github.com/Macioa/EasyPlaywrightMCP to cursor
Client | Doc |
Cursor IDE | |
Cursor CLI | |
Claude Desktop | |
Claude Code CLI |
npm install
npm run build
npm start # stdio MCP
npm test
npm run typecheckAuth profiles and scratch files live under %USERPROFILE%\.easy-playwright-mcp\.
Available Tools
8 toolscompile_demoA
Compile demo clips + slate segways into one narrated MP4. Pipeline: convert (minterpolate 60fps H.264) → burn captions → VO → splice. For recorded clips, pass videoPath only — loads sibling .cues.json (wins over hand-authored narration). Slates still take explicit narration.
Example:
{
"outputPath": "C:/Videos/final-demo.mp4",
"fast": false,
"content": [
{
"kind": "slate",
"eyebrow": "INTRO",
"heading": "Product Demo",
"body": "A quick walkthrough",
"durationMs": 3000,
"narration": [{ "startMs": 0, "endMs": 2800, "text": "Welcome to the demo." }]
},
{
"kind": "clip",
"videoPath": "C:/Videos/demo-clip.webm"
}
]
}Inputs: content (required), outputPath (required), fast, rate, +1 more.
end_sessionA
End a session and finalize recorded video if any. Recording sessions: trims idle head/tail using cues.json actionSpan, then returns videoPath. Example: { "sessionId": "sess_01HXYZ" } Returns: { "ok": true, "videoPath": "C:/Videos/demo-clip.webm" }
Inputs: sessionId (required).
loginA
Orchestrate login and persist Playwright storageState. Strategies: password form, HTTP Basic, bearer/token inject, OAuth cookies/tokens, manual/OAuth window, reuse profileId. Auto (headless) when enough creds/tokens are provided; otherwise opens a headed window and waits.
DO NOT use this tool for Google OAuth / Sign in with Google, Microsoft/Apple/Discord social login, Cloudflare bot walls, or other restricted IdPs — those require set_session_auth. If you are about to open a headed login for Google OAuth, stop and follow the Restricted auth user-message template instead.
Example input:
{
"siteUrl": "https://app.example.com",
"authUrl": "https://app.example.com/login",
"username": "user@example.com",
"password": "secret"
}Example success: { "ok": true, "profileId": "prof_abc", "strategy": "password" }
Inputs: authUrl (required), siteUrl (required), oauth, tokens, +5 more.
orchestrate_sessionA
Execute ordered tap/cursor/keyboard actions. Recording/demoMode: server synthesizes TTS from narration|description, runs the action, holds until VO ends. startMs/endMs are ignored for pacing while recording (placeholders OK). fill=false for live typing. Testing (no recording): startMs/endMs pace the batch; each call clock starts near 0. Optional recordStepsPath writes an MD log. Recording also writes sibling .cues.json.
Example (demo):
{
"sessionId": "sess_01HXYZ",
"commands": [
{
"action": "click",
"description": "Open Settings from the sidebar",
"startMs": 0,
"endMs": 1000,
"selector": "nav >> text=Settings",
"speed": "fast"
},
{
"action": "type",
"description": "Enter the billing search query",
"narration": "Now we search for billing.",
"startMs": 0,
"endMs": 1000,
"selector": "input[type=search]",
"text": "billing",
"fill": false
}
]
}Inputs: commands (required), sessionId (required), recordStepsPath.
query_sessionB
Fast page digest for LLM navigation decisions: url, title, viewport, ariaSnapshot, interactive controls. Example: { "sessionId": "sess_01HXYZ" }
Inputs: sessionId (required).
query_sessionsA
List all active sessions with sessionId, url, title, recording, createdAt, headed.
Inputs: no named parameters.
set_session_authA
Inject user-browser credentials into Playwright (restricted auth). ALWAYS saves profileId; optional sessionId applies to a live session.
BEFORE calling this tool: you MUST already have sent the user (same conversation) the login URL + Network Cookie steps + JS snippet from server instructions. Never call this tool "speculatively" without first giving those instructions. Never open headed login for Google OAuth — use this flow.
Triggers: Google OAuth / Sign in with Google, Gmail/Google apps, Microsoft/Entra, Apple, Discord OAuth, Cloudflare Turnstile on login, Okta/Auth0 social IdP, or any login Playwright cannot complete.
Accepts credentialsJson from the console snippet (Cookie header + storage) or Playwright storageState JSON.
Example (after user pastes):
{
"siteUrl": "https://mail.google.com/",
"credentialsJson": "{...paste from user...}"
}Returns: { "ok": true, "profileId": "prof_…", "strategy": "restricted_auth" }
Inputs: siteUrl (required), credentialsJson (required), authUrl, sessionId.
start_sessionA
Start a Playwright Chromium session (headless or windowed) and keep it open. Optional recordVideoPath enables WebM capture at 1920×1080 @ deviceScaleFactor 2 with synthetic cursor and always-on click highlight. When recording, demoMode is on (narrate defaults true): orchestrate auto-paces to TTS. Pass profileId from login or set_session_auth to reuse auth.
Example:
{
"startUrl": "https://app.example.com/dashboard",
"headed": false,
"recordVideoPath": "C:/Videos/demo-clip.webm",
"profileId": "prof_abc"
}Returns: { "sessionId": "sess_…", "headed": false, "recording": true, "demoMode": true, "startUrl": "…" }
Inputs: rate, voice, headed, narrate, +4 more.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 8 tools
Each tool has a clear, distinct purpose: authentication (login, set_session_auth), session querying (query_sessions, query_session), session lifecycle (start_session, orchestrate_session, end_session), and video compilation (compile_demo). No two tools overlap in functionality.
Tool names follow a mostly consistent verb_noun pattern with snake_case (e.g., query_sessions, start_session). The exception is 'login', which is a bare verb, but it's a common convention and does not cause confusion.
With 8 tools, the server is well-scoped. Each tool adds necessary functionality for Playwright automation and demo creation without redundancy or bloat.
The tool surface covers core workflows: authentication, session management, interaction orchestration, and video compilation. A minor gap is the lack of explicit profile management (e.g., list/delete profiles), but it does not break essential workflows.
Related MCP Connectors
Demo-video assistant: records your web app click by click and returns an MP4 with zooms, captions.
Make narrated demo videos of web apps from your AI assistant.
Approved test intent, reviewed Playwright automation and run evidence, inside your editor.
Record demos of your web app from one sentence and turn its product map into help articles and more.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables automated browser testing of web applications using Playwright, supporting user interactions, form submissions, console monitoring, network request inspection, and visual verification through screenshots.-
- AlicenseNot gradedqualityDmaintenanceEnables users to create subtitled tutorial videos by scripting browser interactions with Playwright, outputting MP4 with burned-in captions and SRT file.47 npm4MIT
- AlicenseNot gradedqualityBmaintenanceEnables browser automation and smoke testing via Playwright, with tools for navigation, DOM interaction, screenshots, network capture, and more.5 npm2MIT
- AlicenseAqualityBmaintenanceRecords narrated walkthroughs of any webapp by orchestrating Playwright, speech-mcp TTS, and FFmpeg composition.62MIT