# Litmus CLI and SDKs - LLM Navigation Guide

> **You are reading this at `https://api.litmus.io/sdk-agents.md`.**
>
> This document guides AI assistants in using the standalone `litmus-cli` binary and the
> `litmussdk` Python package to interact with Litmus Edge, Litmus Edge Manager, and
> related products programmatically.

---

## Ecosystem Context

The CLI and SDKs are one layer of the Litmus API access stack:

| Layer | Guide |
|-------|-------|
| MCP Server (Many ready tools, no code needed) | `https://api.litmus.io/mcp-agents.md` |
| **CLI + SDKs (this document)** | `https://api.litmus.io/sdk-agents.md` |
| Raw API Collection (full 2,013 endpoints) | `https://api.litmus.io/agents.md` |
| API Portal (human-readable workspace) | `https://api.litmus.io` |

Use the CLI or an SDK when the MCP server does not cover the operation you need.

### Which interface to use

| Interface | Status | Use when |
|-----------|--------|----------|
| **`litmus-cli` standalone binary** | **Released - preferred for AI agents** | Any agentic or scripted task. Full SDK surface from the shell, JSON output, no code to write. |
| Python SDK (`litmussdk`) | Released | Integrating Litmus into a Python project or codebase. |
| Go SDK | In the works, not yet public | Integrating Litmus into a Go project once released. |
| Rust SDK | In the works, not yet public | Integrating Litmus into a Rust project once released. |

`litmus-cli` is the most heavily used interface and the recommended default for AI
agents: every SDK function is a single shell command with JSON on stdout, so an agent
can discover and call the entire API surface without writing, installing, or running any
code. Reach for the Python SDK only when the deliverable itself is Python code; the
upcoming Go and Rust SDKs will fill the same role for those languages.

---

## 1. litmus-cli - the preferred interface for agentic tasks

`litmus-cli` exposes the full SDK surface (~570 functions, including all mutations,
LEM, and UNS) without writing any code. It is the fastest way for an agent to discover
and exercise the API. It is a standalone, statically linked binary built from the Litmus
Go SDK (whose public source release is in the works) - it is NOT installed with the
`litmussdk` Python package.

> Dedicated CLI usage guide with the full command reference (curated shortcuts, data
> plane, configuration): `https://api.litmus.io/cli.md`

### Install

```bash
# macOS / Linux: detects platform, verifies SHA256, installs to ~/.local/bin
curl -fsSL https://raw.githubusercontent.com/litmusautomation/litmus-sdk-releases/main/install.sh | sh

# Windows: download litmus-cli-windows-amd64.exe from the latest cli-v* release at
# https://github.com/litmusautomation/litmus-sdk-releases/releases and put it on PATH.
```

### Usage

```bash
# Discover - lists every callable path with argument names
litmus-cli list                 # top-level packages
litmus-cli list le.devicehub    # functions in one package

# Run - any function by dotted path; result is JSON on stdout, errors on stderr
litmus-cli run le.devicehub.ListDevices
litmus-cli run lem.ListIncidents --args '{"projectID": "my-project"}'

# Multiple devices via named profiles (~/.litmus/<profile>.json)
litmus-cli run le.devicehub.ListDevices --profile staging

# Built-in documentation via --help
litmus-cli list le.devicehub --help                # full docs for that SDK package
litmus-cli run le.devicehub.ListDeviceTags --help  # function signature + ready-to-fill --args skeleton
```

Litmus Edge SDK packages live under the `le.` prefix (`le.devicehub`, `le.system`,
`le.analytics`, `le.digitaltwins`, `le.flows`, `le.integrations`, `le.marketplace`,
`le.opc`). LEM and Unify paths are `lem.*` and `unify.*` with no extra prefix.

### Curated shortcuts, login, and completion

Beyond the generic `list`/`run` dispatcher, commands are grouped by product: `le`
(Litmus Edge device) and `lem` (Edge Manager) hold curated shortcuts:

