Playwright MCP Server
Playwright MCP servers enable AI models to perform cross-browser automation, modern web testing, accessibility testing, and end-to-end testing workflows using Playwright's powerful browser automation capabilities.
Overview
The Playwright MCP Server enables AI models to perform browser automation using Microsoft's Playwright framework through the Model Context Protocol. Unlike traditional screenshot-based approaches, it uses structured accessibility snapshots for fast, deterministic, and LLM-friendly browser interactions.
Official & Community Implementations:
Official: Microsoft Playwright MCP - Fast, accessibility-tree based automation
Community: @executeautomation/playwright-mcp-server - Enhanced with code generation and API testing
Key Features
Cross-Browser Testing
Test across Chromium, Firefox, WebKit, and Microsoft Edge browsers
Accessibility-First
Uses structured accessibility trees instead of pixel-based input
Fast & Lightweight
No vision models needed, operates on structured data
Test Code Generation
Record actions and generate Playwright test scripts automatically
Available Tools
Quick Reference
| Tool | Purpose | Category |
|---|---|---|
playwright_navigate | Navigate to URL | Navigation |
playwright_click | Click elements | Interaction |
playwright_fill | Fill input fields | Forms |
playwright_select | Select dropdown options | Forms |
playwright_screenshot | Capture screenshots | Testing |
playwright_evaluate | Execute JavaScript | Scripting |
playwright_hover | Hover over elements | Interaction |
playwright_press_key | Press keyboard keys | Interaction |
playwright_drag | Drag and drop elements | Interaction |
playwright_upload_file | Upload files | Forms |
playwright_get_visible_text | Extract visible text | Content |
playwright_get_visible_html | Get page HTML | Content |
playwright_console_logs | Retrieve console logs | Debugging |
playwright_expect_response | Monitor HTTP responses | API Testing |
start_codegen_session | Start test recording | Code Gen |
end_codegen_session | Generate test file | Code Gen |
Detailed Usage
playwright_navigate▶
Navigate to a URL with configurable browser and viewport options.
// Basic navigation
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com"
}
});
// Navigate with specific browser
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com",
browserType: "firefox" // chromium, firefox, webkit, msedge
}
});
// Navigate with custom viewport
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com",
width: 1920,
height: 1080,
headless: false
}
});
Returns navigation status and page load confirmation.
playwright_click▶
Click elements on the page using CSS selectors.
// Single click
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_click",
arguments: {
selector: "button.submit"
}
});
// Double click
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_click",
arguments: {
selector: ".expandable-item",
doubleClick: true
}
});
// Click and switch to new tab
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_click_and_switch_tab",
arguments: {
selector: "a[target='_blank']"
}
});
// Click inside iframe
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_iframe_click",
arguments: {
iframeSelector: "#payment-iframe",
selector: "button.pay-now"
}
});
Returns click confirmation and element state.
playwright_screenshot▶
Capture screenshots of pages or specific elements.
// Viewport screenshot
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "homepage-view"
}
});
// Full page screenshot
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "full-page",
fullPage: true
}
});
// Element screenshot
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "header",
selector: "header.main-nav"
}
});
// Save as PNG file
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "dashboard",
savePng: true,
downloadsDir: "./screenshots"
}
});
Returns screenshot data or file path.
playwright_fill▶
Fill input fields, textareas, and contenteditable elements.
// Fill text input
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_fill",
arguments: {
selector: "input[name='email']",
value: "[email protected]"
}
});
// Fill password field
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_fill",
arguments: {
selector: "input[type='password']",
value: "SecurePass123!"
}
});
// Fill inside iframe
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_iframe_fill",
arguments: {
iframeSelector: "#contact-form-iframe",
selector: "textarea#message",
value: "Hello, this is a test message"
}
});
Clears existing value before filling.
playwright_select▶
Select options from dropdown menus.
// Select by value
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_select",
arguments: {
selector: "select[name='country']",
value: "US"
}
});
// Select by label
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_select",
arguments: {
selector: "select#language",
value: "English"
}
});
Returns selected option value.
playwright_evaluate▶
Execute JavaScript code in the browser context.
// Get page title
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_evaluate",
arguments: {
script: "document.title"
}
});
// Extract data
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_evaluate",
arguments: {
script: `
Array.from(document.querySelectorAll('.product'))
.map(p => ({
name: p.querySelector('.name').textContent,
price: p.querySelector('.price').textContent
}))
`
}
});
// Modify page
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_evaluate",
arguments: {
script: `
document.querySelector('.modal').style.display = 'none';
return 'Modal hidden';
`
}
});
Returns the result of the JavaScript expression.
playwright_upload_file▶
Upload files to file input elements.
// Single file upload
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_upload_file",
arguments: {
selector: "input[type='file']",
filePath: "/path/to/document.pdf"
}
});
// Multiple file upload
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_upload_file",
arguments: {
selector: "input[type='file'][multiple]",
filePath: [
"/path/to/image1.jpg",
"/path/to/image2.jpg"
]
}
});
Returns upload confirmation.
playwright_get_visible_text▶
Extract all visible text from the page (excludes hidden elements).
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_get_visible_text",
arguments: {}
});
Returns plain text content visible to users.
playwright_get_visible_html▶
Retrieve page HTML with filtering and cleaning options.
// Get clean HTML
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_get_visible_html",
arguments: {
removeScripts: true,
removeComments: true,
cleanHtml: true
}
});
// Get minified HTML
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_get_visible_html",
arguments: {
minify: true
}
});
Returns filtered HTML source code.
playwright_console_logs▶
Retrieve browser console logs with filtering options.
// Get all console logs
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_console_logs",
arguments: {}
});
// Search for specific logs
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_console_logs",
arguments: {
search: "error",
type: "error"
}
});
// Get limited logs and clear
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_console_logs",
arguments: {
limit: 50,
clear: true
}
});
Returns array of console messages with types and timestamps.
start_codegen_session▶
Start recording browser actions to generate Playwright test scripts.
use_mcp_tool({
server_name: "playwright",
tool_name: "start_codegen_session",
arguments: {
outputPath: "./tests",
testNamePrefix: "user-login",
includeComments: true
}
});
Returns session ID for tracking the recording.
end_codegen_session▶
Finalize recording and generate test file.
use_mcp_tool({
server_name: "playwright",
tool_name: "end_codegen_session",
arguments: {
sessionId: "session-123abc"
}
});
Returns generated test file path and content.
playwright_expect_response▶
Monitor and validate HTTP responses during browser interactions.
// Monitor API endpoint
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_expect_response",
arguments: {
id: "api-check-1",
url: "https://api.example.com/users"
}
});
// Assert response value
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_assert_response",
arguments: {
id: "api-check-1",
url: "https://api.example.com/users",
value: { status: 200 }
}
});
Returns response data including status, headers, and body.
Installation
Microsoft Playwright MCP
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest"]
}
}
}
With Browser Selection:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--browser", "firefox"
]
}
}
}
With Custom Configuration:
{
"mcpServers": {
"playwright": {
"command": "npx",
"args": [
"@playwright/mcp@latest",
"--browser", "chromium",
"--viewport-width", "1920",
"--viewport-height", "1080",
"--user-data-dir", "./playwright-data"
]
}
}
}
Persistent Browser Profile:
Use --user-data-dir to persist login sessions and cookies across runs.
Configuration Options
Browser Selection
--browser <browser> # chromium, firefox, webkit, msedge
Viewport Configuration
--viewport-width <width> # Default: 1280
--viewport-height <height> # Default: 720
Device Emulation
--device <device> # iPhone 13, iPad Pro, Pixel 5, etc.
Network Settings
--allowed-origin <url> # Allow specific origins
--blocked-origin <url> # Block specific origins
--proxy-server <url> # Use proxy server
Session Management
--user-data-dir <path> # Persistent browser profile
--isolated # Ephemeral sessions
--storage-state <file> # Load cookies/localStorage
Recording & Debugging
--video <path> # Record video
--trace <path> # Record trace
--timeout <ms> # Default timeout
Common Use Cases
1. End-to-End Testing
Automate complete user workflows:
// Navigate to login page
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://app.example.com/login"
}
});
// Fill credentials
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_fill",
arguments: {
selector: "input[name='email']",
value: "[email protected]"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_fill",
arguments: {
selector: "input[name='password']",
value: "TestPass123!"
}
});
// Submit form
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_click",
arguments: {
selector: "button[type='submit']"
}
});
// Verify login success
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "dashboard-logged-in",
fullPage: true
}
});
2. Cross-Browser Testing
Test across multiple browsers:
// Test in Chromium
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com",
browserType: "chromium"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "chromium-homepage"
}
});
// Test in Firefox
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com",
browserType: "firefox"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "firefox-homepage"
}
});
// Test in WebKit (Safari)
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com",
browserType: "webkit"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "webkit-homepage"
}
});
3. Test Code Generation
Record actions and generate test scripts:
// Start recording
use_mcp_tool({
server_name: "playwright",
tool_name: "start_codegen_session",
arguments: {
outputPath: "./tests",
testNamePrefix: "checkout-flow",
includeComments: true
}
});
// Perform actions (automatically recorded)
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://shop.example.com"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_click",
arguments: {
selector: ".add-to-cart"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_click",
arguments: {
selector: ".checkout-button"
}
});
// Generate test file
use_mcp_tool({
server_name: "playwright",
tool_name: "end_codegen_session",
arguments: {
sessionId: "session-123"
}
});
4. API Testing During Browser Interactions
Monitor network requests and validate responses:
// Navigate to page
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com/dashboard"
}
});
// Monitor API call
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_expect_response",
arguments: {
id: "user-api",
url: "https://api.example.com/users/me"
}
});
// Trigger action that makes API call
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_click",
arguments: {
selector: ".refresh-data"
}
});
// Assert API response
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_assert_response",
arguments: {
id: "user-api",
value: { status: 200 }
}
});
5. Visual Regression Testing
Capture screenshots for visual comparison:
// Baseline screenshot
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_navigate",
arguments: {
url: "https://example.com"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "baseline-homepage",
fullPage: true,
savePng: true,
downloadsDir: "./screenshots/baseline"
}
});
// Component screenshots
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "header",
selector: "header",
savePng: true,
downloadsDir: "./screenshots/components"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_screenshot",
arguments: {
name: "footer",
selector: "footer",
savePng: true,
downloadsDir: "./screenshots/components"
}
});
6. Accessibility Testing
Test keyboard navigation and screen reader compatibility:
// Navigate using keyboard
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_press_key",
arguments: {
key: "Tab"
}
});
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_press_key",
arguments: {
key: "Enter"
}
});
// Extract accessibility tree
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_evaluate",
arguments: {
script: `
const snapshot = await window.accessibility.snapshot();
return snapshot;
`
}
});
// Check for accessibility violations
use_mcp_tool({
server_name: "playwright",
tool_name: "playwright_console_logs",
arguments: {
search: "accessibility",
type: "warning"
}
});
Browser Support
| Browser | Engine | Platforms | Mobile |
|---|---|---|---|
| Chromium | Blink | Windows, macOS, Linux | ✓ |
| Firefox | Gecko | Windows, macOS, Linux | ✓ |
| WebKit | WebKit | macOS, Linux | ✓ |
| Microsoft Edge | Blink | Windows, macOS, Linux | ✗ |
Best Practices
- Use Accessibility Selectors: Leverage
role,aria-label, andtextselectors for robust tests - Wait for Elements: Playwright auto-waits, but explicit waits improve reliability
- Isolate Tests: Use
--isolatedmode to prevent state leakage between tests - Record Traces: Enable tracing for debugging failed tests
- Test Across Browsers: Run tests on Chromium, Firefox, and WebKit
- Screenshot on Failure: Capture screenshots when assertions fail
- Monitor Console: Check console logs for JavaScript errors
- Use Code Generation: Record complex flows to generate test code
Performance Tips
- Headless Mode: Use headless browsers for faster test execution
- Parallel Execution: Run tests in parallel across multiple browsers
- Reuse Browser Context: Share browser context across tests when possible
- Disable Resources: Block images/fonts for faster page loads in tests
- Set Timeouts: Configure appropriate timeouts for different operations
- Cache User Data: Use persistent profiles to avoid repeated logins
Troubleshooting
Common Issues
Issue: Browser fails to launch
- Install Playwright browsers:
npx playwright install - Check system dependencies:
npx playwright install-deps - Verify Node.js version (18+ required)
Issue: Elements not found
- Wait for element to be visible
- Check selector syntax (CSS, text, role-based)
- Verify element isn't in iframe or shadow DOM
Issue: Screenshots are blank
- Ensure page has loaded completely
- Check viewport size is appropriate
- Verify element selector is correct
Issue: Timeouts occurring
- Increase timeout with
--timeoutflag - Check network connectivity
- Verify page isn't stuck loading resources
Issue: Cross-browser differences
- Test on actual target browsers
- Use browser-specific selectors if needed
- Check for browser-specific CSS/JS issues
Security Considerations
Security Warning:
Playwright can execute arbitrary JavaScript and access local files. Only use with trusted URLs and scripts.
Security Best Practices
- Validate URLs: Only navigate to trusted, verified URLs
- Sanitize Inputs: Validate all user-provided selectors and scripts
- Use Isolated Mode: Enable
--isolatedfor untrusted content - Limit Network Access: Use
--blocked-originto restrict domains - Review Scripts: Audit JavaScript executed via
evaluate - Secure Storage: Protect session storage and cookie files
- Container Isolation: Run in Docker for additional security
Limitations
- Docker: Only supports headless Chromium in containers
- File Uploads: Requires local file system access
- Browser Extensions: Limited support for extensions
- WebRTC: May have issues with real-time communication
- Download Handling: Requires configuration for file downloads
- iOS Safari: No direct iOS Safari testing (use WebKit as proxy)
Resources
- Official Playwright Documentation
- Playwright MCP GitHub
- Execute Automation MCP Docs
- Playwright Test Generator
- Accessibility Testing Guide
- Browser Contexts & Pages
Sources
Related Articles
Puppeteer MCP Server
Puppeteer MCP servers enable AI models to perform browser automation, web scraping, testing workflows, and screenshot generation through headless Chrome/Chromium control.
Model Context Protocol (MCP): Open Standard for AI Integration
The Model Context Protocol (MCP) is an open standard enabling AI systems to connect with diverse data sources, tools, and services, eliminating custom integrations for seamless interaction.
ServiceNow MCP Server
ServiceNow MCP server enables AI models to interact with ServiceNow instances, providing capabilities for IT service management, incident tracking, workflow automation, and knowledge base management through natural language.