High-performance browser automation bridge and multi-instance orchestrator with advanced stealth injection and real-time dashboard.
$ npx -y skills add pinchtab/pinchtab --agent claude-code
Run the curl in your terminal, the rest in Claude Code.
What's inside
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
PinchTab defaults to a local-first security posture:
server.bind = 127.0.0.1Secure only when the dashboard is actually served over HTTPSattach is disabled by defaultIf you intentionally access the dashboard over plain HTTP on a non-loopback
address, PinchTab now warns in the UI that the session is running without
transport encryption. Prefer HTTPS or localhost when possible. If you force
server.cookieSecure = true, dashboard login requires HTTPS and will fail
explicitly on plain HTTP instead of looping silently.
[!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.
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.
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.
PinchTab can audit whole sites at the browser level β screenshots, console errors, broken assets, accessibility score, Core Web Vitals, and security findings β and compare two site versions visually before a release:
pinchtab audit https://example.com --output-dir ./audit # report.json + screenshots/
pinchtab audit https://example.com/sitemap.xml --sitemap --sample-size 2 --output-dir ./audit
pinchtab compare https://example.com https://staging.example.com --fail-on-diff # CI gate
See docs/audit.md for the full command reference, report anatomy, and CI examples.
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.
PinchTab can manage multiple Chrome instances (headless or headed) across containers or remote machines.
Typical use cases include:
You can connect to multiple PinchTab servers, or attach to Chrome instances running in remote debug mode.
PinchTab is server-first:
pinchtab server for the full control planepinchtab bridge runtimeIn practice:
The primary user journey is:
pinchtab daemon installhttp://localhost:9867That 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.
e5 survives a change of filter, selector or depth (filtered views are sparse), and expires only on navigation to a new documentmacOS / Linux:
curl -fsSL https://pinchtab.com/install.sh | bash
Homebrew (macOS / Linux):
brew install pinchtab/tap/pinchtab
npm:
npm install -g pinchtab
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.
On macOS, prefer a dedicated automation browser (Google Chrome for Testing or Chromium) over your daily Google Chrome. Driving your primary Chrome headless can prevent it from opening a normal window while PinchTab is running. PinchTab now prefers a dedicated browser automatically, and pinchtab doctor browsers warns if automation would fall back to your primary Chrome β install Chrome for Testing or set browser.binary to a separate build. See docs/reference/config.md.
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
First useful command β auto-starts the local server if needed:
pinchtab nav https://pinchtab.com --snap
Or start the server explicitly when you want foreground logs:
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; starts the server automatically if needed
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"
# Click element
curl -X POST "http://localhost:9867/tabs/$TAB/action" \
-H "Content-Type: application/json" \
-d '{"kind":"click","ref":"e5"}'
Server β The main PinchTab process. It manages profiles, instances, routing, and the dashboard.
Instance β A running Chrome process. Each instance can have one profile.
Profile β Browser state (cookies, history, local storage). Log in once, stay logged in across restarts.
Tab β A single webpage. Each instance can have multiple tabs.
Bridge β The single-instance runtime behind a managed instance. Usually spawned by the server, not started manually.
Read more in the Core Concepts guide.
| Aspect | PinchTab |
|---|---|
| Tokens performance | β |
| Headless and Headed | β |
| Profile | β |
| Advanced CDP control | β |
| Persistent sessions | β |
| Binary size | β |
| Multi-instance | β |
| External Chrome attach | β |
Measured end-to-end agent-loop token cost (Anthropic API), percentages read as "PinchTab is N% cheaper than agent-browser on this metric":
| Scope | Cost cheaper | Fewer requests | Fewer tokens |
|---|---|---|---|
| Basic Haiku (10 steps) | 9.5% | 23.0% | 17.9% |
| Extended Haiku (24 steps) | 19.6% | 31.1% | 26.2% |
| Extended Sonnet (24 steps) | 20.3% | 29.4% | 25.3% |
The cost gap widens with workload length (clickβsnapshot round trips compound) and is roughly model-invariant at extended scope.
See the benchmark summary for an overview, or the benchmark deep dive for full methodology, per-run tables, and raw logs.
PinchTab is a fully open-source, local-first tool. No telemetry, no analytics, and no required outbound service dependency. The binary binds to 127.0.0.1 by default. Persistent profiles store browser sessions locally on your machine, similar to how a human reuses their browser. Remote and distributed deployments are available for advanced use cases, but they are explicit operator-managed setups rather than the default posture. The single Go binary (~16 MB) is fully verifiable: build from source at github.com/pinchtab/pinchtab.
Full docs at pinchtab.com/docs
# Your AI agent can:
pinchtab nav https://pinchtab.com
pinchtab snap -i # Get clickable elements
pinchtab click e5 # Click by ref
pinchtab fill e3 "user@pinchtab.com" # Fill input
pinchtab press e7 Enter # Submit form
# Extract text (token-efficient)
pinchtab nav https://pinchtab.com/article
pinchtab text # ~800 tokens instead of 10,000
# Run multiple instances in parallel
curl -s -X POST http://localhost:9867/instances/start \
-H "Content-Type: application/json" \
-d '{"profileId":"alice","mode":"headless"}'
curl -s -X POST http://localhost:9867/instances/start \
-H "Content-Type: application/json" \
-d '{"profileId":"bob","mode":"headless"}'
# Each instance is isolated
curl http://localhost:9867/instances
See chrome-files.md for technical details on how PinchTab manages Chrome user data directories and ensures isolation between parallel instances.
Want to contribute? Start with CONTRIBUTING.md. The full setup and workflow guide lives at docs/guides/contributing.md.
Quick start:
git clone https://github.com/pinchtab/pinchtab.git
cd pinchtab
./dev doctor # Verifies environment, offers hooks/deps setup
./dev --help # Shows the developer toolkit commands
go build ./cmd/pinchtab # Build pinchtab binary
For runtime diagnostics against your installed PinchTab + browser config (binary exists, executes, fingerprint flags accepted, CDP reachable), use:
pinchtab doctor # human-readable report
pinchtab doctor --json # machine-readable
pinchtab doctor --check <name> # run a single check by name
pinchtab doctor browser <name> # scope to one browser.targets entry
MIT β Free and open source.
Get started: pinchtab.com/docs
.devcontainer/
devcontainer.json
.dockerignore
.github/
DEFINITION_OF_DONE.md
DOCUMENTATION_REVIEW.md
FUNDING.yml
GOVERNANCE.md
ISSUE_TEMPLATE/
bug_report.md
feature_request.md
LABELING_GUIDE.md
PULL_REQUEST_TEMPLATE.md
RELEASING.md
workflows/
ci-branch-naming.yml
ci-dashboard.yml
ci-docs.yml
ci-e2e.yml
ci-go.yml
ci-npm.yml
ci-plugin.yml
ci-smoke.yml
release-manual-publish.yml
release-post-verify.yml
release.yml
reusable-dashboard.yml
reusable-docs.yml
reusable-e2e.yml
reusable-go.yml
reusable-npm.yml
reusable-plugin.yml
reusable-publish-plugin.yml
reusable-publish-skill.yml
reusable-release-publish.yml
reusable-smoke.yml
reusable-validate-release-secrets.yml
reusable-validate-release.yml
.gitignore
.goreleaser.yml
.markdownlint.json
.nvmrc
.pre-commit-config.yaml
assets/
docs-no-background-256.png
favicon.png
pinchtab-headless.png
cmd/
pinchtab/
build_test.go
capability_remedy_executable_test.go
cmd_audit.go
cmd_bridge_test.go
cmd_bridge.go
cmd_bridges_test.go
cmd_bridges.go
cmd_cli_autostart_test.go
cmd_cli_browser_actions.go
cmd_cli_browser_inspect.go
cmd_cli_browser_nav_test.go
cmd_cli_browser_nav.go
cmd_cli_browser_record.go
cmd_cli_button_test.go
cmd_cli_cache.go
cmd_cli_clipboard.go
cmd_cli_console.go
cmd_cli_cookies_test.go
cmd_cli_cookies.go
cmd_cli_current_tab_test.go
cmd_cli_docs_test.go
cmd_cli_emulation.go
cmd_cli_management.go
cmd_cli_network_route.go
cmd_cli_register_test.go
cmd_cli_register.go
cmd_cli_runtime_test.go
cmd_cli_runtime.go
cmd_cli_scroll_test.go
cmd_cli_state.go
cmd_cli_storage.go
cmd_cli_test.go
cmd_cli.go
cmd_compare_test.go
cmd_compare.go
cmd_completion.go
cmd_config_actions.go
cmd_config_clipboard.go
cmd_config_overview.go
cmd_config_secret_test.go
cmd_config_test.go
cmd_config.go
cmd_daemon_render.go
cmd_daemon_status.go
cmd_daemon_test.go
cmd_daemon.go
cmd_dashboard_test.go
cmd_dashboard.go
cmd_doctor_browser.go
cmd_doctor_browsers.go
cmd_doctor_test.go
cmd_doctor.go
cmd_mcp_test.go
cmd_mcp_unix.go
cmd_mcp_windows.go
cmd_mcp.go
cmd_scrape.go
cmd_security_test.go
cmd_security.go
cmd_server_background_processalive_test.go
cmd_server_background_processalive_unix_test.go
cmd_server_background_test.go
cmd_server_background_unix.go
cmd_server_background_windows.go
cmd_server_background.go
cmd_server_ensure_test.go
cmd_server_ensure.go
cmd_server_test.go
cmd_server.go
cmd_session_test.go
cmd_session_unavailable_test.go
cmd_session.go
cmd_terminal.go
cmd_wizard_test.go
cmd_wizard.go
config_advisory_test.go
config_load_test.go
config_load.go
main.go
negative_positionals_test.go
negative_positionals.go
prompt_test.go
prompt.go
remote_token_guard_test.go
root_health.go
root_hints.go
root_status.go
root_test.go
root.go
save_command_json_flag_test.go
server_statedir_test.go
tab_state_test.go
tab_state.go
token_guard_test.go
unknown_subcommand_test.go
unknown_subcommand.go
CODE_OF_CONDUCT.md
CONTRIBUTING.md
dashboard/
.gitignore
bun.lock
eslint.config.js
index.html
package.json
public/
favicon.png
README.md
src/
activities/
ActiveFilterBar.tsx
ActivityExplorer.tsx
ActivityFilterMenu.tsx
ActivityItemLine.tsx
ActivityLine.tsx
ActivityPage.test.tsx
ActivityPage.tsx
ActivityTimeline.tsx
AgentActivityWorkspace.tsx
AgentsPage.test.tsx
AgentsPage.tsx
AgentStreamPanel.tsx
AgentWorkspaceSidebar.tsx
api.ts
CopyIdPill.tsx
FilterPill.tsx
handoffState.ts
helpers.ts
hooks/
useActivityData.ts
useActivityDerivation.ts
useActivityFilters.ts
useAllTabs.ts
index.ts
selectors.test.ts
selectors.ts
SessionDivider.tsx
StreamRow.tsx
types.ts
App.tsx
components/
atoms/
Badge.test.tsx
Badge.tsx
Button.test.tsx
Button.tsx
Card.tsx
DebugPanel.tsx
EmptyState.tsx
ErrorBoundary.tsx
Icon.tsx
index.ts
Input.tsx
Modal.tsx
Select.tsx
StatusDot.test.tsx
StatusDot.tsx
Toolbar.tsx
molecules/
AgentItem.tsx
CreateProfileModal.test.tsx
CreateProfileModal.tsx
EmptyView.tsx
HandoffNotifications.tsx
IdBadge.test.tsx
IdBadge.tsx
index.ts
InstanceStats.tsx
NavBar.css
NavBar.test.tsx
NavBar.tsx
ServerStatusBadge.test.tsx
ServerStatusBadge.tsx
ServerSummary.tsx
SidebarPanel.tsx
SidebarPanelFooterActions.tsx
SidebarPanelHeader.tsx
StartInstanceModal.test.tsx
StartInstanceModal.tsx
TabsChart.test.tsx
TabsChart.tsx
TabsLayout.tsx
screencast/
frameDecode.ts
ScreencastStatusBar.tsx
ScreencastTile.test.tsx
ScreencastTile.tsx
useScreencastInput.test.ts
useScreencastInput.ts
useScreencastStream.ts
generated/
types.ts
index.css
instances/
InstanceCard.tsx
InstanceListItem.tsx
main.tsx
pages/
index.ts
LoginPage.tsx
monitoring/
DefaultInstanceModal.tsx
MonitoringEmptyState.tsx
useMonitoringController.ts
MonitoringPage.test.tsx
MonitoringPage.tsx
profileGroups.test.ts
profileGroups.ts
ProfilesPage.test.tsx
ProfilesPage.tsx
settings/
AutoSolverSettingsSection.tsx
BrowserSettingsSection.tsx
DashboardSettingsSection.tsx
deepEqual.test.ts
deepEqual.ts
DefaultsSettingsSection.tsx
NetworkSettingsSection.tsx
ObservabilitySettingsSection.tsx
OrchestrationSettingsSection.tsx
ProfilesSettingsSection.tsx
SecurityIdpiSettingsSection.tsx
SecuritySettingsSection.tsx
settingsShared.ts
SettingsSharedComponents.tsx
TimeoutsSettingsSection.tsx
useSettingsController.ts
SettingsPage.test.tsx
SettingsPage.tsx
useProfilesController.ts
profiles/
InstanceLogsPanel.test.tsx
InstanceLogsPanel.tsx
ProfileBasicInfoPanel.tsx
ProfileCard.test.tsx
ProfileCard.tsx
ProfileDetailsPanel.tsx
ProfileLiveViewPanel.tsx
ProfileMetaInfoPanel.tsx
ProfileToolbarButtons.tsx
services/
api/
api.test.ts
api.ts
activity.ts
agents.ts
auth.ts
client.ts
config.ts
instances.ts
monitoring.ts
profiles.ts
realtime.ts
tabs.ts
auth.test.ts
auth.ts
dashboardRealtime.ts
realtimeReducers.test.ts
realtimeReducers.ts
stores/
slices/
agentsSlice.ts
monitoringSlice.ts
settingsSlice.ts
useAppStore.test.ts
useAppStore.ts
tabs/
ConsolePanel.tsx
ErrorsPanel.tsx
index.ts
InstanceTabsPanel.test.tsx
InstanceTabsPanel.tsx
SelectedTabPanel.tsx
SelectedTabTitle.tsx
TabBar.tsx
TabItem.tsx
test/
setup.ts
types/
index.ts
tsconfig.app.json
tsconfig.json
tsconfig.node.json
tsconfig.test.json
tygo.yaml
vite.config.ts
DEFINITION_OF_DONE.md
dev
DEVELOPMENT.md
docker-compose.yml
docker-entrypoint.sh
Dockerfile
docs/
architecture/
autosolver.md
browser-abstraction.md
browser-runtime.md
find.md
geo-provider.md
index.md
instance-charts.md
mcp.md
orchestration.md
routing-contract.md
scheduler.md
system-charts.md
terminology.md
audit.md
benchmark.md
commands.md
core-concepts.md
dashboard.md
deep-dive/
benchmark.md
lite-engin-prototype.md
logs/
la1.txt
la2.txt
la3.txt
la4.txt
la5.txt
lae1-sonnet46-1.txt
lae1.txt
lae2-sonnet46-2.txt
lae2.txt
lae3.txt
lp1.txt
lp2.txt
lp3.txt
lp4.txt
lp5.txt
lpe-sonnet46-1.txt
lpe-sonnet46-2.txt
lpe1.txt
lpe2.txt
lpe3.txt
endpoints.md
examples/
enrich/
main.go
get-started.md
guides/
agent-identity.md
annotate-for-llm-fixes.md
attach-chrome.md
cloakbrowser.md
contributing.md
daemon.md
data-storage.md
docker.md
headed-mode.md
identifying-instances.md
... 1600 moreShowing a partial view of a very large repo.
FAQ
pinchtab is a Claude Code plugin with 5 hand-picked skills for automation work, indexed on Flowy. Install it with the command on its page. It includes pinchtab-dev, pinchtab-mcp, pinchtab-opt. Its skills do not fire on their own yet. Request auto-invocation to have Flowy route them as you prompt. Free and open source.