Skip to content

Control surfaces

mvm has several local control surfaces. They all drive the same runtime model: build or select an artifact, admit a plan, boot a microVM, talk to the guest agent where available, and record evidence for security-relevant actions.

This page helps you choose the right surface without assuming that every product entry point is shipped everywhere.

SurfaceBest forCurrent status
mvmctl CLILocal operation, scripting, CI, debugging, build/run lifecycle.Shipped and broadest surface.
Runtime SDKApplication-owned sandbox lifecycle from Python or TypeScript.Partial; see lifecycle matrix.
Declaration SDKCode-first workload declarations compiled into Workload IR.Shipped for supported literal declarations.
MCP stdioLocal model-tool integration over the Model Context Protocol.Shipped for local stdio tool calls.
ConsoleHuman debugging in development images.Shipped where backend/image policy permits it.
Guest RPCProcess, filesystem, readiness, and telemetry operations.Backend/image dependent.
REST APIHTTP management surface.Not claimed in these local docs.
Web dashboardBrowser-based management UI.Not claimed in these local docs.

The CLI remains the stable automation boundary when an SDK helper does not yet cover an operation.

Use mvmctl for the full local lifecycle:

Terminal window
mvmctl build ./agent
mvmctl up ./agent --name agent-dev
mvmctl exec agent-dev -- python /work/task.py
mvmctl logs agent-dev
mvmctl down agent-dev

Prefer JSON where available:

Terminal window
mvmctl ls --json
mvmctl boot-report agent-dev --json
mvmctl run --dry-run --json -- python task.py

CLI automation should use argv arrays, explicit timeouts, and receipts for security-relevant runs.

Use the runtime SDK when application code should own a sandbox lifecycle:

import mvm
with mvm.Sandbox.create("python-3.12", workload_id="tool") as sandbox:
sandbox.files.write("/app/main.py", "print('hello')")
sandbox.commands.start(["python", "/app/main.py"])

Current SDKs expose create, command start, file write, record mode, live mode, and cleanup helpers. Higher-level command results, file read/list/remove, logs, ports, snapshots, cold mode, detach, and destroy remain parity targets.

Use Lifecycle matrix before depending on a method in a language SDK.

Use declarations when the workload should be reviewed and compiled before it runs:

import mvm
@mvm.app(
name="worker",
source=mvm.local_path("."),
image=mvm.nix_packages(["python312"]),
network=mvm.network(mode="deny"),
)
def run() -> str:
return "ok"

The declaration workflow is the safer authoring path for deployable workloads because supported declarations are extracted without importing the module.

Use the local MCP surface when a model client needs a tool server that routes execution into mvm instead of the host process. The server speaks stdio and is intended for local tool integration.

Relevant limits are controlled by:

VariablePurpose
MVM_MCP_SESSION_IDLEIdle timeout for a tool session.
MVM_MCP_SESSION_MAXMaximum lifetime for a tool session.
MVM_MCP_MAX_INFLIGHTMaximum concurrent tool calls.
MVM_MCP_MEM_CEILING_MIBPer-call memory ceiling before dispatch.

MCP is not a general remote management API. Keep it local, bounded, and tied to policy profiles.

Use console access for human debugging:

Terminal window
mvmctl console agent-dev
mvmctl console agent-dev --command "uname -a"

Console access is broad authority inside the guest. Development images can enable it; sealed production-style images should refuse it and rely on declared entrypoints, logs, guest RPC, and audit records instead.

Guest RPC is the underlying controlled path for operations such as process start, filesystem access, readiness probes, console PTY traffic, and telemetry where the backend and image permit them.

Use the high-level CLI or SDK surface unless you are debugging a protocol-level issue. Protocol frames and guest payloads are not a substitute for receipts or audit-chain evidence.

These local docs do not claim a shipped HTTP management API or browser dashboard. Scripts should use mvmctl JSON output or the current SDK surfaces instead of assuming a long-running local server.

If an integration needs language-neutral automation today, prefer subprocess calls to mvmctl with JSON output and explicit state directories.

  • Choose the narrowest surface that fits the task.
  • Use static declarations for reviewable deployable workloads.
  • Use runtime SDK live mode only for trusted SDK scripts.
  • Keep console access out of production-style paths.
  • Keep MCP local and bounded by concurrency, memory, and session limits.
  • Treat stdout, stderr, logs, console bytes, and screenshots as sensitive.
  • Store receipts or audit identifiers with higher-level automation traces.