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

# Earnie CLI

> Authenticate, run scans, read verdicts and policies from a pipeline, and connect a coding agent to Earnie over MCP — all from the earnie command-line tool.

The `earnie` CLI is how pipelines, scripts, and coding agents talk to Earnie without the console. It never selects a default Project, and its JSON output is versioned so automation can rely on it.

## Signing In

For interactive use:

```bash theme={null}
earnie auth login --api-url https://your-earnie.example
```

In CI, supply the API URL and key without a prompt:

```bash theme={null}
printf %s "$EARNIE_API_KEY" | earnie --api-url https://your-earnie.example auth login --api-key-stdin
```

## Running a Scan

```bash theme={null}
earnie scan path [path]
earnie scan staged
earnie scan diff --base origin/main
```

The CLI resolves the Project from `--project`, `EARNIE_PROJECT`, or the connected Git remote, in that order — it never picks a default Project. Use `--format json` (or `--json`) for a single machine-readable result; progress and diagnostics go to standard error, where `--quiet` silences progress but never errors, and `--color auto|always|never` controls styling. Outside a terminal the output is plain lines.

### Exit Codes

A blocking scan waits for scanning **and** policy evaluation, then exits from the gate:

| Exit  | Meaning                                                                                           |
| ----- | ------------------------------------------------------------------------------------------------- |
| `0`   | `pass`, `warn`, or `none` (no policy in force — reported as "scan completed without enforcement") |
| `1`   | `block`                                                                                           |
| `2`   | `require` — returns immediately with the Approval link rather than waiting for a human            |
| `3`   | Scanning, evaluation, or the gate failed or is unknown                                            |
| `4`   | Invalid or expired API key                                                                        |
| `5`   | The key lacks a scope, or the Project is restricted                                               |
| `6`   | Retryable network or API failures were exhausted                                                  |
| `7`   | Local timeout (95 minutes by default; override with `--timeout`)                                  |
| `8`   | Invalid usage or configuration                                                                    |
| `130` | Interrupt                                                                                         |

Exhaustion, timeout, and interruption leave the server-side Scan running and print its ID — they never cancel it.

### Non-Blocking and Follow-Up Commands

* `earnie scan --no-wait` exits `0` as soon as the Scan is accepted, returning its ID with a `null` gate.
* `earnie scan wait <id>` waits for it and applies the gate exit codes above.
* `earnie scan status <id>` and `earnie scan list` are observational — they exit `0` whenever the query succeeds, whatever the Scan's own state is.
* `earnie verdict <id>` reads the gate a completed Scan was given and the policy revisions that produced it, with the current Policy Approval overlay applied. It never re-evaluates; after an Approval decision, running it again shows the updated gate.
* `earnie scan audit <id>` prints the Scan's Audit trail — submission, gate, approvals, and publications, oldest first, one line per event with when, what, and who. It's observational too, exiting `0` whatever the gate says.

### JSON Output

The JSON document carries `schema_version: "1"`: the Project and how it was resolved, the Scan, its effective scanners, enrichments and policy snapshot, the evaluation, the gate and its reason, one entry per policy revision, a findings summary, links, and a typed `error` whose `code`, `category`, `retryable`, and `request_id` are stable for automation.

