Synadia Insights

CLI

The insights binary is a single command with several subcommands. Running insights with no subcommand starts the server — equivalent to insights serve (run is a kept alias). The client subcommands (query, db, checks, and the ops group) talk to an already-running server over NATS. The web, mcp, and http subcommands each run their own long-lived process that connects to a running node as a NATS client.

Synopsis

insights [flags] [subcommand] [subcommand-flags]
SubcommandPurpose
(default) serve (alias run)Start the Insights server.
webRun only the web tier, as a NATS client of a remote indexer/scraper node.
mcpRun a read-only Model Context Protocol server exposing the db and checks tools to AI agents.
httpRun a stateless HTTP gateway fronting the read-only DB query API for HTTP-only clients.
queryRun a SQL query against the embedded DuckDB over the NATS API.
db explain <SQL>Validate and plan (or profile) a SQL statement without running a full query.
db schemas / tables / columns / macrosDiscover the queryable schemas, tables, columns, and macros.
checks listList all available audit checks grouped by category.
checks info <CODE>Show full metadata and configurable parameters for one check.
checks findings <CODE>Run one audit check and return its findings.
ops backupCreate a consistent database snapshot and download it.
ops sizingRecommend a DuckDB memory_limit / threads pair for the running instance.
ops memoryShow the live DuckDB memory profile (current and peak by component).
ops pprofCapture a runtime profile from the running instance for diagnostics.
--versionPrint the binary version and exit.

Configuration precedence

When a setting is defined in more than one place, the highest-priority source wins:

  1. Command-line flags
  2. Environment variables (INSIGHTS_*)
  3. YAML config file (--config / -c)
  4. Built-in defaults

Environment variables mirror the flag path: dots become underscores, everything is uppercased, and the INSIGHTS_ prefix is added. For example, --web.port becomes INSIGHTS_WEB_PORT, and --sys.server becomes INSIGHTS_SYS_SERVER.

Top-level flags

These flags apply to every subcommand.

FlagEnvDefaultDescription
--log-levelINSIGHTS_LOG_LEVELinfoLog level: debug, info, warn, error.
--serverINSIGHTS_NATS_SERVERnats://127.0.0.1:4222NATS server URL used by subcommands (query, db, checks, and the ops group) to reach the Insights API.
--credsINSIGHTS_NATS_CREDS(empty)Path to a NATS credentials file.
--contextINSIGHTS_NATS_CONTEXT(empty)NATS CLI context name (resolved via ~/.config/nats/).

These are nats-CLI-style flags; the pre-rename --nats.* forms (--nats.server, --nats.creds, --nats.context, --nats.tls-ca-cert) remain as aliases. Their environment variables keep the INSIGHTS_NATS_ prefix (for example --server reads INSIGHTS_NATS_SERVER).

See Configuration > nats.* for the full connection reference (TLS, auth, socks proxy).

insights serve

Default subcommand. Starts the Insights server: scraper, indexer, web UI, sink, backup scheduler, and the NATS API endpoints. run is a backward-compatible alias, so insights run and a bare insights both start the server.

insights serve [flags]

Because serve is the default, you can omit the subcommand name:

insights --config /etc/insights/config.yaml

Flags

serve owns every server-only subsystem flag. Rather than duplicate them all here, see the Configuration reference. Each subsystem (scraper, indexer, web, sink, simulator, backup, database, license, and so on) has its own section there.

Frequently used flags:

FlagEnvDefaultDescription
--config / -c(none)(empty)Path to YAML config file.
--data-dirINSIGHTS_DATA_DIR(temp dir)Base directory for DuckDB and JetStream data.
--simulator.enabledINSIGHTS_SIMULATOR_ENABLEDfalseRun against the built-in simulator instead of a real NATS system. License validation is skipped when enabled.
--sys.serverINSIGHTS_SYS_SERVER(empty)NATS URL of the target system to scrape.
--sys.credsINSIGHTS_SYS_CREDS(empty)NATS credentials file for the target system.
--web.hostnameINSIGHTS_WEB_HOSTNAME127.0.0.1Web UI bind address.
--web.portINSIGHTS_WEB_PORT8080Web UI bind port.
--license.tokenINSIGHTS_LICENSE_TOKEN(empty)License JWT string.
--license.fileINSIGHTS_LICENSE_FILE(empty)Path to a file containing the license JWT.

Example

insights \
  --config /etc/insights/config.yaml \
  --license.file /etc/insights/license.jwt \
  --web.hostname 0.0.0.0

