reference

CLI reference (all grain commands)

Complete grain command reference for interactive use.

Global flags:

Flag / envMeaning
--config pathConfig file (default ~/.grain/config.yaml)
--api URLRemote daemon HTTP base (overrides GRAIN_API and config api_url)
GRAIN_APISame as --api
GRAIN_TOKENBearer token (or config api_token)

Local default: unix socket. Remote example:

bash
export GRAIN_API=http://127.0.0.1:7474   # after ssh -L …
export GRAIN_TOKEN=grain ls
grain --api http://sandbox:7474 ls

See Remote sandbox host for firewall and systemd.

Daemon

CommandDescription
grain up [--fg] [--mcp]Start daemon (background by default; --mcp also serves MCP Streamable HTTP)
grain downStop daemon via pidfile (cleans stale pid/socket)
grain mcp [--http] [--listen addr]MCP tool server (stdio default; --http uses mcp.listen)
grain update [--check] [--force]Check GitHub Releases and install the latest CLI (re-runs the install script)
grain uninstall [--purge] [-y]Remove CLI binary; --purge also deletes the data directory
grain doctorDependency checks
grain versionPrint version

grain update

FlagMeaning
--checkOnly compare current vs latest release (exit 1 if an update is available)
--forceRe-run the installer even when already on the latest release

Most other commands may print a one-line stderr note when a newer release is known (cached for 24h). Disable notices with check_updates: false in config, GRAIN_CHECK_UPDATES=0, or GRAIN_NO_UPDATE_CHECK=1.

Images

CommandDescription
grain image lsCatalog + local readiness
grain image pull [id]Download base image (ubuntu-cloud, grain-ubuntu, alpine-cloud)
grain image import <path> [--id grain-ubuntu]Register a local qcow2

VMs

CommandDescription
grain newCreate sandbox (see flags below)
grain lsList VMs
grain rm [name]Delete
grain stop [name]Graceful stop (ephemeral deleted)
grain start [name]Start stopped persistent VM
grain pause / resumeFreeze / unfreeze vCPUs
grain suspend / restoreFree RAM / bring back persistent VM
grain sh [name]Shell (agent PTY preferred)
grain x [name] -- cmd…Exec (streaming agent preferred)
grain cp src dstCopy (NAME:path or host path); both directions
grain sync push|pullIncremental host↔guest directory sync (agent required)
grain fs ls|stat|mkdir|rmGuest filesystem helpers
grain logs [name] [-f] [--qemu]Serial or QEMU logs
grain stats [name]Guest resource stats
grain fwd ls|add|rmPort forwards
grain agent health [name]Agent health JSON (includes readiness when present)
grain agent deploy [name]Install/refresh guest agent over SSH (local daemon)
grain status [name]One-line VM + guest readiness

grain new flags

FlagMeaning
-p / --persistKeep disk after stop
-n / --nameName
-c / --cpusvCPUs
-m / --memMemory MiB
-d / --diskDisk GiB
-i / --imageImage id
--waitauto (default), ssh, agent, userdata, bootstrap
-P / --publishHOST:GUEST or GUEST (repeatable)
-v / --volumeHOST:GUEST share (repeatable)
--publish-socketHost↔guest unix socket forward
--profileNamed profile from config, or builtin remote-coding
--presetdocker, k3s, or act
--recipeSandbox recipe YAML (create + optional bootstrap steps)
--userdata-fileExtra cloud-init / shell (not with --recipe)
--proxyInject HTTPS_PROXY for egress proxy

grain recipe

CommandMeaning
grain recipe validate <file>Schema + compile check
grain recipe show <file>Print resolved create options
grain recipe show <file> --userdataAlso print compiled cloud-init

Guide: Sandbox recipes.

Name is optional for sh / rm / x / fs / etc. when exactly one VM exists.

sh / x / cp path selection

FlagBehavior
(default)Prefer guest agent when healthy
--agentAgent only; error if unavailable
--sshForce SSH/scp

grain cp (both directions)

bash
# host → guest
grain cp ./script.sh lab:/tmp/script.sh
grain cp ~/proj lab:/work/proj/

# guest → host (reverse copy — same command, swap args)
grain cp lab:/work/proj/out.json ./out.json
grain cp lab:/var/log/cloud-init.log ./cloud-init.log

Remote CLI (GRAIN_API) uses the daemon’s agent proxy for cp — no scp from the laptop. Guest↔guest in one step is not supported (pull then push).

grain sync push | pull

Incremental directory sync with a host-side baseline under ~/.grain/sync/ (or data_dir/sync/). Requires the guest agent (no scp fallback). Directory roots only — use cp for single files.

bash
grain sync push  ~/proj  lab:/work/proj
grain sync pull  lab:/work/proj  ~/proj
grain sync push  ~/proj  lab:/work/proj --dry-run
grain sync pull  lab:/work/proj  ~/proj --delete --force
FlagMeaning
--deleteRemove dest paths missing on source (ignored paths never deleted)
--dry-runPlan only; no writes or state update
--forceSource-wins for conflicts and dest-ahead paths
--excludeExtra gitignore-style patterns (repeatable)
--no-defaultsSkip built-in ignores (.git/)
--no-gitignore / --no-grainignoreSkip host ignore files
--verbose / -vList skipped / kept_dest paths
--max-file-sizeSkip source files larger than N bytes

Exit codes: 0 ok, 1 usage, 2 conflicts (zero applies), 3 apply error. Dest-ahead paths are kept unless --force — successful sync is not always a full mirror.

MCP: grain_sync_push / grain_sync_pull with the same semantics.

GitHub Actions (grain act)

Runs nektos/act inside an ephemeral sandbox (Docker + act preset). Put act flags after --.

bash
grain act -- -l
grain act -- -j test
grain act --keep -- -W .github/workflows/ci.yml
FlagDefaultMeaning
--dir.Host project mounted at /work
--nameact-<dirname>Sandbox name
--cpus2vCPUs
--mem4096Memory MiB
--imageautoBase image id
--timeout15mCreate + ready + act
--keepfalseKeep VM after act exits

Full guide: Recipe: GitHub Actions (act).

Secrets & proxy

CommandDescription
grain secret ls|set|rm|injectHost secrets store
grain proxy up|down|allow|deny|ls|clientEgress proxy process

Profiles

bash
grain profile ls
grain new --profile agent