hitl-cdp-browser-provider
v0.1.1
Published
Bridge any CDP-capable browser session (agent-browser, Playwright, Puppeteer, plain Chrome) into an HTTP+WebSocket endpoint for human-in-the-loop remote viewing/control, e.g. HITL Broker's Browser Gateway.
Maintainers
Readme
hitl-cdp-browser-provider
Bridges any Chrome DevTools Protocol (CDP) browser session into a plain
HTTP page + WebSocket endpoint — the shape HITL Broker's
Browser Gateway (and similar systems) expect a task's internal_url to
serve.
Works with anything that exposes a CDP remote-debugging endpoint:
agent-browser, Playwright,
Puppeteer, or a plain chrome --remote-debugging-port=.... It talks CDP's
own standard primitives (Page.startScreencast, Input.dispatchMouseEvent,
Input.dispatchKeyEvent) — not any tool-specific protocol — so one bridge
covers all of them.
Install
npm install -g hitl-cdp-browser-providerUse
# Point it at a CDP HTTP base -- it auto-picks the first "page" target
hitl-cdp-browser-provider --cdp-http http://127.0.0.1:9222 --bind 0.0.0.0:18234 --token "$(openssl rand -hex 16)"
# Or an exact page WebSocket URL if you already have one
hitl-cdp-browser-provider --cdp-url ws://127.0.0.1:9222/devtools/page/ABC123 --bind 0.0.0.0:18234 --token "$(openssl rand -hex 16)"Then point your HITL Source's browser_endpoint (or any equivalent
"internal_url for browser tasks" field) at <bind-host>:<bind-port>?token=<same-secret>.
⚠️ This bridge has no authentication of its own beyond --token.
Without it, anyone who can reach --bind's address and port can view and
remotely control the browser session -- no HITL token, no login, nothing.
127.0.0.1 (the default) is safe on its own since only local processes
can reach it; the moment you bind wider (0.0.0.0, a LAN IP -- which the
typical deployment needs, since the bridge and HITL Broker usually run on
different hosts), always pass --token. The viewer page forwards its
own query string (including ?token=...) into the WebSocket URL it opens,
so setting it once on the page's URL covers both the HTTP GET and the WS
connection.
Finding a CDP endpoint
- agent-browser:
agent-browser get cdp-url --session <name>gives aws://127.0.0.1:<port>/devtools/browser/<id>browser-level URL — pass itshttp://127.0.0.1:<port>base as--cdp-http(screencast needs a page target, which--cdp-httpauto-discovers via/json/list). - Chrome/Chromium directly: launch with
--remote-debugging-port=9222, use--cdp-http http://127.0.0.1:9222. - Playwright: launch the browser with
--remote-debugging-port=<port>as an extra arg (or usebrowserType.launchServer/connect-over-CDP flows), then point--cdp-httpat that port. - Puppeteer:
puppeteer.launch({ args: ['--remote-debugging-port=9222'] }), same as above.
Protocol
The viewer page renders {"t":"frame","data":"<base64 jpeg>"} messages onto
a <canvas> and sends back {"t":"mouse",...} / {"t":"key",...} messages,
which this bridge translates 1:1 into Input.dispatchMouseEvent /
Input.dispatchKeyEvent CDP calls. There's no dependency on any particular
frontend framework or the automation tool that opened the browser — only on
CDP being reachable.
Not CDP? Use noVNC instead
If your browser session isn't driven by anything CDP-capable (or you want a screen-level rather than browser-API-level handoff — e.g. an arbitrary GUI app in a container, not just a browser), see the noVNC recipe in this repo instead — noVNC + websockify already implements the same "HTTP page + WS" contract with zero custom code, at the cost of needing an X server (Xvfb) + VNC server in the container (see that doc for path-prefix caveats).
License
MIT
