> ## Documentation Index
> Fetch the complete documentation index at: https://docs.moda.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# CLI overview

> Install the Moda CLI, authenticate, provision API keys headlessly, and understand profiles, output formats, and exit codes.

The Moda CLI (`@moda-ai/cli`, installed as `moda`) queries your production conversation data from the terminal, manages prompt versions, and syncs your harness. This page covers installation, authentication, profiles, output formats, and exit codes. The full command list is in the [CLI reference](/cli/reference), and agent/CI integration patterns are in [Using the CLI from agents and CI](/cli/agents).

## Install

Requires Node.js 18 or later.

<CodeGroup>
  ```bash Global install theme={"dark"}
  npm install -g @moda-ai/cli
  moda --version
  ```

  ```bash Without installing theme={"dark"}
  npx -y @moda-ai/cli overview
  ```
</CodeGroup>

## Authentication

The CLI uses two credentials for two different groups of commands:

| Credential              | Used by                                                                                                              | How you get it                                                               |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| CLI session             | `auth *` commands and `provision`                                                                                    | `moda auth login` (browser flow)                                             |
| API key (`moda_sk_...`) | Data commands (`search`, `overview`, `emotions`, `problem`, `tail`, `ask`, ...), `prompts`, `skills`, `harness sync` | `moda init`, `moda provision`, or the dashboard at Settings → Ingestion keys |

API keys (called ingestion keys in the dashboard) are tenant-bound: a key always operates on the tenant it was created for, and `MODA_TENANT_ID` cannot re-point it.

### Log in (browser flow)

```bash theme={"dark"}
moda auth login
```

The command opens your browser to moda.dev, where you sign in; the CLI completes a PKCE exchange against a localhost callback (ports 8432–8435, first free port). If the browser cannot reach the CLI — for example when you run the CLI over SSH — paste the callback URL or the one-time code shown in the browser back into the terminal. The resulting CLI session lasts 30 days on a sliding window and renews in the background.

Related commands:

* `moda auth status` — reports session state; exits 4 when logged out. `--online` also probes the API.
* `moda auth whoami` — shows the authenticated user and available tenants.
* `moda auth token` — prints the raw session token (for scripting control-plane calls).
* `moda auth logout` — revokes the session server-side and clears local credentials, including the stored API key.

<Warning>
  The session token authenticates control-plane commands only. Data commands require a `moda_sk_` API key: set `MODA_API_KEY`, or mint one with `moda init` or `moda provision`. `moda auth token` output is not valid for the Data API.
</Warning>

### API key resolution order

Data commands resolve the API key in this order:

1. `MODA_API_KEY` environment variable
2. The active profile's stored key
3. `~/.moda/config.json` (`api_key`)

## Headless provisioning: `moda provision`

`moda provision` mints (or reuses) a tenant API key without any interactive prompts and prints exactly one JSON document to stdout — nothing else. It is built for CI bootstrap scripts and agents:

```bash theme={"dark"}
MODA_API_KEY=$(moda provision --tenant-id=1f7c9a2e-4b3d-4c8e-9a1b-2d3e4f5a6b7c | jq -r .apiKey)
```

```json Output theme={"dark"}
{
  "apiKey": "moda_sk_...",
  "tenantId": "1f7c9a2e-4b3d-4c8e-9a1b-2d3e4f5a6b7c",
  "tenantName": "Acme Support",
  "tenantSlug": "acme-support",
  "ingestUrl": "https://moda-ingest.modas.workers.dev",
  "baseUrl": "https://moda.dev",
  "reused": false
}
```

The field names are a stable contract. `reused` is `true` when an existing stored key passed a liveness check and no new key was created.

Behavior to script around:

* Provision requires an existing CLI session (`moda auth login` run previously on that machine) and **never opens a browser**. Without a session it fails with **exit code 4** and instructions to log in first.
* With access to multiple tenants, `--tenant-id` (or the `MODA_TENANT_ID` env var; the flag wins) is required. Without it, provision fails with **exit code 5** and a machine-readable `input_request` that lists every tenant with its resume flags — it never prompts, even on an interactive terminal.
* `--label=TEXT` names the key (default: machine hostname). `--save` also persists the key and tenant to `~/.moda/config.json`; by default provision only prints, so headless callers own storage.

<Warning>
  Provision's stdout contains a live API key. Capture it into a secret store or variable; do not pipe it to logs.
</Warning>

## Profiles and configuration

CLI state lives in `~/.moda/`: `config.json` (API key, tenant ID, ingest URL), `profiles.json`, and per-profile secrets under `~/.moda/secrets/`. Three profiles exist by default: `prod` (`https://moda.dev`, the default), `staging`, and `local`.

```bash theme={"dark"}
moda profiles list
moda profiles use staging
moda config show --profile=prod
```

Select a profile per invocation with `--profile=NAME` or the `MODA_PROFILE` env var. Two env vars override URLs directly:

* `MODA_BASE_URL` — the moda.dev host used for the Data API and control-plane calls.
* `MODA_INGEST_URL` — the Ingestion API host (used by `skills` commands and remote harness analysis).

## Output formats

The CLI picks an output mode automatically, in this priority order:

1. **Explicit flags**: `--human` (or `--prose`), `--json`, `--agent`, `--agent --stream`
2. **`MODA_FORMAT`** env var: `human` | `json` | `agent` | `agent-stream` | `ndjson`
3. **Agent environment detection**: a truthy `CLAUDECODE`, `CURSOR`, `CI`, or `MODA_AGENT` env var selects `agent`
4. **TTY detection**: piped or redirected stdout selects `agent`; an interactive terminal selects `human`

