Local-first microVM sandbox for AI agents on macOS.
Shuru boots lightweight Linux VMs using Apple's Virtualization.framework. Each sandbox is ephemeral: the rootfs resets on every run, giving agents a disposable environment to execute code, install packages, and run tools without touching your host.
- macOS 14 (Sonoma) or later on Apple Silicon
brew tap superhq-ai/tap && brew install shuruOr via the install script:
curl -fsSL https://raw.githubusercontent.com/superhq-ai/shuru/main/install.sh | sh# Interactive shell
shuru run
# Run a command
shuru run -- echo hello
# With network access
shuru run --allow-net
# Restrict to specific hosts
shuru run --allow-net --allow-host api.openai.com --allow-host registry.npmjs.org
# Custom resources
shuru run --cpus 4 --memory 4096 --disk-size 8192 -- make -j4Share host directories into the VM using VirtioFS. By default the host directory is read-only; guest writes go to a tmpfs overlay layer (discarded when the VM exits). Append :rw to make the mount read-write — guest writes go directly to the host filesystem.
# Mount a directory (guest can read, writes go to overlay — host is untouched)
shuru run --mount ./src:/workspace -- touch /workspace/test.txt
ls ./src/test.txt # not found — write stayed in the overlay
# Read-write mount (guest writes land on host, requires --allow-host-writes)
shuru run --allow-host-writes --mount ./src:/workspace:rw -- touch /workspace/test.txt
ls ./src/test.txt # found — write went to host
# Multiple mounts
shuru run --mount ./src:/workspace --mount ./data:/data -- shMounts can also be set in shuru.json (see Config file).
Note: Directory mounts require checkpoints created on v0.1.11+. Existing checkpoints work normally for all other features. Run
shuru upgradeto get the latest version.
Forward host ports to guest ports over vsock. Works without --allow-net — the guest needs no network device.
# Install python3 into a checkpoint, then serve with port forwarding
shuru checkpoint create py --allow-net -- apt-get install -y python3
shuru run --from py -p 8080:8000 -- python3 -m http.server 8000
# From the host (in another terminal)
curl http://127.0.0.1:8080/
# Multiple ports
shuru run -p 8080:80 -p 8443:443 -- nginxPort forwards can also be set in shuru.json (see Config file).
Checkpoints save the disk state so you can reuse an environment across runs.
# Set up an environment and save it
shuru checkpoint create myenv --allow-net -- sh -c 'apt-get install -y python3 gcc'
# Run from a checkpoint (ephemeral -- changes are discarded)
shuru run --from myenv -- python3 script.py
# Branch from an existing checkpoint
shuru checkpoint create myenv2 --from myenv --allow-net -- sh -c 'pip install numpy'
# List and delete
shuru checkpoint list
shuru checkpoint delete myenvSecrets keep API keys on the host. The guest receives a random placeholder token; the proxy substitutes the real value only on HTTPS requests to the specified hosts. The real secret never enters the VM.
# Inject a secret via CLI
shuru run --allow-net --secret API_KEY=OPENAI_API_KEY@api.openai.com -- curl https://api.openai.com/v1/models
# Multiple secrets
shuru run --allow-net \
--secret API_KEY=OPENAI_API_KEY@api.openai.com \
--secret GH_TOKEN=GITHUB_TOKEN@api.github.com \
-- shFormat: NAME=ENV_VAR@host1,host2 — NAME is the env var the guest sees, ENV_VAR is the host env var with the real value, and hosts are where the proxy substitutes it.
Secrets can also be set in shuru.json (see Config file).
Shuru loads shuru.json from the current directory (or --config PATH). All fields are optional; CLI flags take precedence.
{
"cpus": 4,
"memory": 4096,
"disk_size": 8192,
"allow_net": true,
"ports": ["8080:80"],
"mounts": ["./src:/workspace", "./data:/data"],
"command": ["python", "script.py"],
"secrets": {
"API_KEY": {
"from": "OPENAI_API_KEY",
"hosts": ["api.openai.com"]
}
},
"network": {
"allow": ["api.openai.com", "registry.npmjs.org"]
}
}The network.allow list restricts which hosts the guest can reach. Omit it to allow all hosts.
Use shuru programmatically from TypeScript with the @superhq/shuru package.
bun add @superhq/shuruimport { Sandbox } from "@superhq/shuru";
const sb = await Sandbox.start({ from: "python-env" });
const result = await sb.exec("python3 -c 'print(1+1)'");
console.log(result.stdout); // "2\n"
await sb.checkpoint("after-run"); // saves disk state and stops the VMSee the SDK README for full API docs.
Shuru ships as an agent skill so AI agents (Claude Code, Cursor, Copilot, etc.) can use it automatically.
# Install via Vercel's skills CLI
npx skills add superhq-ai/shuru
# Or manually copy into your project
cp -r skills/shuru .claude/skills/shuruOnce installed, agents will use shuru run whenever they need sandboxed execution.
See CHANGELOG.md for release notes and breaking changes.
File issues at github.com/superhq-ai/shuru/issues.