Skip to content

The CLI (leanctl)

leanctl is the LeanSignal command-line client. It authenticates with a personal access token and acts with your own identity and role — what you can do in the LeanSignal app is what you can do here, and nothing more. Actions taken through it appear in the audit log attributed to you, via CLI.

Terminal window
$ leanctl auth login --tenant acme
Resolving tenant "acme"…
Personal access token: ****
Logged in to https://acme-api.eu11.leansignal.io as you@example.com (admin)
$ leanctl demand list
NAME DESCRIPTION CREATED BY AGE
host-metrics node health and disk you@example.com 12d
kubernetes cluster + workloads you@example.com 5d
$ leanctl demand export host-metrics > demands/host-metrics.json

The CLI is open source: github.com/LeanSignal/leansignal-cli.

One-liner for macOS and Linux:

Terminal window
curl -fsSL https://raw.githubusercontent.com/LeanSignal/leansignal-cli/main/scripts/install.sh | sh

It detects your OS and architecture, downloads the matching release, verifies its checksum, and installs to /usr/local/bin — or ~/.local/bin when that is not writable, so it never demands sudo. Options: --version vX.Y.Z, --bin-dir DIR, --no-verify. Review the script before piping it to a shell.

Prefer a manual download? Releases carry leanctl_<version>_<os>_<arch>.tar.gz for darwin and linux, amd64 and arm64, with cosign-signed checksums — see the releases page and the repo README for verification steps, building from source, and shell completion.

To upgrade, repeat the install — it overwrites in place.

  1. In the LeanSignal app, go to Preferences → Access tokens and mint a token. Scopes are read (always granted), write (create and update), and write:delete (delete; implies write). Write scopes need the editor or admin role.
  2. leanctl auth login --tenant <your-tenant> and paste it.

You name the tenant; the regional API endpoint is looked up for you and treated as a cache, never a fact — if the tenant later moves regions, leanctl re-resolves and retries transparently. --api-url pins an endpoint instead (local development, air-gapped setups) and opts that profile out of resolution.

The token is stored at ~/.config/leanctl/config.yaml with mode 0600. There is deliberately no --token flag — a command line is visible to every process on the host and lands in shell history; use the login prompt, --token-stdin, or the LEANCTL_TOKEN environment variable. leanctl auth logout --revoke revokes the token server-side as well as removing it locally.

In CI, skip login entirely — a pinned endpoint keeps CI free of the resolver:

Terminal window
export LEANCTL_TOKEN=lsp_
export LEANCTL_API_URL=https://<tenant>-api.eu11.leansignal.io
leanctl demand import --file demands/host-metrics.json --dry-run

Each login saves its own profile (the command also answers to context, kubectl-style — same thing):

Terminal window
leanctl auth login --tenant acme # saves profile "acme"
leanctl auth login --tenant globex # and "globex"
leanctl profile use globex # switch the default
leanctl demand list --profile acme # or override per command

LEANCTL_PROFILE selects one from the environment. Each profile carries its own token and its own cached endpoint.

LeanSignal stores only demanded telemetry, so every query command has two sides — the same Stored/Available split as the app’s Metrics, Logs, and Traces pages:

default--available
Readsthe central storethe connected agent’s local store
Holdsonly demanded dataeverything the agent collects
Retention30 days~1 day metrics, ~1 hour logs and traces
Answers”what are we keeping?""what could we demand?”

An empty result from the central store is usually a demand gap, not an outage — leanctl says so and hands you the next command to check both sides (leanctl filter list, then the same query with --available).

CommandDoes
authlogin, logout, status, tokens list|create|revoke
profile / contextlist, use, delete, current
demandlist, get, create, update, delete, export, import
dashboardlist, get, apply, delete, versions
agentlist, get, create, update, delete, diagnose, config get|apply
alertlist, get, create, update, delete, pause, resume, mute, unmute, test
channellist, get, create, update, delete, test
syntheticlist, get, create, update, delete, pause, resume, test, results
ruleingestion rules: list, get, create, update, delete, enable, disable
filterdemand set: list, purged, sync, sweep
metricsnames, query, query-range, series, labels, label-values
logsquery, labels, label-values, stats
tracessearch, get, tags
statuswhat this tenant is storing
auditlist (admin)
settingsget, set (admin)
searchfind anything by name

Run leanctl <command> --help for flags and examples.

User management, invitations, and support cases are not here, by design. Those live in the control center and need a real browser session, which a token does not carry — use the LeanSignal app.

-o json prints the server’s own JSON, unreshaped; -o yaml, -o wide (extra columns, including ids), and -o name (bare ids) round out the set, plus --no-headers. Tables are space-padded text — never box-drawing — so awk and cut keep working. Empty-result explanations go to stderr, leaving stdout clean for pipelines. Exit codes are a contract: 0 success, 2 usage, 3 auth, 4 not found, 5 validation, 6 server, 7 unreachable (1 for everything else). Destructive commands prompt, and refuse to run unattended without --yes.

Export and import round-trip a whole demand — dashboards and alert rules included, UUIDs stripped, channels referenced by name — which makes a demand bundle a reviewable artifact:

Terminal window
leanctl demand export host-metrics > demands/host-metrics.json # commit it
leanctl demand import --file demands/host-metrics.json --dry-run # PR check
leanctl demand import --file demands/host-metrics.json # on merge

--dry-run validates and reports without writing. Missing notification channels are warnings, not errors, and any rule left without a channel is imported paused.

agent config reaches the collector configuration on the agent host itself, over the agent’s control stream — admin role, connected agent required:

Terminal window
leanctl agent config get my-agent # what sources exist
leanctl agent config get my-agent --path /etc/leansignal-agent/config.yaml > c.yaml
$EDITOR c.yaml
leanctl agent config apply my-agent --file c.yaml

The agent validates the write — YAML parse plus a full collector dry-run — and applies it only if it passes; a rejected config changes nothing on the host. See Agent configuration for how applying works and which installs are editable.

Was this page helpful?