Pages in this section
Quick Example
The code below: (1) starts a sandbox that ships with a desktop (ComputerBox, image lscr.io/linuxserver/webtop:ubuntu-xfce); (2) waits until the desktop is ready; (3) prints a local URL you can open directly in a browser, then keeps running until you press Enter. During that window you can operate the sandbox like a remote desktop in your browser.
http://localhost:3000 in a browser to view and operate the sandbox desktop. When you close the script (press Enter), the sandbox and every change inside it are destroyed.
Node users:ComputerBoxis also available in the Node SDK (import { ComputerBox } from "@boxlite-ai/boxlite"), with camelCase method names (waitUntilReady/screenshot, etc.). The GUI port exposure logic is identical.
Three paths for a human to reach the GUI
Choose by what you need to view or operate. Each path corresponds to one GUI-bearing, purpose-built box:All three inherit fromSimpleBox, so you can also run commands withawait box.exec(...)and transfer files withcopy_in/copy_out. The GUI is the extra “human view” they expose.
Path A: full desktop (ComputerBox)
The most direct “remote desktop” approach. See the Quick Example above. Key points:- The GUI ports are fixed and controllable on the host side (constructor arguments
gui_http_port/gui_https_port, defaults3000/3001). - HTTPS uses a self-signed certificate, so the browser shows a security warning; click “Advanced -> Proceed” to continue.
- Default resolution is 1024x768 (controlled by the
DISPLAY_SIZEW/DISPLAY_SIZEHenvironment variables, which are injected for you).
Path B: watch an AI agent run (SkillBox)
SkillBox runs an AI CLI such as Claude Code inside the sandbox and ships with a noVNC desktop, so you can watch in real time while a task completes. Its GUI ports are randomly assigned by default (constructor arguments default to 0); read the assigned values from the instance attributes gui_http_port / gui_https_port:
Path C: manually take over the in-sandbox browser (BrowserBox)
BrowserBox runs a Playwright browser inside the sandbox. What it exposes is a debugging endpoint (CDP / Playwright Server endpoint), not a web desktop. You can:
- Get the CDP address with
await box.endpoint()and paste it into Chrome’schrome://inspectto inspect pages and tune selectors — full walkthrough on Browser DevTools. - Get the Playwright Server address with
await box.playwright_endpoint()and connect to it from a local script to observe while it runs.
For Playwright Server mode (which supports all browser types and is connected to withconnect()from a local script), useawait browser.playwright_endpoint(timeout=60)instead, and do not also callendpoint()on the same instance. Both modes occupy in-sandbox port 3000, so they are mutually exclusive.
Parameters and Returns
ComputerBox (human-access related)
SkillBox (human-access related)
BrowserBox (human-access related)
BrowserBoxconfiguration is not passed as constructor keyword arguments but wrapped inBrowserBoxOptions:BrowserBox(BrowserBoxOptions(browser="firefox")). WritingBrowserBox(browser=...)directly raisesTypeError.
BrowserBoxOptions fields (all optional; a dataclass):
playwright_endpoint()andendpoint()are mutually exclusive modes; a singleBrowserBoxinstance uses only one of them.
Troubleshooting
The browser warns “Your connection is not private” when opening the HTTPS desktop
The HTTPS desktop onComputerBox / SkillBox uses a self-signed certificate; this is expected. Click “Advanced -> Proceed to localhost”, or switch to the HTTP port (gui_http_port, default 3000).
http://localhost:3000 will not open / connection refused
- Confirm the script is still running. Once the
async withblock exits, the sandbox is destroyed and the port closes with it. The Quick Example suspends the process withinput(...)for exactly this reason. - Confirm
await wait_until_ready()has returned; the desktop service takes seconds to tens of seconds to start. - The port is taken by another local program: change
gui_http_port, for exampleComputerBox(gui_http_port=8080). SkillBoxports are randomly assigned, so do not hardcode3000; read the real value frombox.gui_http_port.
SkillBox raises ValueError on startup
The Claude OAuth token is missing. Set the environment variable CLAUDE_CODE_OAUTH_TOKEN, or pass oauth_token="<YOUR_CLAUDE_CODE_OAUTH_TOKEN>" to the constructor (replace with your real token).
BrowserBox errors when calling endpoint() under webkit
CDP direct-connect mode does not support webkit. For webkit, use playwright_endpoint() (Playwright Server mode, which supports all browsers) instead.
The sandbox will not start (no hardware virtualization)
This is an environment constraint:- Hardware virtualization is required. Linux needs KVM (
/dev/kvmreadable/writable, user in thekvmgroup); macOS arm64 uses Apple’s Hypervisor.framework (no/dev/kvmneeded); Windows uses WSL2 + KVM. - The first image pull depends on the network; on failure it raises a standard
RuntimeError(you cantry/exceptand retry), not aBoxliteErrorsubclass. - macOS Intel: not supported.
The third volume element is mistakenly written as a string
If you mount a host directory for the desktop asvolumes=[("/host", "/box", "ro")], you get:
read_only (True = read-only / False = read-write), not the string "ro" / "rw". The correct form is volumes=[("/host/path", "/box/path", True)], or a 2-tuple ("/host/path", "/box/path") (read-write by default).
(Note: only the CLI’s -v syntax uses the ro / rw strings; this differs from the SDK, so do not conflate them.)
Related pages
- Agent Tools: let an AI agent (not a human) operate inside the sandbox.
- Manage Sandbox: lifecycle, runtime methods, the context-manager model.

