Open-source cloud runtime for AI agents.
Give your AI agents a full Linux VM to work with.
Run agent harnesses like Claude Code or Codex in the cloud, giving each session its own isolated microVM with filesystem and shell access. From outside, you talk to the VM through the Moru CLI or TypeScript/Python SDK. Inside, it's just Linux—run commands, read/write files, anything you'd do on a normal machine.
When an agent needs to solve complex problems, giving it filesystem + shell access works well because:
- It handles large data without pushing everything into the model context window
- It reuses tools that already work (Python, Bash, etc.)
- Models are trained to be good at using shell commands and writing code
Now models run for hours on real tasks. As models get smarter, the harness should give models more autonomy, but with safe guardrails. Moru helps developers focus on building agents, not the underlying runtime and infra.
The fastest way to try Moru is with the CLI.
curl -fsSL https://moru.io/cli/install.sh | bash# Login
moru auth login
# Run a command and get destroyed automatically
moru sandbox run base echo 'hello world!'
# List sandboxes
moru sandbox list
# View logs
moru sandbox logs <id># Create a sandbox
moru sandbox create base
# Run a command inside
moru sandbox exec <id> 'sh -c "echo Hello Moru > /tmp/note.txt"'
# Run another command
moru sandbox exec <id> cat /tmp/note.txt
# Kill when done
moru sandbox kill <id>JavaScript / TypeScript:
npm install @moru-ai/corePython:
pip install moruexport MORU_API_KEY=your_api_keyGo to the API Keys tab if you didn't create an API key yet.
JavaScript / TypeScript:
import Sandbox from '@moru-ai/core'
// Create a sandbox using the 'base' template (default)
const sandbox = await Sandbox.create()
console.log(`Sandbox created: ${sandbox.sandboxId}`)
// Run a command
const result = await sandbox.commands.run("echo 'Hello from Moru!'")
console.log(`Output: ${result.stdout}`)
// Clean up
await sandbox.kill()Python:
from moru import Sandbox
# Create a sandbox using the 'base' template (default)
sandbox = Sandbox.create()
print(f"Sandbox created: {sandbox.sandbox_id}")
# Run a command
result = sandbox.commands.run("echo 'Hello from Moru!'")
print(f"Output: {result.stdout}")
# Clean up
sandbox.kill()Stream stdout/stderr in real-time for long-running commands.
JavaScript / TypeScript:
await sandbox.commands.run("for i in 1 2 3; do echo $i; sleep 1; done", {
onStdout: (data) => console.log(data),
onStderr: (data) => console.error(data),
})Python:
sandbox.commands.run(
"for i in 1 2 3; do echo $i; sleep 1; done",
on_stdout=lambda data: print(data),
on_stderr=lambda data: print(data),
)After running your sandbox, you can view logs, monitor activity, and debug issues from the Sandboxes tab in your dashboard.
With custom templates, you can build your own VM snapshot with your own agent pre-installed. See the Maru agent example and the templates documentation for more information.
# Python
sandbox = Sandbox.create("my-template")// JavaScript
const sandbox = await Sandbox.create('my-template')Each VM is a snapshot of a Docker build. You define a Dockerfile, CPU, and memory limits—Moru runs the build inside a Firecracker VM, then pauses and saves the exact state: CPU, dirty memory pages, and changed filesystem blocks.
When you spawn a new VM, it resumes from that template snapshot. Memory snapshots are lazy-loaded via userfaultfd, which helps sandboxes start within a second.
Each VM runs on Firecracker with KVM isolation and a dedicated kernel. Network uses namespaces for isolation and iptables for access control.
For more information, visit moru.io/docs.
- Maru - A research assistant using Claude Agent SDK and Moru
- Sandbox Infrastructure - Self-host the Firecracker runtime
Moru started as a fork of E2B, and most of the low-level Firecracker runtime is still from upstream.
See LICENSE file.