Command line tool

Preview

Run a coding agent in a sandbox with one command. Install, sign in, run an agent, open a desktop, and use the same code as an SDK.

npx @munitoai/cli agent "fix the failing test"

That creates a sandbox, uploads your git worktree, runs Claude Code on the open models of Munito AI, applies the patch to your working copy, prints what it cost and deletes the machine. One command, one key.

Install

npm install -g @munitoai/cli

Or run it with no install, as npx @munitoai/cli <command>. It needs Node 22.12 or later.

The command is munito either way. In a project that wants npx munito as well, take the alias:

npm install -D munito@npm:@munitoai/cli

Sign in

munito login

The command asks for an API key with the Inference permission, checks it, and saves it to ~/.config/munito/auth.json, readable by you only. MUNITO_API_KEY in the environment wins over the saved key, so a scripted run never takes a stale sign-in.

Run an agent

munito agent "fix the failing test"             # claude, on our models
munito agent codex "add a retry to the client"  # another harness
munito agent dsh "explain this module"

The first word is the harness when it names one, and part of the task when it does not.

FlagWhat it does
--providerWhere the model comes from: munito, anthropic or openai. The default is munito
--authtoken or subscription. The default is token
--modelA model id, in place of the recommended one
--repoA directory to upload. The default is the current git worktree
--no-uploadSend no files
--no-applyDo not apply the patch to your worktree
--keepLeave the sandbox running when the task ends
--max-turnsStop the agent after this many turns
--sizetiny, small, default or large
--jsonNDJSON events, for a script or another agent

What goes up, and what comes back

The agent runs on the agent template, which carries the harnesses. Against a region that does not have that template yet, the tool uses ubuntu and installs the harness once, which takes about a minute. Pass --template to choose one yourself.

Only files that git tracks, or would track, go up: git ls-files -co --exclude-standard. So an ignored secret, a build directory and a virtual environment never leave your machine. Binary files and files above 1 MiB are skipped, and the whole upload stops at 16 MiB.

The agent works in a git repository inside the sandbox. When it finishes, the tool reads git diff and applies it to your worktree, leaving build artefacts behind. Nothing is committed: git diff on your side shows what the agent did.

Your own key, or your own plan

munito agent claude --provider anthropic     # your ANTHROPIC_API_KEY
munito agent claude --auth subscription      # your Claude plan, in the sandbox

With --provider anthropic the tool clears every Munito AI variable first, so your Anthropic key reaches Anthropic and nothing else. With --auth subscription it sets no credential at all: sign in inside the sandbox over SSH, and the sign-in stays there. Munito AI never accepts, stores or forwards the token of a subscription.

Machines

munito ls                        # your sandboxes
munito create --template agent   # one that stays
munito create --agent codex      # one with a harness already pointed at us
munito run "pytest -q"           # one command in a throwaway sandbox
munito exec <id> "ls /workspace" # a command in a sandbox you have
munito ssh <id>                  # a shell
munito ssh <id> --forward 3080   # a shell, and a private port on your machine
munito open <id>                 # its desktop, in your browser
munito open <id> --port 3000     # any port, signed
munito pause <id>                # keep its files and processes
munito resume <id>
munito fork <id> --count 8       # eight copies of a paused sandbox
munito rm <id>

munito create --agent <name> takes the same --provider, --auth and --model as munito agent, and leaves the machine running.

munito open signs a URL and opens it, so the port is public while the link lasts. munito ssh --forward keeps the port private: it reaches your machine through the SSH connection and nowhere else. Give it 3080, 3081:3080, or a full local:host:remote, once per port.

An agent with a screen

munito agent --desktop "open the docs in Firefox and read the pricing page"

--desktop starts the agent on the desktop template, signs port 6080 and opens the viewer in your browser, so you watch the agent work. It implies --keep, because a screen is no use once the machine ends. Delete the sandbox with munito rm <id> when you are done.

CI jobs on a warm disk

A CI job spends its first minute installing what the last job installed. Build the disk once, pause it, and fork it for each job. This is the CI recipe, as three commands.

munito ci warm "npm ci && npx playwright install --with-deps chromium"
munito ci run "npm test"
munito ci run "npm run lint"

munito ci warm creates a persistent sandbox, runs your install command, and pauses it. A paused sandbox pays only for saved state. munito ci run forks that base, runs one job in the fork, streams its output, deletes the fork and exits with the job's exit code.

CommandWhat it does
munito ci warm "<install>"Build the base and pause it. A base of the same name is replaced
munito ci run "<job>"Fork, run, delete, and exit with the job's code
munito ci statusWhich base this repository has, and its state
munito ci dropDelete the base

The base is named for the repository: GITHUB_REPOSITORY, then CI_PROJECT_PATH, then the name of the current directory. Pass --name to keep more than one. munito ci warm takes --size, --disk and --template; munito ci run takes --cwd, --timeout and --keep, which leaves a failed fork alive to look at.

Rebuild the base when a lock file changes:

- run: npx @munitoai/cli ci warm "npm ci"
  if: steps.lock.outputs.changed == 'true'
- run: npx @munitoai/cli ci run "npm test"

A fork starts in about 310 ms with the whole warm disk in place, and the job's exit code reaches the shell.

From herdr

munito herdr add --name work

herdr is an open-source runtime for coding agents. It holds no compute: you bring machines and it reaches them over SSH. This command makes a persistent sandbox, mints its SSH credential and hands herdr the connection, with herdr's own --install copying its Linux build in. Our SSH is a plain byte pipe, so that works with no helper of ours.

hc run --bg --on work --cwd /workspace --name agent claude
munito pause <id>     # keeps the terminal, the scrollback and the conversation

A paused sandbox pays only for its saved state, and a resume brings the agent back with its conversation. The minted SSH credential expires, so run munito herdr add again for a new machine.

From another coding agent

claude mcp add munito -- npx @munitoai/cli mcp

munito mcp serves the same work as MCP tools on stdio, so a Claude Code or Codex session can farm a task out to a sandbox instead of running it on your own machine. Three tools:

ToolWhat it does
run_agentRun a coding agent on a fresh microVM and return its answer and a patch
run_commandRun one command on a fresh microVM and return its output
list_agentsThe harnesses and providers that this key can use

Each one deletes its sandbox when it finishes. Several can run at once, each isolated from the others.

On your own machine

munito init dsh
munito init claude --dry-run

munito init writes the configuration of a harness on this computer, from the same table the sandbox uses. For a harness that takes a plugin instead, such as Hermes, pi or OpenClaw, it prints the one command that installs ours.

Colour and output

The tool prints a table and colour only when it writes to a terminal. A pipe, a CI job or a call from another agent gets plain lines, and --json gets NDJSON, one event per line. It respects NO_COLOR and FORCE_COLOR.

As an SDK

The package is the library as well as the binary.

import { Munito } from "@munitoai/cli";

const munito = new Munito({ apiKey: process.env.MUNITO_API_KEY!, region: "eu" });

const run = await munito.agent.run({
  agent: "claude",
  prompt: "fix the failing test",
  maxTurns: 20,
  onEvent: (event) => console.error(event.type),
});
console.log(run.result, run.patch);

const box = await munito.sandboxes.create({ template: "agent", internet: true });
await munito.sandboxes.exec(box.id, { command: "pytest -q" });

munito.agent.run takes an onEvent callback for progress, and returns the answer, the patch, the exit code and the sandbox id.

Exit codes

CodeMeaning
0The agent finished and its command succeeded
1The API or the agent failed
2Your key, your plan or your arguments need a change
otherThe exit code of the agent's own command