Pages in this section
The inverse arrangement — your loop on the host, the box as a tool it calls — is Drive a sandbox from your agent loop. To reach boxes running on another machine, see Manage remote sandboxes over REST.
Section Navigation
This section layers the “agent in Box” capability by control granularity. Each row below corresponds to one implementation approach:Link convention: this page links only to pages that actually exist in docs-v2. For the full parameters and defaults of each approach above, see Agent Tools and Box types.
Choosing Between SkillBox and a Self-Built Box
Only Python and Node provide the high-levelSkillBoxwrapper; C / Go / Rust must use the low-levelexecto drive the CLI themselves.
Quick Example (Minimal Happy Path)
Python: Run a complete agent inside a Box with SkillBox (simplest path)
Python: Pre-install skill packs for the agent
Node: Run an agent with SkillBox
Python: Build your own Box for full control over the Claude CLI (advanced)
When you need to choose your own image, customize CLI flags, or drive the stream-json protocol directly for multi-turn sessions, use the low-levelBox to run claude yourself. Below is a minimal, self-contained skeleton (for the full protocol details, see the repository example examples/python/06_ai_agents/chat_with_claude.py).
Parameters and Returns (Core Entry Points)
This is a navigation page; it lists only the core entry points and return values for placing an agent inside a Box. For full parameters, see each sub-page and Agent Tools.SkillBox (Python, inherits from SimpleBox)
The image defaults toghcr.io/boxlite-ai/boxlite-skillbox:0.1.0. It can be overridden withimage=, but the lazy-install logic assumes that image’s Ubuntu/webtop environment, so overriding is an advanced use case.
Self-Built Box Running Claude (Low-Level Entry Points)
Accessing BoxInfo State
Troubleshooting
Missing OAuth token: entering async with raises ValueError
SkillBox checks for the token in __aenter__. When both the oauth_token parameter and the CLAUDE_CODE_OAUTH_TOKEN environment variable are missing, it raises ValueError. Set it first:
SkillBox(oauth_token="<YOUR_OAUTH_TOKEN>").
Passing image to SkillBox breaks Claude installation
The SkillBox image defaults to ghcr.io/boxlite-ai/boxlite-skillbox:0.1.0. You can override it at construction with image= (Node has an image option too), but the lazy-install logic on the first call() always uses the Ubuntu/apt-get flow and installs Claude into /config/.local/bin (the home directory of webtop’s abc user). Switching to a non-matching image such as node:20-alpine causes installation to fail. If you need a fully custom image to run Claude, use SimpleBox(image=...) / the low-level Box instead and exec the CLI installation yourself (see the “Build your own Box” example above).
Mistakenly awaiting box.info() as if it were async
info() is a synchronous method (it does not touch the VM). Writing await box.info() raises an error (such as TypeError: object BoxInfo can't be used in 'await' expression). Call box.info() directly; access state through box.info().state.status.
Passing the native Box.exec env as a dict
A self-built Box uses the native Box.exec, whose env must be list[tuple[str,str]] (e.g. [("KEY", "value")]), not a dict. Only the wrapper-layer SimpleBox.exec accepts a dict.
Assuming a failed command raises an exception
When a command exits with a non-zero code,exec does not raise. At the native layer, call await execution.wait() to get an ExecResult and check exit_code yourself:
RuntimeError (on Node, a plain Error where instanceof BoxliteError === false). Use a broad except RuntimeError / catch as a fallback rather than catching only BoxliteError.
Box network access fails when pulling models or installing packages
A Box enables networking by default (NetworkSpec defaults to Enabled{allow_net: []}; an empty allowlist means traffic is permitted). If you have explicitly tightened network, allow the domains Claude / npm need; see Network Access.
Writing the token into the image or command logs
An OAuth token is a sensitive credential. In production, inject it via Secrets (BoxOptions(secrets=[Secret(...)])) rather than hard-coding it into env or printing it to logs.
Startup failure: missing hardware virtualization (environment constraint)
BoxLite requires hardware virtualization to boot a microVM:- Linux: requires KVM (
/dev/kvmaccessible; WSL2 needs KVM enabled and the user in thekvmgroup). - macOS: uses Apple’s Hypervisor.framework, no
/dev/kvmrequired. macOS Intel is not supported. - Environments without virtualization (some containers / CI):
start()fails and raises, but the process stays alive; catch it withtry/except.
Comparison: Using a Box as an Agent’s “Tool” (Instead of Putting the Agent in the Box)
If the agent loop runs on the host and only delegates the “run a command” step to a Box (the LLM tool-use pattern), that shape does not belong to this section; it belongs to Agent Tools. Its shape is:- Start a sandbox on the host with
SimpleBox(image=...). - Expose a
sandbox_exectool to the LLM that internally callsawait box.exec(*argv). - The LLM decides which commands to run, and the results are fed back to the model to continue reasoning.
Next Steps
- Learn about the agent’s capabilities inside a Box (exec / file I/O / terminal / browser); see Agent Tools.
- If you have not yet built a mental model of the Box lifecycle, read Manage Sandbox first.
- Learn the positioning and default resources of each Box type; see Box types.
- Inject credentials securely for your agent; see Secrets and Security.

