Skip to main content
rkat is designed for three main workflows:
  • interactive terminal use
  • scripts and CI
  • Unix pipes and chained command composition
The default path is prompt-first:
You can also use subcommands explicitly:

Global flags

The top-level parser exposes the same realm and convention-root flags to each command family:
--default-model <model> persists the default agent model into the scope-resolved config (project/user/realm resolution included) and exits when given without a command — rkat --default-model claude-fable-5 is the one-liner for switching what every future run talks to. The model is validated against the catalog and configured custom models. By default, CLI commands use the current directory as the invocation context and derive a stable workspace realm id from that path. For project-local state, StorageLayout walks upward to the nearest ancestor containing a .rkat entry and stores realms under <project-root>/.rkat/realms/<realm>/. When no ancestor contains .rkat, the context root is the project root fallback. --context-root changes the derived workspace identity and the starting point for that ancestor search; it does not necessarily change the project root when both contexts are inside the same project. --state-root bypasses discovery and changes only where realm directories are stored. Some maintenance or host commands reject combinations that have no safe meaning. In particular, storage verbs reject --isolated and --default-model, and rkat mob host rejects --isolated. Fresh prompt-first runs and rkat help are fail-soft only at the default workspace storage boundary. If the workspace-derived realm cannot be opened, no historical session from that realm is loaded into the fresh run, and the explicit compatibility bridge is never invoked automatically. The ordinary strict open may already have completed supported manifest initialization or an earlier domain migration before a later store refuses. The CLI warns and creates a new generated realm using durable SQLite under the same resolved state root. The workspace’s configuration, auth policy, provider selection, and tool policy remain in force; only persistence-owned state is isolated in the generated realm. The warning names both realms and prints the explicit recovery command:
An explicit --realm, --isolated, every resume form, and all session commands remain fail-closed. Historical session access therefore stays an explicit maintenance operation. The fresh-run fallback is never an in-memory session and never makes a historical session from the failed workspace realm part of the new run.

Common commands

Prompt-first usage

Examples:

Common run flags

  • -m, --model <MODEL>
  • -o, --output <text|json|html>
  • --json
  • -s, --stream
  • --no-stream
  • --no-web-search
  • --export-atif (write an ATIF trajectory to the realm trajectories/ directory after the turn; default off)
  • --resume[=<SESSION>]
  • --skill <BUILTIN_ID> repeatable
  • -d, --max-duration <DURATION>
  • -t, --tools <safe|workspace|full|none>
  • --stdin <auto|blob|lines|off>
  • --keep-alive
  • --wait-for-mcp
  • --mcp-auth <stored|interactive>
  • -v, --verbose
For the full advanced set, use:
Current CLI help labels this value PATH_OR_ID, but rkat run --skill and resume currently construct builtin skill keys. Direct local-path preload is therefore unsupported. rkat skill add <PATH> registers a filesystem source but does not make this flag source-aware, and ordinary CLI sessions do not currently advertise the skill-discovery tool set. Use typed RPC/SDK preload fields when a host must address a source UUID directly.

Tool presets

rkat uses presets instead of many enable/disable booleans. --yolo is an alias for --tools full.

Provider and structured output controls

Use --param for common tuning and --params-json as the escape hatch:
Structured output is file-friendly:
--json is a convenience alias for --output json. HTML output asks the agent to make the final answer a standalone local HTML artifact:
--html is a convenience alias for --output html. --browser is a compact shortcut for HTML output plus --open-in-browser. HTML output writes the file under the active realm’s presentation/html directory and prints the path. Template defaults live under [presentation.html]:
Per run, use --html-template <NAME> or --html-template-file <PATH>. Config template paths are resolved relative to the active config base directory.

Streaming defaults

  • In a TTY, text output streams by default.
  • In pipes and scripts, streaming is off by default.
  • JSON and HTML output stay non-streaming by default so stdout remains machine-friendly unless --stream is explicitly requested.

Stdin modes and Unix pipes

rkat treats piped stdin as a first-class interface:
  • auto default: if stdin is piped, read it as one blob of context
  • blob: always read full stdin to EOF before running
  • lines: keep stdin open and process one line at a time
  • off: ignore stdin even if something is piped in
Batch blob mode:
Live line mode:
--line-format json treats each incoming line as JSON instead of plain text.

run —resume

Examples:
SESSION_ID accepts:
  • a full UUID
  • a short prefix
  • last
  • ~N
Omitting the value means last, so rkat run --resume "keep going" and rkat run --resume last "keep going" are equivalent. Resume supports the same stdin model as run, plus per-turn tool overlays and provider params. Self-hosted aliases work the same way:

session

This is the human/operator session surface. CLI-internal control-plane session APIs are not exposed here. session export-atif reads the currently available event audit/replay projection. A slow live subscriber can receive a typed stream-truncation marker without dropping projector input, but projection is asynchronous best-effort derived state and export does not first drain it to the latest committed session boundary. Meerkat supports ordinary durable-state opens from 0.8.10 onward. For an older SQLite realm, stop every process that can access it and run the explicit current maintenance bridge:
The frozen importer fails closed on unsupported pre-floor shapes. Normal realm opens remain strict. JSONL and memory realms are rejected before any database is mutated. The maintenance transaction preserves queued and nonterminal input rows without scheduling or replaying them. A later session activation follows normal recovery.

