# Run Lessly from a terminal

`lessly` is the command-line interface to the platform: one binary, one login, one configuration file. It exists so the operations the platform exposes can be scripted from a terminal or from CI.

## Install

`@lessly/cli` is published under the `@lessly` npm scope, which is not on public npm yet — point the scope at the Lessly package registry in an `.npmrc` first, then install globally:

```bash
npm i -g @lessly/cli
```

## Sign in

Two ways in, depending on whether a person is present.

**A person at a terminal:**

```bash
lessly auth login
```

This starts a device authorization flow: the CLI prints a short user code and a verification URL, you approve the request in a browser, and the CLI picks up the resulting token.

**An agent or a CI job** passes a product-scoped token instead, which needs no browser and no interaction:

```bash
lessly auth login --token "$LESSLY_TOKEN"
```

The token is then sent on every call. Which product a command acts on is decided by the platform, not by the CLI: a product-scoped token pins its product, and otherwise you choose one with `lessly product select`.

## Run a command

Commands follow the namespaces of the operations themselves:

```text
lessly <namespace> <resource> <action> [flags]
```

For example:

```bash
lessly organization product list
```

Flags come from the operation's own input schema, so each command accepts exactly the parameters that operation takes.

| Convention | What it means |
|---|---|
| Output | Human-readable tables by default; `--json`, or `-o json\|yaml\|table`, for machine consumption. |
| Flag placement | Connection flags such as `--profile` and `--refresh` go before the command; behaviour flags such as `-o`, `--json`, `--input`, `--yes` go after it. |
| Confirmation | Operations that change something ask before proceeding. `--yes` (or `--force`) skips the prompt; without it, a non-interactive shell fails immediately rather than hanging. |

## Branch a script on the exit code

Exit codes are grouped by class, so a script can tell a bad password from a missing product:

| Code | Meaning |
| --- | --- |
| 0 | Success. |
| 1 | Generic failure. |
| 2 | Validation error. |
| 3 | Authentication or token problem. |
| 4 | Not found, or forbidden. |

## Why the command tree matches the agent's tools

The CLI is a rendering of the same operation catalog that agents see over MCP, so the two surfaces stay in step: anything an agent can call, the CLI can run. On startup it asks the platform which operations the current identity and the current product have, and builds its command tree from the answer. Operations added on the platform show up in the CLI without a CLI upgrade.

## Next steps

- [Create an API key](/interfaces/api-and-keys): a long-lived credential pinned to one product, for scripts and CI.
- [Switch the active product](/products/products): `lessly product select`, and what selection settles.
- [Connect an agent instead](/interfaces/mcp): the same catalog over MCP.