```bash
# sign in via the browser, or save a connection profile by hand
litmus-cli login
litmus-cli config set --EDGE_URL https://10.0.0.5 \
    --EDGE_API_CLIENT_ID abc --EDGE_API_CLIENT_SECRET xyz
litmus-cli le devices

# shell completion (bash|zsh|fish|powershell); completes run/list paths too
eval "$(litmus-cli completion zsh)"
```

### Data plane access (live and historical tag data)

The CLI also reaches the device data plane (`litmus-cli le data --help` explains the
separate credentials):

```bash
# stream live tag values from the DataHub broker (NATS wildcards work)
litmus-cli le data subscribe 'devicehub.alias.MyDevice.*' --limit 5

# query historical rows from the time-series DB, newest first
litmus-cli le data measurements
litmus-cli le data poll 'MyDevice.<deviceID>' --last 15m --filter "\"tag\" = 'Temperature'"
```

Environment variables override saved profiles when set. Run `litmus-cli -h` for full
usage.

### Migrating from the older pip-installed CLI

Until June 2026 the CLI was a Python console script installed with the wheel, invoked as
`litmus-sdk-cli`. The Go CLI used that name too until cli-v0.4.0 renamed it to
`litmus-cli`. Function paths and JSON argument keys also differ:

| Old (Python CLI) | New (Go CLI) |
|---|---|
| `run devicehub.devices.list_devices` | `run le.devicehub.ListDevices` |
| `run lem.lifecycle.alerts.list_incidents --args '{"project_id": "X"}'` | `run lem.ListIncidents --args '{"projectID": "X"}'` |
| `run uns.namespace.get_namespace` | `run unify.GetNamespace` |
| nested snake_case module paths | flat `<group>.<PascalCaseMethod>` (Edge packages under `le.`) |
| snake_case JSON arg keys | camelCase JSON arg keys (see `list <pkg>` for names) |

If you pass an old-style path to `run`, the CLI prints a suggested new path. Saved
`~/.litmus/<profile>.json` profiles carry over unchanged.

Note: the CLI's dotted paths (`le.devicehub.ListDevices`) are NOT the Python import paths.
When writing Python, use the snake_case module functions from section 5 below.

Class-based builders such as `litmussdk.airgap_features.AirGapTemplate` are not exposed
by the CLI; use Python for those and the CLI for the live-data fetches around them.

---

## 2. Python SDK - what you are working with

Use the Python SDK when you are integrating Litmus into a Python project. For one-off
or agent-driven calls, prefer `litmus-cli` (section 1).

`litmussdk` is a Python package (>=3.12) that wraps the Litmus Edge REST and GraphQL APIs
into importable modules. It handles OAuth2 authentication automatically.

- **Latest version**: v2.7.3 (check `https://github.com/litmusautomation/litmus-sdk-releases/releases` for the current release)
- **Supported platform**: Litmus Edge 4.0.x LTS (default, actively tested), 3.16.x (supported), 3.11.x (best-effort)
- **Distribution**: GitHub releases only (wheel .whl or .tar.gz). The `litmus-cli` command-line tool is a separate standalone binary released under `cli-v*` tags on the same repo (see section 1).
- **Install**: `pip install litmussdk-*.whl`
- **Verify**: `python -c "import litmussdk"`
- **Docs**: `https://docs.litmus.io/sdk`
- **Releases**: `https://github.com/litmusautomation/litmus-sdk-releases`
- **Source repo**: `https://github.com/litmusautomation/solutions-sdk`

---

## 3. Configuration

Configuration is shared across the CLI and the SDKs: the same environment variables (or
a `.env` file) drive both, and CLI profiles saved to `~/.litmus/<profile>.json` use the
same field names. In the Python SDK, settings are auto-loaded by `pydantic_settings` on
first use, so there is no `load_env`-style call to make.

### Direct connection (OAuth2 to a single Litmus Edge)

