playwright-mcp-server

ljchang/playwright-mcp-server

3.2

If you are the rightful owner of playwright-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to henry@mcphub.com.

The Playwright MCP Server is a Model Context Protocol server designed to facilitate browser automation for web application testing, documentation generation, and accessibility checks.

Tools
5
Resources
0
Prompts
0

Playwright MCP Server

A Model Context Protocol (MCP) server that provides Playwright browser automation tools for testing web applications, capturing screenshots, generating documentation, and running accessibility checks.

Features

Core Tools

  • screenshot - Capture full page or element screenshots
  • test_login - Test login flows with credentials
  • fill_form - Fill and submit forms automatically
  • check_element - Verify element existence and content
  • navigate_and_wait - Navigate to URLs with custom wait conditions
  • click_and_wait - Click elements and wait for results
  • extract_text - Extract text content from page elements
  • run_accessibility_check - Run WCAG accessibility audits
  • generate_pdf - Convert webpages to PDF documents
  • monitor_network - Monitor and capture network requests

Session Management Tools

  • start_session - Start a persistent browser session that stays open
  • end_session - Close a specific browser session
  • list_sessions - List all active browser sessions
  • get_session_state - Get current state of a browser session
  • get_page_context - Get detailed page context including forms, buttons, and links
  • get_screenshot_history - Get screenshot history for a session

Multi-Participant Test Scenarios (NEW!)

  • create_test_scenario - Create named test scenarios to group related sessions
  • list_test_scenarios - View all active test scenarios
  • get_test_scenario - Get detailed scenario information and session list
  • update_scenario_state - Track test phases and custom state data
  • end_test_scenario - Clean up scenario and close all associated sessions
  • Enhanced sessions - Sessions can have roles (admin/participant) and labels

Debugging & Console Tools

  • console - Interactive JavaScript console - execute commands in page context
  • console_history - Get console command history for the session
  • inspect_object - Deep inspect any JavaScript object or variable
  • execute_script - Execute JavaScript code in the page
  • get_debug_info - Get console logs, errors, and network activity
  • get_dom_snapshot - Get structured DOM representation
  • set_breakpoint - Set debugging breakpoints in JavaScript code

All tools now support both one-off operations and persistent sessions!

Installation

Prerequisites

  • Node.js 18+
  • npm or yarn
  • Docker (optional, for containerized deployment)

Local Setup

  1. Clone the repository:
git clone https://github.com/yourusername/playwright-mcp-server.git
cd playwright-mcp-server
  1. Install dependencies:
npm install
  1. Install Playwright browsers:
npx playwright install chromium
  1. Create environment file:
cp .env.example .env
  1. Edit .env with your configuration:
TEST_USER=testuser@example.com
TEST_PASS=testpassword123
HEADLESS=true
APP_BASE_URL=http://localhost:3000

Usage

Using with Claude Code (Recommended)

Claude Code automatically manages the MCP server lifecycle - no need to manually start the server!

Quick Setup (Global Installation)
  1. First, ensure you have the server installed:
git clone https://github.com/ljchang/playwright-mcp-server.git
cd playwright-mcp-server
npm install
npx playwright install chromium
  1. Add the server to Claude Code globally (available in all sessions):
claude mcp add playwright-mcp "node" "/absolute/path/to/playwright-mcp-server/src/index.js" --scope user
  1. Verify the server is connected:
claude mcp list

That's it! The server will automatically start when Claude Code needs it.

Usage Examples in Claude Code
One-off Operations
  • Headless mode (default - fast, no UI):

    "Use playwright to screenshot https://example.com"
    
  • Visible mode (see the browser in action):

    "Use playwright to screenshot https://example.com with headless=false"
    
Persistent Browser Sessions

