Disposable computers on your Mac. Hardware-isolated Linux VMs in 0.5s.
$ mvm start sandbox --net-policy deny # 0.5s, network locked down
$ mvm ssh sandbox
$ claude --dangerously-skip-permissions # full root access, can't touch your MacAI coding agents need root access, shell access, and network access. Docker gives them that behind a shared kernel — one CVE away from a container escape. Cloud sandboxes give them real isolation, but your code and credentials leave your machine.
mvm gives each agent its own hardware-isolated VM on your Mac. Separate kernel per VM via KVM. Your secrets stay local. Network locked down per-VM. Fast enough to feel instant.
- Apple Silicon M3 or newer (nested virtualization requires M3+)
- macOS 15 (Sequoia) or newer
- Homebrew
- Claude Code (recommended for guided setup)
git clone https://github.com/agentstep/mvm.git
cd mvm
claude
> /setup-mvmClaude Code handles everything: checking your hardware, installing dependencies, configuring Lima and Firecracker, building the base image, warming the pool, and walking you through your first VM. It troubleshoots errors as they come up. No docs required.
npm install -g @agentstep/mvm
mvm initbrew install agentstep/tap/mvm
mvm initgit clone https://github.com/agentstep/mvm.git
cd mvm
make install
mvm init # or: mvm init --minimal (no AI agents, smaller image)# Instant starts with the warm pool
mvm pool warm # pre-boot in background (~10s)
mvm start my-app # 0.5s — claimed from pool
# Or boot fresh (~10s cold boot)
mvm start my-app
# Shell in
mvm ssh my-appCheckpoint full VM state — memory, CPU registers, everything — in 0.15s. Resume in 0.14s. The guest doesn't know it was ever frozen.
Use this as a habit, not an escape hatch. Pause before risky operations the way you'd hit Cmd-S. Agent about to install a pile of npm packages from a hallucinated package.json? Pause first. Agent wants to rewrite your config? Pause first. If it goes sideways, resume.
mvm pause my-app # 0.15s — freeze VM, zero CPU, state preserved in memory
mvm resume my-app # 0.14s — instant resume, full stateNo Virtualization.framework-based tool on macOS can do this. It requires Firecracker's snapshot support, which is why mvm uses nested virtualization via KVM.
Most prompt injection attacks need exfiltration — the injected instructions tell the agent to curl something or post data somewhere. If the VM can't reach the internet, most of those attacks are dead on arrival.
mvm start sandbox --net-policy deny # block all outbound
mvm start sandbox --net-policy allow:api.anthropic.com,github.com # allowlist onlymvm exec my-app -- apt update
mvm exec my-app -it -- bash # interactive shell
mvm exec my-app -e FOO=bar -- env # environment variables
mvm exec my-app -w /tmp -- pwd # working directorymvm start web -p 8080:80 # host:8080 -> guest:80
mvm start api -p 3000:3000 -p 5432:5432 # multiple portsmvm logs my-app # guest system log
mvm logs my-app -f # follow (stream)
mvm logs my-app --boot -f # stream boot log livemvm list # show all VMs
mvm stop my-app # graceful shutdown
mvm stop my-app --force # kill immediately
mvm delete my-app # remove all resources
mvm delete --all --force # nuke everything| Operation | mvm (warm pool) | Apple Containers | Docker |
|---|---|---|---|
| Start VM | 0.5s | 0.95s | ~3s |
| Run command | ~20ms | 0.95s | ~1.5s |
| Pause | 0.15s | — | — |
| Resume | 0.14s | — | — |
| Memory per VM | ~25MB | ~30MB | ~150MB |
| Isolation | Hardware (KVM) | Hardware (VZ) | Namespace |
10 concurrent VMs: ~450MB total. Docker Desktop: ~3GB for the same.
Each VM comes with:
- Claude Code (
claude) — Anthropic - Codex CLI (
codex) — OpenAI - Node.js 22, Python 3, git, curl, wget, ripgrep
Use mvm init --minimal for a slim image without AI agents.
Each VM includes a file at /.mvm/SKILLS.md that teaches agents the VM environment — capabilities, port management, checkpoints, and networking. Agents don't need you to explain the sandbox to them.
| Command | Description |
|---|---|
mvm init |
One-time setup (--minimal for slim image without agents) |
mvm start <n> |
Create and boot a microVM (-p, --net-policy, -d) |
mvm stop <n> |
Graceful shutdown (--force to kill) |
mvm pause <n> |
Checkpoint: freeze VM in memory (zero CPU) |
mvm resume <n> |
Resume a paused VM instantly |
mvm ssh <n> |
Shell into a running microVM (delegates to mvm exec -it -- sh) |
mvm exec <n> -- <cmd> |
Run a command (-it, -e, -w, -u) |
mvm logs <n> |
View logs (--boot, -f, -n) |
mvm list |
List all microVMs (--json, -q) |
mvm delete <n> |
Delete a microVM (--force, --all) |
mvm pool warm |
Pre-boot VMs for instant starts |
mvm pool status |
Show warm pool status |
| Tool | Isolation | Start | Pause/Resume | Net sandbox | Min chip | License |
|---|---|---|---|---|---|---|
| mvm | KVM (Firecracker) | 0.5s | Yes (full memory state) | Yes | M3+ | Apache-2.0 |
| Shuru | VZ (Apple) | ~1s | Disk only | Yes | M1+ | Apache-2.0 |
| microsandbox | KVM (libkrun) | <0.2s | No | Yes | M1+ | Apache-2.0 |
| Apple Containers | VZ (Apple) | ~0.95s | No | No | M1+ | Apache-2.0 |
| Docker Sandboxes | microVM | ~3s | No | Yes | M1+ | Proprietary |
| Firecracker (default) | Apple VZ (experimental) | |
|---|---|---|
| Chips | M3+ | M1+ |
| Pause/resume | Yes | No |
| Warm pool | Yes (0.5s) | No |
| Init | mvm init |
mvm init --backend applevz |
Auto-detection: M3+ → Firecracker, M1/M2 → Apple VZ. Override with --backend.
The Apple VZ backend is experimental — no pause/resume, no warm pool, no snapshots. For mature M1/M2 alternatives, see Shuru or microsandbox.
How do I check if my Mac supports nested virtualization?
sysctl kern.hv_support
# kern.hv_support: 1 means hypervisor is supported
# M3+ is required for nested virtualization within a VMCheck your chip: Apple menu → About This Mac. If it says M1 or M2, mvm won't work — see alternatives above.
mvm init fails or hangs
This usually means Lima isn't configured correctly. Run mvm init again with verbose output:
mvm init --verboseIf the issue persists, open an issue with the output.
VMs won't start from warm pool
Make sure the pool is running:
mvm pool status
mvm pool warm # restart the pool if neededNetwork policy isn't blocking traffic
Verify the policy is applied:
mvm list # check the net-policy columnIf you set the policy after start, stop and restart the VM with the --net-policy flag — policies are set at boot.
Lima provides a Linux VM with nested virtualization on Apple Silicon. Firecracker runs inside Lima, creating microVMs with hardware-level isolation via KVM — the same isolation model behind AWS Lambda. The warm pool pre-boots VMs in the background so mvm start claims one instantly.
Contributions are welcome. See CONTRIBUTING.md for guidelines.
If you find a bug or have a feature request, open an issue. If you'd like to contribute code, fork the repo, create a branch, and open a pull request.
See Releases for version history and release notes.
Built on Firecracker and Lima. Inspired by Fly.io Sprites and yashdiq/firecracker-lima-vm.