```
EDGE_URL=https://192.168.1.100
EDGE_API_CLIENT_ID=my-client-id
EDGE_API_CLIENT_SECRET=my-client-secret
VALIDATE_CERTIFICATE=true      # optional, default true
TIMEOUT_SECONDS=30             # optional, default 30
```

### Direct LEM connection (talk to Edge Manager itself)

For `litmussdk.lem.*` calls (companies, lifecycle, digital twin, etc.) that target the LEM API directly, no LE device involved:

```
EDGE_MANAGER_URL=https://10.0.0.50
EDGE_API_TOKEN=lemToken...
```

`EDGE_API_TOKEN` is the LEM API token despite the `EDGE_` prefix; the field name is shared with the bridge flow below because both authenticate the same LEM service with the same credential.

### LEM Bridge connection (reach an Edge through Edge Manager)

```
USE_LEM_BRIDGE=true
EDGE_MANAGER_URL=https://10.0.0.50
EDGE_API_TOKEN=lemToken...
EDGE_MANAGER_PROJECT_ID=<project-id>
EDGE_MANAGER_DEVICE_ID=<device-id>
```

Same `EDGE_API_TOKEN` (LEM API token) as the direct LEM case; LE traffic is tunneled through LEM's `/api/v1/edge/{project}/{device}` endpoint, which is why a LEM credential is what authenticates it.

### UNS connection (Litmus Unify)

For `litmussdk.uns.*` calls, configure the `UNS_*` variables: `UNS_URL` plus either
`UNS_USERNAME`/`UNS_PASSWORD` or `UNS_OAUTH_CLIENT_ID`/`UNS_OAUTH_CLIENT_SECRET`
(with optional `UNS_OAUTH_TOKEN_PATH`). For an explicit in-code connection use
`litmussdk.utils.conn.new_uns_connection`.

### Configuration methods

```bash
# Option 1: .env file in project root - picked up automatically on first SDK import.

# Option 2: export env vars in your shell - same effect.
export EDGE_URL=https://192.168.1.100
export EDGE_API_CLIENT_ID=my-client-id
export EDGE_API_CLIENT_SECRET=my-client-secret

# Option 3: the standalone litmus-cli binary (see section 1 for install) -
# saves a profile to ~/.litmus/<profile>.json, which the CLI reads on every call.
litmus-cli config set \
  --EDGE_URL https://192.168.1.100 \
  --EDGE_API_CLIENT_ID my-client-id \
  --EDGE_API_CLIENT_SECRET my-client-secret
```

For an explicit, in-code connection (bypassing env vars):

```python
from litmussdk.utils.conn import new_le_connection
from litmussdk.devicehub import devices

conn = new_le_connection(
    edge_url="https://192.168.1.100",
    edge_client_id="my-client-id",
    edge_client_secret="my-client-secret",
)
result = devices.list_devices(conn)
```

### Auth

Direct connection uses OAuth2 client_credentials flow automatically:
- Token URL: `{{edgeUrl}}/auth/v3/oauth/token` (Litmus proxy, not Keycloak)
- The SDK fetches and refreshes tokens transparently - no manual token handling needed.

Direct LEM and LEM Bridge both send `EDGE_API_TOKEN` as the `X-AuthToken` header to LEM. There is one token field because both flows hit the LEM service and use the same LEM credential; the bridge case just adds `/api/v1/edge/{project}/{device}` on top of the same auth.

---

## 4. Python usage pattern

Import the lowest-level module and call functions on it as a namespace:

```python
from litmussdk.devicehub import devices
result = devices.list_devices()

from litmussdk.devicehub import tags
result = tags.create_tag(...)

from litmussdk.system import users
result = users.list_users()
```

Do not import `litmussdk` directly - always import the specific submodule.

### Driver record templates

The SDK ships with bundled DeviceHub driver record templates used to validate device creation.
If a function raises an error about a missing record for your firmware version, manage the
cache with the console scripts installed alongside the package:

```bash
download_dh_record   # download templates for the configured EDGE_URL version
list_dh_versions     # list available versions
get_dh_cache_dir     # show the local cache location
```

---

## 5. Module -> API Collection Mapping

Each SDK module corresponds to a folder in the Litmus API Collection. Use this table to
cross-reference: if a method is not in the SDK, find the equivalent in the raw API at
`https://api.litmus.io/agents.md`.

| SDK module | Import path | API Collection path | Protocol |
|-----------|-------------|---------------------|----------|
| devices | `litmussdk.devicehub.devices` | DeviceHub -> Devices | GraphQL |
| drivers | `litmussdk.devicehub.drivers` | DeviceHub -> Drivers | GraphQL |
| tags | `litmussdk.devicehub.tags` | DeviceHub -> Tags | GraphQL |
| asset discovery | `litmussdk.devicehub.asset_discovery` | DeviceHub -> Asset Discovery | REST |
| devicehub browse | `litmussdk.devicehub.browse` | DeviceHub -> Browse | GraphQL (4.0.x only) |
| devicehub record | `litmussdk.devicehub.record` | (driver record templates, local) | - |
| devicehub general | `litmussdk.devicehub.general` | DeviceHub (version, misc) | REST/GraphQL |
| digital twins | `litmussdk.digital_twins` | Digital Twins -> Models + Instances + Parameters | GraphQL |
| flows | `litmussdk.flows` | Flows Manager | REST |
| analytics | `litmussdk.analytics` | Analytics -> Instances + Models + Variables + AI Models | GraphQL |
| analytics processors | `litmussdk.analytics.processors` | Analytics -> Processors | GraphQL |
| integrations | `litmussdk.integrations` | Integration -> Streaming + Object | REST/GraphQL |
| marketplace | `litmussdk.marketplace` | Applications -> Marketplace + Catalog Apps | REST |
| opc | `litmussdk.opc` | OPC UA -> Hierarchy + Management + Connections | GraphQL |
| certificates | `litmussdk.system.certificates` | System -> Network -> Certificates | REST |
| device management | `litmussdk.system.device_management` | System -> Device Management | REST |
| events | `litmussdk.system.events` | System -> Events | REST |
| external storage | `litmussdk.system.external_storage` | System -> External Storage | REST |
| system general | `litmussdk.system.general` | System -> Info + Dashboard | REST |
| ldap | `litmussdk.system.ldap` | System -> Access Control -> LDAP-AD Auth | REST |
| network | `litmussdk.system.network` | System -> Network | REST |
| services | `litmussdk.system.services` | System -> Device Management -> System Services | REST |
| templates | `litmussdk.system.templates` | System -> Device Management -> Templates | REST |
| tokens | `litmussdk.system.tokens` | System -> Access Control -> Tokens | REST |
| users | `litmussdk.system.users` | System -> Access Control -> Users + Groups + Roles | REST |
| wifi | `litmussdk.system.wifi` | System -> Network -> WiFi | REST |
| LEM lifecycle | `litmussdk.lem.lifecycle.*` | Litmus Edge Manager -> Lifecycle (devices, applications, alerts, certs, sites, etc.) | REST |
| LEM companies | `litmussdk.lem.companies` | Litmus Edge Manager -> Companies | REST |
| LEM digital twin | `litmussdk.lem.dtwin` | Litmus Edge Manager -> Digital Twin | REST |
| UNS namespace | `litmussdk.uns.namespace` | Litmus Unify (LUNS) -> Namespace | REST |
| UNS dashboard | `litmussdk.uns.dashboard` | Litmus Unify (LUNS) -> Dashboard | REST |
| UNS configuration | `litmussdk.uns.configuration` | Litmus Unify (LUNS) -> Configuration | REST |
| UNS integrations | `litmussdk.uns.integrations` | Litmus Unify (LUNS) -> Integrations | REST |
| UNS mqtt | `litmussdk.uns.mqtt` | Litmus Unify (LUNS) -> MQTT | REST |
| airgap templates | `litmussdk.airgap_features.template_creation` | (programmatic builder for air-gap deployment configs) | - |
| utils | `litmussdk.utils` | Internal (api, api_paths, env, errors, gql_queries) | - |