Keep a browser open for multiple operations - perfect for debugging and interactive testing:

  1. Start a session with debugging and screenshots:

    "Start a playwright session with debugMode=true and recordScreenshots=true"
    

    Response will include a sessionId like: session-1234567890-abc123

  2. Use the session for multiple operations:

    "Use playwright session-1234567890-abc123 to click the login button"
    "Use playwright session-1234567890-abc123 to fill the form with test data"
    "Use playwright session-1234567890-abc123 to take a screenshot"
    
  3. Interactive JavaScript console:

    "Use playwright console for session-1234567890-abc123 to execute: document.title"
    "Use playwright to inspect window.localStorage in session-1234567890-abc123"
    "Use playwright to check console logs for session-1234567890-abc123"
    
  4. Debug and inspect:

    "Get debug info for playwright session-1234567890-abc123"
    "Get DOM snapshot for #app in session-1234567890-abc123"
    "Get page context for session-1234567890-abc123"
    
  5. List active sessions:

    "List all playwright sessions"
    
  6. End a session when done:

    "End playwright session-1234567890-abc123"
    

The browser window stays open between commands, maintaining state, cookies, and login sessions!

Optional: Add Environment Variables

To add credentials or customize behavior:

claude mcp add playwright-mcp "node" "/path/to/playwright-mcp-server/src/index.js" \
  --scope user \
  -e TEST_USER=your_email@example.com \
  -e TEST_PASS=your_password \
  -e HEADLESS=false \
  -e SLOW_MO=500

Using with Claude Desktop

Add the server to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "playwright": {
      "command": "node",
      "args": ["/path/to/playwright-mcp-server/src/index.js"],
      "env": {
        "TEST_USER": "testuser@example.com",
        "TEST_PASS": "testpassword123",
        "HEADLESS": "true"
      }
    }
  }
}

Manual Server Mode

For development or testing without Claude:

Standard Mode
npm start
Development Mode (with auto-reload)
npm run dev
Docker Mode
docker-compose up

Tool Examples

All tools now support:

  • headless parameter (default: true) - Set to false to see the browser in action
  • sessionId parameter (optional) - Use an existing browser session for the operation
Take a Screenshot
{
  "tool": "screenshot",
  "arguments": {
    "url": "https://example.com",
    "fullPage": true,
    "filename": "homepage.png",
    "headless": false  // Optional: see the browser window
  }
}
Test Login Flow
{
  "tool": "test_login",
  "arguments": {
    "url": "https://app.example.com/login",
    "usernameSelector": "#email",
    "passwordSelector": "#password",
    "submitSelector": "button[type='submit']",
    "headless": false  // Optional: watch the login process
  }
}
Fill a Form
{
  "tool": "fill_form",
  "arguments": {
    "url": "https://example.com/contact",
    "formData": {
      "#name": "John Doe",
      "#email": "john@example.com",
      "#message": "Test message"
    },
    "submitSelector": "#submit-button"
  }
}
Check Element Content
{
  "tool": "check_element",
  "arguments": {
    "url": "https://example.com",
    "selector": "h1",
    "expectedText": "Welcome"
  }
}
Extract Text Content
{
  "tool": "extract_text",
  "arguments": {
    "url": "https://example.com/blog",
    "selectors": ["h1", ".article-title", ".author"],
    "extractAll": true
  }
}
Run Accessibility Check
{
  "tool": "run_accessibility_check",
  "arguments": {
    "url": "https://example.com",
    "standard": "WCAG2AA"
  }
}
Generate PDF
{
  "tool": "generate_pdf",
  "arguments": {
    "url": "https://example.com/report",
    "filename": "report.pdf",
    "format": "A4",
    "landscape": false
  }
}
Monitor Network Requests
{
  "tool": "monitor_network",
  "arguments": {
    "url": "https://example.com",
    "captureTypes": ["xhr", "fetch"],
    "filterPattern": "api.*"
  }
}
Session Management
Start a Persistent Session with Debugging
{
  "tool": "start_session",
  "arguments": {
    "headless": false,  // Default false for sessions
    "url": "https://example.com",  // Optional initial URL
    "debugMode": true,  // Capture console logs, errors, network
    "recordScreenshots": true  // Auto-capture screenshots after each action
  }
}
// Returns: sessionId to use with other tools
Use Session with Other Tools
{
  "tool": "screenshot",
  "arguments": {
    "url": "https://example.com/page2",
    "sessionId": "session-1234567890-abc123"  // Use existing session
  }
}
List Active Sessions
{
  "tool": "list_sessions",
  "arguments": {}
}
End a Session
{
  "tool": "end_session",
  "arguments": {
    "sessionId": "session-1234567890-abc123"
  }
}
Debugging Tools
Interactive JavaScript Console
{
  "tool": "console",
  "arguments": {
    "sessionId": "session-1234567890-abc123",
    "command": "document.querySelector('#app').innerText",
    "mode": "eval"  // Options: eval, inspect, watch
  }
}
Deep Object Inspection
{
  "tool": "inspect_object",
  "arguments": {
    "sessionId": "session-1234567890-abc123",
    "expression": "window.localStorage",
    "depth": 3
  }
}
Get Debug Information
{
  "tool": "get_debug_info",
  "arguments": {
    "sessionId": "session-1234567890-abc123",
    "includeConsole": true,
    "includeErrors": true,
    "includeNetwork": true
  }
}
Get DOM Snapshot
{
  "tool": "get_dom_snapshot",
  "arguments": {
    "sessionId": "session-1234567890-abc123",
    "selector": "#app",
    "includeStyles": true
  }
}
Get Page Context (Forms, Buttons, Links)
{
  "tool": "get_page_context",
  "arguments": {
    "sessionId": "session-1234567890-abc123"
  }
}
// Returns all interactive elements on the page

