Skip to main content
Glama

Playwright MCP Server

by alexrwilliam
README.md9.48 kB
# 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 - **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 ```bash # Install directly from GitHub pip install git+https://github.com/alexrwilliam/playwright-mcp-server.git # Install Playwright browsers playwright install ``` ### For Development ```bash # 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: ```bash # 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 ```bash # 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" # 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`: ```json { "mcpServers": { "playwright": { "command": "playwright-mcp", "args": ["stdio"] } } } ``` ### Testing with MCP Inspector ```bash # Install and run MCP inspector uv run mcp dev src/playwright_mcp/server.py ``` ## 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)` - Query for single element - `query_selector_all(selector: str)` - Query for all matching elements - `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 #### Content & Snapshots - `get_html()` - Get page HTML - `get_accessibility_snapshot()` - Get accessibility tree - `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: ```python # 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) ### 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:** ```bash playwright-mcp stdio --channel chrome --user-data-dir "/Users/$(whoami)/Library/Application Support/Google/Chrome" ``` **Example for Linux:** ```bash playwright-mcp stdio --channel chrome --user-data-dir "/home/$(whoami)/.config/google-chrome" ``` ## Development ```bash # 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

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/alexrwilliam/playwright-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server