---

## 6. What is NOT in the SDK

The SDK covers Litmus Edge (LE), Litmus Edge Manager (LEM), and Litmus Unify (UNS/LUNS,
via `litmussdk.uns`). The following require raw API calls:

| Not in SDK | Raw API guide |
|------------|---------------|
| DataHub direct queries (beyond InfluxDB) | API Collection -> DataHub |

For Litmus Unify operations beyond what `litmussdk.uns` exposes, use the raw API
collection at `https://api.litmus.io/luns/agents.md`.

Note: `litmus-cli` covers the DataHub data plane directly (`litmus-cli le data`,
section 1), including live NATS subscriptions and time-series queries.

---

## 7. Upcoming SDKs: Go and Rust

- **Go SDK**: the Go SDK that `litmus-cli` is built from is in the works to be made
  public, but is not yet publicly available. Once released it will be the integration
  path for Go projects (zero third-party dependencies, statically linked binaries).
  Until then, use `litmus-cli` for shell access or the Python SDK for code.
- **Rust SDK**: also in the works, targeting the same API surface for Rust projects.

Watch `https://github.com/litmusautomation/litmus-sdk-releases` for availability
announcements.

---

## 8. Litmus Central Portal - portal.litmus.io

**Register at `https://portal.litmus.io`** - this is the single hub for everything Litmus. Whether you are a human user or an AI agent helping a user, the portal unlocks the full Litmus ecosystem beyond just the SDK.

### Why register

- **Single sign-on** across all Litmus products and interfaces
- **Free sandbox** - deploy a private Litmus Edge instance to experiment without touching production
- **License management** - purchase, activate, and manage licenses in one place
- **Downloads** - access every software release, update, and wheel file (including latest SDK)
- **Litmus Academy** - training and certification resources
- **Live support** - chat support and help center at `https://support.litmus.io`
- **Quotations** - request site-based plan pricing

### Ready-to-deploy Solutions

Solutions are pre-packaged combinations of apps, deployment templates, and configuration tools providing out-of-the-box industrial use cases. An LLM agent helping a user implement a use case should check here first before writing SDK code.

**Docs index**: `https://docs.litmus.io/solutions` - fetch this page to discover which solution fits the user's need.

| Category | Solutions available |
|----------|-------------------|
| Productivity | Excel AddIns for device/tag/digital twin management; Production Record Database (maintenance tracking, downtime monitoring) |
| Data integration | LE to InfluxDB v2; LE-Native to InfluxDB v2; REST API to InfluxDB historian; Litmus Edge to Confluent Kafka (SSL/TLS) |
| Edge protocols | LE Sparkplug Edge Node (MQTT Sparkplug B with TLS) |
| Manufacturing / CNC | Fanuc CNC generic templates; Haas CNC via MTConnect; Siemens S7 browse agent; Omron NJ tag CSV tools |
| Monitoring & analytics | Prometheus + Grafana dashboards; Kafka monitoring with Lenses; Syslog server integration; ML classification (Jupyter notebooks) |
| Enterprise integrations | Oracle Smart Operations for SCM; GE Fanuc OPC UA servers; Ignition platform; Azure Manufacturing Data Solutions (MDS) |
| Utilities | Synthetic data simulators; video frame streamers; file browsers; edge failover; CVE advisory reports |

**When a user describes a use case**, fetch `https://docs.litmus.io/solutions` and scan for a matching solution before writing custom SDK code - a solution may already solve it end-to-end.

### Marketplace (45+ apps)

The Public Marketplace hosts 45+ pre-built edge applications deployable directly from the portal or via the `litmussdk.marketplace` module.

