WitNote / docs /guides /attach-chrome.md
AUXteam's picture
Upload folder using huggingface_hub
6a7089a verified

Attach Chrome

Use this guide when:

  • Chrome already exists outside PinchTab
  • you want the PinchTab server to register that browser as an instance
  • you already have a browser-level DevTools WebSocket URL

Do not use this guide if your goal is simply:

  • start a browser for your agent
  • run the normal local PinchTab workflow

For that, use managed instances with pinchtab and POST /instances/start.


Launch vs attach

The mental model is:

launch = PinchTab starts and owns the browser
attach = PinchTab registers an already running browser

With attach:

  • Chrome is started somewhere else
  • PinchTab receives a cdpUrl
  • the server registers that browser as an attached instance

What is implemented today

The current codebase implements:

  • POST /instances/attach
  • attach policy in config under security.attach
  • attached-instance metadata in GET /instances

The attach request body is:

{
  "name": "shared-chrome",
  "cdpUrl": "ws://127.0.0.1:9222/devtools/browser/..."
}

There is currently no CLI attach command.


Step 1: enable attach policy

Attach is disabled unless you allow it in config.

Example:

{
  "security": {
    "attach": {
      "enabled": true,
      "allowHosts": ["127.0.0.1", "localhost", "::1"],
      "allowSchemes": ["ws", "wss"]
    }
  }
}

What this does:

  • enables the attach endpoint
  • restricts which hosts are accepted
  • restricts which URL schemes are accepted

What this does not do:

  • it does not start Chrome
  • it does not define a global remote browser
  • it does not replace managed instances

Step 2: start Chrome with remote debugging

Example:

google-chrome --remote-debugging-port=9222
# Or on some systems:
# chromium --remote-debugging-port=9222

This makes Chrome expose a browser-level DevTools endpoint.


Step 3: get the browser WebSocket URL

Query Chrome:

curl -s http://127.0.0.1:9222/json/version | jq .
# Response
{
  "webSocketDebuggerUrl": "ws://127.0.0.1:9222/devtools/browser/abc123"
}

The value of webSocketDebuggerUrl is the cdpUrl you pass to PinchTab.


Step 4: attach it to PinchTab

curl -X POST http://localhost:9867/instances/attach \
  -H "Content-Type: application/json" \
  -d '{
    "name": "shared-chrome",
    "cdpUrl": "ws://127.0.0.1:9222/devtools/browser/abc123"
  }'
# Response
{
  "id": "inst_0a89a5bb",
  "profileId": "prof_278be873",
  "profileName": "shared-chrome",
  "port": "",
  "headless": false,
  "status": "running",
  "attached": true,
  "cdpUrl": "ws://127.0.0.1:9222/devtools/browser/abc123"
}

Notes:

  • name is optional; if omitted, the server generates one like attached-...
  • the server validates the URL against security.attach.allowHosts and security.attach.allowSchemes

Step 5: confirm it is registered

curl -s http://localhost:9867/instances | jq .
# CLI Alternative
pinchtab instances

An attached instance appears in the normal instance list with:

  • attached: true
  • cdpUrl: ...
  • status: "running"

Ownership and lifecycle

Attached instances are externally owned.

That means:

  • PinchTab did not launch the browser
  • PinchTab stores metadata about that browser as an instance
  • the external Chrome process remains outside PinchTab lifecycle ownership

In practical terms:

  • stopping the attached instance in PinchTab unregisters it from the server
  • it does not imply that PinchTab launched or can fully manage the external Chrome process

When attach makes sense

Use attach when:

  • Chrome is managed by another system
  • Chrome is already running in a separate service or container
  • you want the server to know about an externally managed browser
  • you want to keep browser ownership outside PinchTab

Security

Attach widens the trust boundary, so keep it locked down.

Recommended rules:

  • leave attach disabled unless you need it
  • keep allowHosts narrow
  • keep allowSchemes narrow
  • set PINCHTAB_TOKEN when the server is reachable outside localhost
  • only attach to CDP endpoints you trust

Also remember:

  • Chrome DevTools gives powerful browser control
  • a reachable CDP endpoint should be treated as sensitive infrastructure

If Chrome is remote, prefer a tunnel rather than exposing the debugging port broadly.


Operational model

The intended model is:

agent -> PinchTab server -> attached external Chrome

This is an expert path, not the default user path.

The default path remains:

pinchtab

then managed instance start via:

curl -X POST http://localhost:9867/instances/start \
  -H "Content-Type: application/json" \
  -d '{"mode":"headless"}'
# CLI Alternative
pinchtab instance start