Playwright MCP Server
An MCP (Model Context Protocol) server that provides browser automation capabilities using Playwright. Control browsers, automate web interactions, test web applications, and generate test scripts - all through Claude Desktop or any MCP-compatible client.
Features
🌐 Browser Automation
- Launch and control headless or visible Chrome browsers
- Navigate, click, fill forms, take screenshots
- Execute JavaScript in page context
- Handle multiple browser sessions simultaneously
- Automatic resource cleanup and memory management
🖥️ Electron App Testing
- Launch and control Electron applications
- Execute code in main and renderer processes
- Take screenshots of desktop apps
- Get app information and window states
🧪 Test Generation
- Record user interactions for test generation
- Generate Playwright, Jest, or Mocha test scripts
- Create regression tests from current page state
- Build comprehensive test suites
🔧 Resource Management
- Automatic session timeout (30 minutes by default)
- Memory usage monitoring and cleanup
- Zombie process detection and removal
- Graceful shutdown handling
📊 Console Logging (v1.1.0 - NEW!)
- Real-time capture of browser console output
- Logs saved to
playwright/log/directory - Captures console.log, info, warn, error, debug messages
- Includes timestamps and source code locations
- Records page errors with stack traces
- Tracks failed network requests
- Supports live monitoring with
tail -f
Installation
Prerequisites
- Node.js 18 or higher
- Claude Desktop or any MCP-compatible client
Setup
- Clone the repository:
git clone https://github.com/yourusername/playwright-mcp.git
cd playwright-mcp
- Install dependencies:
npm install
- Build the TypeScript code:
npm run build
Configuration
For Claude Desktop
Add to your Claude Desktop configuration (claude_desktop_config.json):
{
"mcpServers": {
"playwright": {
"command": "node",
"args": ["/path/to/playwright-mcp/dist/index.js"]
}
}
}
For Claude Code
Add to your settings file:
{
"mcp": {
"servers": {
"playwright": {
"command": "node",
"args": ["/path/to/playwright-mcp/dist/index.js"]
}
}
}
}
Usage
Browser Automation
// Launch a browser
browser_launch({
sessionId: "my-session",
headless: true,
viewport: { width: 1920, height: 1080 }
})
// Navigate to a URL
page_navigate({
sessionId: "my-session",
url: "https://example.com"
})
// Take a screenshot
page_screenshot({
sessionId: "my-session",
fullPage: true,
filename: "screenshot.png"
})
// Fill a form
page_fill({
sessionId: "my-session",
selector: "#username",
value: "user@example.com"
})
// Click a button
page_click({
sessionId: "my-session",
selector: "#submit-button"
})
// Close the browser
browser_close({
sessionId: "my-session"
})
Console Logging (NEW in v1.1.0)
Console logs are automatically captured for every browser session and saved to the playwright/log/ directory.
# Log files are created automatically with the format:
# playwright/log/console-{sessionId}-{pageId}-{timestamp}.log
# Monitor logs in real-time
tail -f playwright/log/console-*.log
# View specific session logs
tail -f playwright/log/console-my-session-main-*.log
# Search for errors
grep ERROR playwright/log/console-*.log
# Filter by timestamp
grep "2025-01-02T15:30" playwright/log/console-*.log
Example log output:
=== Console Log Started: 2025-01-02T15:30:45.123Z ===
Session: my-session, Page: main
URL: https://example.com
==================================================
[2025-01-02T15:30:45.456Z] [LOG] Page loaded successfully
[2025-01-02T15:30:45.789Z] [WARN] [https://example.com/app.js:42:15] Deprecation warning
[2025-01-02T15:30:46.123Z] [ERROR] [https://example.com/app.js:58:10] ReferenceError: undefined variable
[2025-01-02T15:30:46.456Z] [REQUEST_FAILED] net::ERR_CONNECTION_REFUSED - https://api.example.com/data
Test Generation
// Start recording
test_start_recording({
sessionId: "my-session",
testName: "login-test"
})
// Perform actions...
// Stop and generate test
test_stop_recording({
sessionId: "my-session",
format: "playwright"
})
Resource Management
// Get session statistics
session_stats()
// Close all browsers and cleanup
browser_close_all()
Directory Structure
All generated files are organized under the playwright/ directory in your project:
your-project/
└── playwright/
├── screenshot/ # Screenshots from page_screenshot
├── test/ # Generated test scripts
└── log/ # Console logs (auto-created for each session)
└── console-{sessionId}-{pageId}-{timestamp}.log
Available Tools
Browser Management
browser_launch- Launch a new browser instancebrowser_close- Close a browser sessionbrowser_close_all- Close all sessions and cleanuplist_sessions- List active sessionssession_stats- Get resource usage statistics
Page Interactions
page_navigate- Navigate to URLpage_click- Click an elementpage_fill- Fill form fieldspage_press- Press keyboard keyspage_select- Select dropdown optionspage_evaluate- Execute JavaScriptpage_wait_for_selector- Wait for elementspage_get_content- Get HTML contentpage_get_text- Get element textpage_screenshot- Take screenshots
Electron Support
electron_launch- Launch Electron appelectron_close- Close Electron appelectron_evaluate_main- Execute in main processelectron_evaluate_renderer- Execute in rendererelectron_get_info- Get app informationelectron_window_state- Get window stateelectron_screenshot- Take app screenshot
Test Generation
test_start_recording- Start recording actionstest_stop_recording- Stop and generate testtest_generate_regression- Generate regression testtest_generate_suite- Create test suitetest_list_recordings- List recordings
Configuration Options
Environment variables:
SESSION_TIMEOUT- Session timeout in milliseconds (default: 1800000)CLEANUP_INTERVAL- Cleanup check interval (default: 300000)MAX_MEMORY_MB- Maximum memory usage (default: 2048)
Examples
Web Scraping
// Launch browser and scrape data
browser_launch({ sessionId: "scraper" })
page_navigate({ sessionId: "scraper", url: "https://news.site.com" })
page_evaluate({
sessionId: "scraper",
script: "Array.from(document.querySelectorAll('.headline')).map(h => h.textContent)"
})
browser_close({ sessionId: "scraper" })
Form Testing
// Test a login form
browser_launch({ sessionId: "form-test" })
page_navigate({ sessionId: "form-test", url: "https://app.com/login" })
page_fill({ sessionId: "form-test", selector: "#email", value: "test@example.com" })
page_fill({ sessionId: "form-test", selector: "#password", value: "password123" })
page_click({ sessionId: "form-test", selector: "#login-button" })
page_wait_for_selector({ sessionId: "form-test", selector: ".dashboard" })
page_screenshot({ sessionId: "form-test", filename: "login-success.png" })
browser_close({ sessionId: "form-test" })
Development
Building from source
npm run build
Running in development mode
npm run dev
Running tests
npm test
Troubleshooting
Browser won't launch
- Ensure Chrome/Chromium is installed
- Check if running in Docker/WSL (may need additional flags)
High memory usage
- Reduce
MAX_MEMORY_MBsetting - Ensure sessions are properly closed
- Use
browser_close_all()to cleanup
Zombie processes
- The server automatically cleans up zombie processes
- Manual cleanup:
pkill -f "headless_shell"
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Acknowledgments
- Built on Playwright for browser automation
- Implements the Model Context Protocol
- Designed for Claude Desktop integration
Author
zhuzhe