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 lab for the host + laptop workflow, and 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 + Desktop (install.sh –desktop)
grain uninstall [--purge] [-y]Remove CLI binary; --purge also deletes the data directory
grain doctorDependency checks
grain versionPrint version

grain update

Upgrades the CLI and Grain Desktop via the public install script (bash -s -- --desktop). Desktop is skipped gracefully when no release asset or GUI deps are available.

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 clone <src> [dst]Offline clone of a stopped/suspended persistent disk
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|rm|tunnelPort forwards; tunnel prints ssh -L lines for host loopback
grain agent health [name]Agent health JSON (includes readiness when present)
grain agent deploy [name]Install/refresh guest agent over SSH (local or remote via daemon API)
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
--from TEMPLATEFast spawn: clone a stopped/suspended persistent template and start (-loadvm when snapshotted)
--from-poolClaim a pre-cloned warm pool member and start (mutually exclusive with --from)
--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 or library name (create + optional bootstrap steps)
--userdata-fileExtra cloud-init / shell (not with --recipe)
--proxyInject HTTPS_PROXY for egress proxy

Create path notes

  • Cold boot (grain new without --from / --from-pool): host work is ~hundreds of ms; remaining time is guest UEFI/kernel/agent (~seconds on grain-ubuntu). Daemon logs create timing (image/disk/seed/start/wait ms).
  • Agent-ready images use a minimal cloud-init seed; disk growpart is deferred after agent when the clone disk is larger than the base image.
  • --from / --from-pool skip a full cold boot when the template was grain suspend’d with a qcow2 snapshot. Guide: lifecycle — fast create.

Warm pool (grain pool)

Pre-clone suspended (or optionally running) template VMs for fast claim. Config:

yaml
warm_pool:
  template: golden   # persistent stopped/suspended VM name
  size: 2            # ready members to keep (0 disables; max 32)
  running: false     # true = keep members agent-ready (uses host RAM)
CommandDescription
grain pool statusReady count, desired size, members, running mode
grain pool fillClone template until ready == size (starts members if running: true)
grain pool claim [-n NAME]Claim one member, rename, start (or rename-only if already running)
grain pool drainDelete all ready pool members
bash
grain new -i grain-ubuntu -n golden -p --wait agent
grain suspend golden
# set warm_pool in config, then:
grain pool fill
grain new --from-pool -n work1
grain pool status

Desktop: Settings → Warm pool and More → Promote to golden + fill pool. See Desktop and config.

grain recipe

CommandMeaning
grain recipe listRecipes in ~/.grain/recipes
grain recipe add <file|url|id>Install into the library (never creates a VM)
grain recipe searchOfficial catalog index
grain recipe preview <url|id>Validate + summary without install
grain recipe delete <id>Remove library file only
grain recipe validate <file|id>Schema + compile check
grain recipe show <file|id>Print resolved create options
grain recipe show … --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). Directory copies include hidden entries such as .git.

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. Regular symlinks are transferred as links (target string; not followed); directory symlinks are not descended. Hidden directories (including .git) are transferred so a git working tree stays a repository in the guest.

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); --exclude '.git/' omits git metadata
--no-defaultsSkip built-in ignore patterns (none currently; .git is included)
--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