Multi-Participant Test Scenarios (NEW!)

Coordinate multiple browser sessions for testing experiments with multiple participants, different user roles, and complex interactions.

Create a Test Scenario
{
  "tool": "create_test_scenario",
  "arguments": {
    "name": "Collaborative Task Test",
    "description": "Testing 2 participants in a collaborative task",
    "experimentName": "collab_study_v2",
    "testParameters": {
      "condition": "synchronous",
      "difficulty": "medium"
    },
    "tags": ["collaboration", "multi-user"]
  }
}
// Returns: scenarioId to group related sessions
Start Sessions with Roles and Labels
// Admin session
{
  "tool": "start_session",
  "arguments": {
    "scenarioId": "scenario-123",  // Link to scenario
    "role": "admin",               // Role: admin, participant, observer
    "label": "Admin1",             // Friendly label
    "headless": false,
    "url": "https://experiment.com/admin"
  }
}

// Participant sessions
{
  "tool": "start_session",
  "arguments": {
    "scenarioId": "scenario-123",
    "role": "participant",
    "label": "P1",
    "headless": false,
    "url": "https://experiment.com/join"
  }
}
List Sessions by Scenario or Role
{
  "tool": "list_sessions",
  "arguments": {
    "scenarioId": "scenario-123",  // Optional: filter by scenario
    "role": "participant"           // Optional: filter by role
  }
}
List All Test Scenarios
{
  "tool": "list_test_scenarios",
  "arguments": {}  // Optional: { "tag": "collaboration" } to filter
}
Get Scenario Details
{
  "tool": "get_test_scenario",
  "arguments": {
    "scenarioId": "scenario-123"
  }
}
// Returns scenario metadata, all sessions, and event history
Update Scenario State
{
  "tool": "update_scenario_state",
  "arguments": {
    "scenarioId": "scenario-123",
    "phase": "running",  // created, running, completed, failed
    "customData": {
      "participantsReady": true,
      "tasksCompleted": 0
    }
  }
}
End Scenario and Clean Up All Sessions
{
  "tool": "end_test_scenario",
  "arguments": {
    "scenarioId": "scenario-123"
  }
}
// Closes all browser sessions associated with the scenario
Complete Multi-Participant Example

Testing multiple participants joining an experiment:

// 1. Create scenario
const scenario = create_test_scenario({
  name: "Two-Player Game Test",
  experimentName: "multiplayer_game_v1"
});

// 2. Start admin and create experiment
const admin = start_session({
  scenarioId: scenario.id,
  role: "admin",
  label: "Admin"
});

// 3. Start participant 1
const p1 = start_session({
  scenarioId: scenario.id,
  role: "participant", 
  label: "P1"
});

// 4. Start participant 2 with delay
await new Promise(r => setTimeout(r, 3000));
const p2 = start_session({
  scenarioId: scenario.id,
  role: "participant",
  label: "P2"
});

