Skip to content
Stand with Ukraine flag

Manage Solutions with CLI

Once your project is initialized, you can build IoT solutions with Claude, manage multi-target deployments, and work with entities directly from the terminal. This page covers the full solution lifecycle — from first prompt to production push.

Haven’t set up the CLI yet? Start with Getting Started with CLI.

The AI-first workflow is short: ask Claude for a solution, review what it built, run tb push <slug> when Claude tells you it’s ready.

  1. You ask. Describe the solution you want. Claude designs the full IoT solution for you — devices and their hierarchy, dashboards, alarms, calculated metrics, and customers and users. It also generates demo telemetry emulators so your dashboards have data from day one, and validates the design against ThingsBoard throughout the process.

  2. You review. By default, Claude pauses for your approval after each design step — first the entity model, then the dashboards. You can also tell Claude to run autonomously and just show you the final result.

  3. You deploy. When Claude says the solution is ready, run tb push <slug>. Add --run-tasks to also generate demo telemetry and backfill calculated fields with historical inputs:

    Terminal window
    tb push smart-building --run-tasks
  4. You iterate. Ask Claude for changes — “add a humidity sensor to each room”, “split the kitchen dashboard”. Claude regenerates the affected pieces, and you re-run tb push. Push is idempotent: ThingsBoard tracks entity identity by external ID, so the same solution can be pushed many times with no duplication.

Claude does its best work when you mention these things up front. It will ask if you don’t, but doing so means fewer follow-up questions:

  • Domain & entities — what’s being monitored or controlled. Sensors, vehicles, machines, meters, infrastructure.
  • Hierarchy — are these standalone devices, or are they grouped inside container assets (a building, a fleet, a site)?
  • Customers & users — single tenant, or multiple independent customers / sites that should see only their own data?
  • Alarms & metrics — specific thresholds or derived values you care about. Optional; Claude proposes sensible defaults if you don’t specify.

Example prompts:

  • “Create a smart house monitoring solution with a few temperature, humidity, and motion sensors per room.”
  • “Build a fleet tracking system for two delivery customers, with location and battery alarms.”

/create-solution is the umbrella command; behind the scenes Claude uses purpose-built skills for entity generation, dashboards, alarms, calculated fields, and emulators. These ship with the CLI and update automatically with it.

ThingsBoard CLI treats your tenant configuration as code: entity definitions live in your project on disk, and tb push deploys them to ThingsBoard. The same solution can be pushed to multiple ThingsBoard targets — dev, staging, prod — without code changes.

Each entity directory under the project root holds entities that aren’t part of any solution. Solutions are self-contained slices under solutions/<slug>/ with the same directory layout.

To start a new solution by hand (without Claude):

Terminal window
tb solution new smart-building

When a solution is on disk, you can target it from anywhere in the project with the --solution flag:

Terminal window
tb device save --solution smart-building --json '{"name": "Sensor-01", "type": "Temperature Sensor"}'

If you already have a solution deployed in ThingsBoard and want to bring it under CLI management, use the interactive pull to select exactly which entities to import into your project.

Terminal window
tb pull -i

The CLI opens a terminal UI that lets you browse your ThingsBoard tenant across all entity types, including entity groups. Select the entities you want and press Enter to import them.

  • Press space to toggle selection on an individual entity.
  • Press m on an entity group to automatically select all entities in that group.
  • Press a to select all entities in the current view.

Use owner:<name> or server:<query> in the search bar to filter by owner or run a server-side query.

Once pulled, the entities land in your project files and are tracked by the CLI — any subsequent tb push will keep them in sync with ThingsBoard.

Multi-Target Push: dev → staging → prod

Section titled “Multi-Target Push: dev → staging → prod”

The same solution can be deployed to multiple ThingsBoard environments by pushing it under different config profiles:

Terminal window
tb push smart-building --profile dev
tb push smart-building --profile staging
tb push smart-building --profile prod

The CLI writes no state files to your project — push to the same target twice and existing entities are updated, not duplicated. Develop and test against dev, promote to staging once you’re happy, and ship to prod with the exact same files.

Terminal window
tb validate # validate root entities
tb validate smart-building # validate one solution

Validation is a dry-run against the target ThingsBoard instance. Combine it with --profile <name> to validate against any environment.

tb push --run-tasks does the regular push and then runs two extra steps:

  • Telemetry emulators. The CLI writes synthetic telemetry for the devices Claude set up emulators for, so dashboards have something to display.
  • Calculated field backfill. The CLI replays historical inputs through each calculated field expression so derived values are populated for the time range covered by the emulators.

Both steps are safe to omit on subsequent pushes once the data exists — they are most useful on the very first push to a fresh tenant.

tb pull is the inverse of push: it fetches the current server state for entities you already track locally and rewrites the JSON files on disk. Reach for it when someone tweaked a dashboard in the UI, when you want a fresh local copy of what’s running on staging, or when you need to bring a server-created entity into the project.

Terminal window
tb pull # refresh every locally-tracked entity in the current solution (auto-detected from cwd)
tb pull --solution smart-building # same, with the solution named explicitly
tb pull dashboard --all # refresh every dashboard in the current solution
tb pull device <uuid> # fetch a single entity by its server-internal UUID
tb pull device <uuid1> <uuid2> # …or several at once

The UUID form is the way to pick up entities that exist on the server but aren’t in the project yet — pass the entity’s internal ID and the CLI writes a fresh file under the right directory.

A few flags worth knowing about:

  • --dry-run prints the planned writes (created / updated / renamed) without touching disk. Use it to preview changes before they land.
  • --with-credentials includes device credentials in the pulled files. Off by default; opt in only when you want them committed alongside the device JSON.
  • --force skips the safety check that aborts when target files have uncommitted git changes.

By default, tb pull refuses to overwrite files with uncommitted local changes, so it never silently clobbers work in progress. Commit, stash, or pass --force to proceed.

  • tb push has no automatic rollback. If you push a broken solution, fix it locally and push again.
  • Entity identity is tracked server-side by external ID. UI edits to project-managed entities are overwritten on the next tb push unless you tb pull them back first. Brand-new entities created outside the CLI can also be brought into the project with tb pull.

“No entities to push”

The solution or project root has no entity files yet. Generate some with Claude or create them manually with tb device save (or another entity command), then push again.

“Commands target the wrong solution”

Don’t cd into solution directories to scope commands. Always use --solution <name> — the flag works from anywhere inside your project and is more reliable than relying on the current directory.