puppeteer-swarm-mcp
v0.1.0
Published
MCP server for browser automation with tab pool support using Puppeteer
Readme
Puppeteer Swarm MCP
MCP server for browser automation with tab pool support using Puppeteer.
Features
- Tab Pool: Manage multiple browser tabs concurrently
- Auto-release: Automatically release tabs after idle timeout (default: 5 minutes)
- Auto-recovery: Automatically recover crashed tabs
- Configurable: Set tab count and headless mode via CLI arguments
Installation
Option 1: Install from npm
npm install -g puppeteer-swarm-mcpOr run directly using npx:
npx puppeteer-swarm-mcpOption 2: Install from source
git clone https://github.com/greatSumini/puppeteer-swarm-mcp.git
cd puppeteer-swarm-mcp
npm install
npm run buildUsage
# Default: 5 tabs, headless=false
puppeteer-swarm-mcp
# Custom tab count
puppeteer-swarm-mcp --tabs=10
# Headless mode
puppeteer-swarm-mcp --headless
# Combined options
puppeteer-swarm-mcp --tabs=10 --headlessEnvironment Variables
TAB_COUNT=10 HEADLESS=true puppeteer-swarm-mcpMCP Client Integration
Puppeteer Swarm MCP can be integrated with various AI coding assistants and IDEs that support the Model Context Protocol (MCP).
Requirements
- Node.js >= v18.0.0
- An MCP-compatible client (Claude Code, Cursor, VS Code, Windsurf, etc.)
Run this command:
claude mcp add puppeteer-swarm -- npx -y puppeteer-swarm-mcp --tabs=5 --headlessOr with custom options:
claude mcp add puppeteer-swarm -- npx -y puppeteer-swarm-mcp --tabs=10Go to: Settings -> Cursor Settings -> MCP -> Add new global MCP server
Add the following configuration to your ~/.cursor/mcp.json file:
{
"mcpServers": {
"puppeteer-swarm": {
"command": "npx",
"args": ["-y", "puppeteer-swarm-mcp", "--tabs=5", "--headless"]
}
}
}Add the following to your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"puppeteer-swarm": {
"command": "npx",
"args": ["-y", "puppeteer-swarm-mcp", "--tabs=5", "--headless"]
}
}
}Add this to your VS Code MCP config file. See VS Code MCP docs for more info.
"mcp": {
"servers": {
"puppeteer-swarm": {
"type": "stdio",
"command": "npx",
"args": ["-y", "puppeteer-swarm-mcp", "--tabs=5", "--headless"]
}
}
}Add this to your Windsurf MCP config file:
{
"mcpServers": {
"puppeteer-swarm": {
"command": "npx",
"args": ["-y", "puppeteer-swarm-mcp", "--tabs=5", "--headless"]
}
}
}- Open Cline
- Click the hamburger menu icon (☰) to enter the MCP Servers section
- Choose Remote Servers tab
- Click the Edit Configuration button
- Add puppeteer-swarm to
mcpServers:
{
"mcpServers": {
"puppeteer-swarm": {
"command": "npx",
"args": ["-y", "puppeteer-swarm-mcp", "--tabs=5", "--headless"]
}
}
}Add this to your Zed settings.json:
{
"context_servers": {
"puppeteer-swarm": {
"source": "custom",
"command": "npx",
"args": ["-y", "puppeteer-swarm-mcp", "--tabs=5", "--headless"]
}
}
}Available Tools
get_pool_status
Get the current status of the tab pool.
Parameters: None
Returns:
{
"total": 5,
"idle": 3,
"busy": 2
}navigate
Allocate an idle tab and navigate to a URL.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| url | string | Yes | URL to navigate to |
| waitUntil | string | No | Wait condition (load, domcontentloaded, networkidle0, networkidle2) |
Returns:
{
"tabId": "tab-1",
"url": "https://example.com",
"title": "Example Domain"
}get_content
Extract HTML or text content from a page.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| tabId | string | Yes | Target tab ID |
| type | string | No | Extract format (html, text). Default: text |
Returns:
{
"content": "..."
}screenshot
Capture a page screenshot.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| tabId | string | Yes | Target tab ID |
| fullPage | boolean | No | Capture full page. Default: false |
Returns: Image content (base64 PNG)
click
Click an element by CSS selector.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| tabId | string | Yes | Target tab ID |
| selector | string | Yes | CSS selector |
Returns:
{
"success": true
}type
Type text into an input field.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| tabId | string | Yes | Target tab ID |
| selector | string | Yes | CSS selector |
| text | string | Yes | Text to type |
Returns:
{
"success": true
}evaluate
Execute JavaScript in the page context.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| tabId | string | Yes | Target tab ID |
| script | string | Yes | JavaScript code to execute |
Returns:
{
"result": "..."
}wait_for_selector
Wait for an element to appear in the DOM.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| tabId | string | Yes | Target tab ID |
| selector | string | Yes | CSS selector |
| timeout | number | No | Timeout in ms. Default: 30000 |
Returns:
{
"success": true
}release_tab
Release a tab back to idle state.
Parameters:
| Name | Type | Required | Description |
|------|------|----------|-------------|
| tabId | string | Yes | Tab ID to release |
Returns:
{
"success": true
}Workflow Example
1. navigate({ url: "https://example.com" })
-> Returns { tabId: "tab-1", ... }
2. get_content({ tabId: "tab-1", type: "text" })
-> Returns page content
3. click({ tabId: "tab-1", selector: "button.submit" })
-> Click a button
4. release_tab({ tabId: "tab-1" })
-> Release the tab for reuseLogging
Logs are stored in the logs/ directory:
- File Pattern:
mcp-puppeteer-YYYY-MM-DD.log - Daily rotation, max 20MB per file
- 14 days retention with auto-compression
License
MIT License - see the LICENSE file for details.
Author
Choi Sumin - GitHub
