CLI reference

Every Evident CLI command, flag, and environment variable.

The evident CLI runs OpenCode locally and connects it to Evident. It is published as @evident-ai/cli and installs a binary named evident.

Install

npm install -g @evident-ai/cli

Or run it directly with npx without installing:

npx @evident-ai/cli@latest <command>

Commands

The CLI has five commands: login, logout, whoami, status, and run.

evident login

Authenticate with Evident. By default this uses the browser-based device flow: the CLI shows a one-time code and opens your browser to confirm it. Sessions are stored per endpoint, so you can stay signed in to more than one backend at the same time.

evident login

Options:

  • --token — Use token-based authentication instead of the device flow (for CI/CD); paste a token when prompted. Create one from Settings → CLI tokens in the dashboard.
  • --no-browser — Don't open the browser automatically (visit the URL manually).

evident logout

Remove stored credentials. By default this signs you out of the current endpoint only (the one selected by --endpoint / EVIDENT_API_URL, otherwise production).

evident logout

Options:

  • --all — Remove stored credentials for every endpoint.

evident whoami

Show the currently authenticated user for the current endpoint.

evident whoami

evident status

Check whether the configured credentials can reach Evident — nothing else. It resolves credentials the same way evident run does (EVIDENT_RUNNER_KEY / EVIDENT_AGENT_KEYEVIDENT_TOKENevident login) and calls GET /me to confirm they're accepted.

evident status

Options:

  • --json — Print a single JSON object instead of formatted text.

The exit code distinguishes a genuinely bad/missing credential (fixable) from Evident simply being unreachable (the credential was never actually tested):

Exit code Meaning
0 The credentials were accepted (200 from /me).
1 The credentials were rejected (401, or any other non-401 4xx), or no credentials were configured at all.
75 Evident could not be reached (network/DNS/timeout, or any 5xx) — the credentials were not validated either way.

evident run

