@formant/formant-cli
v1.0.7
Published
Formant CLI — manage your robot fleet from the command line
Readme
Formant CLI (formant)
The official command-line interface for Formant — a cloud platform for monitoring, operating, and analyzing robot fleets at scale.
Formant helps robotics teams observe, troubleshoot, and control their robots in production. With formant, you can manage your entire fleet from the terminal: query telemetry, trigger AI-powered investigations, delegate tasks to AI personas, send remote commands, manage users and permissions, and automate workflows.
What is Formant?
Formant is a cloud observability and operations platform designed specifically for robotics. It provides:
- Real-time monitoring — Live telemetry streams (battery, sensors, cameras, logs) from all your robots
- Event tracking — Automatic detection and alerting of critical issues (crashes, errors, anomalies)
- AI-powered investigations — Intelligent root cause analysis that diagnoses problems automatically
- AI personas — Configurable AI agents with tools for async task delegation
- Remote operations — Send commands, trigger actions, and control robots from anywhere
- Fleet management — Organize devices by location, type, or purpose; manage user permissions
- Analytics & reporting — Query historical data with SQL to understand performance trends
Features
This CLI provides programmatic access to all Formant capabilities:
Device Management
- List, create, rename, and delete robots/sensors
- Add tags for organization (environment, location, customer)
- View real-time device status and configuration
- List available telemetry streams with per-stream data presence (datapoint counts, last seen, freshness)
- Data-based last seen timestamps and datapoint counts on device listings
- Filter to devices that have ingested data (
--with-data) - Search by name across all devices (online and offline) with
--name; repeat the flag for multiple names
Telemetry Queries
- Query historical sensor data (battery, temperature, position, custom metrics)
- Retrieve latest values with
--latest-values-only - Auto-discover all streams with
--all-streams - Filter by time range, device, and stream type
- Export data as JSON for analysis
Telemetry Ingestion
- Send numeric, text, JSON, image, video, bitset, and health data to devices
- Add tags and custom timestamps to telemetry points
- Batch upload multiple data points in a single request
- Programmatically populate device streams from scripts and automation
Event Monitoring
- View events filtered by severity (info, warning, critical, error)
- Track device online/offline status
- Investigate alert history for troubleshooting
- Filter events by device, time range, or type
AI Personas
- List available AI personas and their configurations
- View persona details including integrations and available tools
- Delegate async tasks to personas (fire-and-forget)
- Check task status and results
AI Investigations
- List available investigation workflows
- Trigger investigations manually with custom input
- View investigation runs, execution logs, and results
- Get investigation statistics and success rates
- Trace investigations back to their triggering signals
Signal Management & Ground Truth
- Create manual signals for testing and evaluation
- List and query signals (investigation triggers)
- Assign ground truth (expected outcomes) to signals for evaluation
- View signals with their ground truth annotations
- Count signals by type
- Trace the workflow: Signal -> Investigation -> Run -> Result
Remote Commands
- List available command templates for your fleet
- Send commands to individual devices with parameters
- View command execution history
- Check command delivery status
Event Triggers (Automation)
- View configured trigger rules
- Understand what conditions create events and signals
- See trigger configuration (thresholds, exit conditions, device scope)
User & Organization Management
- View organization details (plan, retention, support tier)
- Update organization name and description
- List all users and their roles
- Inspect user permissions and account status
Fleet & Group Management
- Create logical groups of devices (by location, project, customer)
- List all fleets and their member devices
- Organize your fleet for easier management
Scheduled Tasks
- View scheduled investigations and commands
- Understand recurring workflows and automation
Analytics & SQL
- Execute custom SQL queries against your analytics database
- List available tables and schemas
- Analyze fleet performance, uptime, and trends
Schema Introspection
- Export machine-readable command schemas from the CLI itself
- Filter by topic or command for agent/tool integration
- Validate args/flags/options/exclusivity before execution
Key-Value Metadata Store
- Store custom metadata per device
- Retrieve configuration values
- Update device-specific settings
Installation
npm
npm install -g @formant/formant-cliYarn
yarn global add @formant/formant-clipnpm
pnpm add -g @formant/formant-cliAfter installation, verify it works:
formant --helpTool Integration Setup (Cowork, Claude, Codex, Gemini)
This repository's primary distribution goal is:
- Formant CLI commands (
formant) - packaged skills/plugins for Cowork, Claude, Codex, and Gemini
1) Build all integration artifacts
From repo root:
npm run agents:packageThis generates:
dist/formant-admin.plugindist/agent-integrations/claude-skill-packdist/agent-integrations/codex-skill-packdist/agent-integrations/gemini-workspace-packdist/agent-integrations/gemini-extension-formant-admin
Note: npm run smoke:ci runs a fresh build (npm run build) and clears dist/.
Run packaging (agents:package / plugin:package) after smoke checks.
2) Cowork / Claude plugin import
- Artifact:
dist/formant-admin.plugin - Import this file into Cowork plugin manager / Claude plugin tooling.
Plugin source:
cowork/formant-admin/
3) Claude standalone workspace setup (skills + /check command)
Copy the Claude bundle into your target workspace root:
cp -R dist/agent-integrations/claude-skill-pack/. /path/to/workspace/This installs:
.claude/skills/*.claude/commands/check.mdCLAUDE.md
4) Codex Desktop workspace setup
Copy the Codex bundle into your target workspace root:
cp -R dist/agent-integrations/codex-skill-pack/. /path/to/workspace/This installs:
.codex/skills/*AGENTS.md
If your Codex runtime expects .agents/skills instead, copy skill folders there and keep AGENTS.md at workspace root.
5) Gemini workspace setup
Copy the Gemini workspace bundle into your target workspace root:
cp -R dist/agent-integrations/gemini-workspace-pack/. /path/to/workspace/This installs:
.gemini/skills/*.gemini/commands/formant/check.tomlGEMINI.md
6) Gemini extension install
gemini extensions install dist/agent-integrations/gemini-extension-formant-admin7) Post-install validation (all runtimes)
Run these in the target workspace:
formant --help
formant auth status --json
formant org get --json
formant schema commands --jsonDetailed packaging/distribution notes:
docs/agent-integration-distribution.mdcowork/formant-admin/README.md
Authentication
Formant CLI uses service account credentials for authentication. You'll need to create a service account in your Formant organization first.
Creating a Service Account
- Log in to Formant
- Go to Settings -> Users
- Click Create Service Account
- Copy the generated email and password
Setting Credentials
Formant CLI supports two credential sources:
- Stored defaults (recommended for npm/homebrew installs)
Save credentials once and reuse them from any directory:
formant auth login --user "[email protected]" --password "your-password"
formant auth statusStored credentials are saved at:
- macOS/Linux:
~/.config/formant/credentials.json - Windows:
%APPDATA%\\formant\\credentials.json
- Environment variables
Use for local/session-level credentials or one-off overrides:
export FORMANT_USER="[email protected]"
export FORMANT_PASSWORD="your-password"Or create a .env file in your project:
[email protected]
FORMANT_PASSWORD=your-passwordThe CLI will automatically load credentials from your .env file.
Credential Precedence
FORMANT_USER+FORMANT_PASSWORD(environment /.env)- Stored defaults from
formant auth login
For commands that accept explicit credential flags (--user, --password), inline flag values override environment values.
This means you can keep defaults on the machine, then override per request:
FORMANT_USER="[email protected]" FORMANT_PASSWORD="override-password" formant org get --jsonQuick Start
# View your organization (singleton; no "org list")
# JSON/TOON are minimal by default; add --full for complete payloads
formant org
# List devices with data
formant device list --with-data --dev
# Look up a device by name (searches all devices, online + offline)
formant device list --name "mech-0" --dev --toon
formant device list --name "mech-0" --name "mech-1" --dev --toon
# Get device details
formant device get <device-id> --dev
# Query battery telemetry over the last day
formant query --device <device-id> --stream battery_level \
--start 2026-02-17 --end 2026-02-18 --dev
# View recent critical events
formant event list --severity critical --limit 20 --dev
# List AI personas and delegate a task
formant persona list --dev
formant persona delegate-task <persona-id> "Analyze recent device failures" --dev
formant persona task-status <task-id> --dev
# List all investigations
formant investigation list --dev
# Send a command to a robot
formant command send <device-id> <template-id> --param speed=5 --devCommand Reference
Organization
View your Formant account settings. This is a singleton resource.
formant org # Shorthand: view organization details
formant org get # Explicit equivalentDevice
Create, list, and manage robots/sensors in your fleet.
# Listing and filtering
formant device list # Online devices (default)
formant device list --include-offline # Include offline devices
formant device list --with-data # Only devices with ingested data
formant device list --with-data --days 90 # Widen the search window (default: 30d)
formant device list --tag location=warehouse # Filter by tag
formant device list --name "mech-0" # Search all devices by name (online + offline)
formant device list --name "mech-0" --name "mech-1" # Multiple names (parallel queries, merged)
# Device details
formant device get <device-id> # Get full device details
formant device config <device-id> # Get device configuration
# Stream discovery with data presence
formant device streams <device-id> # List streams with datapoint counts,
# last seen (ISO), and freshness
formant device streams <device-id> --days 30 # Adjust presence lookback (default: 7d)
# Device management
formant device create "robot-001" # Create a new device
formant device rename <device-id> "new-name" # Rename a device
formant device disable <device-id> # Disable a device
# Tagging
formant device tag <device-id> --tag env=prod # Add/update tag
formant device untag <device-id> --key env # Remove tagEvent
View and filter important events emitted by your devices.
formant event list # List all recent events
formant event list --device <device-id> # Events for one device
formant event list --severity critical # Filter by severity
formant event list --limit 50 # Limit results
formant event list --start 2026-01-01 # Filter by date range
formant event get <event-id> # Get event detailsSeverity levels: info, warning, error, critical
Query
Retrieve historical telemetry and sensor data. --start and --end are always required.
# Historical data
formant query --device <device-id> --stream battery_level \
--start 2026-01-01 --end 2026-01-02
# Multiple streams in one query
formant query --device <device-id> --stream heat.current --stream power.available \
--start 2026-02-01 --end 2026-02-20
# Multiple devices in one query
formant query --device <id1> --device <id2> --stream battery_level \
--start 2026-02-01 --end 2026-02-20
# Aggregated data (downsample to hourly)
formant query --device <device-id> --stream temperature \
--start 2026-01-01 --end 2026-02-01 --aggregate hour
# Latest value per stream (within the time range)
formant query --device <device-id> --stream battery_level \
--start 2026-01-01 --end 2026-02-01 --latest-values-only
# Auto-discover and query all streams on a device
formant query --device <device-id> --all-streams \
--start 2026-01-01 --end 2026-02-01 --latest-values-only
# Common streams: battery_level, temperature, cpu_usage, memory_usage, locationIngest
Send telemetry data to devices via the Formant ingestion API.
# Numeric data
formant ingest numeric 42.5 --device <device-id> --stream battery_level
formant ingest numeric 23.8 --device <device-id> --stream temperature --tag location=warehouse
# Text data
formant ingest text "System operational" --device <device-id> --stream status
formant ingest text "Low battery warning" --device <device-id> --stream alerts --tag severity=warning
# JSON data
formant ingest json '{"x":10,"y":20}' --device <device-id> --stream position
# Image data
formant ingest image https://example.com/camera.jpg --device <device-id> --stream camera_front
# Video data
formant ingest video https://example.com/recording.mp4 --device <device-id> --stream camera_feed --duration 30000
# Bitset data (multiple boolean key-value pairs)
formant ingest bitset --device <device-id> --stream sensors \
--keys motor_on,door_open,battery_charging \
--values true,false,true
# Health status
formant ingest health --device <device-id> --stream health_status --status operational
# Batch ingestion (multiple items from JSON file or stdin)
formant ingest batch --file payload.json
cat batch.json | formant ingest batch --stdinCommon flags for all ingest commands:
--device <id>- Target device ID (required)--stream <name>- Stream name (required)--tag key=value- Add tags as string key-value pairs (repeatable)--timestamp <ms>- Unix timestamp in milliseconds (defaults to current time)
Health status values: unknown, operational, offline, error
Persona
Manage AI personas and delegate async tasks.
# Listing and details
formant persona list # List all personas
formant persona get <persona-id> # View persona details and tools
# Async task delegation
formant persona delegate-task <persona-id> "Analyze recent device failures"
formant persona delegate-task <persona-id> "Generate a daily report" --name "Daily Report"
formant persona task-status <task-id> # Check task status and results
# Conversational chat threads
formant persona chat start <persona-id> --name "Ops triage"
formant persona chat send <thread-id> "Summarize current fleet issues"
formant persona chat send <thread-id> "Continue with remediation plan" --async
formant persona chat poll <thread-id> --wait --after 2026-01-01T00:00:00Z
formant persona chat history <thread-id> --limit 20
formant persona chat switch-persona <thread-id> <persona-id>The delegate-task command creates a task, assigns it to the persona, and queues it for
async execution. It returns immediately with a task ID. Use task-status to check progress.
Investigation
Trigger and monitor AI-powered analysis workflows that diagnose device issues.
# Listing
formant investigation list # List all investigations
formant investigation get <investigation-id> # Get investigation details
# Definition lifecycle
formant investigation create --file investigation.json
formant investigation update <investigation-id> --file update.json
formant investigation delete <investigation-id>
# Version lifecycle
formant investigation version-list <investigation-id>
formant investigation version-get <investigation-id> <version-number>
formant investigation version-create <investigation-id> --label "baseline"
formant investigation version-restore <investigation-id> <version-number>
formant investigation version-delete <investigation-id> <version-number>
# Triggering
formant investigation trigger <id> --input "Robot stopped responding"
# Runs
formant investigation runs <investigation-id> # List all runs
formant investigation run <inv-id> <run-id> # Get run details & logs
# Analytics
formant investigation stats --start 2026-01-01 # Get metrics
formant investigation analytics <investigation-id> # Get investigation analyticsSignal
Signals are points of interest (from events, schedules, or manual triggers) that start investigations. You can create signals manually and assign ground truth (expected outcomes) for evaluation.
# Listing and querying
formant signal list # List all signals
formant signal list --investigation <inv-id> # List with ground truth annotations
formant signal query --start 2026-01-01 --end 2026-02-01 # Query by time
formant signal count # Count signals by type
formant signal get <signal-id> # Get signal details
# Creating signals
formant signal create "Motor overheated on device X"
formant signal create "Sensor fault" --device <device-id>
formant signal create "Test scenario" --investigation <inv-id> \
--ground-truth "Should detect thermal issue"
# Ground truth (expected outcomes for evaluation)
formant signal set-ground-truth <signal-id> <investigation-id> "Expected outcome text"Command
Send remote commands to devices and view execution history.
formant command list # List all command templates
formant command get <command-id> # Get template details
formant command for-device <device-id> # Commands available for device
formant command send <device-id> <template-id> --param key=value # Send command
formant command history --device <device-id> # View command historyEvent Trigger
View automated trigger rules that generate events and signals based on device conditions.
formant event-trigger list # List all trigger rules
formant event-trigger get <trigger-id> # Get trigger configurationUser
Manage users in your organization.
formant user list # List all users
formant user get <user-id> # Get user detailsFleet
Organize devices into logical groups (by location, type, project, customer).
formant fleet list # List all fleets
formant fleet get <fleet-id> # Get fleet detailsSchedule
View recurring tasks and one-time scheduled jobs.
formant schedule list # List all schedules
formant schedule get <schedule-id> # Get schedule detailsAnalytics
Execute custom SQL queries against your Formant analytics database.
formant analytics tables # List available tables
formant analytics query --sql "SELECT * FROM events WHERE severity='critical' LIMIT 10"Schema
Inspect machine-readable CLI command schemas for tooling and agents.
formant schema commands --json # All command schemas
formant schema commands --topic device --json # Filter by topic
formant schema commands --command "device list" --json # One command
formant schema commands --command "device list" --json | jq '.commands[0].output'
formant schema operations --json # Backend operation contracts
formant schema operation admin.channels.create --json # One backend operation contractKey-Value Store
Store and retrieve custom metadata for devices.
formant kv list # List all keys
formant kv get <key> # Get value
formant kv set <key> <json-value> # Set value
formant kv delete <key> # Delete keyGlobal Flags
These flags work with any command:
--dev— Target the dev environment (for testing)--stage— Target the stage environment (for staging)--json— Output minimal machine-readable JSON (projected fields)--toon— Output minimal machine-readable TOON (projected fields)--field <path>— Include additional field path(s) in JSON/TOON output (repeatable)--full— Disable projection and return full API payloads in JSON/TOON output-h, --help— Show help for any command
Default environment: Production (unless --dev or --stage is specified)
Output Formats
Table (default)
Human-readable tables optimized for terminal viewing:
$ formant device list --with-data --dev
Devices — with data (dev):
NAME ID ONLINE TYPE LAST SEEN (30D) DATAPOINTS (30D)
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
carter.1 a8840212-a0a4-4d0b-8a47-098563894748 false default 2026-02-19T19:05:37.536Z 720156
DJI Matrice 4E 10f78fd5-c00d-42d9-94c4-b310646f59be false default 2026-02-18T01:17:41.167Z 917051$ formant device streams <device-id> --dev
Device Streams (dev):
Device: Walt (020e59a1-...)
Configured: 10 | Discovered from data: 34
Presence (last 7d): 0 active, 32 recent, 0 stale, 0 dormant, 12 no data
NAME TYPE SOURCE DATAPOINTS LAST SEEN FRESHNESS
spot.robot_state.battery numeric data 20195 2026-02-19T23:37:01.281Z recent
spot.localization text data 16962 2026-02-19T23:37:01.271Z recent
spot.hand.image custom config — — —$ formant query --device <device-id> --stream heat.current --stream power.available \
--start 2026-02-01 --end 2026-02-20 --dev
Telemetry Data (dev environment):
Stream: heat.current (numeric) Device: 01397354-d17a-4b53-ac27-61753de7918c
Points: 1
TIME VALUE
──────────────────────────────────────────────────────────────────────────────
2026-02-18T21:15:38.491Z 47
Stream: power.available (numeric) Device: 01397354-d17a-4b53-ac27-61753de7918c
Points: 1
TIME VALUE
──────────────────────────────────────────────────────────────────────────────
2026-02-18T21:15:38.520Z 72JSON
Machine-readable JSON for scripting and automation. By default, JSON output is minimal and command-specific (optimized for direct operations and agent use).
$ formant device list --with-data --dev --json
{
"items": [
{
"id": "a8840212-...",
"name": "carter.1",
"online": false,
"last_seen": "2026-02-19T19:05:37.536Z",
"datapoints": 720156
}
]
}Request additional fields as needed:
formant org get --json --field flags --field billingInfo
formant device get <device-id> --json --field state.ros.topicsReturn the full backend payload when needed:
formant device list --include-offline --json --fullUse with jq for advanced processing:
formant device list --json | jq '.items[] | select(.online==true) | .name'TOON
--toon is the recommended output format when working with AI tools, LLM prompts, or any context where token efficiency matters.
TOON (Token-Oriented Object Notation) is a compact, schema-aware encoding of
structured data that is both human-readable and significantly more token-efficient
than JSON. Like --json, TOON output is projected to minimal fields by default.
$ formant org get --toon
name: Acme Robotics
id: 6380a48c-0847-4543-a67f-9b7ccc41ec21
plan: paid
daysDataRetained: 600
enabled: true
updatedAt: 2026-02-23T20:17:06.225Z$ formant user list --toon
items[2]{id,email,firstName,lastName,enabled}:
4f79f32b-...,[email protected],Alice,Smith,true
9a1c22de-...,[email protected],Bob,Jones,trueKey properties of TOON output:
- Arrays are schema-compressed —
items[N]{field1,field2,...}:header followed by rows, rather than repeating field names for every object - Scalars are unquoted — only strings with special characters are quoted
- Nested objects are indented — structure is preserved but without JSON's punctuation overhead
- Null and boolean values are compact —
null,true,falsewithout quotes
When to use --toon vs --json:
| Use case | Recommended flag |
|---|---|
| Pasting into an LLM prompt | --toon |
| AI agent / agentic scripting | --toon |
| Shell scripting with jq | --json |
| Saving to a file for later processing | --json |
| Quick human inspection | (default) |
# Pipe directly into an LLM context or agent prompt
formant device list --toon
formant event list --severity critical --toon
formant investigation runs <id> --toon
formant org get --toonExamples
Monitor fleet health
# Find devices that have data
formant device list --with-data
# Find devices with data, wider search window
formant device list --with-data --days 90
# Check which devices are offline
formant device list --include-offline --json | jq '.items[] | select(.online==false) | .name'
# View recent critical events across the fleet
formant event list --severity critical --limit 50
# Discover what streams a device has and their data freshness
formant device streams <device-id>Delegate a task to an AI persona
# List available personas
formant persona list
# Delegate an async task
formant persona delegate-task <persona-id> "Check all offline devices and summarize issues"
# Check the result
formant persona task-status <task-id>Investigate a device issue
# 1. View recent events for the device
formant event list --device <device-id> --limit 20
# 2. Trigger an investigation
formant investigation trigger <investigation-id> --input "Device stopped responding"
# 3. Check investigation runs
formant investigation runs <investigation-id>
# 4. Query relevant telemetry (multiple streams and/or devices at once)
formant query --device <device-id> --stream temperature --stream battery_level \
--start 2026-02-17T10:00:00Z --end 2026-02-17T12:00:00ZAutomate fleet operations
# Tag all production devices
for device in $(formant device list --json | jq -r '.items[].id'); do
formant device tag $device --key environment --value production
done
# Send command to all devices in a fleet
for device in $(formant fleet get <fleet-id> --json | jq -r '.devices[].id'); do
formant command send $device <template-id> --param mode=standby
doneExport data for analysis
# Export all critical events to JSON
formant event list --severity critical --limit 1000 --json > critical_events.json
# Export device list with tags
formant device list --json | jq '.items[] | {name, id, tags}' > devices.json
# Query analytics and save results
formant analytics query --sql "SELECT * FROM events WHERE created_at > '2026-01-01'" \
--json > analytics_export.jsonUse with AI tools and LLMs
--toon produces compact, token-efficient output that is well-suited for LLM
prompts and agentic workflows. Use --field to expand specific paths, or --full
when you need full payloads.
# Summarize your fleet for an LLM
formant device list --with-data --toon
# Get org context in compact form
formant org get --toon
# Pipe investigation results into an AI workflow
formant investigation runs <investigation-id> --toon
# Combine with other tools for agentic scripting
formant event list --severity critical --limit 20 --toon | your-ai-tool analyze
# Check recent events and device state together
{
echo "=== Critical Events ==="
formant event list --severity critical --limit 10 --toon
echo "=== Fleet Status ==="
formant device list --include-offline --toon
} | your-ai-tool "Summarize what's wrong with my fleet"Development
Build from source
git clone https://github.com/FormantIO/formant-cli.git
cd formant-cli
npm install
npm run buildRun in development mode
npm run dev -- device list --devRun directly
./bin/run.js --helpCapability Validation Matrix
# Read-only capability sweep
npm run capability:test:readonly
# Read-only capability sweep against built CLI (bin/run.js)
npm run capability:test:readonly:built
# Read-only + safe-write checks (currently KV set/get/delete smoke)
npm run capability:test:safe-write
# Safe-write checks against built CLI
npm run capability:test:safe-write:built
# Mutating operation checks (create/update/delete, operational triggers)
npm run capability:test:mutate
# Mutating checks against built CLI
npm run capability:test:mutate:built
# Optional: fail mutate run if any skip is not in the known expected skip set
npm run capability:test:mutate:strict
# Regenerate docs/capability-validation-matrix.md from latest results
npm run capability:matrix
# Run both sweeps and regenerate the matrix doc
npm run capability:refresh
# Run readonly + safe-write + mutate in dev and built runtimes + matrix
npm run capability:refresh:full
# Pre-release validation: repo checks + strict contracts + non-destructive capability sweep
npm run validate:releaseResult files are written to tmp/capability-results/.
Mutation result JSON includes residue (artifacts we could not fully clean up) and skipAudit (expected vs unexpected skips).
validate:release requires working Formant credentials and performs one temporary KV set/get/delete smoke check. It does not run the broader mutate suite.
Manifest-dependent validation scripts now self-generate oclif.manifest.json when needed, so local validation no longer depends on manually leaving that ignored file around after packaging.
Manual checks for descriptions/help/README/skills are documented in:
docs/manual-cli-content-review.md
Requirements
- Node.js >= 18.0.0
- A Formant account with service account credentials
- Appropriate permissions for the operations you want to perform
Support & Resources
- Documentation: https://formant.io/docs
- Support Email: [email protected]
- GitHub Issues: https://github.com/FormantIO/formant-cli/issues
- Formant Platform: https://app.formant.io
License
MIT
See LICENSE for details.
Made with care by Formant