blob

Without either output flag, blob get writes the decoded raw bytes to stdout. --output writes those bytes to a file. --json prints the complete BlobPayload (blob_id, media_type, and base64 data) instead of raw bytes. Blob IDs are realm-scoped, so use the same realm that produced the session or artifact reference.

realm

realm current prints the realm selected by the CLI scope. realm list and realm show inspect manifests in the active state root. realm prune defaults to a 24-hour age threshold. --force bypasses active-lease safety checks, so use it only after confirming that no process still owns the target realm.

config

The positional argument is always a file path; inline payloads use --json (or --toml for set). Examples:

auth

rkat auth login provisions the reserved global realm in the home-rooted doc at ~/.rkat/config.toml — both the credential token and the [realm.global] binding section. Login therefore materializes global as the optional chain tail, after which a single sign-in is inherited by workspace realms without a per-realm re-login. Earlier dev-realm logins are migrated to global on the run path (one-time, idempotent, no-clobber), so an existing sign-in keeps working without re-auth. Credential reads inherit down the realm chain (a child realm resolves a binding defined in a parent or in global), but credential writes are strict-owner: the caller must explicitly target the realm that defines the binding; a child-addressed inherited write is rejected. --realm on profile, status, test, and refresh commands selects the realm and composes its chain for resolution. Logout is different: its positional [<realm>:]<binding> selects the token owner directly, and a bare binding means global; --realm does not retarget logout. See Realm inheritance and the auth guide for the full model.

models

This prints the effective runtime model registry for the active realm, including configured self_hosted aliases and their server_id.

doctor

For self-hosted setups, doctor checks the normalized /v1/models endpoint for each configured server and warns when configured aliases are missing from the returned model list. For Gemma 4, prefer chat_completions in your server config unless you have validated a specific responses path for your serving stack. Follow Self-hosting models for the full Gemma 4 examples.

storage

Storage administration verbs. All of them dispatch before realm resolution, so they run against the exact on-disk state they diagnose — including split-brain realms the normal resolver refuses. Because no runtime scope is resolved, the global --isolated and --default-model flags are rejected as usage errors on every storage verb rather than silently ignored; scope the sweep with --realm, --root, or --state-root instead.
Read-only and safe against a live realm: takes no leases, never changes logical database content, and never creates a database or directory. SQLite may create or update the -wal/-shm sidecars needed for a coherent WAL read. Sweeps the invocation-context-local (<context-root>/.rkat/realms) and user-global roots by default. Ordinary runtime resolution first walks to the nearest ancestor containing .rkat, so run the storage verb from that project root (or pass --root) to inspect the same local candidate; any explicit root (--state-root or repeatable --root) restricts the sweep to exactly those roots. --realm focuses the sweep on one realm. Reports per-root realm inventory, schema-ledger state per database, dual-root twins, dangling session→blob references, and orphaned lease/lock/backup artifacts. Exit 0 means no error-severity findings; exit 1 means errors were found.
migrate is dry-run by default, offline, resumable, and fail-closed. It sweeps the same roots (and honors the same --realm filter) as storage doctor. The dry run reads each realm’s schema-ledger baseline read-only — no fence, no store opens, no mutation. --apply acquires the realm’s exclusive maintenance fence (--fence-wait-secs, default 10, bounds the wait for in-flight store operations to drain), then per realm: stamps ledgers by opening every store through its normal constructor under the held fence and reports state-root adoption (report-only — realms are used where they lie). Exact 0.8.10 session-state conversion is owned by each backend’s activation transaction, which binds the released schema, key, and source bytes before installing current store authority; storage migrate does not bulk-adopt documents or defer conversion to ordinary reads. A realm materialized under multiple swept roots is a fail-closed refusal unless --apply --adopt-root <path> names the swept root whose copy to keep: every copy is fenced first, the divergence report is recomputed under the held fences, and archiving is gated on that comparison being conclusive (an unreadable entry poisons it and refuses) — then every other copy is archived read-only under the registered *.pre-<version>-<timestamp> backup naming. Divergent data is preserved and reported, never merged. Per-mob databases under mobs/ are report-only, and credential stores are never read, moved, or reported. Exit 0 = clean; exit 1 = errors or fail-closed refusals (split-brain without --adopt-root, unacquirable maintenance fence). --bridge-pre-0-8-10 is an explicit --apply-only maintenance lane for SQLite realms. JSONL and memory realms are rejected before any database is mutated. While the realm fence is held, it runs a frozen importer before the normal store constructors. A domain is authenticated as exactly one caller-authorized source catalog; an unknown or ambiguous catalog refuses that domain instead of being inferred or stamped, and each domain owns its own transaction, so a domain that committed stays committed when a later one refuses. The same authentication answers the eligibility sentence an ordinary open prints, so a realm the bridge recovers is never described as unrecoverable and a realm it cannot recover is never handed this command. Row admission is per record, not per domain. Every runtime input row is carried forward when it decodes through the current typed contract and re-encodes without losing a field; a row that cannot be is left with its bytes exactly as found - never deleted, never blanked - and named in the output with the reason and the consequence. Rows are preserved in the current representation without being scheduled or replayed, and that includes their ingress payloads: a rescued realm keeps the operator’s own prompt whatever lifecycle state its input reached. A later session activation follows normal recovery, which applies this binary’s ordinary payload retirement to rows it writes itself. Ordinary store opens never enter this bridge.
prune owns the lifecycle of registered maintenance artifacts only — *.pre-<version>-<timestamp> migration backups and *.corrupt-<timestamp> index quarantines; nothing outside those naming patterns is ever touched. The default run lists artifacts with sizes and ages; --apply deletes those at least --older-than-days (default 30; 0 = all) days old. Age comes from the timestamp embedded in the registered name, not filesystem mtime — renames preserve mtime, so a long-idle file archived today would otherwise look instantly prunable. --realm restricts eligibility to one realm’s artifacts. Exit 0 = clean; exit 1 = deletion failures. Not to be confused with rkat realm prune, which deletes whole realm directories.