insights web

Runs only the web tier — no indexer, scraper, or simulator, and no embedded NATS server — so the process holds no local state and serves the UI entirely from data it reaches over NATS. Point it at the node running the indexer and scraper with --server (or --context); that node owns the DuckDB and serves the $INS.db.* / $INS.ops.* endpoints this tier consumes. The instance's capabilities — geo enrichment, the realtime advisory feed, the scrape interval, retention, and the license — are discovered from that node over $INS.ops.info (see the API reference), so none of it needs to be configured locally. A web-only node validates no license of its own; it renders the backend's.

Because it is a pure client of the API, it exposes only the flags a web tier uses — the web server (--web.*), the Prometheus endpoint (--prometheus.*), the updater (--updater.*), and the top-level connection flags. The full server configuration lives on insights serve.

insights web [flags]

Example

# Node A — indexer + scraper, no web, embedded NATS on a fixed port:
insights --web=false --sink.port=4222 --data-dir /var/lib/insights

# Node B — stateless web tier pointing at Node A:
insights web --server nats://node-a:4222 --web.hostname 0.0.0.0 --web.port 8080

insights mcp

Runs a read-only Model Context Protocol server that exposes ten tools over the db and checks endpoints for AI agents. Like query, it owns no database: it forwards each tool call to a running Insights node over NATS and is read-only by construction, so pointing an agent at a production instance is safe. For client setup (Claude Desktop, Claude Code, Cursor) and the full tool list, see the AI Agents guide.

insights mcp [flags]

Flags

FlagEnvDefaultDescription
--transportINSIGHTS_MCP_TRANSPORTstdiostdio for a client-spawned subprocess, or http for a long-running Streamable HTTP service.
--httpINSIGHTS_MCP_HTTP127.0.0.1:8090Listen address when --transport http.
--http-tlsINSIGHTS_MCP_HTTP_TLSfalseServe the http transport over HTTPS. Requires --http-tls-cert and --http-tls-key.
--timeoutINSIGHTS_MCP_TIMEOUT2mPer-tool NATS request timeout.

Plus the top-level connection flags for reaching the node.

Example

# Local stdio server, launched by an MCP client:
insights mcp --context my-nats-context

# Long-running HTTP service:
insights mcp --transport http --http 127.0.0.1:8090

insights http

Runs a stateless HTTP gateway that fronts the read-only db query API over plain HTTP, so an HTTP-only client — a BI or dashboard datasource, a script, another service — can query Insights without a NATS client. Like web, it owns no database: each HTTP request is translated into the matching $INS.db.* NATS request and the reply is returned as-is, so the read-only guard, the row cap, and per-account NATS auth all stay enforced upstream. See the HTTP gateway section of the API reference for the route map.

Point it at the node serving the $INS.db.* endpoints with --server (or --context), exactly like query. It adds a bearer token at its own edge and refuses to start without one unless --allow-unauthenticated is given.

insights http [flags]

Flags

FlagEnvDefaultDescription
--listenINSIGHTS_HTTP_LISTEN127.0.0.1:8080HTTP listen address. Use 0.0.0.0:<port> to accept remote connections (e.g. behind a TLS-terminating ingress).
--auth-tokenINSIGHTS_HTTP_AUTH_TOKEN(empty)Bearer token required on every request except /healthz (Authorization: Bearer <token>). Required unless --allow-unauthenticated.
--allow-unauthenticatedINSIGHTS_HTTP_ALLOW_UNAUTHENTICATEDfalseRun without a bearer token. Only for trusted, network-isolated deployments — never for public exposure.
--timeoutINSIGHTS_HTTP_TIMEOUT1mPer-request NATS request timeout.
--max-body-bytesINSIGHTS_HTTP_MAX_BODY_BYTES1048576Maximum request body size in bytes.

Plus the top-level connection flags for reaching the node that serves $INS.db.*.

Example

# Run the gateway pointed at an Insights node, with a bearer token:
export INSIGHTS_HTTP_AUTH_TOKEN=$(openssl rand -hex 32)
insights http \
  --server nats://insights.example.com:4222 \
  --creds ~/.config/nats/query.creds \
  --listen 0.0.0.0:8080

# Query it over HTTP:
curl -s localhost:8080/db/query \
  -H "Authorization: Bearer $INSIGHTS_HTTP_AUTH_TOKEN" \
  -d '{"sql":"SELECT name, cpu FROM hx.servers ORDER BY cpu DESC LIMIT 10"}'

