SDK
Rust SDK
Rust build-time SDK and Workload IR contract.
Rust has two SDK surfaces:
- Authoring β
mvm-sdk: build Workload IR (the same IR the Python/TypeScript decorators emit). - Runtime β
mvm-client: theMvmClientfacade for driving machines (create/run/exec/stop/reconfigure), shared with the CLI, the GUI, and the fleet orchestrator.
Authoring β build Workload IR (mvm-sdk)
Section titled βAuthoring β build Workload IR (mvm-sdk)βCurrent:
- Workload and app builders;
- image, source, resources, network, entrypoint helpers;
- Workload IR emission;
- static decorator parsing support in
mvm-sdk; - runtime recording types and lowering.
use mvm_sdk::*;
let workload = workload("worker") .app( app("worker") .source(local_path(".")) .image(nix_packages(["python312"])) .entrypoint(entrypoint_command(["python", "-m", "worker"])) .resources(resources(1, 256, 512)) .build()?, ) .build()?;emit(&workload)?;Rust is the right layer for tools that generate or validate Workload IR directly.
Runtime β drive machines (mvm-client)
Section titled βRuntime β drive machines (mvm-client)βThe MvmClient trait is the runtime SDK: a LocalBackend drives the host
in-process, and a GatewayBackend (feature remote) drives a remote fleet over
REST. Both speak the same MachineSpec intent type.
Build a MachineSpec fluently with MachineSpec::builder(name, image) β the two
required fields are supplied up front, so build() is infallible; cpus
(default 1), memory_mib (default 512), and env (accumulates) are optional.
builder itself returns a Result: image is parsed into a RootfsSource (an
absolute / ./ / ~/ path or path:<p> is a local rootfs, flake:<ref>#<attr>
is a flake output, anything else or oci:<ref> is a registry reference), so a
declaration that names nothing is refused here rather than at boot. The spec
carries the parsed value and serializes it back as that same string.
use mvm_client::{LocalBackend, MachineSpec, MvmClient};
// inside an async context:let client = LocalBackend::new();
let spec = MachineSpec::builder("web", "nginx")? .cpus(2) .memory_mib(512) .env("PORT", "8080") .build();
let machine = client.run_machine(spec).await?;let out = client .exec_machine(&machine.id, vec!["nginx".into(), "-v".into()]) .await?;println!("{}", String::from_utf8_lossy(&out.stderr));client.stop_machine(&machine.id).await?;The builder is equivalent to a struct literal β every field stays public β but reads far better at call sites and lets new optional fields land without churning existing callers.
Embedding it β studio, mvmd, and custom frontends
Section titled βEmbedding it β studio, mvmd, and custom frontendsβconnect(Target) returns a Box<dyn MvmClient> and hides the transport, so one
piece of UI/service code drives either this host or a remote fleet:
use mvm_client::{connect, MvmClient, Target};
// In-process β this host's microVMs (auto-selected VMM). No daemon required.let local = connect(Target::Local)?; // == mvm_client::LocalBackend::new()
// Remote β a hosted fleet or a local sidecar over REST (feature `remote`).let remote = connect(Target::Gateway { base_url: "https://fleet.example.com".into(), token: std::env::var("MVM_TOKEN")?,})?;
for m in remote.list_machines(Default::default()).await? { println!("{}", m.id.0);}The studio desktop app is this pattern: a GatewayBackend by default, or the
in-process LocalBackend when built --features local with
MVM_STUDIO_BACKEND=local β one dyn MvmClient behind its Tauri commands.
# a frontend that drives machinesmvm-client = { path = "../mvm/crates/mvm-client", features = ["remote"] }mvm-client-local = { path = "../mvm/crates/mvm-client-local" } # optional, in-process backendA host-side daemon that manages instances directly β the mvmd fleet
orchestrator, or your own controller β instead links the mvmctl library facade
for the runtime types, host shell seam, and the gated hostβguest IPC transport.
default-features = false keeps it lean (no async runtime unless you opt into the
transport):
# a daemon that runs the host that hosts sandboxesmvmctl = { path = "../mvm", default-features = false, features = ["hostd-transport"] }use mvmctl::core::{instance::InstanceStatus, pool::Role, protocol};use mvmctl::runtime::shell; // host command-execution seamRule of thumb: drive sandboxes β the MvmClient facade; run the host that hosts
them β the mvmctl facade.