TheDocumentation Index
Fetch the complete documentation index at: https://docs.tensorlake.ai/llms.txt
Use this file to discover all available pages before exploring further.
ubuntu-vnc image ships with Google Chrome pre-installed. Combined with Local Tunnels, this gives you a real, sandboxed Chrome that any DevTools-Protocol client (Playwright, Puppeteer, chrome-remote-interface, plain WebSocket) can drive from your laptop as if it were running locally — no headless container, no screenshot polling, no public port.
This guide walks through:
- Launching
ubuntu-vnc. - Starting Chrome with CDP enabled on the desktop session.
- Tunneling the CDP port to
127.0.0.1. - Driving the browser from Python or Playwright.
Prerequisites
tl login to obtain a Personal Access Token interactively. The desktop password for the managed ubuntu-vnc image is tensorlake.
1. Launch the Sandbox
chrome-cdp is a name (optional, but it lets you suspend and resume later). The CLI prints the new sandbox id; reuse it as <sandbox-id> below. Four CPUs and 4 GiB of RAM is a comfortable default for a single Chrome session.
2. Start Chrome with CDP Enabled
Start Chrome on the existing VNC display (:1) as the desktop user (tl-user). Two flags matter:
--remote-debugging-port=9222opens the DevTools Protocol endpoint on127.0.0.1:9222inside the sandbox.--remote-allow-origins=*is required by current Chrome versions before they will accept a WebSocket whoseOriginis anything other than the request host. Without it the HTTP/json/versionendpoint works butws://127.0.0.1:9222/devtools/...returns403 Forbidden.
Browser, Protocol-Version, and webSocketDebuggerUrl.
Because Chrome is running on the VNC display
:1, you can also attach a VNC viewer through the Local Tunnels workflow and watch it operate in real time. CDP control and human observation can run side by side.3. Open a Tunnel
Forward127.0.0.1:9222 on your laptop to 127.0.0.1:9222 inside the sandbox:
- CLI
- JavaScript
9222 never has to be in exposed_ports.
4. Drive the Browser
Open a Tab
CDP exposes an HTTP control surface on the same port. Open a fresh tab with aPUT:
webSocketDebuggerUrl for the new tab. List all tabs with curl http://127.0.0.1:9222/json/list and close one with curl http://127.0.0.1:9222/json/close/<target-id>.
Playwright
Raw CDP via WebSocket
When you want to issue protocol calls directly —Runtime.evaluate, Page.navigate, DOM.getDocument — connect to the per-tab WebSocket and exchange JSON messages:
open_url, evaluate, and list_targets as tools that wrap these calls.
5. Tear Down
Stop the tunnel withCtrl+C. Stop Chrome inside the sandbox when you no longer need it:
Notes and Pitfalls
--remote-allow-origins=*is required for Chrome ≥ 111. Without it, the HTTP CDP endpoints work but every WebSocket handshake fails with403. Restart Chrome with the flag if you forget.- Bind address.
--remote-debugging-portonly listens on127.0.0.1by default, which is exactly what you want — the tunnel forwards to127.0.0.1inside the sandbox, so DevTools stays unreachable from anywhere else. --user-data-diris required for CDP. Chrome ≥ 136 refuses to enable--remote-debugging-portagainst the default profile and printsDevTools remote debugging requires a non-default data directory. Specify this using --user-data-dir.to its log. Always pass--user-data-dir=/tmp/<something>(or any path other than~/.config/google-chrome).- Headless mode. If you do not need the VNC view, you can launch with
--headless=newinstead of attaching to display:1. The tunneling and CDP usage remain identical. - Sandboxing inside containers. Chrome’s setuid sandbox sometimes fails inside container/VM combinations. If you see
Failed to move to new namespaceerrors, add--no-sandboxto the launch flags. - Multiple agents. Each tab has its own
webSocketDebuggerUrl. Two clients can drive different tabs of the same Chrome at the same time — useful when an agent loop and a human reviewer both want a window.