playwright-mcp-server

alexrwilliam/playwright-mcp-server

3.3

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 minimal and robust server that provides core browser automation capabilities through a simple API.

Tools
6
Resources
0
Prompts
0

Playwright MCP Server

A minimal, robust Playwright MCP (Model Context Protocol) server that exposes core browser automation capabilities via a simple API.

Features

  • Browser Context Management: Persistent browser context (headless or headed, configurable)
  • Multi-Page Support: Handle multiple tabs/windows, switch between pages, manage popups
  • Navigation: Open URLs, reload, go back/forward
  • DOM Interaction: Click, type, fill, select, hover, scroll using Playwright selectors
  • Element Discovery: Query elements using CSS, XPath, role, text, and other Playwright locators
  • Snapshotting: Get HTML, accessibility snapshots, screenshots, and PDFs
  • Token-Aware Outputs: Configurable caps keep element queries and accessibility snapshots within safe sizes for LLM consumption
  • Overflow Artifacts: Large responses are trimmed automatically, auto-cleaned after ~2 hours by default, and include previews plus file references you can reopen via the read_artifact tool
  • Script Evaluation: Run JavaScript in the page context
  • Network Monitoring: Capture and analyze all network requests and responses
  • Network Interception: Block, modify, or mock network requests
  • Cookie Management: Get, set, and clear browser cookies
  • Storage Access: Manage localStorage and sessionStorage data
  • Headers & User Agent: Customize request headers and browser identity
  • Raw Output: All outputs are raw Playwright results with no post-processing

Installation

Quick Install from GitHub

# Install directly from GitHub
pip install git+https://github.com/alexrwilliam/playwright-mcp-server.git

# Install Playwright browsers
playwright install

For Development

# Clone the repository
git clone https://github.com/alexrwilliam/playwright-mcp-server.git
cd playwright-mcp-server

# Install in development mode
pip install -e .

# Install browsers
playwright install

Usage

Running the Server

After installation, you can use it from anywhere:

# Run with stdio transport (for MCP clients)
playwright-mcp stdio

# Run with HTTP transport
playwright-mcp http --port 8000

# Run in headed mode (default is headless)
playwright-mcp stdio --headed

Command Line Usage

# Run the MCP server
playwright-mcp stdio

# Run with visible browser
playwright-mcp stdio --headed

# Run HTTP server
playwright-mcp http --port 8000

# Use different browsers
playwright-mcp stdio --browser firefox
playwright-mcp stdio --browser webkit

# Use real Chrome instead of bundled Chromium
playwright-mcp stdio --channel chrome

# Use real Chrome with your profile (cookies, extensions, history)
playwright-mcp stdio --channel chrome --user-data-dir "/Users/you/Library/Application Support/Google/Chrome"

# Adjust response budgets (defaults: 4k inline, 400-char previews)
playwright-mcp stdio --max-response-chars 6000 --preview-chars 600

# Choose where overflow artifacts are written
playwright-mcp stdio --artifact-dir /tmp/playwright-artifacts

# Other Chrome channels
playwright-mcp stdio --channel chrome-beta
playwright-mcp stdio --channel chrome-dev

Integration with Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "playwright": {
      "command": "playwright-mcp",
      "args": ["stdio"]
    }
  }
}

Testing with MCP Inspector

# Install and run MCP inspector
uv run mcp dev src/playwright_mcp/server.py

Response Budgeting & Artifacts

High-volume tools (evaluate, get_accessibility_snapshot, get_network_requests, get_network_responses, and future additions) now honor a shared response budget. When the serialized payload would exceed --max-response-chars:

  • The inline result is trimmed to fit the budget and marked with truncated: true.
  • A compact preview (default 400 chars) snapshots what was retained.
  • The full payload is written to the artifact directory (default tmp/playwright_mcp) and returned as overflow_path plus the original size in overflow_characters.
  • Use the read_artifact tool (or open the file locally) to retrieve the saved payload. Artifacts that are binary fall back to base64 when read.
  • Artifacts are auto-pruned—by default anything older than two hours is deleted and the directory is capped at 200 files (--artifact-max-age-seconds, --artifact-max-files).