By default, findings are summarised with `included: false`, a `total` (`null` when the key can't read findings), and a `findings_url`. `--include-findings` fetches every page with each finding's verdicts and evidence, and fails rather than silently truncate when it can't. New optional fields may be added under version 1; nothing is removed or renamed without a new version.

<Note>
  `earnie scan audit <id>` also has a `--format json` form: the trail is an optional `audit` member, each event carrying its type, time, the actor as recorded at the time, and a frozen set of payload keys a script can branch on.
</Note>

## Policies (Read-Only)

Three read-only commands answer for the policies of one Project, resolved the same way `scan` resolves it:

* `earnie policy list` — the policies attached to the Project (the set that gates its next scan), one line each with slug, action, whether it's enabled, its latest state, and its revision.
* `earnie policy show <slug>` — one policy in full: name, source, module, action, the sentence given to an agent (flagged when stale), the CEL expression, each parameter's effective value, and the Project's latest result for it.
* `earnie policy violations <slug>` — the findings currently violating that policy, one line each with finding ID, verdict, the status of any Policy Approval, component, and file. Paged locally with `--limit` (1–200, default 50) and `--offset`.

There is no way to change a policy from the CLI — that stays in the app.

Every policy carries a `revision`, the `sha256:` digest of what the gate does — the same value a Scan's policy snapshot and `earnie verdict` report, so you can tell whether the policy that blocked a scan is the one in force now. All three commands exit `0` whenever the query succeeds, whatever the policies say; an unknown slug exits `8` with the typed error `policy_not_found`.

## Connecting a Coding Agent (MCP)

A coding agent — Claude Code, Cursor, VS Code, Codex — can talk to Earnie directly over MCP, with one API key. What it can ask for depends on the Earnie tools your deployment offers and the permissions on that key; the agent lists its granted tools when it connects.

Create the key with the **Coding agent (MCP)** preset, which grants read access to projects, policies, findings, and scans, plus the ability to submit a scan — the same permission a CI key holds, so the same key can start a full scan that records findings and moves the project's posture. Triage stays off unless **allow agents to triage findings** is enabled; the audit log attributes each decision to the key.

### Setup

```bash theme={null}
earnie auth login --api-url https://your-earnie.example
earnie mcp setup
```

You don't need to export `EARNIE_API_KEY` for Claude Code, Cursor, VS Code, or Codex — setup writes the stored key into each client's user-level configuration. Earnie detects installed clients from their executables, application paths, and native configuration files, and preselects what it finds. Use `--client detected` or an explicit list (`--client claude,codex`) in scripts and redirected runs — without `--client`, a non-interactive setup stops rather than guessing.

Repository setup resolves the Project the same way `scan` does (`--project`, `EARNIE_PROJECT`, or the Git remote) and needs `policies:read` to fetch the Project's managed policy block before changing any file. Useful flags:

| Flag                         | What it does                                                                                                 |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------ |
| `--dry-run`                  | Prints the exact per-file diff without writing                                                               |
| `--json`                     | Emits one machine-readable result                                                                            |
| `--no-color` (or `NO_COLOR`) | Disables styled output                                                                                       |
| `--global`                   | Installs only the user-level client — no Project, no policy instructions. Can't be combined with `--project` |
| `--no-hooks` / `--hooks`     | Opt out of, or explicitly install/upgrade, the review hooks below                                            |

Setup validates the complete change first, then applies identity, policy instructions, and hooks as one transaction — a write failure restores the previous files.

<Note>
  Earnie owns only the text between its own markers (for example `<!-- earnie:policies:start -->` … `<!-- earnie:policies:end -->`) and, in Cursor's dedicated `earnie.mdc`, the front matter that makes the rule apply to every chat. It leaves every other byte and the file's permissions alone, and stops rather than guessing if it finds duplicate, nested, incomplete, or hand-edited markers.
</Note>

Per client, identity and the managed policy block land in:

| Client      | Identity                       | Repository files                                                                          |
| ----------- | ------------------------------ | ----------------------------------------------------------------------------------------- |
| Claude Code | `~/.claude.json`               | `CLAUDE.md`, review hooks in `.claude/settings.json`                                      |
| Cursor      | `~/.cursor/mcp.json`           | `.cursor/rules/earnie.mdc`, review hooks in `.cursor/hooks.json`                          |
| VS Code     | native user-profile `mcp.json` | `.github/copilot-instructions.md` (no review hook — the VS Code hook contract is Preview) |
| Codex       | `~/.codex/config.toml`         | `AGENTS.md`, review hooks in `.codex/hooks.json`                                          |

<Note>
  Codex project hooks don't run until you review and trust their exact definition with `/hooks` inside Codex — setup never bypasses that trust control.
</Note>

### Review Hooks and Self-Checks

On first repository installation, setup enables project-local end-of-turn review hooks for Claude Code, Cursor, and Codex (VS Code has none yet). When the agent reaches a turn's end, any files it changed during that turn — including documentation-only changes — are sent once to Earnie for review. This is a **Self-check**, not a Scan: it creates no findings and doesn't move the project's posture. Every Self-check is listed under the project's Self-Checks page for 30 days, and the agent gets a deep link to the result. A blocking result gives the agent one correction turn before the next end-of-turn review always ends, reporting whatever findings remain.

For a manual check outside the hook flow:

```bash theme={null}
earnie mcp review --staged
earnie mcp review --diff <base>
earnie mcp review <file> [<file>...]
```

Set `EARNIE_SKIP_REVIEW=1` to record a visible, user-requested skip instead of making a review call.

### Doctor and Uninstall

```bash theme={null}
earnie mcp doctor
# equivalent to:
earnie mcp setup --check
```

Doctor inspects the installation without writing: API URL compatibility, whether `EARNIE_API_KEY` or a stored key is valid, the effective Project, and user-level identity. It calls the server's live MCP `tools/list` to report each tool's visibility, required scope, and absence reason — it never grants a hidden tool. `--global` checks connection and authentication only. Doctor never mutates config, rules, hooks, or credentials.

```bash theme={null}
earnie mcp uninstall
```

Removes leftover Earnie repository MCP servers, managed policy blocks, and owned review-hook handlers, using the same client detection and `--client` selection as setup. It does **not** remove the user-level API URL and key, so other checkouts keep working. `--dry-run` previews every removal, and repeated runs are safe.

## What's Next

Every command here authenticates with an API key. See [API Keys](/en/latest/earnie/administration/api-keys) for how to create one, choose its scopes, and pick the right preset for a pipeline versus a coding agent.

Need help? [Contact our AI assistant](?assistant=open)
