Skip to content

Reference

CLI

Every command and option of the thinger CLI, plus how to install it, sign in, use profiles, script it with JSON output and run its MCP server.

Reference14 min read

The thinger command-line interface works with a Thinger.io server from your terminal: devices, products, Data Buckets and dashboard apps. It also runs an MCP server, so an AI client can use your account through the CLI's sign-in. The command reference on this page is generated from the CLI itself.

  • Install: Install, on this page (@thinger-io/cli-core comes with it). To use its MCP server from an AI client, follow Connect an AI agent.
  • Changelog: CLI changelog: every release, with what it adds, changes and fixes.

Versions 0.x

While the CLI is in 0.x versions, commands and options can still change between minor versions. Check the changelog before you upgrade scripts that depend on it.

Install ​

The CLI needs Node.js 20 or later. Install it globally from npm:

bash
npm install -g @thinger-io/cli

Check the installed version:

bash
thinger --version

You can also run any command without installing it, with npx -y @thinger-io/cli <command>.

Sign in ​

thinger login signs in to a server and stores the session in a profile. Without options it asks for the sign-in method and the server. YOUR_SERVER is iot.thinger.io on the free Cloud account, or your own domain on a private instance. A bare host means HTTPS; give a full URL (http://… or a custom port) for anything else.

MethodHowWhat the profile keeps
Username and passwordthinger login, then choose Username and password. The password is always asked interactively.An access token named Thinger CLI, created in your account with full permissions. thinger logout revokes it.
Tokenthinger login --server YOUR_SERVER --username YOUR_USER --token YOUR_TOKEN. Works without a terminal, for scripts and CI.The access token you gave. Here YOUR_TOKEN is an access token of your account.
OAuththinger login --oauth --client-id <id>. Opens the browser (OAuth device flow). Needs an OAuth client registered on the server.The OAuth access and refresh tokens.

When a profile is active, thinger login signs in again on that same profile. To add another server, use thinger profile add.

thinger logout forgets the current profile and revokes the token the CLI created at sign-in; --keep-token keeps it on the server, and --all forgets every profile.

Self-signed certificates are accepted only for localhost and 127.0.0.1, or when THINGER_INSECURE=1 is set.

Profiles ​

A profile is one server and one account. Use profiles to work with several servers or accounts:

bash
thinger profile add staging --server YOUR_SERVER --username YOUR_USER --token YOUR_TOKEN
thinger profile list
thinger profile use staging
thinger device list --profile production

The CLI picks the profile in this order:

  1. The --profile <name> option of the command.
  2. The THINGER_PROFILE environment variable.
  3. THINGER_TOKEN and THINGER_SERVER, when both are set (see Environment variables).
  4. The default profile, set with thinger profile use. The first profile you create becomes the default.

Environment variables ​

VariableEffect
THINGER_TOKENAccess token to use instead of the saved profiles. Set it together with THINGER_SERVER. The token must be a JWT access token: the CLI reads the username from it.
THINGER_SERVERServer for THINGER_TOKEN: a host, or a URL for HTTP or a custom port. Setting THINGER_TOKEN without it is an error.
THINGER_PROFILEProfile to use when the command has no --profile.
THINGER_INSECURESet it to 1 to accept self-signed certificates on any host. Any other value is ignored.

THINGER_TOKEN and THINGER_SERVER take precedence over the saved default profile, but not over a profile you name with --profile or THINGER_PROFILE. They are the usual way to run the CLI in CI:

bash
THINGER_SERVER=YOUR_SERVER THINGER_TOKEN=YOUR_TOKEN thinger device list --json

JSON output ​

Commands that take -j, --json print a JSON envelope on standard output instead of tables and messages, so scripts and agents can parse the result. login, logout and mcp do not take it.

On success, data holds the result. For example, thinger device set-product YOUR_DEVICE "" --json (which removes the device from its product) prints:

json
{
  "ok": true,
  "data": { "device": "YOUR_DEVICE", "product": null }
}

On failure, the envelope carries the error message and a code:

json
{
  "ok": false,
  "error": {
    "message": "Unauthorized. Your token may have expired. Please reconfigure.",
    "code": "unauthorized"
  }
}
codeMeaning
unauthorizedThe token is missing, expired or not valid for the server (HTTP 401), or it is not allowed to do this (HTTP 403, Forbidden).
not_foundThe device, product, bucket or other resource does not exist.
already_existsA resource with that ID already exists.
input_errorAn argument or option is not valid.
not_configuredThere is no profile: run thinger login.
needs_confirmA destructive command needs --yes in JSON mode or when there is no terminal to confirm it.
server_errorThe server answered with an error.
network_errorThe server could not be reached.
timeoutThe server did not answer in time.
errorAny other error.

The exit status is 0 on success and 1 on error.

Configuration file ​

Profiles are stored in ~/.config/thinger-cli/config.json in your home folder, on macOS, Linux and Windows alike. The folder is readable only by your user and the file is written with owner-only permissions, because it contains access tokens. Do not share it or commit it.

Global options ​

These options work with every command:

text
thinger [options] [command]
OptionDescription
-V, --versionoutput the version number
-u, --user <username>API user override (admin impersonation)
--profile <name>Configuration profile to use (defaults to the saved default)
-h, --helpDisplay help for the command.

Add --help to any command or group to print its usage, for example thinger dashboard publish --help.

Commands ​

CommandDescription
thinger deviceDevices: list, inspect, create, delete, properties and resources
thinger productProducts: list, inspect, create, delete and product properties
thinger bucketData buckets: list them and read their time series
thinger dashboardDashboard apps (HTML + the dashboard SDK): develop them on their dev server and publish them
thinger loginSign in: re-authenticate the current profile, or create the first one. Use profile add for more servers.
thinger logoutForget the current profile (or --all) and revoke the API token the CLI created
thinger profileManage configuration profiles
thinger mcpStart the MCP server (stdio) for AI tool integration

thinger device ​

Devices: list, inspect, create, delete, properties and resources

text
thinger device [options] [command]
CommandDescription
thinger device listList devices, optionally filtered by name/id pattern (case-insensitive regex)
thinger device infoShow the server record of a device (type, product, connection…)
thinger device createRegister a device; Generic/MQTT ones get random credentials unless given
thinger device deleteDelete a device record from the platform (irreversible)
thinger device set-productAssign a device to a product ("" to unassign)
thinger device propertyList device properties, or read one by ID
thinger device property-setCreate or overwrite a device property (value parsed as JSON)
thinger device resourceList device resources, or call one by name (the device must be online)

thinger device list ​

List devices, optionally filtered by name/id pattern (case-insensitive regex)

text
thinger device list [options] [pattern]
ArgumentRequired
patternNo
OptionDescription
-j, --jsonOutput as JSON

thinger device info ​

Show the server record of a device (type, product, connection…)

text
thinger device info [options] <deviceId>
ArgumentRequired
deviceIdYes
OptionDescription
-j, --jsonOutput as JSON

thinger device create ​

Register a device; Generic/MQTT ones get random credentials unless given

text
thinger device create [options] <deviceId>
ArgumentRequired
deviceIdYes
OptionDescriptionDefault
-t, --type <type>Device type: Generic, MQTT, HTTP, Virtual, SubdeviceGeneric
-c, --credentials <credentials>Device credentials (6+ characters)
-n, --name <name>Display name
-d, --description <text>Description
-p, --product <productId>Assign to a product
-j, --jsonOutput as JSON

thinger device delete ​

Delete a device record from the platform (irreversible)

text
thinger device delete [options] <deviceId>
ArgumentRequired
deviceIdYes
OptionDescription
-y, --yesSkip the interactive confirmation prompt
-j, --jsonOutput as JSON

thinger device set-product ​

Assign a device to a product ("" to unassign)

text
thinger device set-product [options] <deviceId> <productId>
ArgumentRequired
deviceIdYes
productIdYes
OptionDescription
-j, --jsonOutput as JSON

thinger device property ​

List device properties, or read one by ID

text
thinger device property [options] <deviceId> [propertyId]
ArgumentRequired
deviceIdYes
propertyIdNo
OptionDescription
-j, --jsonOutput as JSON
-f, --field <field>Extract a sub-field (dot path, e.g. data.value)

thinger device property-set ​

Create or overwrite a device property (value parsed as JSON)

text
thinger device property-set [options] <deviceId> <propertyId> <value>
ArgumentRequired
deviceIdYes
propertyIdYes
valueYes
OptionDescription
-j, --jsonOutput as JSON

thinger device resource ​

List device resources, or call one by name (the device must be online)

text
thinger device resource [options] <deviceId> [resource]
ArgumentRequired
deviceIdYes
resourceNo
OptionDescription
-j, --jsonOutput as JSON
-f, --field <field>Extract a sub-field from the result (dot path)
-i, --input <key=value>Resource input, value parsed as JSON (repeatable)

thinger product ​

Products: list, inspect, create, delete and product properties

text
thinger product [options] [command]
CommandDescription
thinger product listList every product configured on the account
thinger product infoPrint the full product document (config and profile) as JSON
thinger product createCreate a product, bare or from a JSON document (config + profile)
thinger product deleteDelete a product (its devices stay, unassigned)
thinger product property-listList the names of the properties attached to a product
thinger product property-getRead a property attached to a product
thinger product property-setCreate or overwrite a product property (value parsed as JSON)
thinger product property-deleteDelete a product property (idempotent)

thinger product list ​

List every product configured on the account

text
thinger product list [options]
OptionDescriptionDefault
-j, --jsonOutput as JSON
-c, --concurrency <n>Max parallel API-resource lookups (default: 10)10

thinger product info ​

Print the full product document (config and profile) as JSON

text
thinger product info [options] <productId>
ArgumentRequired
productIdYes
OptionDescription
-j, --jsonOutput as JSON envelope

thinger product create ​

Create a product, bare or from a JSON document (config + profile)

text
thinger product create [options] <productId>
ArgumentRequired
productIdYes
OptionDescription
-n, --name <name>Display name
-d, --description <text>Description
--from <file>JSON document with config and/or profile ("-" for stdin)
-j, --jsonOutput as JSON

thinger product delete ​

Delete a product (its devices stay, unassigned)

text
thinger product delete [options] <productId>
ArgumentRequired
productIdYes
OptionDescription
-y, --yesSkip the interactive confirmation prompt
-j, --jsonOutput as JSON

thinger product property-list ​

List the names of the properties attached to a product

text
thinger product property-list [options] <productId>
ArgumentRequired
productIdYes
OptionDescription
-j, --jsonOutput as JSON

thinger product property-get ​

Read a property attached to a product

text
thinger product property-get [options] <productId> <propertyId>
ArgumentRequired
productIdYes
propertyIdYes
OptionDescription
-j, --jsonOutput as JSON

thinger product property-set ​

Create or overwrite a product property (value parsed as JSON)

text
thinger product property-set [options] <productId> <propertyId> <value>
ArgumentRequired
productIdYes
propertyIdYes
valueYes
OptionDescription
-j, --jsonOutput as JSON

thinger product property-delete ​

Delete a product property (idempotent)

text
thinger product property-delete [options] <productId> <propertyId>
ArgumentRequired
productIdYes
propertyIdYes
OptionDescription
-j, --jsonOutput as JSON

thinger bucket ​

Data buckets: list them and read their time series

text
thinger bucket [options] [command]
CommandDescription
thinger bucket listList the data buckets of the account
thinger bucket readRead samples from a bucket (latest first by default)

thinger bucket list ​

List the data buckets of the account

text
thinger bucket list [options]
OptionDescription
-j, --jsonOutput as JSON

thinger bucket read ​

Read samples from a bucket (latest first by default)

text
thinger bucket read [options] <bucketId>
ArgumentRequired
bucketIdYes
OptionDescriptionDefault
-d, --device <deviceId>Series a product bucket keeps for this device
-n, --items <n>Number of samples (default: 10)10
-m, --minutes <n>Only the last N minutes
--sort <order>asc or desc (default: desc)desc
--agg <window>Aggregation window, e.g. 5m, 1h
--agg-type <reducer>Reducer: mean, max, min, sum, count, first, last…
--fields <list>Comma-separated fields to return
--group-by <key>Group key, e.g. device
-j, --jsonOutput as JSON

thinger dashboard ​

Dashboard apps (HTML + the dashboard SDK): develop them on their dev server and publish them

text
thinger dashboard [options] [command]
CommandDescription
thinger dashboard initCreate a dashboard app (TypeScript, on @thinger-io/dashboard-sdk) from a template of the SDK
thinger dashboard devLink that opens the app on its own dev server (ng serve, Vite…) against the server, with a temporary token
thinger dashboard publishUpload an app to a public storage and point dashboards at it

thinger dashboard builds dashboards as web apps on the Dashboard SDK. init creates the project from a template of the SDK, dev prints a link that opens the app from its own dev server as a standalone page connected to your server, with a temporary token, and publish uploads the build to a public file storage and points the dashboards at it. See Dashboard apps for the workflow.

init writes a thinger.json manifest in the project folder. dev and publish read it from the current folder, or from the file given with --config; their options override it:

thinger.json
json
{
  "dashboard": {
    "dir": "dist",
    "storage": "app_greenhouse_1a2b",
    "prune": true,
    "to": [{ "type": "device", "id": "YOUR_DEVICE" }],
    "dev": { "url": "http://localhost:5173/" }
  }
}
FieldContent
dirBuild folder that publish uploads, relative to the manifest. It must be inside the project folder.
storageFile storage the app is published to. publish creates it, public, if it does not exist.
prunetrue deletes files of the storage that are not in the upload.
toDestinations whose dashboard opens the app: { "type": "device", "id": "…" } with type device, product, asset_type, asset_group or project, or { "dashboard": "…" } for a dashboard. Each one can set its own entry and route.
devOptions of thinger dashboard dev: url of the dev server, context, route and hours the temporary token lasts.
bash
thinger dashboard init greenhouse --to device:YOUR_DEVICE --install
cd greenhouse
npm run build
thinger dashboard publish

thinger dashboard init ​

Create a dashboard app (TypeScript, on @thinger-io/dashboard-sdk) from a template of the SDK

text
thinger dashboard init [options] <dir>
ArgumentRequired
dirYes
OptionDescription
-t, --template <name>Template of the SDK package: react, angular… (default react)
--to <destination>Where it publishes: device:<id>, product:<id>, dashboard:<id>…
-s, --storage <id>Storage it publishes to (default app_<folder>_<random>)
--from <package>SDK package to take the template from: a version or tag on npm, or a folder or .tgz
--ciAdd a GitHub workflow that publishes it on every push to main
--installRun npm install
-j, --jsonOutput as JSON

thinger dashboard dev ​

Link that opens the app on its own dev server (ng serve, Vite…) against the server, with a temporary token

text
thinger dashboard dev [options] [url]
ArgumentRequired
urlNo
OptionDescription
--to <destination>Context of a destination: device:<id>, product:<id>, dashboard:<id>…
--device <id>Device in the SDK context
--product <id>Product in the SDK context
--asset-type <id>Asset type in the SDK context
--asset-group <id>Asset group in the SDK context
--project <id>Project the app runs in
--route <route>Initial route, e.g. /devices
--hours <hours>Hours the token lasts (default 8)
--openOpen the link in the browser
--allow-remoteAllow an app url that is not on this machine (the link carries a full-access token)
--config <file>Manifest (default thinger.json)
-j, --jsonOutput as JSON

thinger dashboard publish ​

Upload an app to a public storage and point dashboards at it

text
thinger dashboard publish [options] [dir]
ArgumentRequired
dirNo
OptionDescription
-s, --storage <id>Storage of the app (created public if missing)
--to <destination>Dashboard to point (repeatable): dashboard:<id>, device:<id>, product:<id>, asset_type:<id>, asset_group:<id>, project:<id>
--entry <page>Page the destinations open (default index.html)
--route <route>Initial route of the destinations
--name <name>Name of a collection dashboard
--pruneDelete files of the storage that are not in this upload
--no-pruneKeep the storage's other files (overrides the manifest)
--bumpMake consoles that have the app open reload it at once
--preview [hours]Also print standalone preview links (read-only, 1 h by default)
--no-pointUpload without pointing the destinations (preview links only)
--config <file>Manifest (default thinger.json)
-j, --jsonOutput as JSON

thinger login ​

Sign in: re-authenticate the current profile, or create the first one. Use profile add for more servers.

text
thinger login [options]
OptionDescription
--server <server>Server host (or URL for http / custom ports)
--username <username>Account username
--token <token>Existing API token (non-interactive login with --server and --username)
--oauthSign in through the browser (OAuth device flow)
--client-id <id>OAuth client id registered on the server

thinger logout ​

Forget the current profile (or --all) and revoke the API token the CLI created

text
thinger logout [options]
OptionDescription
--allForget every profile
--keep-tokenDo not revoke the API token on the server

thinger profile ​

Manage configuration profiles

text
thinger profile [options] [command]
CommandDescription
thinger profile listList configured profiles
thinger profile currentPrint the active profile
thinger profile useSet the default profile
thinger profile addAdd a profile for another server (interactive, or with --server/--username/--token)
thinger profile deleteRemove a profile

thinger profile list ​

List configured profiles

text
thinger profile list [options]
OptionDescription
-j, --jsonOutput as JSON

thinger profile current ​

Print the active profile

text
thinger profile current [options]
OptionDescription
-j, --jsonOutput as JSON

thinger profile use ​

Set the default profile

text
thinger profile use [options] <name>
ArgumentRequired
nameYes
OptionDescription
-j, --jsonOutput as JSON

thinger profile add ​

Add a profile for another server (interactive, or with --server/--username/--token)

text
thinger profile add [options] [name]
ArgumentRequired
nameNo
OptionDescription
--no-activateDo not set the new profile as default
--server <server>Server host (or URL for http / custom ports)
--username <username>Account username
--token <token>Existing API token (non-interactive with --server and --username)
--oauthSign in through the browser (OAuth device flow)
--client-id <id>OAuth client id registered on the server
-j, --jsonOutput as JSON

thinger profile delete ​

Remove a profile

text
thinger profile delete [options] <name>
ArgumentRequired
nameYes
OptionDescription
-j, --jsonOutput as JSON

thinger mcp ​

Start the MCP server (stdio) for AI tool integration

text
thinger mcp [options]

thinger mcp starts an MCP server over standard input and output with the session of the active profile, so an AI client can work with your account. Sign in first with thinger login. To register it in Claude Code for all your projects:

bash
claude mcp add --scope user thinger -- thinger mcp

Other MCP clients take the same command: thinger with the argument mcp. How to set up each client (Claude Desktop, VS Code, Cursor and others) is in Connect an AI agent, and the tools the server offers are listed in MCP tools.

Without installing the CLI

npx -y @thinger-io/cli mcp runs the server without installing the CLI, for example in Claude Code or a CI job. Desktop apps are more reliable with the installed thinger command: see Connect an AI agent.

See also ​