CLI Reference

Tumult provides a single binary tumult with the following commands.

tumult run

Execute a chaos experiment.

tumult run <experiment.toon> [OPTIONS]
Option Default Description
--journal-path <path> journal.toon Output journal location
--force false Overwrite the journal file if it already exists
--dry-run false Validate and show plan without executing
--rollback-strategy <s> on-deviation always, on-deviation, or never (deviated is accepted as an alias for on-deviation)
--baseline-mode <m> full full, skip, or only
--no-ingest false Skip auto-ingestion into persistent analytics store
--output-format <f> json — print journal as JSON to stdout after run
--var KEY=VALUE Template variable substitution (repeatable)
--load <tool> Run a load test concurrently with the method (k6 or none)
--load-script <path> Path to load test script (k6 .js)
--load-vus <n> Number of virtual users for the load test
--load-duration <d> Load test duration (e.g. 30s, 5m)

Examples

# Basic run
tumult run experiment.toon

# Dry run — show plan without executing
tumult run experiment.toon --dry-run

# Custom journal path
tumult run experiment.toon --journal-path results/run-001.toon

# Always rollback regardless of outcome
tumult run experiment.toon --rollback-strategy always

# Skip baseline acquisition, use static tolerances
tumult run experiment.toon --baseline-mode skip

# Skip auto-ingest into persistent DuckDB store
tumult run experiment.toon --no-ingest

# Print journal as JSON to stdout (for piping/scripting)
tumult run experiment.toon --output-format json | jq '.status'

# Template variable substitution
tumult run experiment.toon --var env=staging --var cluster=eu-west-1

With the default on-deviation strategy, rollbacks run when the experiment deviates from its hypothesis or when a method step fails after a fault was injected. always runs them on every outcome; never skips them entirely.

Template Variables

The --var flag substitutes ${KEY} placeholders in the experiment’s title and activity names before execution. This allows a single experiment template to be reused across environments:

title: Resilience test for ${env} cluster ${cluster}

method[1]:
  - name: kill-${env}-primary
    ...
tumult run template.toon --var env=production --var cluster=us-east-1

Undefined variables cause a hard error at startup, not at execution time.

Exit Codes

Code Meaning
0 Experiment completed successfully
1 Experiment failed, deviated, interrupted, or aborted

Auto-Ingest

By default, tumult run writes the journal file and ingests experiment data into the persistent DuckDB store at ~/.tumult/lake.duckdb. Pass --no-ingest to skip store ingestion (useful in CI pipelines that manage their own storage).