Tweak the caps per run with --max-response-chars, --preview-chars, and --artifact-dir or override per-call limits where a tool exposes them.

API Reference

Tools

Navigation & Page Control
  • navigate(url: str) - Navigate to a URL
  • reload() - Reload the current page
  • go_back() - Go back in history
  • go_forward() - Go forward in history
  • get_current_url() - Get current page URL with parsed components and query parameters
  • wait_for_url(url_pattern: str, timeout: int) - Wait for URL to match pattern
  • wait_for_load_state(state: str, timeout: int) - Wait for page load states (domcontentloaded, load, networkidle)
  • set_viewport_size(width: int, height: int) - Set viewport dimensions
Multi-Page Management (Tabs/Windows)
  • list_pages() - List all open browser pages/tabs with IDs, URLs, and titles
  • switch_page(page_id: str) - Switch to a different page/tab by its ID
  • close_page(page_id: str) - Close a specific page/tab (cannot close last one)
  • wait_for_popup(timeout: int) - Wait for and capture a new popup/tab
  • switch_to_latest_page() - Switch to the most recently opened page
Element Interaction
  • click(selector: str) - Click an element
  • type_text(selector: str, text: str) - Type text into an element
  • fill(selector: str, value: str) - Fill an input field
  • clear_text(selector: str) - Clear input field text
  • select_option(selector: str, value: str) - Select an option
  • hover(selector: str) - Hover over an element
  • scroll(selector: str, x: int, y: int) - Scroll element
  • press_key(key: str) - Press keyboard key
Form Handling
  • check_checkbox(selector: str) - Check a checkbox
  • uncheck_checkbox(selector: str) - Uncheck a checkbox
  • upload_file(selector: str, file_path: str) - Upload file to input
Element Discovery & Validation
  • query_selector(selector: str, max_text_length: int | None = None) - Query for single element (optional per-call text cap override)
  • query_selector_all(selector: str, max_elements: int | None = None, max_text_length: int | None = None) - Query for all matching elements (optional per-call overrides)
  • query_selector_meta(selector: str, preview_length: int = 200, max_elements: int | None = None) - Quick metadata preview (tag, role, short text, key attributes)
  • Element query tools obey global caps, accept per-call overrides, and return truncated / returned_count metadata when results are clipped.
  • is_visible(selector: str) - Check if element is visible
  • is_enabled(selector: str) - Check if element is enabled
  • wait_for_element(selector: str, timeout: int) - Wait for element to appear
  • get_element_bounding_box(selector: str) - Get element position and size
  • get_element_attributes(selector: str) - Get all element attributes
  • get_computed_style(selector: str, property: str) - Get CSS computed style
Script Evaluation & Diagnostics
  • evaluate(script: str) - Execute JavaScript in page context (results respect the shared response budget and emit overflow metadata as needed)
Network Monitoring & Overflow Retrieval
  • get_network_requests(url_pattern: str | None = None) - Inspect captured requests; large result sets spill to artifacts with previews
  • get_network_responses(url_pattern: str | None = None) - Inspect captured responses with the same budgeting behaviour
  • read_artifact(path: str) - Load an overflow artifact referenced in a previous response (returns text or base64 content)
Content & Snapshots
  • get_html() - Get page HTML
  • get_accessibility_snapshot(interesting_only: bool = True, root_selector: str | None = None, max_nodes: int | None = None) - Get accessibility tree with optional filters and per-call node caps
  • Accessibility snapshots are pruned to the configured node budget, accept per-call overrides, and include truncated, max_nodes, and node_count metadata.
  • screenshot(selector: str, full_page: bool) - Take screenshot of page or element
  • pdf() - Generate PDF of page
JavaScript & Debugging
  • evaluate(script: str) - Execute JavaScript in page context
  • wait_for_network_idle(timeout: int) - Wait for network activity to settle
  • get_page_errors() - Get JavaScript errors from page
  • get_console_logs() - Get console output from page
Network Monitoring & Interception
  • get_network_requests(url_pattern: str) - Retrieve captured network requests with filtering
  • get_network_responses(url_pattern: str) - Retrieve captured network responses with filtering
  • clear_network_logs() - Clear all captured network request/response logs
  • intercept_route(url_pattern: str, action: str, ...) - Intercept and handle network requests
  • unroute_all() - Remove all route interceptors
  • wait_for_response(url_pattern: str, timeout: int) - Wait for specific network responses
  • get_response_body(url_pattern: str) - Extract response body content from network calls
