The opschain CLI
Included from Basic tier
opschain is one binary carrying every surface: the operator and developer
command tree, the server itself (opschain server start), the runner
(opschain runner) and the embedded reference documentation
(opschain docs). This page covers the CLI as a component — global flags,
targeting, authentication, output and exit conventions. Each command's own
manual lives under docs/reference/cli/ and is read with
opschain docs cli/<command-path> (e.g. opschain docs cli/runs-create).
Global flags
Persistent flags, accepted by every command:
| Flag | Meaning |
|---|---|
-o, --output table|json|yaml | Output format (default table). A machine format suppresses tables, live rendering and progress chatter. |
-q, --quiet | Suppress progress output; print identifiers and errors only. |
--home <dir> | The opschain home directory (default $OPSCHAIN_HOME, else the per-OS data directory). |
--server <url> | Target server URL (overrides OPSCHAIN_SERVER and the active context; default: local mode). |
--local | Run against the local repository, ignoring the active context. |
--debug | Shorthand for --log-level debug. |
--log-level debug|info|warn|error | Minimum log level (default info). |
--log-file <path> | Write logs to a rotated file instead of stderr (default rotation 100 MB / 30 days / 10 backups; server start re-reads rotation from the config.yaml logging: block). |
--no-keychain | Never use the OS keychain for secrets/tokens; use key/credential files instead. |
The home directory and what lives in it
--home → $OPSCHAIN_HOME → the per-OS default: ~/Library/Application Support/opschain (macOS), %LOCALAPPDATA%\opschain (Windows),
$XDG_DATA_HOME/opschain else ~/.local/share/opschain (Linux). It holds
the local store (runs, logs, artifacts — managed with opschain state,
see opschain docs cli/state), the secret store, contexts.json, the
credentials/ token-file fallback, and the runner's state directory
(<home>/runner).
Contexts and targeting
Every invocation resolves one execution target, in precedence order:
--server <url>(an ad-hoc target),$OPSCHAIN_SERVER,- the active named context (
contexts.jsonin the home directory), - otherwise local mode — the repository and per-user store on this machine.
--local short-circuits the whole chain — the escape hatch back to the
local repository on a machine whose active context would otherwise make the
local catalog unreachable. Combining it with --server is refused as
contradictory. opschain context shows the resolution; opschain context use <name> switches the active context (local returns to local mode);
opschain context list lists them. Contexts are created by opschain login --server <url> --context <name>.
Local vs server lanes
Some commands are inherently local and never call an API: init, learn,
docs, eula, version, state, config, context, server start /
server configure / server backup / server restore, and doctor's
host probes. opschain runner talks to the server named by its own
--server flag, not the context. Everything else follows the resolved
target: in local mode the resource verbs act on the local repository and
store; against a server, run inspection, logs, artifacts and the catalog are
served remotely, host-scoped services (the secret store, doctor) stay local,
and store-backed verbs the server cannot serve refuse loudly instead of
silently acting on the local store. opschain api sends raw requests to the
targeted server (opschain docs cli/api).
Authentication and token storage
opschain login verifies a token against the targeted server, stores it,
and records a named context. With --username the credentials (password
prompted, or read from stdin) are exchanged for a session token pair via
the v2 AuthService Login procedure. Tokens are stored per normalized server
URL in the OS keychain (service opschain), falling back to 0600 files
under <home>/credentials/ when the keychain is unavailable — or always
with --no-keychain. A stored refresh token (kept under a derived
<server>#refresh slot in the same store) arms automatic renewal: on a 401
the access token is rotated into a fresh pair, persisted back, and the call
retried once. opschain logout removes the stored tokens; opschain whoami
shows who the stored token authenticates as; opschain passwd changes a
local user's password. The admin plane has its own opschain admin login/logout pair.
Output conventions and exit codes
- Tables are the human default;
-o json/-o yamlrender the same data as one machine-readable document (YAML is derived from the JSON encoding, so the two always agree). Streamed sequences (--watch,--follow) render as NDJSON under json and----separated documents under yaml. - TTY detection decides live rendering;
OPSCHAIN_TTY=always|neveroverrides it andTERM=dumbforces plain output. - Exit codes:
0OK,1run/command failed,2usage error,3cancelled,4timeout. A usage error also printsRun 'opschain --help' for usage.
Filtering list output (--filter)
Every list command carries a repeatable --filter flag with one shared
grammar — each command's manual page names the flag, this section defines
it once:
--filter <column>=<value> keep rows whose column matches the value
--filter <column>!=<value> keep rows whose column does NOT match
--filter <column>=<a>,<b> comma = any-of (membership in the set)
- Columns are the printed table headers, lowercased, with spaces,
dashes and slashes folded to underscores (
LAST SEEN→last_seen,CREATED-BY→created_by,STARTED/FROM→started_from) — the vocabulary is discoverable from the command's own output, and matches the machine formats' key style. A column a--wideflag adds is filterable only when--wideis given (the vocabulary is what the invocation prints). An unknown column is a usage error naming the valid columns for that command. - Matching is whole-cell and case-insensitive. A value without
*is plain equality — never a substring match.*matches any run of characters (including none):--filter action=*deploy*finds the substring,--filter target=demo/*the prefix. The cell compared is exactly what the table prints (so-for an empty cell, RFC 3339 timestamps,true/falsebooleans). - Repeated terms AND; the only OR is the comma set within one term. Nothing richer exists — no ranges, no cross-column OR, no regular expressions.
- Filters run before any
--limit/--tailtruncation and select the same rows whichever output format renders them (-o table|json|yaml). - Filters are applied client-side. Commands whose dedicated flags
narrow server-side (e.g.
events --errors --since,audit --type --username,triggers firings --status,admin runners list --group) still send only those flags to the server;--filterthen narrows the fetched rows. Each command's manual page says which of its flags push down.
opschain runs list --filter status=error --filter action=*deploy*
opschain runs list --filter status=error,queued --filter target!=demo/*
The embedded reference documentation
The reference set — component pages like this one, the data dictionary and
the CLI manual — is embedded in the binary, so it always matches the
opschain version you are running:
opschain docsprints the index;opschain docs <slug>one page.opschain docs search <term>full-text searches the set.opschain docs export [-o <dir>]writes the pages to disk (default directoryopschain-reference) for intranets or printing.- Every command whose manual ships in the set carries a help trailer —
Full manual: opschain docs cli/<slug>— so--helpstays terse and the depth is one command away.
Related pages
opschain docs cli/context/cli/login/cli/whoami— targeting and authentication commands in full.opschain docs cli/state— managing the local store.opschain docs cli/server-start/cli/server-configure— the server lane of the same binary.opschain docs cli/runner— the runner lane.opschain docs cli/api— raw API access against the targeted server.opschain docs cli/docs— the docs command itself.