CLI Quick Start
The csy command-line interface is a first-class, supported client — not a developer scaffold. It authenticates against the same schemes the browser uses, drives the same server-side UI session the browser drives, and runs declarative scenarios for CI. This page walks you from a fresh install to rendering a view in your terminal and importing a demo tenant.
For the full command reference, see the CLI client guide. For the platform’s first run-through, see the Quick Start.
What you will do
Section titled “What you will do”- Install the CLI and point it at an endpoint.
- Authenticate — interactively (OIDC) or with an API key for automation.
- Open
csy uiand render a view in the terminal. - Import a demo tenant from YAML.
Prerequisites
Section titled “Prerequisites”- A Consystence endpoint you can reach — a cloud cell or a site server.
- Credentials for that endpoint: a member account (interactive login) or an API key (automation).
Install
Section titled “Install”The CLI is a single .NET 10 binary named csy. During the beta, build it from the monorepo (below). Tagged releases will publish single-file binaries for Windows and Linux (csy-<version>-linux-x64, csy-<version>-win-x64.exe) plus a cross-platform .NET global tool (dotnet tool install --global Consystence.Cli, also invoked as csy) that covers macOS — the first packaged release has not shipped yet. For OS-specific steps, follow the installation guide.
To build from the monorepo:
# From the repository rootdotnet build backend/Cli/Consystence.Cli -c Release
# Run a command directly from the projectdotnet run --project backend/Cli/Consystence.Cli -- --helpRunning csy with no arguments prints a branded splash; csy --help lists the command groups: account, ai, auth, config, context, controller, electrical, instance, org, provision, server, site, status, tenant, trend-import, and ui. Live operational reads — current tag values, historian trends, active alarms, the command audit — live under the instance and site groups; see the CLI reference.
Point the CLI at an endpoint
Section titled “Point the CLI at an endpoint”The CLI works in contexts. A context is one endpoint — its server URL, its type (cell, site, edge, or account), an optional tenant slug, and its own stored credential. The auth-mode is derived from the type, so you never pick a login flow by hand.
# Define a context for a cloud cellcsy context add demo \ --server https://acme.consystence.com \ --type cell \ --tenant acme
# Make it currentcsy context use demo
# Inspect what is definedcsy context listcsy context currentAuthenticate
Section titled “Authenticate”Interactive login (OIDC → Bearer)
Section titled “Interactive login (OIDC → Bearer)”For a cell context, csy auth login runs OIDC against Entra External ID and stores a Bearer token. With a browser present it uses an authorization-code + PKCE loopback flow; for headless hosts add --device for the OIDC device-authorization grant (RFC 8628).
# Headless / SSH — enter the code at the displayed URLcsy auth login --deviceInitiating device code flow...
Enter code: ABCD-EFGHAt: https://microsoft.com/devicelogin
Waiting for authentication...Login successful (context 'demo').Token expires at: 2026-06-29 11:42:00ZThe verification URL is taken verbatim from the identity provider’s device-authorization response — for the Consystence CIAM tenant (Entra External ID) that is Microsoft’s device-login page, not a consystence.com address.
The refresh token is stored in your OS keyring (Windows Credential Manager / macOS Keychain / libsecret), with a plaintext-file fallback only where no keyring exists. The short-lived access token is refreshed automatically against the identity provider — no re-login.
For a site context the same command takes the site-PIN path (the LocallyIssuedJwt scheme), which needs an email and PIN:
Check and decode your session at any time:
csy auth status # mechanism + credential source (no server call; never prints the credential)csy auth whoami # decode the stored token locally (oid, tid, preferred_username)csy auth logout # clear this context's credential, keep the context definedNon-interactive (API key)
Section titled “Non-interactive (API key)”For CI, scripts, and partner automation, use a tenant API key. Keys are minted at POST /api/admin/api-keys (owner/admin), shown in plaintext exactly once, and prefixed csk_. See API keys.
The key is sent as the X-Api-Key header; the server’s MultiAuth selector routes it to the ApiKey scheme. Provide it three ways, in precedence order:
# 1. Explicit flag (wins over everything — an operator overriding CI)csy --token csk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx auth status
# 2. Environment variable (typical for CI)export CONSYSTENCE_TOKEN=csk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxcsy auth status
# 3. Stored in the context configAn API key is the credential itself — there is no refresh, and it is never printed back by auth status.
Render a view in the terminal
Section titled “Render a view in the terminal”csy ui is the CLI renderer: it consumes the server’s semantic UI tree over the wire format — a peer of the browser’s wire renderer, which consumes the same L1/L2 protocol on the same /hubs/ui-wire hub — so a view renders as text instead of DOM. It connects over SignalR to /hubs/ui-wire with the credential the CLI already resolved and drives the same server-side UI session actor (keyed by sessionId) the browser drives. For the architecture, see the multi-renderer pipeline.
flowchart LR CLI["csy ui<br/>(terminal)"] -->|"SignalR /hubs/ui-wire"| Hub["UI wire hub"] Hub --> Session["UI session actor<br/>(keyed by sessionId)"] Session -->|"wire format (L1 render, L2 patch)"| Hub Hub -->|"text patches"| CLI
Open the REPL, optionally with an initial route:
csy ui admin/api-keysInside the REPL these verbs are available (type help to list them):
| Command | Action |
|---|---|
goto <route> | Open a view (e.g. goto admin/api-keys) |
show | Re-render the current view |
inspect | Dump the semantic tree (ids, pointIds, types) |
actions | List invocable actions on the current view |
action <n|id> | Invoke an action by index or actionId |
chat <message> | Message the assistant (needs a chat view, e.g. goto assistant/chat) |
refresh | Poll the server for changes |
wait [seconds] | Watch for changes (default 30 s) |
wait until <p> | Block until a predicate holds: rows <pointId> <n> | row-absent <id> | row-present <id> | view <id> |
quit / exit | Leave the REPL |
For CI, run a view non-interactively from a declarative YAML scenario instead of the REPL:
csy ui --script scenario.csy.yaml --no-colorScript mode is single-shot and deterministic, and exits with a meaningful code: 0 = all steps passed, 1 = a step failed, 2 = a scenario or connect error. This is the surface that replaces browser click-throughs for integration testing.
Import a demo tenant
Section titled “Import a demo tenant”A tenant configuration (org, sites, devices, tags) is portable as a single YAML file. Importing it targets an existing organisation; the org is part of the route and you must be its owner or admin.
First select the org (or pass --org on each call):
csy tenant select acmecsy tenant currentValidate the file locally before touching the server — --dry-run parses and reports the contents with no server call:
csy tenant import tenant.yaml --dry-runParsed: org=acme, 2 site(s), 14 device(s)Dry run: validation passed, no changes made.Then import for real (use --force to overwrite an existing tenant, and --org to override the selected org):
csy tenant import tenant.yaml --org acmeParsed: org=acme, 2 site(s), 14 device(s)Import successful.The server rejects a file whose org.slug does not match the route, so a mis-targeted import fails cleanly rather than writing to the wrong org. To produce a YAML file from a live site, use the inverse:
csy tenant export --site SITE-01 --org acme --output tenant.yamlNext steps
Section titled “Next steps”- CLI client guide — full command reference and scripting patterns.
- Quick Start — the end-to-end platform walkthrough.
- Authentication — the MultiAuth model behind
auth login. - Cloud onboarding — provision an organisation and get your first API key.