Cookie Management
  • get_cookies(urls: List[str]) - Retrieve browser cookies with optional URL filtering
  • add_cookies(cookies: List[Dict]) - Add cookies to browser context
  • clear_cookies(name: str, domain: str) - Clear cookies with optional filtering
Storage Management
  • get_local_storage(origin: str) - Access localStorage data
  • set_local_storage(key: str, value: str) - Set localStorage items
  • get_session_storage() - Access sessionStorage data
  • set_session_storage(key: str, value: str) - Set sessionStorage items
  • clear_storage(storage_type: str) - Clear localStorage and/or sessionStorage
Request Headers & Identity
  • set_extra_headers(headers: Dict) - Add custom HTTP headers to all requests
  • set_user_agent(user_agent: str) - Change browser User-Agent string

Examples

Handling Multiple Pages/Tabs

The server automatically tracks all browser pages/tabs:

# Example: Clicking a link that opens in a new tab
1. navigate("https://example.com")
2. click("a[target='_blank']")  # Opens new tab
3. list_pages()  # Shows all open tabs with IDs
4. switch_to_latest_page()  # Switch to the new tab
5. get_current_url()  # Get URL of new tab
6. switch_page(original_page_id)  # Switch back

# Example: Handling JavaScript popups
1. evaluate("window.open('https://example.com', '_blank')")
2. wait_for_popup(timeout=5000)  # Wait for and capture popup
3. list_pages()  # See all pages including popup
4. close_page(popup_id)  # Close the popup

All existing tools automatically work on the currently active page. When you switch pages, subsequent operations apply to the new active page.

Configuration

The server accepts the following configuration options:

  • --headed / --headless - Run browser in headed or headless mode
  • --browser - Browser type (chromium, firefox, webkit)
  • --channel - Browser channel (chrome, chrome-beta, msedge, etc.) for real browsers
  • --user-data-dir - Path to browser profile directory for persistent context
  • --port - Port for HTTP transport
  • --timeout - Default timeout for operations (ms)
  • --max-elements - Maximum number of DOM nodes returned by query tools (default: 20)
  • --max-element-text-length - Maximum characters returned for element text and attribute values (default: 2000)
  • --max-accessibility-nodes - Maximum accessibility tree nodes returned by get_accessibility_snapshot (default: 500)
  • --max-response-chars - Maximum serialized characters returned inline before results spill to artifact files (default: 4000)
  • --preview-chars - Maximum characters included in inline previews when truncation occurs (default: 400)
  • --artifact-dir - Directory where overflow artifacts are written (default: ./tmp/playwright_mcp)
  • --artifact-max-age-seconds - Maximum age before artifacts are purged (default: 7200 seconds)
  • --artifact-max-files - Maximum number of artifact files kept in the directory (default: 200)

All caps accept 0 or negative values to disable truncation entirely. When truncation occurs, tool responses include truncated flags and metadata so clients can optionally re-issue a narrower request.

Real Chrome vs Bundled Chromium

By default, Playwright uses bundled Chromium. For web scraping that requires real Chrome features:

Use --channel chrome to use your installed Google Chrome:

  • Access to all Chrome features and codecs
  • Better compatibility with some websites
  • Chrome-specific behaviors

Use --user-data-dir to access your real profile:

  • All your cookies and login sessions
  • Browser extensions (AdBlock, etc.)
  • Browsing history and autofill data
  • Bookmarks and saved passwords

Example for macOS:

playwright-mcp stdio --channel chrome --user-data-dir "/Users/$(whoami)/Library/Application Support/Google/Chrome"

Example for Linux:

playwright-mcp stdio --channel chrome --user-data-dir "/home/$(whoami)/.config/google-chrome"

Development

# Clone the repository
git clone <repo-url>
cd playwright-mcp

# Install dependencies
uv sync --dev

# Run tests
uv run pytest

# Format code
uv run black src/
uv run ruff check src/

# Type check
uv run mypy src/

License

MIT