insights query

Send a SQL query to the running Insights server over NATS and write the result to stdout. See the Search reference for the Insights query language. Use query for arbitrary DuckDB SQL against the hx schema.

insights query [flags] [SQL]

The SQL statement can be passed as a positional argument or piped on stdin. If both are omitted, the command exits with an error.

Flags

FlagEnvDefaultDescription
--format / -f(none)csvOutput format: csv or json.
--timeout(none)30sNATS request timeout.

Plus the top-level connection flags for reaching the server.

Examples

Inline SQL:

insights query "SELECT name, cpu FROM hx.servers ORDER BY cpu DESC LIMIT 10"

SQL via stdin:

cat query.sql | insights query --format json

Against a remote Insights server:

insights --server nats://insights.example.com:4222 \
  --creds ~/.config/nats/ops.creds \
  query "SELECT COUNT(*) FROM hx.connections"

insights db

Inspect the database without writing a full query: validate and plan (or profile) a statement, and discover the queryable schemas, tables, columns, and macros. These subcommands mirror the $INS.db.* discovery endpoints (see the API reference) and are scoped to the allowlisted schemas (hx, main, audit). The discovery commands read catalog metadata only and scan no data; db explain --analyze is the exception, since it executes the query to gather runtime timing. All of it is read-only, like query.

insights db explain [flags] [SQL]
insights db schemas [flags]
insights db tables  [flags]
insights db columns [flags]
insights db macros  [flags]

Flags

FlagDefaultDescription
--format / -ftextOutput format. explain: text or json; the discovery commands also accept csv.
--analyze / -afalse(explain) Execute the query with EXPLAIN ANALYZE and include per-operator runtime timing.
--schema(none)(tables, columns, macros) Restrict to one schema. Omit to span all allowlisted schemas.
--table(none)(columns) Restrict to one table or view.
--timeout30sNATS request timeout.

Plus the top-level connection flags. explain takes the SQL as a positional argument or on stdin, like insights query.

Examples

Discover schemas, then drill into one:

insights db schemas
insights db tables --schema hx
insights db columns --schema hx --table servers
insights db macros --schema audit

Plan a query before running it, or execute and profile it with --analyze:

insights db explain "SELECT name, cpu FROM hx.servers ORDER BY cpu DESC LIMIT 10"
insights db explain --analyze "SELECT name, cpu FROM hx.servers ORDER BY cpu DESC LIMIT 10"

insights checks list

List every audit check the server knows about, grouped by category. Default output is an aligned text table; pass --format for CSV or JSON.

insights checks list [flags]

Flags

FlagEnvDefaultDescription
--format / -f(none)textOutput format: text, csv, or json.
--timeout(none)30sNATS request timeout.

Example

insights checks list --format json | jq '.[] | .label'

insights checks info

Show the full metadata for a single check: description, severity, scope, and any tunable parameters with their default and currently resolved values.

insights checks info [flags] <CODE>

Flags

FlagEnvDefaultDescription
--format / -f(none)textOutput format: text or json.
--timeout(none)30sNATS request timeout.

Example

insights checks info SERVER_003

insights checks findings

Run one audit check by code over a time window and return the resulting findings.

insights checks findings [flags] <CODE>

<CODE> is a check code such as SERVER_001 or JETSTREAM_015. See the Audit Checks Reference for the full catalogue.

Flags

FlagEnvDefaultDescription
--format / -f(none)textOutput format: text, csv, or json. The JSON response includes pagination metadata.
--timeout(none)30sNATS request timeout.
--duration(none)(empty)Relative window as a DuckDB interval (e.g. 1 hour, 15 minutes, 7 days).
--start(none)(empty)Absolute start time (UTC, YYYY-MM-DDTHH:MM:SS). When omitted, derived from --duration.
--end(none)(empty, meaning "live")Absolute end time (UTC).
--page(none)1Page number (1-based) when results exceed one page.

Example

Run SERVER_003 (High CPU Usage) against the last hour:

insights checks findings SERVER_003 --duration "1 hour"

Page through findings as JSON (1-based):

insights checks findings JETSTREAM_001 --format json --page 2

insights ops backup

Create a consistent snapshot of the Insights database, upload it to the JetStream object store, and download it locally. This is the recommended way to archive historical data. The server copies tables into a new DuckDB file without blocking live writes.

insights ops backup [flags]

