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.

GitHub starsnpm versionnpm downloads

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

ToolPurposeCategory
playwright_navigateNavigate to URLNavigation
playwright_clickClick elementsInteraction
playwright_fillFill input fieldsForms
playwright_selectSelect dropdown optionsForms
playwright_screenshotCapture screenshotsTesting
playwright_evaluateExecute JavaScriptScripting
playwright_hoverHover over elementsInteraction
playwright_press_keyPress keyboard keysInteraction
playwright_dragDrag and drop elementsInteraction
playwright_upload_fileUpload filesForms
playwright_get_visible_textExtract visible textContent
playwright_get_visible_htmlGet page HTMLContent
playwright_console_logsRetrieve console logsDebugging
playwright_expect_responseMonitor HTTP responsesAPI Testing
start_codegen_sessionStart test recordingCode Gen
end_codegen_sessionGenerate test fileCode 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

BrowserEnginePlatformsMobile
ChromiumBlinkWindows, macOS, Linux
FirefoxGeckoWindows, macOS, Linux
WebKitWebKitmacOS, Linux
Microsoft EdgeBlinkWindows, macOS, Linux

Best Practices

  1. Use Accessibility Selectors: Leverage role, aria-label, and text selectors for robust tests
  2. Wait for Elements: Playwright auto-waits, but explicit waits improve reliability
  3. Isolate Tests: Use --isolated mode to prevent state leakage between tests
  4. Record Traces: Enable tracing for debugging failed tests
  5. Test Across Browsers: Run tests on Chromium, Firefox, and WebKit
  6. Screenshot on Failure: Capture screenshots when assertions fail
  7. Monitor Console: Check console logs for JavaScript errors
  8. Use Code Generation: Record complex flows to generate test code

Performance Tips

  1. Headless Mode: Use headless browsers for faster test execution
  2. Parallel Execution: Run tests in parallel across multiple browsers
  3. Reuse Browser Context: Share browser context across tests when possible
  4. Disable Resources: Block images/fonts for faster page loads in tests
  5. Set Timeouts: Configure appropriate timeouts for different operations
  6. 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 --timeout flag
  • 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

  1. Validate URLs: Only navigate to trusted, verified URLs
  2. Sanitize Inputs: Validate all user-provided selectors and scripts
  3. Use Isolated Mode: Enable --isolated for untrusted content
  4. Limit Network Access: Use --blocked-origin to restrict domains
  5. Review Scripts: Audit JavaScript executed via evaluate
  6. Secure Storage: Protect session storage and cookie files
  7. 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

Sources