When TUMULT_DAEMON_URL is set (e.g. http://localhost:4318), the journal is POSTed to the daemon’s /api/import/journal instead, so the write rides the daemon’s single-writer channel rather than racing its store lock. If the daemon is unreachable (no HTTP response), the CLI falls back to the direct store write; any HTTP answer — including an error — is treated as final.

When TUMULT_DAEMON_TOKEN is set (a kro_... API token), the journal POST to the daemon sends Authorization: Bearer <token>. Unset means no header is sent, which matches a loopback dev daemon running without authentication.

The daemon can also execute experiments itself via its run-control API — POST /api/runs/validate (register a definition), POST /api/runs/dry-run (resolved plan preview), POST /api/runs (enqueue, bounded queue with 429 backpressure), POST /api/runs/{id}/stop (e-stop with rollbacks), GET /api/runs[/{id}] (state + audit trail), GET /api/runs/{id}/audit/verify (re-verify the audit hash chain). See ADR-011.

tumult validate

Validate experiment syntax, structure, and plugin references.

tumult validate <experiment.toon>

Note: tumult validate only validates experiment files — it does not validate .gameday.toon files (those are checked when you run tumult gameday run).

Reports:

  • Title, description, tags
  • Method and rollback step counts
  • Hypothesis probe count
  • Phase 0/1 configuration presence
  • Configuration and secret resolution status
  • Template variable references (warns on undefined vars)

Example

tumult validate experiment.toon

tumult discover

List all available plugins and their actions — both script plugins (discovered from the filesystem) and native plugins (compiled into the binary), labeled (script) / (native).

tumult discover [OPTIONS]
Option Description
--plugin <name> Show details for a specific plugin

Plugin Search Paths

Script plugins are discovered from (in order):

  1. ./plugins/ — local to the experiment
  2. ~/.tumult/plugins/ — user-global
  3. $TUMULT_PLUGIN_PATH — custom paths (colon-separated)

At runtime you can override the search paths without modifying the binary. Native plugins (tumult-ssh, tumult-net, tumult-kubernetes, tumult-cloud, tumult-windows) are registered in the binary itself and are always listed.

Examples

# List all plugins
tumult discover

# Show details for a specific plugin (script or native)
tumult discover --plugin tumult-kafka
tumult discover --plugin tumult-ssh

From the repository root (11 script plugins in ./plugins/ plus the 5 built-in native plugins):

$ tumult discover
Discovered 16 plugin(s) (11 script, 5 native):

  tumult-cloud (native)
  tumult-containers (script)
  tumult-db-mysql (script)
  tumult-db-postgres (script)
  tumult-db-redis (script)
  tumult-kafka (script)
  tumult-kubernetes (native)
  tumult-loadtest (script)
  tumult-net (native)
  tumult-network (script)
  tumult-process (script)
  tumult-pumba (script)
  tumult-ssh (native)
  tumult-stress (script)
  tumult-timewarp (script)
  tumult-windows (native)

Actions: 91
  tumult-containers::kill-container
  ...
  tumult-kubernetes::delete_pod
  ...
  tumult-ssh::execute
  ...

tumult init

Create a new experiment from a template.

tumult init [OPTIONS]
Option Description
--plugin <name> Reference a specific plugin name in the generated template

Scaffolds experiment.toon in the current directory from a bundled, self-contained template (steady-state hypothesis, method, and rollbacks built only on uname/sh/echo — no Docker or network needed). This writes a static template; it does not prompt interactively.

Example

tumult init
tumult init --plugin tumult-db-postgres

tumult analyze

SQL analytics over journal files using embedded DuckDB.

tumult analyze [journals-dir] [OPTIONS]
Option Description
--query <sql> Custom SQL query
--last <n> Show summary of the last N experiments (default: 1 if no --query)
--all Show store-wide aggregate summary

If journals-dir is omitted, queries the persistent store at ~/.tumult/lake.duckdb.

--query is read-only: only SELECT and WITH statements are accepted; anything else is rejected before execution.

Examples

# Query persistent store (no path needed)
tumult analyze --query "SELECT status, count(*) FROM experiments GROUP BY status"

# Query a specific directory of journals
tumult analyze journals/ --query "SELECT title, duration_ms FROM experiments ORDER BY duration_ms DESC"

# Default query: experiment summary
tumult analyze journals/

tumult export

Convert journal to other formats.

tumult export <journal.toon> [OPTIONS]
Option Default Description
--format <f> parquet parquet, arrow, csv, or json

tumult compliance

Generate regulatory compliance reports.

tumult compliance <journals-dir> --framework <name>

Supported frameworks: dora, nis2, pci-dss, iso-22301, iso-27001, soc2, basel-iii

Example

tumult compliance journals/ --framework dora
tumult compliance journals/ --framework pci-dss

tumult trend

Cross-run trend analysis over journal files. trend requires a <journals> path (directory or file) — it loads those journals into a temporary in-memory store for the query; it does not read the persistent store.

tumult trend <journals-dir> [OPTIONS]
Option Default Description
--metric <m> resilience_score Metric to trend (resilience_score, duration_ms, estimate_accuracy, method_step_count)
--last <window> Time window: 30d, 90d, etc.
--target <tech> Filter by target system (matches experiment title)

Examples

tumult trend journals/ --metric duration_ms --last 30d
tumult trend journals/ --target postgresql --metric resilience_score

tumult report

Generate a report from a journal — HTML (default), PDF-ready HTML, JSON, or JUnit XML.

tumult report <journal.toon> [OPTIONS]
Option Description
--output <path> Output file path (default: report.html)
--format <f> html (default), pdf, json, or junit
--trace-ui-base <url> Base URL of a trace UI (e.g. Jaeger/Tempo) — HTML reports render each activity’s trace_id as a clickable link (falls back to the TUMULT_TRACE_UI_BASE env var)

tumult import

Import journals from a Parquet backup directory.

tumult import <parquet-dir>

Transactional import — data is committed only if all files load successfully.

tumult store

Manage the persistent analytics store.

tumult store <subcommand>
Subcommand Description
stats Show experiment/activity counts and store file size
backup [--output <dir>] Dump store to Parquet files
purge --older-than-days <N> Delete experiments older than N days
path Print the store file path
migrate Migrate data from DuckDB to ClickHouse backend
import-legacy [--analytics-db <path>] [--kronika-db <path>] [--store <path>] Import databases from older installs (old analytics store and/or kronika lake) into the current store; idempotent

Examples

tumult store stats
tumult store backup --output ~/tumult-backup-2026-03
tumult store purge --older-than-days 90
tumult store migrate   # requires TUMULT_CLICKHOUSE_URL
tumult store import-legacy --analytics-db ~/.tumult/analytics.duckdb

tumult recommend

Recommend the next useful chaos experiment from deterministic heuristics over the analytics store (coverage gaps, failing experiments, stale experiments), optionally enhanced by a local agent CLI.

tumult recommend [OPTIONS]
Flag Description
--goal <GOAL> Recommendation goal or operator intent
--store-path <PATH> Analytics store path to inspect (default: persistent store)
--model <MODEL> Model label to include in deterministic recommendation metadata
--no-draft Do not include a draft TOON experiment
--format <text\|json> Output format (default: text)
--agent <NAME> Enhance recommendations with an agent CLI adapter (claude-code, codex)
--agent-model <MODEL> Model override passed to the agent CLI (requires --agent)
--agent-timeout <SECS> Agent CLI timeout in seconds (default: 120)
--generate-experiments <DIR> Write validated agent-proposed experiments into <DIR> (requires --agent)

With --agent, the heuristic output is printed first, followed by an “Agent-enhanced recommendations” section. With --generate-experiments, every proposed experiment is parsed and validated (parse_experiment + validate_experiment) before writing; valid ones are written to <DIR>/<title-slug>.toon (collisions get -2, -3, … — never overwritten), invalid ones are rejected with the validation error and counted in a summary line. In JSON mode the output gains an agent object: { adapter, model, recommendations, experiments_written, experiments_rejected }.

Examples

# Deterministic heuristics only
tumult recommend --goal "harden the cache tier"

# Enhanced by Claude Code, generating experiment files
tumult recommend --agent claude-code --generate-experiments out/experiments

# Enhanced by Codex with model + timeout overrides, JSON output
tumult recommend --agent codex --agent-model gpt-5-codex --agent-timeout 300 --format json

See the Agentic Recommendations guide for how the prompt is built and how the validation gate works.

tumult agents

List agent CLI adapters and their detected state: name, installed, version, auth detail, and an install hint when the binary is missing.

tumult agents
ADAPTER        INSTALLED  VERSION    DETAIL
claude-code    yes        2.0.13     Authenticated via ANTHROPIC_API_KEY.
codex          no         -          Codex CLI not found on PATH. Install with: npm i -g @openai/codex

Binary resolution honors the CLAUDE_CODE_BIN / CODEX_BIN env overrides.

tumult mcp serve

Start the MCP (Model Context Protocol) server from the main tumult binary. This is the recommended way to launch the server — it runs in-process, so no separate tumult-mcp executable needs to be installed alongside the CLI. (The standalone tumult-mcp binary below remains available and behaves identically.)

tumult mcp serve                                    # stdio (IDE integration)
tumult mcp serve --transport http --port 3100       # Streamable HTTP (containers, CI/CD)
tumult mcp serve --transport http --token my-secret # require bearer auth
Option Description
--transport <stdio\|http> Transport mode (default: stdio)
--host <addr> Bind address for HTTP transport and health endpoint (default: 127.0.0.1; a non-loopback bind such as 0.0.0.0 requires --token)
--port <port> Port for the HTTP transport (default: 3100)
--health-port <port> Port for the /health endpoint (default: port + 1)
--token <token> Require this bearer token on every request (sets TUMULT_MCP_TOKEN, mapped to the operator role)
--auth-config <path> TOML auth config granting per-token roles (viewer/operator); overrides --token (sets TUMULT_MCP_AUTH_CONFIG)

The exposed tools, authentication, and data model are identical to the standalone binary documented next.

tumult-mcp

Start the MCP (Model Context Protocol) server: a separate binary using stdio by default or Streamable HTTP. Equivalent to tumult mcp serve.

tumult-mcp                                # stdio (IDE integration)
tumult-mcp --transport http --port 3100   # Streamable HTTP (containers, CI/CD)

Exposes 40 tools to AI assistants, grouped by area:

Area Tools
Experiments tumult_run_experiment, tumult_validate, tumult_discover, tumult_create_experiment, tumult_list_experiments
Journals and analytics tumult_read_journal, tumult_list_journals, tumult_analyze, tumult_analyze_store, tumult_store_stats, tumult_query_traces, tumult_report, tumult_compliance, tumult_trend
GameDays tumult_gameday_run, tumult_gameday_analyze, tumult_gameday_create, tumult_gameday_list
Intelligence tumult_recommend, tumult_coverage, tumult_agents, tumult_fault_catalog, tumult_scaffold_experiment
Agentic testing tumult_agentic_list_scenarios, tumult_agentic_smoke, tumult_agentic_run_experiment
ChaosGraph tumult_chaosgraph_query, tumult_chaosgraph_neighbors, tumult_chaosgraph_coverage_gaps, tumult_chaosgraph_cypher
Topology tumult_topology_import, tumult_topology_map, tumult_compliance_lineage, tumult_recommend_injection
Autopilot tumult_autopilot_run, tumult_autopilot_status, tumult_autopilot_respond, tumult_autopilot_export, tumult_autopilot_notify
Access tumult_whoami

Every tool carries MCP tool annotations (readOnlyHint / destructiveHint / idempotentHint / openWorldHint), 30 tools return structuredContent with advertised output schemas, and workspace files are served as tumult://journal|experiment|gameday/{file} resources. The four destructive-annotated tools are tumult_run_experiment, tumult_gameday_run, tumult_autopilot_run, and tumult_autopilot_respond. See the MCP Guide for the full data model.

Tool failures are returned with isError: true per the MCP specification. Authentication and rate-limit rejections are reported as such — not as “Unknown tool”.

Authentication

Set TUMULT_MCP_TOKEN to require bearer token auth on all tool calls. If not set, the server runs without authentication (log warning emitted).

TUMULT_MCP_TOKEN=my-secret tumult-mcp

Callers must pass Authorization: Bearer my-secret in MCP request metadata.

tumult chaosgraph

Query the ChaosGraph knowledge graph — the typed node/edge model over accumulated chaos data that also backs the chaosgraph_* MCP tools. These commands read the analytics store directly, so an operator can explore the graph without an MCP client.

tumult chaosgraph query --kind <kind> [--filter <substr>]
tumult chaosgraph neighbors --node <id> [--rel <rel>] [--depth <n>]
tumult chaosgraph coverage-gaps [--framework <fw>] [--domain <plugin>]
Option Description
--kind <kind> Node kind to list: experiment, fault, service, journal, …
--filter <substr> Case-insensitive label substring filter (query)
--node <id> Node id to center on, e.g. exp:My experiment (neighbors)
--rel <rel> Restrict traversal to one relation, e.g. injects, targets (neighbors)
--depth <n> Traversal depth in hops (neighbors, default 1)
--framework <fw> Annotate gaps with a framework’s still-unevidenced articles (coverage-gaps)
--domain <plugin> Filter gaps to a fault domain / plugin (coverage-gaps)
--refresh Also persist the derived gap sub-graph into the store so chaosgraph query/neighbors can navigate it — takes a write lock, so it conflicts with a running MCP server on the same store (coverage-gaps)
--format <text\|json> Output format (all; default text)
--store <path> Analytics store path (all; default ~/.tumult/lake.duckdb)

Examples

# Every fault primitive that has appeared in a run
tumult chaosgraph query --kind fault

# What one experiment touched — nodes and edges within 1 hop
tumult chaosgraph neighbors --node "exp:Redis resilience — verify recovery after disruption"

# Untested actions, with DORA articles still lacking evidence
tumult chaosgraph coverage-gaps --framework dora

# Structured output for scripting
tumult chaosgraph query --kind service --format json

The store must exist (run at least one experiment first); a missing store yields a clean store not found error.

tumult new

Interactive experiment builder: pick a fault (domain → action → args → target → probe → title) and get a validated, ready-to-run experiment. With --from <template> it instantiates a curated starter non-interactively.

tumult new [--from <template>] [--set KEY=VALUE]... [--out <path>]

Examples

# Interactive picker
tumult new

# Instantiate a curated starter with parameter overrides
tumult new --from postgres-connection-kill --set host=db.internal --out pg-kill.toon

tumult templates

List the curated starter templates (name, description, params) accepted by tumult new --from.

tumult templates

tumult agentic

Agentic AI fault-injection scenarios and local smoke tests — scenario packs, deterministic fixtures, multi-turn trajectories, and a live-traffic proxy.

tumult agentic <list-packs|smoke|run|trajectory|replay|proxy|run-live>

See the Agentic Scenarios guide for pack authoring and the Agentic Observability guide for trace capture.

tumult gameday

Coordinated experiment campaigns with resilience scoring and compliance mapping.

tumult gameday <create|run|analyze>
Subcommand Description
create Create a .gameday.toon file from experiment paths
run Run all experiments in a GameDay under shared load
analyze Show aggregate analysis of a completed GameDay

See the Experiment Scheduling guide for recurring GameDays.

tumult topology

Declared service topology, compliance lineage, and injection recommendations over the analytics store.

tumult topology <import|discover-k8s|map|lineage|recommend>
Subcommand Description
import Import a declared topology TOML (services + depends_on) into the store
discover-k8s Propose a topology TOML from a live cluster (never writes the store)
map Render the compliance-aware service map (text, Mermaid, or JSON)
lineage Show the (article × service) compliance lineage matrix
recommend Rank the next most valuable fault injections, with reasons

See the Topology guide.

tumult autopilot

Policy-gated autopilot: decide, record, and (only when told to) enact the next compliance-driven fault injections. Audit-before-act: decisions are persisted before anything runs.

tumult autopilot <once|status|approve|deny|notify-change|export>
Subcommand Description
once Run one pass of the decision loop (without --execute nothing is injected)
status List recorded decisions with their latest lifecycle event
approve Approve a proposed decision — runs its playbook experiment
deny Deny a proposed decision — records veto feedback
notify-change Record a deploy/config change event against a service
export Export the decision and event tables as Parquet files

See the Autopilot guide.

tumult tui

Open the interactive analytics TUI over the store (read-only dashboard).

tumult tui [--store <path>] [--refresh-secs <n>]

Environment Variables

Variable Description
TUMULT_PLUGIN_PATH Additional plugin search paths (colon-separated)
TUMULT_OTEL_ENABLED Enable/disable OTel (default: true)
TUMULT_OTEL_CONSOLE Print spans to console (default: false)
RUST_LOG Tracing filter. When unset and no OTLP endpoint is configured, the CLI defaults it to warn to keep interactive output clean; set it explicitly (e.g. info) to see audit/telemetry logs
TUMULT_MCP_TOKEN Bearer token for MCP server authentication
TUMULT_DAEMON_URL Daemon URL (e.g. http://localhost:4318) — tumult run POSTs journals to the daemon’s /api/import/journal instead of writing the store directly (see Auto-Ingest under tumult run)
TUMULT_DAEMON_TOKEN kro_... API token sent as Authorization: Bearer on daemon journal POSTs
CLAUDE_CODE_BIN Explicit path to the Claude Code binary for recommend --agent / agents
CODEX_BIN Explicit path to the Codex binary for recommend --agent / agents
TUMULT_CLICKHOUSE_URL ClickHouse URL for SigNoz cross-correlation mode
OTEL_EXPORTER_OTLP_ENDPOINT OTLP endpoint URL
OTEL_SERVICE_NAME Service name for telemetry (default: tumult)
DATABASE_HOST / custom Resolved via configuration blocks in experiment

Tumult is open source under the Apache-2.0 license.