cdpUrl is a WebSocket endpoint to the session’s Chrome. Any CDP client can attach. You never launch a browser.
Patchright (recommended)
Other clients
Playwright
Works, with the caveats above.
Puppeteer
puppeteer-core with browserWSEndpoint.Browser Use
Agents on a Driver browser.
Stagehand
Natural-language actions over CDP.
Reuse the context and tab
The browser opens with one context and one tab. Reuse them; fresh incognito contexts and blank pages don’t look like a person’s Chrome.context.newPage() on the existing context.
Mouse and keyboard
Your framework’sclick, fill and type work as usual. To drive the mouse and keyboard directly (move a cursor, press buttons and keys, scroll), send native input commands on the same connection.
Disconnecting versus stopping
browser.close() (Patchright, Playwright) and browser.disconnect() (Puppeteer) end your connection only. The session runs, and bills, until DELETE /v1/browser/session or its duration. Reconnect to the same cdpUrl as often as you like while it’s active.
Reconnecting
If your process crashes,GET /v1/browser/session: while status is active the cdpUrl still works. If the session ended, a profile with persist: true carries the state into a new one.
Several clients can attach at once (your script and the live view, say), but two scripts driving one tab fight each other: one automation client per session. cdpUrl is a credential. Its hostname is a relay near the machine, not the session’s network; egress is from the country you asked for whatever host you connect to.
Timeouts and waits
Real machines on real networks: page loads take real time. Use the framework’s auto-waiting (page.click, locator.waitFor), not fixed sleeps, and raise the navigation timeout for slow sites instead of retrying in a loop.