pinchtab-mcp-wrapper
Token-efficient browser automation MCP server for AI agents. Web scraping, monitoring & testing with 12x cost savings vs traditional browsers.
Pinchtab MCP Wrapper
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.
Why Use Pinchtab for AI Agents?
When AI agents need to browse the web, efficiency matters. Pinchtab delivers 5-13x cost savings compared to traditional browser automation.
Cost Comparison (Real Numbers)
| 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 |
Key Advantages for AI Workflows
1. Data Extraction & Web Scraping
- Extract clean, structured text without HTML overhead
- Accessibility tree provides semantic structure (roles, labels, states)
- Filter to interactive elements only when needed
2. Website Change Monitoring
diff=truereturns only changed elements since last snapshot- Track price changes, content updates, or availability
- Monitor 50+ pages without context overflow
3. Async Multi-Tab Operations
- Run 20+ tabs simultaneously (vs 3-5 with Playwright)
- Tab locking prevents conflicts between agents
- Each tab ~1MB RAM vs 50MB+ for full browser instances
4. Stable Automation
- Stable element references (
e0,e1) survive CSS changes - No brittle CSS selectors that break on redesigns
- Works with sites that block traditional automation (stealth mode)
Quick Start
One-Line Installation
curl -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.)
Test It
Open https://example.com and take a screenshot
Or use commands:
/browse https://example.com
/screenshot
Use Cases & Examples
1. Web Scraping at Scale
Problem: Extract product prices from 100 e-commerce pages
Traditional approach:
- Load full DOM (~10,000 tokens per page)
- Parse HTML manually
- Cost: 1,000,000 tokens (~$3.00)
Pinchtab approach:
// Extract structured text only
pinchtab_read_page({url: "https://store.com/product"})
// Returns clean text with prices, descriptions
- Cost: 80,000 tokens (~$0.24)
- Savings: $2.76 (12.5x cheaper)
2. Change Detection & Monitoring
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:
- Track 50 sites without context overflow
- Instant detection of changes
- 200x less data transfer
3. Multi-Source Research
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:
- 20+ concurrent tabs
- No memory issues (1MB per tab)
- Async operations
4. Form Automation That Lasts
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
})
5. Accessibility-First Testing
Built-in accessibility tree:
- Element roles (button, link, heading)
- Accessible names and labels
- Focus states and visibility
- Screen reader compatible
// Get only interactive elements
interactives = pinchtab_list_interactives()
// Returns: buttons, links, inputs with labels
Available Tools
| 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 |
CLI Integration
OpenCode
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
Claude Code
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.
Cursor
Add to Cursor's MCP settings (Settings → Features → MCP):
{
"mcpServers": {
"pinchtab": {
"type": "stdio",
"command": "bash",
"args": ["~/.pinchtab-mcp-wrapper/run-mcp.sh"]
}
}
}
Zed
Add to ~/.config/zed/settings.json:
{
"assistant": {
"version": "2",
"enabled": true
},
"context_servers": {
"pinchtab": {
"command": "bash",
"args": ["~/.pinchtab-mcp-wrapper/run-mcp.sh"]
}
}
}
Automatic Configuration for Multiple AI Agents
The installer now automatically detects and configures pinchtab for multiple AI agents:
- OpenCode (
~/.config/opencode/opencode.json) - Claude Code (
~/.mcp.jsonor./.mcp.json) - Cursor (
~/.config/Cursor/User/settings.json) - Zed (
~/.config/zed/settings.json)
If a config file already exists, the installer will:
- Create a backup (
.backup.YYYYMMDD_HHMMSS) - Automatically merge pinchtab configuration using Node.js
- Preserve all existing settings
No manual editing required - just run the installer and restart your AI agent!
Installation Options
The install script now supports automatic mode detection and graceful fallback:
Automatic Mode (Default)
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:
- Checks for Docker (including macOS-specific paths: Homebrew, OrbStack, Docker Desktop)
- If Docker is available → builds Docker image and uses
dockermode - If Docker is unavailable → automatically downloads Pinchtab binary and uses
externalmode
Docker Mode
Recommended 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
External Mode (Binary)
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
macOS Support
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
Manual Installation
# 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
Configuration
Screenshot File Delivery (New)
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 |
Environment Variables
# 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
HTTP Mode (v0.5.0+)
Pinchtab MCP Wrapper now supports Streamable HTTP transport for remote/cloud deployments.
Use cases for HTTP mode:
- Cloud deployments (AWS, GCP, Azure)
- Remote AI agent access
- Serverless architectures
- Load balancing across multiple instances
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:
- Always use authentication in production (
MCP_AUTH_TYPE=bearer) - Restrict CORS origins (
MCP_ALLOWED_ORIGINS=https://yourdomain.com) - Use HTTPS with a reverse proxy (nginx, traefik)
- Keep auth tokens secure and rotate regularly
Streamable HTTP Endpoint Details:
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) |
LobeChat Integration
For LobeChat v2 (and other HTTP-based MCP clients):
- Start MCP in HTTP mode (listening on all interfaces for Docker network access):
./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:
- Go to Settings → Plugins → MCP
- Add new MCP server:
- Name:
pinchtab - Type:
HTTP(orStreamable HTTP) - URL:
http://172.21.0.1:3001/mcp(adjust IP based on your Docker network) - Auth Type:
None
- Name:
- Click "Test Connection"
Finding the correct IP address:
- Check your Docker network:
docker network inspect bridge - Find the gateway IP for your container network
- Common values:
172.17.0.1- default Docker bridge172.21.0.1- custom networkshost.docker.internal- Docker Desktop (Mac/Windows)
- Check your Docker network:
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"
}
}
}
}
Running Multiple AI Agents with One Pinchtab Instance
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:
- Start Pinchtab Docker container:
docker run -d \
--name pinchtab \
-p 127.0.0.1:9867:9867 \
-e PINCHTAB_TOKEN=opencode-browser-token-secure \
pinchtab:local
- Start HTTP MCP server for server-based agents (LobeChat, etc.):
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:
- OpenCode:
~/.config/opencode/opencode.json(see OpenCode section) - Claude Code:
.mcp.json(see Claude Code section) - Cursor: MCP settings (see Cursor section)
- Zed:
~/.config/zed/settings.json(see Zed section)
- OpenCode:
Configure server-based agents (LobeChat) to use HTTP:
- URL:
http://172.21.0.1:3001/mcp - Type:
Streamable HTTP - Auth:
None
- URL:
Benefits:
- Single Pinchtab instance for all AI agents
- No port conflicts (stdio for CLI, HTTP for servers)
- Resource efficient (one browser instance)
- Consistent browser state across all agents
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 Options (via Docker)
Pinchtab Options (via Docker)
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 Options (via Docker)
BRIDGE_STEALTH=full # Bypass bot detection
BRIDGE_BLOCK_IMAGES=true # Faster loading
BRIDGE_NO_ANIMATIONS=true # Consistent snapshots
BRIDGE_TIMEOUT=30 # Action timeout (seconds)
Troubleshooting
| 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 |
Token Efficiency Guide
Best practices for minimizing costs:
- Use
/textfor reading - 800 tokens vs 10,000 for DOM - Filter interactives - 3,600 tokens vs 10,500 for full page
- Use
diff=true- Only changed elements (50-200 tokens) - Block images/media - Faster loading, less noise
- Lock tabs - Prevent conflicts, avoid re-work
Development
npm install
npm run build
npm test
Release History
See CHANGELOG.md for detailed version history and changes.
Latest release: v0.6.1 (2026-03-19)
- E2E HTTP tests stability - Fixed intermittent timeouts in HTTP mode E2E tests
- All v0.6.0 features included
Previous release (v0.6.0):
- Pinchtab v0.7.8 support - Updated to stable Pinchtab version
- Fixed MCP Streamable HTTP transport - Improved connection stability and error handling
Previous releases:
- v0.5.1 - Pinchtab v0.6.3 support, file upload tool
- v0.5.0 - Streamable HTTP transport, multi-transport architecture
- v0.4.0 - CI/CD pipeline, ESLint, comprehensive test suite
- v0.2.0 - Download tool, Pinchtab 0.6.1, multi-agent configuration
Credits & License
This MCP wrapper is built on Pinchtab by Luigi Agosti and contributors.
- Pinchtab: github.com/pinchtab/pinchtab
- MCP Protocol: modelcontextprotocol.io
MIT License
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi