Skeleton MCP Server
A template project for building Model Context Protocol servers with FastMCP framework, providing example CRUD API implementations, Docker support, and development best practices.
README
Playwright MCP Proxy
A proxy server for Microsoft's playwright-mcp that provides efficient handling of large binary data (screenshots, PDFs) through blob storage and supports browser pools for concurrent operations.
Version 2.0.0: Now with browser pools! Run multiple isolated browser instances with different configurations simultaneously.
Features
- Browser Pools: Multiple isolated browser instances organized into named pools with different configurations
- Concurrent Operations: Lease browser instances for exclusive use, enabling parallel browser automation
- Playwright Browser Automation: Full access to all playwright-mcp browser automation tools
- Stealth Mode: Built-in anti-detection capabilities (see STEALTH.md)
- Efficient Binary Handling: Large screenshots and PDFs automatically stored as blobs to reduce token usage
- Blob Storage: Built-in blob management using mcp-mapped-resource-lib
- Automatic Cleanup: TTL-based automatic expiration of old blobs
- Docker Support: Containerized deployment with multi-runtime support (Python + Node.js + Playwright)
- Health Monitoring: Real-time pool status and instance health checks
Quick Start
Prerequisites
- Python 3.10 or higher
- Node.js 18+ (for playwright-mcp)
- uv package manager (recommended)
- Docker (optional, for containerized deployment)
Installation
- Clone this repository:
git clone <this-repo> playwright-proxy-mcp
cd playwright-proxy-mcp
- Install dependencies:
uv sync
- Create your environment file:
cp .env.example.single-pool .env
# Edit .env with your configuration
- Run the server:
uv run playwright-proxy-mcp
The server will:
- Start the playwright-mcp subprocess(es) via npx
- Initialize blob storage
- Initialize browser pools
- Listen for MCP client connections on stdio
Browser Pools
Overview
Browser pools allow you to run multiple browser instances with different configurations:
# Global defaults (apply to all pools)
PW_MCP_PROXY_BROWSER=chromium
PW_MCP_PROXY_HEADLESS=true
# Define a pool with 3 instances
PW_MCP_PROXY__DEFAULT_INSTANCES=3
PW_MCP_PROXY__DEFAULT_IS_DEFAULT=true
PW_MCP_PROXY__DEFAULT_DESCRIPTION="General purpose browsing"
# Instance-level overrides
PW_MCP_PROXY__DEFAULT__0_BROWSER=firefox # Instance 0 uses Firefox
PW_MCP_PROXY__DEFAULT__1_ALIAS=debug # Instance 1 has alias "debug"
PW_MCP_PROXY__DEFAULT__1_HEADLESS=false # Instance 1 runs headed
Using Pools
All browser tools accept optional browser_pool and browser_instance parameters:
# Use default pool, FIFO instance selection
await browser_navigate(url="https://example.com")
# Use specific pool
await browser_navigate(url="https://example.com", browser_pool="FIREFOX")
# Use specific instance by alias
await browser_navigate(url="https://example.com", browser_instance="debug")
Monitoring Pools
# Get status of all pools
status = await browser_pool_status()
for pool in status["pools"]:
print(f"{pool['name']}: {pool['available_instances']}/{pool['total_instances']} available")
See docs/BROWSER_POOLS_SPEC.md for complete configuration reference.
Docker Deployment
Build and run with Docker Compose:
docker compose up -d
This will:
- Build a container with Python, Node.js, and Playwright browsers
- Create persistent volumes for blob storage and playwright output
- Start the proxy server
Configuration
Configure the proxy via environment variables in .env:
Global Browser Settings
PW_MCP_PROXY_BROWSER: Browser to use (chromium, firefox, webkit) - default: chromiumPW_MCP_PROXY_HEADLESS: Run headless - default: truePW_MCP_PROXY_CAPS: Capabilities (vision,pdf,testing,tracing) - default: vision,pdfPW_MCP_PROXY_TIMEOUT_ACTION: Action timeout in ms - default: 15000PW_MCP_PROXY_TIMEOUT_NAVIGATION: Navigation timeout in ms - default: 30000
Pool Configuration
PW_MCP_PROXY__<POOL>_INSTANCES: Number of instances in poolPW_MCP_PROXY__<POOL>_IS_DEFAULT: Mark as default poolPW_MCP_PROXY__<POOL>_DESCRIPTION: Pool descriptionPW_MCP_PROXY__<POOL>__<ID>_BROWSER: Browser for specific instancePW_MCP_PROXY__<POOL>__<ID>_ALIAS: Alias for specific instancePW_MCP_PROXY__<POOL>__<ID>_HEADLESS: Headless mode for specific instance
Stealth Settings (Anti-Detection)
PW_MCP_PROXY_STEALTH_MODE: Enable built-in stealth mode - default: falsePW_MCP_PROXY_USER_AGENT: Custom user agent string - optionalPW_MCP_PROXY_INIT_SCRIPT: Path to custom init script - optionalPW_MCP_PROXY_IGNORE_HTTPS_ERRORS: Ignore HTTPS errors - default: false
See docs/STEALTH.md for detailed stealth configuration.
Blob Storage Settings
BLOB_STORAGE_ROOT: Storage directory - default: /mnt/blob-storageBLOB_MAX_SIZE_MB: Max size per blob - default: 500BLOB_TTL_HOURS: Time-to-live for blobs - default: 24BLOB_SIZE_THRESHOLD_KB: Size threshold for blob storage - default: 50BLOB_CLEANUP_INTERVAL_MINUTES: Cleanup frequency - default: 60
See example env files in the repository root for complete configuration examples.
How It Works
Binary Data Interception
The proxy automatically detects large binary data in playwright tool responses:
- When playwright tools return screenshots or PDFs
- If the data size exceeds the threshold (default: 50KB)
- The proxy stores the binary data as a blob
- The response is transformed to include a blob reference instead
Before (direct playwright-mcp):
{
"screenshot": "data:image/png;base64,iVBORw0KGgo...500KB of data..."
}
After (through proxy):
{
"screenshot": "blob://1733577600-a3f2c1d9e4b5.png",
"screenshot_size_kb": 500,
"screenshot_mime_type": "image/png",
"screenshot_expires_at": "2024-12-08T10:00:00Z"
}
Retrieving Blobs
Blob retrieval is handled by a separate MCP Resource Server. See mcp-mapped-resource-lib for details.
Available Tools
Browser Tools
All playwright-mcp tools are available with browser pool support:
browser_navigate: Navigate to a URLbrowser_click: Click an elementbrowser_fill: Fill a form fieldbrowser_screenshot: Take a screenshot (auto-stored as blob if large)browser_snapshot: Get ARIA snapshotbrowser_evaluate: Execute JavaScript- And 40+ more tools...
All tools accept optional browser_pool and browser_instance parameters.
Pool Management
browser_pool_status(pool_name): Get pool health, lease activity, and instance status
Architecture
┌─────────────────────────────────┐
│ MCP Client (Claude Desktop) │
└────────────┬────────────────────┘
│ stdio
┌────────────▼────────────────────┐
│ FastMCP Proxy (Python) │
│ - Pool Manager │
│ - Binary Interception │
│ - Blob Storage Integration │
│ - Instance Leasing (FIFO) │
└────────────┬────────────────────┘
│ stdio (per instance)
┌────────────▼────────────────────┐
│ playwright-mcp instances │
│ - Browser Automation │
│ - Screenshot/PDF Generation │
└─────────────────────────────────┘
Testing
Run the test suite:
uv run pytest -v
Lint the code:
uv run ruff check src/ tests/
uv run ruff format src/ tests/
Project Structure
src/playwright_proxy_mcp/
├── server.py # Main MCP proxy server
├── types.py # TypedDict definitions
├── playwright/ # Playwright proxy components
│ ├── config.py # Configuration loading (pool config)
│ ├── pool_manager.py # Browser pool management
│ ├── process_manager.py # Subprocess management
│ ├── blob_manager.py # Blob storage wrapper
│ ├── middleware.py # Binary interception
│ └── proxy_client.py # Stdio transport integration
└── utils/
├── navigation_cache.py # TTL-based pagination cache
├── aria_processor.py # ARIA snapshot processing
└── jmespath_extensions.py # Custom JMESPath functions
Benefits
Token Savings
Large screenshots can consume 50,000+ tokens. With blob storage:
- Screenshots stored as blobs use ~100 tokens for the reference
- Retrieve full data only when needed
- Automatic cleanup prevents storage bloat
Concurrent Operations
Browser pools enable:
- Parallel browser automation
- Instance isolation for concurrent tasks
- Different browser configurations for different use cases
Performance
- Faster response times for tool calls
- Reduced context window usage
- Efficient deduplication of identical screenshots
- FIFO instance leasing for fair resource allocation
Troubleshooting
npx not found
Ensure Node.js is installed and npx is in your PATH:
node --version
npx --version
Playwright browser installation fails
Install browsers manually:
npx playwright@latest install chromium --with-deps
Blob storage permissions
Ensure the blob storage directory is writable:
chmod -R 755 /mnt/blob-storage
Pool not starting
Check the pool configuration in your .env file. Ensure:
- At least one pool has
IS_DEFAULT=true - Instance counts are valid (positive integers)
- No alias conflicts with numeric instance IDs
License
MIT
Contributing
Contributions welcome! Please open an issue or pull request.
Resources
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
E2B
Using MCP to run code via e2b.