A community-driven registry for Claude, Cursor, Windsurf, Cline & more. Not affiliated with Anthropic.
Are you the author? Sign in to claim
Token-efficient browser automation MCP server for AI agents. Web scraping, monitoring & testing with 12x cost savings v
An MCP (Model Context Protocol) server that exposes the full Pinchtab browser API to AI coding agents. Built with token efficiency in mind — perfect for data extraction, web scraping, and automated testing workflows.
🙏 Credits: This wrapper is built on top of the excellent Pinchtab project by Luigi Agosti and the Pinchtab team. Pinchtab is a lightweight 12MB Go binary that provides browser automation via HTTP API with accessibility-first snapshots.
When AI agents need to browse the web, efficiency matters. Pinchtab delivers 5-13x cost savings compared to traditional browser automation.
| Task | Traditional Browser | Pinchtab | Savings |
|---|---|---|---|
| Extract article text | ~10,000 tokens (full DOM) | ~800 tokens | 12.5x cheaper |
| Find interactive elements | ~10,500 tokens | ~3,600 tokens | 3x cheaper |
| 50-page monitoring task | ~$0.30 | ~$0.01 | 30x cheaper |
1. Data Extraction & Web Scraping
2. Website Change Monitoring
diff=true returns only changed elements since last snapshot3. Async Multi-Tab Operations
4. Stable Automation
e0, e1) survive CSS changescurl -fsSL https://raw.githubusercontent.com/BDuba/pinchtab-mcp-wrapper/main/install.sh | bash
Requirements: Docker, Node.js 18+, npm
Then restart your AI agent (OpenCode, Claude Code, etc.)
Open https://example.com and take a screenshot
Or use commands:
/browse https://example.com
/screenshot
Problem: Extract product prices from 100 e-commerce pages
Traditional approach:
Pinchtab approach:
// Extract structured text only
pinchtab_read_page({url: "https://store.com/product"})
// Returns clean text with prices, descriptions
Problem: Monitor competitor prices or news updates
// First visit - establish baseline
snapshot1 = pinchtab_snapshot({url: "https://competitor.com/prices"})
// Later visits - get only changes
diff = pinchtab_snapshot({
url: "https://competitor.com/prices",
diff: true
})
// Returns only modified elements (50-200 tokens vs 10,000)
Benefits:
Problem: Gather information from 10+ documentation sites simultaneously
// Open multiple tabs in parallel
tab1 = pinchtab_tab_open({url: "https://docs.api1.com"})
tab2 = pinchtab_tab_open({url: "https://docs.api2.com"})
tab3 = pinchtab_tab_open({url: "https://docs.api3.com"})
// Extract text from all tabs
text1 = pinchtab_read_page({tabId: tab1.tabId})
text2 = pinchtab_read_page({tabId: tab2.tabId})
text3 = pinchtab_read_page({tabId: tab3.tabId})
Benefits:
Problem: Automate login/checkout flows that break on website updates
Traditional selectors break:
// Brittle - breaks when CSS changes
await page.click('#login-btn') // ❌
Pinchtab stable refs:
// Stable - survives redesigns
pinchtab_action({
tabId: "...",
kind: "click",
ref: "e5" // ✅ Persistent reference
})
Built-in accessibility tree:
// Get only interactive elements
interactives = pinchtab_list_interactives()
// Returns: buttons, links, inputs with labels
| Tool | Purpose |
|---|---|
pinchtab_tab_open | Open URL in new tab |
pinchtab_read_page | Extract page text (token-efficient) |
pinchtab_list_interactives | Get clickable elements |
pinchtab_snapshot | Get accessibility tree |
pinchtab_action | Click, type, fill forms |
pinchtab_screenshot | Take JPEG screenshot |
pinchtab_evaluate | Run JavaScript |
pinchtab_download | Download files using browser session (preserves cookies, auth, stealth) |
pinchtab_upload | Upload files to file inputs (local paths, base64, or data URLs) |
pinchtab_tab_lock | Lock tab for exclusive access |
Add to ~/.config/opencode/opencode.json:
{
"\$schema": "https://opencode.ai/config.json",
"mcp": {
"pinchtab": {
"type": "local",
"command": [
"/usr/bin/node",
"~/.pinchtab-mcp-wrapper/dist/index.js"
],
"environment": {
"PINCHTAB_MODE": "external",
"PINCHTAB_URL": "http://127.0.0.1:9867",
"PINCHTAB_TOKEN": "opencode-browser-token-secure",
"MCP_TRANSPORT": "stdio",
"LOG_LEVEL": "info"
},
"enabled": true
}
},
"agent": {
"browser": {
"description": "Browser automation specialist",
"prompt": "Use pinchtab MCP tools for all web browsing tasks. Prefer text extraction over screenshots for efficiency.",
"tools": {
"pinchtab*": true,
"playwright*": false
}
}
},
"default_agent": "browser"
}
Prerequisites: Ensure Pinchtab Docker container is running:
docker ps | grep pinchtab # Check if running
docker start pinchtab # Start if stopped
Add to .mcp.json:
{
"mcpServers": {
"pinchtab": {
"command": "bash",
"args": ["~/.pinchtab-mcp-wrapper/run-mcp.sh"]
}
}
}
Claude Code Skill (Experimental): We also provide a skill file for Claude Code CLI users. See CLAUDE_CODE_SKILL.md for detailed installation and usage instructions in Spanish. You can save this file to ~/.claude/commands/pinchtab.md and use /pinchtab to access the full reference directly in your CLI.
Add to Cursor's MCP settings (Settings → Features → MCP):
{
"mcpServers": {
"pinchtab": {
"type": "stdio",
"command": "bash",
"args": ["~/.pinchtab-mcp-wrapper/run-mcp.sh"]
}
}
}
Add to ~/.config/zed/settings.json:
{
"assistant": {
"version": "2",
"enabled": true
},
"context_servers": {
"pinchtab": {
"command": "bash",
"args": ["~/.pinchtab-mcp-wrapper/run-mcp.sh"]
}
}
}
The installer now automatically detects and configures pinchtab for multiple AI agents:
~/.config/opencode/opencode.json)~/.mcp.json or ./.mcp.json)~/.config/Cursor/User/settings.json)~/.config/zed/settings.json)If a config file already exists, the installer will:
.backup.YYYYMMDD_HHMMSS)No manual editing required - just run the installer and restart your AI agent!
The install script now supports automatic mode detection and graceful fallback:
The installer automatically detects your environment and chooses the best mode:
curl -fsSL https://raw.githubusercontent.com/BDuba/pinchtab-mcp-wrapper/main/install.sh | bash
What happens:
docker modeexternal modeRecommended for most users. Requires Docker to be installed.
export PINCHTAB_MODE=docker
curl -fsSL https://raw.githubusercontent.com/BDuba/pinchtab-mcp-wrapper/main/install.sh | bash
For systems without Docker. The installer automatically downloads the Pinchtab binary for your architecture.
export PINCHTAB_MODE=external
curl -fsSL https://raw.githubusercontent.com/BDuba/pinchtab-mcp-wrapper/main/install.sh | bash
The installer automatically detects Docker in the following locations:
/opt/homebrew/bin/docker (Homebrew on Apple Silicon)/usr/local/bin/docker (Homebrew on Intel)/Applications/OrbStack.app/Contents/MacOS/../bin/docker (OrbStack)/Applications/Docker.app/Contents/Resources/bin/docker (Docker Desktop)~/.docker/bin/docker (Docker Desktop alternative)You can also manually specify the Docker path:
export DOCKER_PATH=/opt/homebrew/bin/docker
curl -fsSL https://raw.githubusercontent.com/BDuba/pinchtab-mcp-wrapper/main/install.sh | bash
# Clone
git clone https://github.com/BDuba/pinchtab-mcp-wrapper.git
cd pinchtab-mcp-wrapper
# Build
npm install && npm run build
# Build Docker image
docker build -f pinchtab.Dockerfile -t pinchtab:local .
# Create wrapper
cat > run-mcp.sh << 'EOF'
#!/bin/bash
export PINCHTAB_MODE=docker
export PINCHTAB_TOKEN=opencode-browser-token-secure
export PINCHTAB_DOCKER_IMAGE=pinchtab:local
exec node "$(dirname "$0")/dist/index.js"
EOF
chmod +x run-mcp.sh
When using delivery: "file", you can now use relative paths and auto-naming:
{
"tool": "screenshot",
"params": {
"delivery": "file"
// Auto-saved to: ~/Pictures/Screenshots/2026-02-21T12-34-56-tab-123.jpg
}
}
{
"tool": "screenshot",
"params": {
"delivery": "file",
"path": "google/homepage.jpg"
// Saved to: ~/Pictures/Screenshots/google/homepage.jpg
}
}
{
"tool": "screenshot",
"params": {
"delivery": "file",
"path": "/absolute/path/to/screenshot.png"
// Absolute paths still work as before
}
}
| Variable | Description | Default |
|---|---|---|
SCREENSHOTS_DIR | Base directory for screenshots | OS-specific (~/Pictures/Screenshots) |
SCREENSHOTS_AUTO_CREATE | Auto-create directories | true |
SCREENSHOTS_PATTERN | Filename pattern | {timestamp}-{tabId}.jpg |
# Transport (v0.5.0+)
MCP_TRANSPORT=stdio # stdio | streamable-http | sse
MCP_HTTP_PORT=3000 # HTTP server port
MCP_HTTP_HOST=0.0.0.0 # HTTP server host
MCP_AUTH_TYPE=none # none | bearer | api-key
MCP_AUTH_TOKEN=secret-token # Auth token for HTTP mode
MCP_ALLOWED_ORIGINS=* # CORS origins
# Pinchtab connection
PINCHTAB_MODE=docker # docker | external
PINCHTAB_TOKEN=secret-token # Auth token
DEFAULT_SNAPSHOT_FORMAT=compact # compact | text | json
DEFAULT_MAX_TOKENS=2500 # Token budget
SCREENSHOT_DEFAULT_DELIVERY=base64 # base64 | s3 | file
Pinchtab MCP Wrapper now supports Streamable HTTP transport for remote/cloud deployments.
Use cases for HTTP mode:
Quick start with HTTP:
# Terminal 1: Start MCP server in HTTP mode
export MCP_TRANSPORT=streamable-http
export MCP_HTTP_PORT=3000
export MCP_AUTH_TYPE=bearer
export MCP_AUTH_TOKEN=your-secret-token
npm start
# Terminal 2: Test the HTTP endpoint
curl http://localhost:3000/health
HTTP Mode Configuration:
| Variable | Description | Default |
|---|---|---|
MCP_TRANSPORT | Transport type | stdio |
MCP_HTTP_PORT | HTTP server port | 3000 |
MCP_HTTP_HOST | HTTP server host | 0.0.0.0 |
MCP_HTTP_PATH | MCP endpoint path | /mcp |
MCP_AUTH_TYPE | Auth type: none, bearer, api-key | none |
MCP_AUTH_TOKEN | Auth token (required for bearer/api-key) | - |
MCP_ALLOWED_ORIGINS | CORS allowed origins (comma-separated) | * |
MCP_ENABLE_SESSIONS | Enable stateful sessions | true |
MCP_SESSION_TIMEOUT | Session timeout in seconds | 3600 |
Security best practices for HTTP mode:
MCP_AUTH_TYPE=bearer)MCP_ALLOWED_ORIGINS=https://yourdomain.com)When running in HTTP mode, the MCP server exposes:
| Endpoint | Method | Description |
|---|---|---|
http://host:port/mcp | POST/GET | Main MCP Streamable HTTP endpoint |
http://host:port/health | GET | Health check endpoint |
http://host:port/health | GET | |
http://host:port/status | GET | Status endpoint (alias for health) |
For LobeChat v2 (and other HTTP-based MCP clients):
./run-mcp-http-all.sh
# or
export MCP_TRANSPORT=streamable-http
export MCP_HTTP_HOST=0.0.0.0
export MCP_HTTP_PORT=3001
export MCP_AUTH_TYPE=none
npm start
Configure in LobeChat:
pinchtabHTTP (or Streamable HTTP)http://172.21.0.1:3001/mcp (adjust IP based on your Docker network)NoneFinding the correct IP address:
docker network inspect bridge172.17.0.1 - default Docker bridge172.21.0.1 - custom networkshost.docker.internal - Docker Desktop (Mac/Windows)Note: The run-mcp-http-all.sh script listens on 0.0.0.0 to allow connections from any Docker container.
Example MCP Client Configuration:
// MCP Client Streamable HTTP configuration
{
"mcpServers": {
"pinchtab": {
"transport": "streamable-http",
"url": "http://localhost:3000/mcp",
"headers": {
"Authorization": "Bearer your-secret-token"
}
}
}
}
HTTP Headers:
| Header | Required | Description |
|---|---|---|
Authorization | If auth enabled | Bearer <token> or raw token for api-key |
Content-Type | Yes | application/json |
Mcp-Session-Id | Optional | Session ID for stateful mode |
Authentication Examples:
# Bearer token auth
curl -H "Authorization: Bearer your-secret-token" \
http://localhost:3000/mcp
# API key auth (header)
curl -H "Authorization: your-api-key" \
http://localhost:3000/mcp
# API key auth (query param)
curl "http://localhost:3000/mcp?api_key=your-api-key"
Connecting from AI Agents:
Most MCP clients support Streamable HTTP natively. Configure your AI agent with:
{
"mcp": {
"pinchtab": {
"type": "http",
"url": "http://your-server:3000/mcp",
"headers": {
"Authorization": "Bearer your-secret-token"
}
}
}
}
Scenario: You have multiple AI agents (OpenCode, LobeChat, Claude Code, Cursor, etc.) and want to use a single Pinchtab Docker container for all of them.
Problem: Each AI agent may require a different MCP transport (stdio for CLI agents, HTTP for server-based agents).
Solution: Use one Pinchtab container with multiple MCP servers:
┌─────────────────────────────────────────────────────────────┐
│ Pinchtab Docker Container │
│ (http://127.0.0.1:9867) │
└─────────────────────────┬───────────────────────────────────┘
│
┌─────────────────────────▼───────────────────────────────────┐
│ MCP Wrapper HTTP Server │
│ (http://0.0.0.0:3001/mcp) │
│ • LobeChat ───────┐ • Other HTTP clients ───┐ │
│ • Remote agents ──┘ • Cloud services ───────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ MCP Wrapper stdio Servers │
│ • OpenCode ───────┐ • Claude Code ───────┐ │
│ • Cursor ─────────┘ • Zed ───────────────┘ │
└─────────────────────────────────────────────────────────────┘
Setup Steps:
docker run -d \
--name pinchtab \
-p 127.0.0.1:9867:9867 \
-e PINCHTAB_TOKEN=opencode-browser-token-secure \
pinchtab:local
export PINCHTAB_MODE=external
export PINCHTAB_URL=http://127.0.0.1:9867
export PINCHTAB_TOKEN=opencode-browser-token-secure
export MCP_TRANSPORT=streamable-http
export MCP_HTTP_PORT=3001
export MCP_HTTP_HOST=0.0.0.0
export MCP_AUTH_TYPE=none
export MCP_ENABLE_SESSIONS=true
node dist/index.js
Configure CLI agents (OpenCode, Claude Code, Cursor, Zed) to use stdio:
~/.config/opencode/opencode.json (see OpenCode section).mcp.json (see Claude Code section)~/.config/zed/settings.json (see Zed section)Configure server-based agents (LobeChat) to use HTTP:
http://172.21.0.1:3001/mcpStreamable HTTPNoneBenefits:
Making HTTP MCP server persistent:
sudo tee /etc/systemd/system/pinchtab-mcp.service << 'EOF'
[Unit]
Description=Pinchtab MCP HTTP Server
After=network.target docker.service
[Service]
Type=simple
User=root
WorkingDirectory=/root/.pinchtab-mcp-wrapper
ExecStart=/bin/bash -c 'export PINCHTAB_MODE=external && export PINCHTAB_URL=http://127.0.0.1:9867 && export PINCHTAB_TOKEN=opencode-browser-token-secure && export MCP_TRANSPORT=streamable-http && export MCP_HTTP_PORT=3001 && export MCP_HTTP_HOST=0.0.0.0 && export MCP_AUTH_TYPE=none && export MCP_ENABLE_SESSIONS=true && node dist/index.js'
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable pinchtab-mcp
sudo systemctl start pinchtab-mcp
PINCHTAB_MODE=docker # docker | external
PINCHTAB_TOKEN=secret-token # Auth token
DEFAULT_SNAPSHOT_FORMAT=compact # compact | text | json
DEFAULT_MAX_TOKENS=2500 # Token budget
SCREENSHOT_DEFAULT_DELIVERY=base64 # base64 | s3 | file
BRIDGE_STEALTH=full # Bypass bot detection
BRIDGE_BLOCK_IMAGES=true # Faster loading
BRIDGE_NO_ANIMATIONS=true # Consistent snapshots
BRIDGE_TIMEOUT=30 # Action timeout (seconds)
| Issue | Solution |
|---|---|
| "Connection closed" | Check docker ps, verify container running |
| "MCP error -32000" | Restart AI agent completely |
| Health check timeout | docker logs pinchtab for errors |
| 401 errors | Verify PINCHTAB_TOKEN matches |
Best practices for minimizing costs:
/text for reading - 800 tokens vs 10,000 for DOMdiff=true - Only changed elements (50-200 tokens)npm install
npm run build
npm test
See CHANGELOG.md for detailed version history and changes.
Latest release: v0.6.1 (2026-03-19)
Previous release (v0.6.0):
Previous releases:
This MCP wrapper is built on Pinchtab by Luigi Agosti and contributors.
MIT License
MCP server integration for DaVinci Resolve Studio
A trilingual (繁中 / English / 简中) learning roadmap for agentic AI: from LLM basics to multi-agent systems, with 240+ cura
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots