Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.tensorlake.ai/llms.txt

Use this file to discover all available pages before exploring further.

Tunnels give your machine a localhost:<port> that maps directly to a port inside a running sandbox. The relay travels over a WebSocket through the sandbox proxy, so your TensorLake credentials authenticate every connection — you do not need to add the port to exposed_ports or make it public. Reach for a tunnel when you need a raw TCP connection into a sandbox. The sandbox proxy at *.sandbox.tensorlake.ai only speaks HTTP, WebSocket, gRPC, and SSH. Anything else — VNC’s RFB protocol, the Postgres wire protocol, MySQL, Redis’s RESP, MongoDB, custom binary protocols — needs a tunnel because the proxy cannot frame those bytes for you. You can also use a tunnel for HTTP/WS/gRPC traffic when you would rather keep the port private to your laptop than expose it through the public sandbox URL. Driving Chrome’s DevTools Protocol from your laptop is a typical case: CDP is WebSocket, so the proxy could carry it, but a tunnel keeps the debugger reachable only at 127.0.0.1 and skips the per-port exposed_ports configuration. Tunnels and exposed ports are independent. A tunnel works even when the port is not in exposed_ports.

Open a Tunnel

The simplest way is the CLI. Pick any local port (defaults to the same number as the remote port) and leave the command running.
tl sbx tunnel <sandbox-id-or-name> 5901 --listen-port 15901
The command keeps running and prints connection events. Press Ctrl+C to stop the tunnel; the sandbox keeps running.Without --listen-port, the local port matches the remote port:
tl sbx tunnel <sandbox-id-or-name> 9222
The local listener is per-process. If you want two clients to share one tunnel, run the CLI once and connect both clients to the same localhost:<port>.

How It Works

The CLI and the TypeScript SDK both speak the same protocol:
  1. A WebSocket is opened to the sandbox proxy, carrying your API key, PAT, or session cookie.
  2. The proxy authorizes the request, finds the dataplane that owns the sandbox, and pipes bytes to 127.0.0.1:<remote-port> inside the sandbox.
  3. The local TCP listener accepts a connection from your client and relays bytes both ways across the WebSocket.
Because every byte rides on an authenticated WebSocket, the remote port stays private to your account — there is no public hostname for it.

Common Patterns

Inside the sandboxLocal portClient
5901 (TigerVNC)15901macOS Screen Sharing, RealVNC, TigerVNC, Remmina
9222 (Chrome DevTools Protocol)9222Playwright connect_over_cdp, Puppeteer, chrome-remote-interface
5432 (Postgres)5432psql, DBeaver, TablePlus
3000 (dev server)3000Browser at http://localhost:3000
Tunneling is also the easiest way to reach the sandbox’s authenticated Computer Use VNC port from a desktop client without polling screenshots.

Troubleshooting

  • Connection refused from the local end. The remote service inside the sandbox is not listening on the port yet. Tail its logs (tl sbx exec <id> -- bash -lc 'ss -ltnp') and retry.
  • 502 Bad Gateway during handshake. The sandbox has not finished booting the workload. Wait a few seconds and reconnect; the proxy returns 502 when nothing is listening on the remote port.
  • WebSocket auth failures. Confirm tl whoami shows the right organization and project, or that TENSORLAKE_API_KEY is set in the shell that runs the CLI.