Pinchtab
High-performance browser automation bridge and multi-instance orchestrator with advanced stealth injection and real-time dashboard.
Install / Use
/learn @pinchtab/PinchtabREADME
What is PinchTab?
PinchTab is a standalone HTTP server that gives AI agents direct control over Chrome.
For day-to-day local use, the server is typically installed as a user-level daemon, allowing agent tools to reuse the same browser control plane running in the background.
curl -fsSL https://pinchtab.com/install.sh | bash
# or
pinchtab daemon install
This installs the control-plane server and starts a default headless Chrome instance, ready to accept requests from agents or manual API calls.
PinchTab is designed first for local, single-user control on a machine you manage. Remote and distributed layouts are supported, but they are advanced operator-managed deployments. If you bind beyond loopback, publish ports, or attach remote bridges, you are responsible for tokens, network boundaries, TLS or reverse proxying, and which endpoint families you expose.
If you run PinchTab on a different machine, do it only when you understand the security model. Keep it on a private or otherwise closed network, avoid exposing it directly to the public internet, and keep high-risk endpoint families disabled unless you explicitly need them. If you do enable them, lock them down so only the systems that need them can reach them.
[!WARNING] The dashboard, HTTP API, MCP server, and remote CLI integrations are privileged operator control surfaces. They are not designed for untrusted users, multi-tenant exposure, or direct public-internet access. If you are unsure how to secure a non-local deployment, review docs/guides/security.md and use the private security contact path in SECURITY.md before exposing the service.
If you prefer not to run a daemon, or if you're on Windows, you can instead run:
pinchtab server — runs the control-plane server directly
pinchtab bridge — runs a single browser instance as a lightweight runtime
PinchTab also provides a CLI with an interactive entry point for local setup and common tasks:
pinchtab
Security
PinchTab defaults to a local-first security posture:
server.bind = 127.0.0.1- sensitive endpoint families are disabled by default
attachis disabled by default- IDPI is enabled with a local-only website allowlist
[!CAUTION] By default, IDPI restricts browsing to locally hosted websites only. This prevents agents from navigating the public internet until you explicitly allow it. The restriction exists to make the security implications of browser automation clear before enabling wider access.
Expanding browsing to non-local or non-trusted websites is a security-reducing choice. Hostile pages can still increase browser attack surface and interact badly with enabled automation features even when PinchTab's content defenses are on.
See the full guide: docs/guides/security.md
Remote, container, and distributed setups are possible, but PinchTab is not positioned as a turnkey internet-facing browser service. Treat any non-local deployment as an advanced setup that you must secure explicitly.
What can you use it for
Headless navigation
With the daemon installed and an agent skill configured, an agent can execute tasks like:
"What are the main news about aliens on news.com?"
PinchTab exposes browser tools that allow agents to navigate pages, extract structured content, and interact with the DOM without wasting tokens on raw HTML or images.
Headed navigation
In addition to headless automation, PinchTab supports headed Chrome profiles.
You can create profiles configured with authentication, cookies, extensions, or specific environments. Each profile can have a name and description.
For example, an agent request like:
"Log into my work profile and download the weekly report"
can automatically select the appropriate profile and perform the action.
Local container isolation
If you prefer stronger isolation, PinchTab can run inside Docker.
This allows agents to control browsers in a sandboxed environment, reducing risk when running automation tasks locally.
Distributed automation
PinchTab can manage multiple Chrome instances (headless or headed) across containers or remote machines.
Typical use cases include:
- QA automation
- testing environments
- distributed browsing tasks
- development tooling
You can connect to multiple PinchTab servers, or attach to Chrome instances running in remote debug mode.
Process Model
PinchTab is server-first:
- install the daemon or run
pinchtab serverfor the full control plane - let the server manage profiles and instances
- let each managed instance run behind a lightweight
pinchtab bridgeruntime
In practice:
- Server — the main product entry point and control plane
- Bridge — the runtime that manages a single browser instance
- Attach — an advanced mode for registering externally managed Chrome instances
Primary Usage
The primary user journey is:
- install Pinchtab
- install and start the daemon with
pinchtab daemon install - point your agent or tool at
http://localhost:9867 - let PinchTab act as your local browser service
That is the default “replace the browser runtime” scenario.
Most users should not need to think about pinchtab bridge directly, and only need pinchtab when they want the local interactive menu.
Key Features
- CLI or Curl — Control via command-line or HTTP API
- Token-efficient — 800 tokens/page with text extraction (5-13x cheaper than screenshots)
- Headless or Headed — Run without a window or with visible Chrome
- Multi-instance — Run multiple parallel Chrome processes with isolated profiles
- Self-contained — ~15MB binary, no external dependencies
- Accessibility-first — Stable element refs instead of fragile coordinates
- ARM64-optimized — First-class Raspberry Pi support with automatic Chromium detection
Quick Start
Installation
macOS / Linux:
curl -fsSL https://pinchtab.com/install.sh | bash
Homebrew (macOS / Linux):
brew install pinchtab/tap/pinchtab
npm:
npm install -g pinchtab
Platform Support
PinchTab's primary tested operator workflow is local macOS and Linux.
Windows binaries are published, but Windows support is currently limited and best-effort because the project does not have the same level of automated and manual coverage there. On Windows, prefer running pinchtab server or pinchtab bridge directly instead of relying on the daemon workflow.
Shell Completion
Generate and install shell completions after pinchtab is on your PATH:
# Generate and install zsh completions
pinchtab completion zsh > "${fpath[1]}/_pinchtab"
# Generate bash completions
pinchtab completion bash > /etc/bash_completion.d/pinchtab
# Generate fish completions
pinchtab completion fish > ~/.config/fish/completions/pinchtab.fish
Docker:
docker run -d \
--name pinchtab \
-p 127.0.0.1:9867:9867 \
-v pinchtab-data:/data \
--shm-size=2g \
pinchtab/pinchtab
The bundled container persists its managed config at /data/.config/pinchtab/config.json.
If you want to supply your own config file instead, mount it and point PINCHTAB_CONFIG at it:
docker run -d \
--name pinchtab \
-p 127.0.0.1:9867:9867 \
-e PINCHTAB_CONFIG=/config/config.json \
-v "$PWD/config.json:/config/config.json:ro" \
-v pinchtab-data:/data \
--shm-size=2g \
pinchtab/pinchtab
Use It
Terminal 1 — Start the server:
pinchtab server
Recommended for daily local use — install the daemon once:
pinchtab daemon install
pinchtab daemon
That keeps PinchTab running in the background so your agent tools can reuse it without an open terminal.
Terminal 2 — Control the browser:
# Navigate
pinchtab nav https://pinchtab.com
# Get page structure
pinchtab snap -i -c
# Click an element
pinchtab click e5
# Extract text
pinchtab text
Or use the HTTP API directly:
# Create a profile first (returns profile id)
PROF=$(curl -s -X POST http://localhost:9867/profiles \
-H "Content-Type: application/json" \
-d '{"name":"work"}' | jq -r '.id')
# Start an instance for that profile (returns instance id)
INST=$(curl -s -X POST http://localhost:9867/instances/start \
-H "Content-Type: application/json" \
-d "{\"profileId\":\"$PROF\",\"mode\":\"headless\"}" | jq -r '.id')
# Open a tab in that instance
TAB=$(curl -s -X POST http://localhost:9867/instances/$INST/tabs/open \
-H "Content-Type: application/json" \
-d '{"url":"https://pinchtab.com"}' | jq -r '.tabId')
# Get snapshot
curl "http://localhost:9867/tabs/$TAB/snapshot?filter=interactive"
# Cli