ops backup always prints a plan summary (time range, epoch coverage, estimated file size) to stderr. When stdin is a terminal, it prompts for confirmation before running. Pass --force / -f to skip the prompt. --force is required when running non-interactively (for example, cron or CI).

Flags

FlagEnvDefaultDescription
--output / -o(none)(server-generated filename)Local output path. Use - to stream to stdout.
--start(none)(no lower bound)Start time: absolute (YYYY-MM-DD, RFC3339, or YYYY-MM-DDTHH:MM:SS UTC) or relative duration (7d, 1h, 30m).
--end(none)(latest epoch)End time: same formats as --start.
--force / -f(none)falseSkip the confirmation prompt. Required for non-interactive use.
--timeout(none)10mNATS request timeout for the backup operation.

Examples

Back up the last seven days, prompting for confirmation:

insights ops backup --start 7d --output weekly-backup.db

Non-interactive full backup to a dated filename:

insights ops backup --force --output "insights-$(date +%Y%m%d).db"

Stream a backup to another host over SSH:

insights ops backup --force --output - | ssh archive "cat > /backups/insights-$(date +%s).db"

insights ops sizing

Recommend a DuckDB memory_limit and threads configuration for the running instance, grounded in DuckDB's per-thread guidance and the instance's real host capacity (cores and RAM) plus its observed memory use. Because it runs against the live database on the actual host the limits apply to, it is most useful run against an instance that is under load — for example when investigating a performance issue — after which you can decide whether to retune the limits or add host memory.

When the memory profiler is enabled (the default), the estimates are grounded in the peak memory measured under real load rather than conservative constants; the report flags when it had no samples to work from. The largest single write is usually a retention prune, which runs far less often than the profiler's rolling window — use --observe <duration> to watch the live profile long enough to span one so that peak is captured.

insights ops sizing [flags]

Flags

FlagDefaultDescription
--per-thread2GB per thread used in the query budget (DuckDB recommends 1–4).
--threads0Threads to size for (0 = recommend min(cores, 4)).
--observe / -o0Observe the live memory profile for this long and size from the peaks seen (0 = one-shot).
--timeout30sNATS request timeout.

Examples

# Size the running instance against its real host:
insights ops sizing

# Size for a specific thread count and per-thread budget:
insights ops sizing --threads 8 --per-thread 4

# Observe live load for an hour (ideally spanning a retention prune):
insights ops sizing --observe 1h

insights ops memory

Show the running instance's live DuckDB memory profile: current and peak resident bytes per component over a rolling window. This is the ground truth behind ops sizing's measured estimates, and a quick way to watch what the database is actually doing under load.

A background sampler in the server records the memory profile on an interval into a rolling window (both configurable under --db.memory-profile.*); ops memory reads that retained snapshot over NATS rather than sampling on demand. The same readings are also exported as the insights_duckdb_memory_bytes Prometheus gauge. Output is a summary table (current / peak / peak time per component) followed by a small self-scaled trend chart per component.

insights ops memory [flags]

Flags

FlagDefaultDescription
--live / -lfalseContinuously re-render the profile as the server samples it (Ctrl-C to stop).
--timeout30sNATS request timeout.

Example

insights ops memory --live

If the profiler is disabled (--db.memory-profile.enabled=false), the command reports that no samples are available.

insights ops pprof

Capture a runtime profile from the running instance for diagnostics — most usefully a goroutine dump to see where the process is parked when something has stalled (for example, a scrape or index loop that stopped advancing). The server does not expose HTTP profiling handlers, so this subcommand is the way to reach the standard profiles.

insights ops pprof [flags]

Flags

FlagDefaultDescription
--typegoroutineProfile to capture: goroutine, heap, allocs, threadcreate, block, mutex.
--debug0Debug level: 0 = binary protobuf for go tool pprof; 1 = text with aggregated counts; 2 = full per-goroutine stacks.
--output / -o(none)Write the profile to this file instead of stdout.
--timeout30sNATS request timeout.

A binary profile (--debug 0) is refused when stdout is a terminal — pass --output to write it to a file, or --debug 2 for a readable text dump.

Examples

# Read a goroutine dump directly:
insights ops pprof --type goroutine --debug 2

# Capture a heap profile and open it in pprof:
insights ops pprof --type heap --output heap.pprof
go tool pprof heap.pprof

block and mutex return an empty profile unless their sampling was enabled at server startup.

--version

Print the binary version and exit. Recognized only as the sole argument:

insights --version

Official release binaries print a semantic version. Unstamped binaries print dev.