// 5. Verify all connected
check_element({
  sessionId: admin.id,
  selector: "#participant-count",
  expectedText: "2"
});

// 6. Clean up everything
end_test_scenario({ scenarioId: scenario.id });
Use Cases
  1. Multiple Participants: Test experiments requiring 2+ simultaneous users
  2. Role-Based Testing: Different views for admin vs participants
  3. Parameter Changes: Verify changes propagate to all participants
  4. Dropout Recovery: Test handling of participant disconnections
  5. Synchronization: Ensure all participants see consistent state

Docker Deployment

Build and Run with Docker Compose

# Build the image
docker-compose build

# Run the server
docker-compose up

# Run with test app (optional)
docker-compose --profile with-test-app up

Docker Environment Variables

Configure via docker-compose.yml or .env:

  • NODE_ENV - Environment (development/production)
  • HEADLESS - Run browser in headless mode
  • TEST_USER - Default test username
  • TEST_PASS - Default test password
  • MCP_AUTH_TOKEN - Authentication token for MCP

Environment Configuration

Core Settings

VariableDescriptionDefault
HEADLESSRun browser in headless modetrue
TEST_USERDefault username for login tests-
TEST_PASSDefault password for login tests-
MCP_AUTH_TOKENMCP authentication token-

Application URLs

VariableDescriptionExample
APP_BASE_URLLocal development URLhttp://localhost:3000
APP_STAGING_URLStaging environment URLhttps://staging.example.com
APP_PRODUCTION_URLProduction environment URLhttps://example.com

Browser Settings

VariableDescriptionDefault
BROWSER_TIMEOUTBrowser operation timeout (ms)30000
NAVIGATION_TIMEOUTPage navigation timeout (ms)30000
SLOW_MODelay between actions (ms)0

Screenshot Settings

VariableDescriptionDefault
SCREENSHOTS_DIRDirectory to save screenshots~/.playwright-mcp/screenshots/
SCREENSHOT_QUALITYJPEG quality (1-100)80
SCREENSHOT_TYPEImage format (png/jpeg)png

Screenshots are saved to ~/.playwright-mcp/screenshots/ by default (in your home directory). You can override this by setting the SCREENSHOTS_DIR environment variable.

File Structure

playwright-mcp-server/
ā”œā”€ā”€ src/
│   └── index.js          # Main MCP server implementation
ā”œā”€ā”€ docker/
│   └── Dockerfile        # Docker container configuration
ā”œā”€ā”€ tests/               # Test files
ā”œā”€ā”€ docker-compose.yml   # Docker Compose configuration
ā”œā”€ā”€ package.json         # Node.js dependencies
ā”œā”€ā”€ .env.example        # Environment template
ā”œā”€ā”€ .gitignore          # Git ignore rules
ā”œā”€ā”€ run-dev.sh          # Development mode script
└── README.md           # Documentation

Note: Screenshots are saved to ~/.playwright-mcp/screenshots/ in your home directory by default.

Development

Running Tests

npm test

Adding New Tools

  1. Add tool definition in tools/list handler
  2. Implement tool logic in tools/call switch statement
  3. Update README with usage example

Debugging

Set HEADLESS=false in .env to see browser actions:

HEADLESS=false
SLOW_MO=500  # Add 500ms delay between actions

Security Considerations

  • Never commit .env files with real credentials
  • Use environment-specific credentials
  • Rotate MCP_AUTH_TOKEN regularly
  • Run in containers for isolation
  • Limit network access in production

Troubleshooting

Browser Installation Issues

# Reinstall Playwright browsers
npx playwright install --with-deps chromium

Permission Errors in Docker

# Run with proper permissions
docker-compose run --user root playwright-mcp npm install

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

MIT License - See LICENSE file for details

Support

For issues and questions:

  • Open an issue on GitHub
  • Check existing issues for solutions
  • Review environment configuration

Acknowledgments

  • Built with Playwright for browser automation
  • Implements Model Context Protocol (MCP) specification
  • Uses official Playwright Docker images for containerization