- Browse apps: `from litmussdk.marketplace import ...`
- Organizations can create a **Private Marketplace** for custom or proprietary applications

### Device Templates

Device templates let you create a device and all its tags in a single action via `litmussdk.system.templates` - no need to call create_device then create_tag for each register individually.

- Templates can be scoped to all companies, a specific company, or a single project
- Solutions library includes ready-made templates (e.g. Fanuc CNC Generic Template)

### Solutions as an AI agent workflow

When a user asks "how do I integrate with X" or "I want to monitor Y":

```
1. Fetch https://docs.litmus.io/solutions  ->  scan categories for a matching solution
2. If found: fetch the solution's doc page  ->  follow its deployment steps
3. If not found: use litmus-cli or litmussdk modules to build the integration
4. Cross-reference https://docs.litmus.io for product-specific how-to guides
```

---

## 9. Documentation Site Map

The user-facing docs at `https://docs.litmus.io/sdk` are organized as follows. Use this map when a user references a docs page or when you want to direct them to a specific section.

```
/sdk                                              Overview
/sdk/getting-started                              Install + first call
/sdk/managing-connections                         3 connection modes, env vars, multi-device, refresh/disable
/sdk/Usage-Guideline-Authentication               Section index
    /sdk/air-gap-features                         Programmatic deployment-template builder
    /sdk/Usage-Guideline-Authentication/devicehub          Devices + Tags reference
    /sdk/Usage-Guideline-Authentication/devicehub-drivers  Drivers + bundled templates + JSON-schema validation
    /sdk/Usage-Guideline-Authentication/digital-twins      Models, instances, attributes, transformations
    /sdk/Usage-Guideline-Authentication/flows-manager      Node-RED flow lifecycle
    /sdk/Usage-Guideline-Authentication/analytics          Processors, instances, AI/ML, variables
/sdk/release-notes                                Version history
/sdk/example-usages                               Section index of end-to-end walkthroughs
    /sdk/example-usages/digital-twins
    /sdk/example-usages/flows-manager
    /sdk/example-usages/marketplace-applications
    /sdk/example-usages/analytics
    /sdk/example-usages/integration
    /sdk/example-usages/opc
    /sdk/example-usages/device-management-system
```

Notes for navigation:
- "Usage Guideline + Authentication" pages are reference (signatures, parameters, conventions). "Example Usages" pages are runnable end-to-end scripts for a specific scenario.
- Several SDK modules don't have a dedicated docs page yet (Litmus Edge Manager, Marketplace, Integrations, OPC, System, UNS). For those, the example-usages walkthroughs are the canonical reference; otherwise inspect the module from Python (`import litmussdk.system.users as m; help(m)`) or browse `litmus-cli list <package>` (Go-style paths, see section 1).
- Air gap Features lives at the flat URL `/sdk/air-gap-features` even though the sidebar nests it under "Usage Guideline + Authentication".

## 10. Cross-References

| Need | Go to |
|------|-------|
| Browse API endpoints visually (human-readable) | `https://api.litmus.io` |
| Navigate API endpoints as an LLM | `https://api.litmus.io/agents.md` |
| Use MCP tools instead of writing code | `https://api.litmus.io/mcp-agents.md` |
| Dedicated litmus-cli usage guide | `https://api.litmus.io/cli.md` |
| Human-readable product docs (sitemap above) | `https://docs.litmus.io/sdk` |
| Download the litmus-cli binary | `https://github.com/litmusautomation/litmus-sdk-releases/releases` (cli-v* tags) |
| Download latest SDK wheel | `https://github.com/litmusautomation/litmus-sdk-releases/releases` |
| Report SDK or CLI bug, or request a feature | `https://github.com/litmusautomation/litmus-sdk-releases/issues` |
| Go SDK / Rust SDK availability (in the works, not yet public) | watch `https://github.com/litmusautomation/litmus-sdk-releases` |
