# 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: ```text 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: ```json { "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: ```json { "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: ```bash 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: ```bash 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 ```bash 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 ```bash 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: ```text agent -> PinchTab server -> attached external Chrome ``` This is an expert path, not the default user path. The default path remains: ```bash pinchtab ``` then managed instance start via: ```bash curl -X POST http://localhost:9867/instances/start \ -H "Content-Type: application/json" \ -d '{"mode":"headless"}' # CLI Alternative pinchtab instance start ```