The modes:

| Mode           | Output                                                                                                                 |
| -------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `human`        | Readable output for a terminal (data commands print pretty JSON; `overview`, `ask`, `doctor`, and others render prose) |
| `json`         | The raw payload as pretty-printed JSON; errors print a structured error envelope                                       |
| `agent`        | One `moda.agent.v1` JSON envelope per invocation                                                                       |
| `agent-stream` | NDJSON `moda.agent_event.v1` events (`--agent --stream`)                                                               |

This means a piped or CI invocation gets machine-parseable output with zero flags. Three commands bypass envelopes in every mode because their stdout is meant to be captured directly: `moda provision` (one JSON credentials document), `moda auth token` (the bare token), and `moda tail` (NDJSON — one JSON line per event, since a live tail is a stream rather than a single response).

### The `moda.agent.v1` envelope

In `agent` mode every command emits a single JSON envelope:

```json theme={"dark"}
{
  "schema_version": "moda.agent.v1",
  "command": "tool-failures",
  "status": "ok",
  "generated_at": "2026-08-16T09:14:02.318Z",
  "summary": { "text": "3 tools failed in the last 7 days.", "confidence": "high" },
  "findings": [],
  "evidence_refs": [],
  "recommended_actions": [],
  "next_commands": [],
  "artifacts": [],
  "warnings": [],
  "errors": [],
  "data": { "summary": { "total": 41 }, "tools": [] },
  "meta": { "run_id": "1c3f...", "tip": "Help us improve! ..." }
}
```

`status` is `ok`, `degraded`, or `error`; the command's payload is always under `data`. The full field reference, the streaming event schema, and exit-code recipes are on [Using the CLI from agents and CI](/cli/agents). `moda manifest --json` and `moda --json-schemas` describe the protocol machine-readably.

## Exit codes

| Code  | Meaning                                                                                                 |
| ----- | ------------------------------------------------------------------------------------------------------- |
| `0`   | Success.                                                                                                |
| `1`   | Error: command, input, API, network, or unexpected failure.                                             |
| `3`   | Degraded: an answer was produced from a local fallback instead of Moda Cloud (only `moda ask`).         |
| `4`   | Authentication required: run the login command in the error payload, then resume.                       |
| `5`   | Input required: a non-interactive caller must choose a value (for example `--tenant-id`) and re-invoke. |
| `130` | Cancelled: interrupted (Ctrl+C) or the output consumer closed the pipe.                                 |

## Update check and telemetry

Both are on by default and both can be turned off:

* **Update check.** At most once a day the CLI checks the npm registry for a newer `@moda-ai/cli` version and prints a notice to stderr. Disable with `--no-update-check` or `MODA_CLI_UPDATE_CHECK=0`. The check is automatically skipped in CI and when `DO_NOT_TRACK=1` is set.
* **Usage telemetry.** The CLI reports command name, flag *names* (never values or arguments), exit status, and duration. Disable with `--no-telemetry`, `MODA_CLI_TELEMETRY=0`, or `DO_NOT_TRACK=1`.
* **Feedback tip.** Successful commands print a one-line `moda feedback` tip (stderr on a TTY, `meta.tip` in envelopes). Hide the stderr line with `MODA_CLI_TIPS=0`.

## Environment variables

| Variable                      | Effect                                                                                        |
| ----------------------------- | --------------------------------------------------------------------------------------------- |
| `MODA_API_KEY`                | API key for data commands (highest precedence).                                               |
| `MODA_TENANT_ID`              | Tenant selection for `provision` and `init` (a flag wins over it).                            |
| `MODA_PROFILE`                | Active profile name.                                                                          |
| `MODA_BASE_URL`               | Override the moda.dev host.                                                                   |
| `MODA_INGEST_URL`             | Override the Ingestion API host.                                                              |
| `MODA_FORMAT`                 | Force an output mode: `human`, `json`, `agent`, `agent-stream`, `ndjson`.                     |
| `MODA_AGENT`                  | Truthy value forces agent-environment detection.                                              |
| `MODA_AUTH_TIMEOUT_MS`        | How long `moda auth login` waits for the browser (default 10 minutes, clamped 30 s – 30 min). |
| `MODA_ASK_TIMEOUT_MS`         | `moda ask` cloud timeout in milliseconds (default 250,000).                                   |
| `MODA_HEARTBEAT_MS`           | Idle heartbeat interval in `agent-stream` mode (default 10,000).                              |
| `MODA_AGENT_MAX_OUTPUT_BYTES` | Bound on envelope `data` size; a `truncation` block reports what was trimmed.                 |
| `MODA_CLI_TELEMETRY`          | `0` disables usage telemetry.                                                                 |
| `MODA_CLI_UPDATE_CHECK`       | `0` disables the daily update check.                                                          |
| `MODA_CLI_TIPS`               | `0` hides the feedback tip line.                                                              |
| `DO_NOT_TRACK`                | `1` disables telemetry and the update check.                                                  |

## Next steps

* [CLI reference](/cli/reference) — every command with flags and example output.
* [Using the CLI from agents and CI](/cli/agents) — envelopes, exit-code recipes, and CI examples.
* [Data API overview](/data-api/overview) — the HTTP API behind the data commands.
* [Authentication](/administration/authentication) — how API keys and sessions work across Moda.