Connect to Evident and serve your runner. evident run authenticates, resolves which runner to serve, ensures opencode serve is running on loopback, opens the streaming tunnel (which transparently proxies the runner's web surface), and delivers any connector messages (such as Slack) to your local OpenCode.

# Connect a specific runner
evident run --runner <runner-id>

# Drive a single conversation
evident run --runner <runner-id> --conversation <conversation-id>

# CI: exit after 30s with no work
evident run --runner <runner-id> --idle-timeout 30

Options:

Flag Description
--runner [id] Runner ID to connect to. Optional when EVIDENT_RUNNER_KEY is set — the runner is then resolved automatically from the key.
-a, --agent [id] Deprecated alias for --runner. Still supported, but it prints a deprecation warning; --runner wins if both are given.
-p, --port <port> OpenCode port. Default: 4096.
--log-level <level> Log verbosity: debug | info | warn | error. Default: info. Env: EVIDENT_LOG_LEVEL.
-v, --verbose Alias for --log-level debug (an explicit --log-level wins).
-c, --conversation <id> Process only this specific conversation.
--idle-timeout <seconds> Exit after N seconds with no pending work. Useful in CI to avoid polling indefinitely.
--opencode-start-timeout <seconds> How long to wait for OpenCode to become healthy when the runner starts it itself. Default: 180. On expiry the runner warns and comes online anyway rather than failing. Env: EVIDENT_OPENCODE_START_TIMEOUT (seconds).
--opencode-version <v1|v2> Which OpenCode major version to launch: v1 or v2. Default: v1. Env: EVIDENT_OPENCODE_VERSION. When selected, the CLI starts or attaches to opencode2 and authenticates its local requests with the generated server credential when it starts the process. V1 remains the default.
--litestream-config <path> Start litestream replicate for the OpenCode session database with this config file. Use this for runner images that persist the session database; the file is produced by runner-synchroniser litestream-config. Omit it to disable replication.
--opencode-pid-file <path> Record the image-owned OpenCode process ID here and leave that process running at shutdown for the runner image's lifecycle hooks to stop.
--litestream-pid-file <path> Record the image-owned Litestream process ID here and leave that process running at shutdown for the runner image's lifecycle hooks to stop.
--session-db-no-replicate-marker <path> Read this marker before starting Litestream; session-DB restore writes it when this boot's database is not safe to replicate.
--restore-session-db Restore and verify the OpenCode session database before starting OpenCode. Requires --litestream-config for the replica location and --session-db-no-replicate-marker for give-up records. Omit it for a normal local run.
--restore-runner-credentials Restore the hosted runner secret and persisted credential stores before starting OpenCode. Intended for runner images; omit it for a normal local run.
--opencode-config-overlay <path> Apply a runner-provided OpenCode config before starting OpenCode. Relative paths are resolved from the working directory; an existing opencode.jsonc is replaced before opencode.json.
--credential-sync-marker <path> Own the interval credential sync and write this marker once the shutdown flush has finished, so the runner image's lifecycle hooks can wait on it.
--json Output in JSON format. Forces non-interactive mode.
--session-cleanup-max-age <duration> Delete OpenCode sessions idle longer than this window (format <number><unit>, unit one of s, m, h, d — e.g. 7d, 24h). Setting this (or --session-cleanup-max-count) is what enables cleanup — there is no separate on/off flag. An invalid value is warned about and ignored, which can leave cleanup off if it was the only rule set. Env: EVIDENT_SESSION_CLEANUP_MAX_AGE. With cleanup off, a runner whose local session store has grown large warns once at startup, on the runner's page, naming this flag — pruning stops the store growing, but it does not shrink what has already grown.
--session-cleanup-max-count <n> Keep only the newest N OpenCode sessions by last activity, deleting the rest. Also enables cleanup; combines with --session-cleanup-max-age as OR. A session with a turn actively in progress is never deleted, regardless of either rule. Env: EVIDENT_SESSION_CLEANUP_MAX_COUNT.
--max-active-sessions <n> Cap how many sessions the runner will have actively working at once. Default: unlimited. Counts sessions with work in flight and is per runner process, not global. Once the cap is reached, new work simply stays pending and is picked up on a later poll tick — nothing is dropped or errored — but a follow-up into an already-active session is never blocked, since it costs no extra slot. A legitimately long-running turn holds its slot for as long as it runs (bounded only by the 6h absolute processing ceiling), so pick N with that in mind. After a restart the runner re-adopts already-claimed work, which can briefly push the active count above the cap — that is deliberate. An invalid value falls back to unlimited with a warning. Env: EVIDENT_MAX_ACTIVE_SESSIONS.
--session-cleanup-interval <duration> How often the cleanup sweep runs. Default: 1h. An invalid value falls back to the default rather than disabling cleanup. Env: EVIDENT_SESSION_CLEANUP_INTERVAL.
--claude-usage-reporting <mode> Whether to report the local Claude Code subscription's rate-limit usage to Evident, so it shows on the runner page: auto (default) reports it when a usable Claude Code login is found on this machine and stays silent otherwise; on forces reporting and warns loudly (and keeps retrying) if no usable login is found; off disables it entirely — no Claude credential is ever read. An unrecognized value falls back to auto with a warning. Env: EVIDENT_CLAUDE_USAGE_REPORTING. See Model providers for how to connect a Claude subscription.
--openai-usage-reporting <mode> Whether to report ChatGPT plan usage from an OpenCode login to Evident, so it shows on the runner page: auto (default) reports it when a usable ChatGPT login is found and stays silent otherwise; on forces reporting and warns loudly (and keeps retrying) if no usable login is found; off disables it entirely — no OpenCode login is ever read. An unrecognized value falls back to auto with a warning. Env: EVIDENT_OPENAI_USAGE_REPORTING.
--no-resource-usage-reporting Don't report this machine's CPU utilization, total and available memory, core count, disk space, and the OpenCode session-store size to Evident, so it shows on the runner page. On by default; nothing else about the machine leaves it. Env: EVIDENT_RESOURCE_USAGE_REPORTING=off.
--enable-file-sync-to <dir> Let the runner write files Evident has queued for it into this directory — it collects them as part of the polling it already does, so they land a couple of seconds after you hand them over. Repeatable (up to 16); each value must be absolute once a leading ~ is expanded, and the filesystem root is rejected. Omit it entirely and the runner collects nothing and refuses any queued file, telling you why. Use --enable-file-sync-to ~/.claude to connect a Claude subscription from the web — see Model providers.

Global flags

These apply to every command and select which backend the CLI talks to. The CLI targets the production Evident platform by default.

Flag Description
--endpoint <url> Evident REST API base URL (e.g. http://localhost:3001). A trailing /v1 is optional — it is added automatically.
--tunnel <url> Tunnel WebSocket URL (e.g. ws://localhost:8787).

Environment variables

Variable Description
EVIDENT_RUNNER_KEY A runner key. When set, evident run authenticates as that runner and resolves the runner ID automatically, so --runner is not required. Ideal for CI/CD.
EVIDENT_AGENT_KEY Deprecated alias for EVIDENT_RUNNER_KEY. Still supported; EVIDENT_RUNNER_KEY wins if both are set.
EVIDENT_TOKEN A user token used for authentication, as an alternative to a keychain login from evident login. Create one from Settings → CLI tokens in the dashboard — it is shown once, so save it immediately.
EVIDENT_API_URL Override the API base URL (equivalent to --endpoint).
EVIDENT_TUNNEL_URL Override the tunnel relay URL (equivalent to --tunnel).
EVIDENT_LOG_LEVEL Override the log verbosity: debug | info | warn | error. Default: info. (equivalent to --log-level; -v/--verbose also outranks this)
EVIDENT_OPENCODE_START_TIMEOUT Override --opencode-start-timeout, in seconds. Default: 180.
EVIDENT_OPENCODE_VERSION Equivalent to --opencode-version; the flag wins if both are set. Default: v1.
EVIDENT_SESSION_CLEANUP_MAX_AGE Equivalent to --session-cleanup-max-age.
EVIDENT_SESSION_CLEANUP_MAX_COUNT Equivalent to --session-cleanup-max-count.
EVIDENT_MAX_ACTIVE_SESSIONS Equivalent to --max-active-sessions; the flag wins if both are set.
EVIDENT_SESSION_CLEANUP_INTERVAL Equivalent to --session-cleanup-interval. Default: 1h.
EVIDENT_CLAUDE_USAGE_REPORTING Equivalent to --claude-usage-reporting.
EVIDENT_OPENAI_USAGE_REPORTING Equivalent to --openai-usage-reporting.
EVIDENT_RESOURCE_USAGE_REPORTING Equivalent to --no-resource-usage-reporting; set it to off to disable.

Precedence

Authentication for run is resolved in this order: a runner key (EVIDENT_RUNNER_KEY, or its deprecated alias EVIDENT_AGENT_KEYEVIDENT_RUNNER_KEY wins if both are set) → EVIDENT_TOKEN → the credentials stored by evident login.

Backend URLs are resolved per setting: an explicit --endpoint / --tunnel flag wins over the matching environment variable (EVIDENT_API_URL / EVIDENT_TUNNEL_URL), which in turn overrides the production default.

The same rule applies to every other flag/env-var pair above (--log-level, --opencode-start-timeout, the three --session-cleanup-* flags, --claude-usage-reporting, and --no-resource-usage-reporting): an explicit flag always wins over its matching environment variable.

Configuration

Configuration and credentials are stored under:

  • $XDG_CONFIG_HOME/evident/ if XDG_CONFIG_HOME is set
  • otherwise ~/.config/evident/

Credentials are stored per endpoint, so a token is only ever used for the backend that minted it.

Next steps