Initial pilot: use the invited organization, at most 20 sandboxes, and at most
4 vCPU / 8 GiB per sandbox. GPU and live migration are unavailable. A host-loss
recovery creates a new sandbox from a durable checkpoint; it is not automatic
same-ID failover. See launch and support.
.md to its URL; the whole site is at
/llms.txt.
TL;DR — two commands
pip install into the
system interpreter (externally-managed-environment), and ship python3/pip3 only. /sdk/LATEST
is a one-line file naming the current wheel URL, so nothing here pins a version. Do not
pip install nanovm from PyPI — that name belongs to an unrelated project.
Then tell your agent: “set up nanoVM”. The skill it just loaded carries the
setup procedure: it asks you for an API key (console → API Keys), exports it,
runs the 30-second self-test and reports VERDICT: PASS. From there it uses
the SDK for real work. That’s the whole onboarding; everything below is
detail.
skill installwrites./.claude/skills/nanovm/— project scope, this directory only (it prints the absolute path and says so).--dir ~/.claude/skillsinstalls for every project;--cursoradds a Cursor rule.python -m nanovm skill showprints the skill.- Prefer tools over code, or your agent has no shell (Claude Desktop, chat
hosts)?
pip install "mcp>=2,<3"andclaude mcp add nanovm --transport stdio -e NANOVM_TOKEN=lith_sk_... -- python -m lithosbox mcp. - With a
lith_sk_key onlyNANOVM_TOKENis needed; the SDK defaults to the key edgehttps://sk.nanovm.dev.lithosai.cloud.
0. What you get
A sandbox = a microVM you fully control: run commands, write files, start servers, expose a port on a public HTTPS URL, checkpoint (snapshot) and restore or fork it. Boots from any OCI image; the default sandbox has Python 3.12, Node 22 and the usual data-science stack, 2 vCPU / 1 GiB, and starts in well under a second. Sandboxes are isolated per organization.1. Prove the environment (30 seconds)
ok line per step (auth, create, exec, stdin, session, tools,
snapshot, wait-until-durable, restore, delete) and VERDICT: PASS. A FAIL line names the step
and the exception; the text is enough to act on (bad key → AuthError, image
still building → inspect its template status before another create). --keep leaves the sandbox running and
prints its vm_id; --image X tests a specific image; --json appends a
machine-readable summary.
2. Use it from Python (preferred)
- One
LithosBox()per process. Its connections are reused; a new client per call costs ~200 ms each. run/execare scoped: they return when the command and everything it spawned exit. Usebackground=Truefor servers,session()for multi-step shell work, and the argv formexec(["cmd", arg])whenever the command carries untrusted input.- Bulk data goes through
stdin, not argv (argv strings are capped at 128 KiB by the guest kernel; stdin at 4 MiB per call — loop for more). - First use of an image builds a template once (seconds to tens of minutes depending on image size and cache state).
create()waits for it by default; the wait is per image, not per sandbox, and public images are shared by every organization. - Delete what you create.
with nv.sandboxes.create() as sb:deletes on exit. Snapshots outlive their sandbox. - Long jobs: one request has ~2 minutes at the edge (
creategets 5). Start long work withbackground=Trueor in a session, poll a file or a log with later calls.
3. Claude Code skill (default)
python -m nanovm skill install. The skill teaches the agent
the SDK patterns above and when to reach for a sandbox (untrusted code, heavy
dependencies, a clean environment per task, parallel experiments via fork).
4. Use it as MCP tools (no shell / interactive)
create_sandbox, exec, shell (persistent session), exec_background,
write_file, read_file, expose_port, snapshot, branch, list_sandboxes,
delete_sandbox, and the lifecycle verbs pause, resume, sleep, stop, start, reboot
plus list_snapshots / delete_snapshot. Ids are plain strings you carry between calls.
To query these docs as an MCP tool instead, connect this site’s own server:
claude mcp add --transport http nanovm-docs https://docs.nanovm.dev.lithosai.cloud/mcp.
5. Raw HTTP, if you must
POST /vms {} → {"vm_id": …}; POST /vms/{id}/exec {"args": [...], "stdin_b64": "..."} →
{"exit_code", "stdout", "stderr"}; DELETE /vms/{id}. Header
Authorization: Bearer $NANOVM_TOKEN. 503 with template_id = first use of
an image: poll GET /templates/{template_id} until status is ready, then
retry. 503 whose body says connection error = a control-plane component
restarting: retry in a few seconds. Full route table: HTTP API.
6. Verify before you report success
sb.exec(["true"]).exit_code == 0after any wake/start (sleep andsnapshot(leave_paused=True)wake transparently;stop()needsstart()).- Read back files you wrote (
read_file/exec(["cat", path])) — the write path is a shell redirect and its exit code is the truth. - Snapshots are the only artifact that outlives a sandbox. One is restorable the moment it is taken
and durable (survives its node; exportable) a few seconds later when
.durableis True —snapshot(wait_durable=True)waits. A deleted sandbox’s disk is gone.
Long-running work and idle sleep
The platform never auto-sleeps a sandbox that is doing work (a background process, guest CPU, live connections, or an exposed port). You do not need to poll or “keep-alive” a sandbox to keep a job, server or in-sandbox agent running. Preferrun(..., background=True) for anything that outlives the call;
exec() returns as soon as the foreground command exits even if it left daemons behind.