mcp

rkat mcp is for local and project configuration only.
Examples:
Omit --scope on list or get to search all configured scopes. HTTP OAuth is discovered when connecting, not stored in .rkat/mcp.toml. Use rkat mcp login <NAME> to open the browser flow ahead of time, or rkat run "..." --mcp-auth interactive to allow a TTY run to authenticate when an HTTP MCP server first requires it. The default --mcp-auth stored uses persisted tokens only.

mob

rkat mob is the artifact, typed callable run, and operational run-resource surface. Runtime semantics still live in the shared mob runtime; the CLI only binds to it.
Multi-host notes:
  • rkat mob host starts only the signed member-host and optional live listeners. It uses the workspace-derived realm (or explicit --realm) and rejects --isolated; it does not expose an RPC, REST, or MCP console.
  • When enabling the host pairing branch, prefer --pairing-password-env or --pairing-password-file so the secret does not appear in process arguments. The three pairing-secret options are mutually exclusive; --pairing-password remains available for compatibility. Pairing secrets must be at least 32 bytes and are validated before host startup effects. Pairing is accepted only on an IP loopback listener because it returns the one-time binding descriptor over the plaintext comms transport. Use the 0600 descriptor out-of-band for remote hosts, or tunnel a loopback listener.
  • rkat mob bind-host consumes the descriptor JSON written by rkat mob host --descriptor-out; the 0600 descriptor carries a single-use bootstrap token, and the bind report (host id, authority epoch, capability record) prints as JSON.
  • grant, revoke-grant, and grants manage the closed control-scope set: list, read_history, subscribe_events, send_command, cancel, retire, wire_topology, live, admin_host, and admin_grants.
  • rkat mob live open prints the wire LiveOpenResult JSON — including the live URL and single-use token — to stdout only; stderr carries a token-free note. The socket it names is the input plane: there is no live send verb.
  • Member live channels are WebSocket-only in the current runtime. The shared CLI transport enum accepts --transport webrtc, but the member host rejects that selection. Session-scoped JSON-RPC live/open plus live/webrtc/answer supports WebRTC only when the caller can address the owning session directly. Controller session/* methods do not proxy a placed member’s host-local session in multi-host v1.
  • Mob verbs exit with typed codes for the four multi-host error classes: scope denied 45, host unavailable 46, stale cursor 47, stale fence 48, each with a one-line detail: {...} JSON rendering on stderr. Everything else keeps the generic exit 1.
  • Durable member role migration is not a CLI spawn option. The one-shot resume_from_role declaration is restricted to trusted in-process SpawnMemberSpec construction and the private member-host materialization protocol. CLI helpers, public RPC/SDK spawn requests, REST, MCP, and standing profiles cannot grant it.
Examples:

Trust policy

  • --trust-policy strict rejects unsigned packs and unknown signers
  • --trust-policy permissive allows unsigned packs with warnings but still rejects invalid signatures

Web build prerequisites

The CLI does not compile wasm32 itself. --wasm is required and must point at the prebuilt meerkat-web-runtime artifacts — either the wasm-pack --target web output directory (which holds meerkat_web_runtime.js + meerkat_web_runtime_bg.wasm) or that *_bg.wasm file (the sibling .js glue is copied alongside). mob web build copies those artifacts into its output. wasm-pack is one way to generate the required input:
The emitted bundle is self-contained and runnable: serve the output directory and open index.html (it includes the glue, a meerkat-bootstrap.js module, and the mobpack). The generated page trust-verifies the package and initializes the WASM runtime only. It does not call mob_create, spawn members, or provide a transcript UI; integrate the package with the generated WASM glue or @rkat/web to build those application flows.

skill

workgraph

rkat workgraph provides operator lookup plus narrow goal and attention controls for the active realm.
Agents mutate WorkGraph through workgraph_* tools. The CLI exposes only the narrow trusted goal/attention controls above; attention continuation injection remains runtime-host owned rather than a REST-backed CLI command.

capabilities

Shows status for compiled/runtime capabilities.

init

Creates .rkat/config.toml from the global template.