Reconnecting
Restoring connection…
Reconnecting
Restoring connection…
Docs navigation
Get started
Connect an LLM
Operate
Build packs
Runner CLI
The emisar
binary on each host is two things: the daemon that executes gated actions, and the
operator's local toolbox for inspecting packs, reading the journal, verifying the audit
chain, and setting up signed dispatch. This page is the reference for its operator verbs —
grouped the way the binary groups them — with the key flags and whether each command only
reads or changes the host.
$ sudo emisar doctor # preflight: config · credential · packs · binaries · service $ sudo emisar events tail -f # the host-side security log, live $ sudo emisar pack list ID VERSION ACTIONS HASH DESCRIPTION debugging 0.2.10 31 sha256:ae3b9a7c8f11 General-purpose Linux diagnostics + remediation… linux-core 0.3.19 34 sha256:8d0ba17ca0e4 Read-only Linux diagnostics + narrow service control… systemd-deep 0.1.10 24 sha256:84f814476179 Deeper systemd state + operator surface…
Running the CLI#
On an installed host the binary lives at
/usr/local/bin/emisar
and every subcommand auto-discovers its configuration, so you rarely pass --config. The config and the
cached token are root-owned, and the packs directory is root-owned too, so run commands with sudo. Running
emisar
with no arguments prints a Paths footer showing exactly where this host keeps its config,
packs, token, and journal.
-
—
--config <path>— the config.yaml to load. Defaults to$EMISAR_CONFIG, then the/etc/emisar/config.yamlinstall location, then a per-user~/.config/emisar/config.yaml. -
—
--packs-dir <dir>— extra pack search directories, overriding the config'spaths.packs(repeatable). Lets a read command work without a full config. -
—
--json— machine-readable JSON where a command supports it:action list/describe,pack list/info,state, and the signing verbs.
Where an installed host keeps things — the installer's defaults; config keys or the install flags below move them:
| What | Default path |
|---|---|
| Config | /etc/emisar/config.yaml |
| Packs | /etc/emisar/packs |
| Data dir (identity, dispatch log, signing nonces) | /var/lib/emisar |
| Cached runner token | /var/lib/emisar/token |
| Events journal | /var/log/emisar/events.jsonl |
The connect daemon#
emisar connect
is the long-running daemon: it dials out over a TLS websocket, advertises this host's
actions, executes incoming dispatches, streams redacted output back, and journals every
attempt locally. There is no inbound listener on the host. On the first connect it trades the
enrollment key (from the env var named by cloud.enrollment_key_env, by
default EMISAR_ENROLLMENT_KEY)
for a cached per-runner token, so the key can be unset afterward.
You normally don't run
connect
by hand — the installer registers it as a supervised service
(emisar.service
under systemd, a LaunchDaemon on macOS) running as the
emisar
user. Manage it through the init system.
reload
sends SIGHUP, which re-reads packs and rebuilds the signing verifier and re-advertises the
catalog on the live connection — in-flight runs keep executing across it.
$ sudo systemctl status emisar # is the daemon up? $ sudo journalctl -u emisar -f # stream its logs $ sudo systemctl reload emisar # re-read packs + signing config (SIGHUP) $ sudo systemctl restart emisar # full restart
On a --no-service
host (a container, CI box, or cloud shell) there is no unit; run the daemon yourself with emisar connect --config /etc/emisar/config.yaml. The full fleet lifecycle — groups, enrollment keys, pack credentials — is in the
runner fleet
guide.
Actions#
Inspect the catalog this host advertises, and run one action locally while you're debugging a
pack. emisar actions
is an accepted alias for the group.
| Command | What it does | Mode |
|---|---|---|
| emisar action list | Every action this host advertises — id, pack, kind, risk, title. | Reads only |
| emisar action describe <id> | The full JSON definition of one action, including its argument schema. | Reads only |
| emisar action run <id> | Execute one action on this host now, for debugging a pack. | Runs on the host |
Flags on action run:
-
—
--arg key=value— one argument, repeatable. Numbers,true/false, and JSON arrays/objects are decoded; everything else stays a string. -
—
--reason "…"— free-text reason recorded on the local event. -
—
--timeout 30s— override the action's timeout, clamped to its own min/max. -
—
--stream— stream stdout/stderr live instead of returning buffered JSON.
Packs#
emisar pack
(alias packs) manages this host's
action catalog — the versioned bundles of action schemas it may execute.
| Command | What it does | Mode |
|---|---|---|
| emisar pack suggest | Recommend packs for what's running on this host (binaries, processes, ports). | Reads only |
| emisar pack list | Installed packs with version, action count, and content hash. | Reads only |
| emisar pack info <id> | A pack's setup: required binaries, the env vars its actions read, a verify command. | Reads only |
| emisar pack validate <path> | Validate a pack directory on disk without loading it into the runner. | Reads only |
| emisar pack install <name|path|url> | Fetch, validate, hash-verify, and install one pack into the packs dir. | Changes the host |
| emisar pack update [id...] | Update installed packs to the registry's current versions. | Changes the host |
| emisar pack uninstall <id> | Remove an installed pack (aliases: rm, remove, delete). | Changes the host |
Flags on pack install:
-
—
--hash sha256:…— pin the exact content hash the portal advertises; the install aborts on any mismatch, so a tampered or mismatched copy never reaches the runner. -
—
--force— overwrite a pack already installed under the same id. -
—
--registry <url>— install from your own registry (or setEMISAR_PACKS_REGISTRY); defaults to the public registry atemisar.dev. -
—
--dest <dir>— the packs directory to install into; defaults to the config's firstpaths.packsentry.
# install one pack, pinned to the hash the portal advertises $ sudo emisar pack install redis --hash sha256:9f2c… # update every installed pack (or name a few); preview with --dry-run $ sudo emisar pack update $ sudo emisar pack update redis postgres --dry-run # validate a pack you are authoring, before you trust it $ emisar pack validate ./my-pack
install, update, and
uninstall
signal a running daemon to reload — the same SIGHUP as
systemctl reload emisar
— so
changed actions re-advertise without a restart or a dropped run; when no live daemon is
reachable the CLI prints the manual reload command instead. Installing bytes doesn't trust
them: a changed hash lands as pending
on the Packs page until someone trusts it. Names accept
name=version
to pin a specific published version. See
the pack reference
for what goes in a pack.
Diagnose and audit#
When a runner won't connect or an action fails, these read-only verbs answer why without opening a cloud session.
| Command | What it does | Mode |
|---|---|---|
| emisar doctor | Offline preflight: config, credential, packs, action binaries, service, and control-plane reachability. Exits nonzero if any check fails. | Reads only |
| emisar state | Print the runner_state JSON this host would advertise to the control plane. | Reads only |
| emisar events tail | Print recent journal events; -f follows new ones (--lines sets the count, default 50). | Reads only |
| emisar events cat / grep | Dump the whole journal, or filter it by --action, --caller, or --event. | Reads only |
| emisar audit verify [path] | Re-derive a journal file's SHA-256 hash chain and report breaks; --all walks rotated siblings. | Reads only |
$ sudo emisar doctor # offline preflight — run this first $ sudo emisar events tail -f # the local journal, live $ sudo emisar audit verify --all # re-derive the journal hash chain
doctor
never opens a cloud session and one failing check never aborts the rest, so a single run
surfaces every problem at once.
audit verify
exits 0 when the chain is intact and 1 on the first break, naming the line and event id;
--all
walks the active file plus every rotated
.N
sibling, each chain verified independently. There's also emisar state check-dispatch-log,
which the installer runs before an upgrade to confirm the durable dispatch log still loads.
audit verify
proves the on-host journal hasn't been edited in place, but root on the host can truncate the
tail and re-chain it. The record that can't be forged from the host is the off-host cloud
audit — stream both and cross-reference them. See Audit & SIEM.
Signed-dispatch keys#
emisar signing
sets up client-attested dispatch: an enforcing runner then requires a CA-signed certificate
on every action, so a compromised control plane can relay a dispatch but never mint one.
Everything here is offline — keys are printed to your terminal and sent nowhere.
| Command | What it does | Mode |
|---|---|---|
| emisar signing init | One-shot on-ramp: mint a CA, a leaf key, and a cert; print the runner config, the offline CA private key, and the two MCP env vars. | Prints key material |
| emisar signing new-ca | Mint just the offline CA keypair — the root of trust (rarely). | Prints key material |
| emisar signing new-cert | Sign a short-lived operator cert against the offline CA (routinely, as certs expire). | Prints key material |
-
—
--ttl 24h— the cert's validity window; accepts Go durations plus long-form30d/1y(default 24h). Short is better — a long TTL trades away revocation granularity. -
—
--scope group=prod,env=edge— bind the cert to matching runners; empty means any runner that trusts the CA. -
—
--ca-idand--ca-key(both required onnew-cert) — the CA id, which must match the runner'strusted_cas, and the offline CA private hex seed fromnew-ca. The key is read locally and never transmitted. -
—
--key-idand--pubkey— label the leaf key, or supply your own leaf public key instead of minting one.
# one-shot: prints the runner config block, the offline CA key, and the MCP env vars $ emisar signing init --ca-id acme-2026 --scope group=prod --ttl 24h # later, renew a cert against the offline CA (no runner reload needed) $ emisar signing new-cert --ca-id acme-2026 --ca-key <offline CA key> --scope group=prod
The generated
EMISAR_SIGNING_KEY
and EMISAR_SIGNING_CERT
are the env vars your MCP client carries; the CA private key stays offline, never on a runner
or the control plane. The full model — enforcement, scoping, rotation, and revocation — is in Signed dispatch.
Install, update, and removal#
The binary is installed and upgraded by the same script; it isn't self-updating. Re-running
the installer upgrades in place and preserves config and packs. It requires systemd on Linux
(use --no-service
for hosts without a real init).
# install or upgrade in place (config + packs preserved) $ curl -sSL https://emisar.dev/install.sh | sudo bash # pin a version, or provision unattended with a fixed pack set $ curl -sSL https://emisar.dev/install.sh | sudo bash -s -- --version runner-v0.3.0 $ curl -sSL https://emisar.dev/install.sh | sudo bash -s -- --yes --packs linux-core,postgres
-
—
--version TAG— install a specific runner release (runner-vX.Y.Z,vX.Y.Z, or bareX.Y.Z); default is the latest. -
—
--yes— skip prompts; requires an explicit--packs(orEMISAR_PACKS) so an unattended run never guesses. -
—
--packs LIST— install exactly these packs, comma- or space-separated, with no host detection (for cloud-init, Packer, Ansible). -
—
--no-start— install and enable the service but leave it stopped;--no-service— binary only, with no service user, unit, or activation. -
—
--uninstall— stop the service and remove the binary, unit, and cached token, keeping config, data, and logs;--purgewith it also deletes config, data, logs, and the service user. -
—
--bin-dir·--etc-dir·--data-dir·--log-dir·--user— override the install locations and the service account.
# remove the binary, service, cached token, and identity — keep config + journal $ sudo bash install.sh --uninstall # …or delete everything, including config, data, and logs $ sudo bash install.sh --uninstall --purge
After uninstalling, delete the runner in the dashboard — its run history and audit events survive the host. Removing a runner cleanly, including manual identity resets, is covered in the runner fleet guide.