CLI Reference
Every maple command, argument, and flag — plus the server endpoints, environment variables, and troubleshooting for local mode.
The maple binary is one CLI with two backends: a local server (maple start) and a remote workspace (maple login). Every query command runs against whichever is resolved for that invocation. Output is JSON by default — clean enough to pipe into jq or an agent.
This page is the complete surface. For a guided walkthrough, start with Maple Local.
Global flags
These are accepted by every command (position-independent — maple --local traces and maple traces --local both work):
| Flag | Description |
|---|---|
--local | Force local mode (requires a running maple start) |
--remote | Force remote mode (requires maple login) |
--debug | Print the compiled SQL and per-query timing to stderr (stdout stays clean JSON) |
--format <json|table> | Output format; default json. table renders a flat row set as an aligned table |
Most query commands also share a set of filter flags. Defaults and availability vary per command (listed below), but the shapes are consistent:
| Flag | Alias | Default | Description |
|---|---|---|---|
--since <range> | 6h | Relative time range — 30m, 1h, 6h, 24h, 7d | |
--start <time> | Absolute start, YYYY-MM-DD HH:mm:ss UTC (use with --end) | ||
--end <time> | Absolute end, YYYY-MM-DD HH:mm:ss UTC | ||
--service <name> | -s | Filter by service name | |
--env <name> | -e | Filter by deployment environment (e.g. production) | |
--limit <n> | -n | 20 | Maximum number of results |
--offset <n> | 0 | Pagination offset |
Server commands
Local mode only. maple start is the long-lived process that owns the embedded chDB connection; the query commands talk to it over HTTP.
maple start
Start the local ingest + query server (embedded ClickHouse via chDB).
| Flag | Default | Description |
|---|---|---|
--host <address> | 127.0.0.1 | Bind address; non-loopback exposes all unauthenticated local routes |
--advertise-host <host> | connection-safe bind address | Host printed for clients and the bundled UI |
--port <int> | 4318 | Port for OTLP/HTTP ingest, query API, and bundled UI |
--data-dir <path> | ~/.maple/data | Embedded ClickHouse data directory |
--chdb-config-file <path> | Optional ClickHouse config file passed to embedded chDB | |
--offline | false | Serve the bundled same-origin UI instead of local.maple.dev |
--background, -d | false | Run detached; stop with maple stop |
--reset | false | Wipe live chDB data while preserving checkpoints |
--on-dirty-store <wipe|fail|restore-checkpoint> | fail | Recovery policy when the store was not cleanly closed |
maple start # foreground, UI from local.maple.dev
maple start --offline # foreground, bundled UI, no internet needed
maple start -d --port 4400 # detached on a custom port
maple start --host 0.0.0.0 --advertise-host maple.home.arpa --offline
Detached startup forwards the selected --on-dirty-store policy unchanged to
the foreground child. Before any reset, compatibility check, dirty-store
decision, or data-directory creation, startup reconciles a recorded reset or
checkpoint-restore transaction. Ambiguous, malformed, or conflicting
transaction state fails closed and prints the preserved paths.
The default dirty-store policy is fail, so an unclean shutdown never silently
deletes telemetry. Choose restore-checkpoint to recover the selected
checkpoint, or explicitly choose wipe to discard only live chDB data.
Checkpoint snapshots, pins, operation evidence, and quarantine state under
<data-dir>/backups are preserved by both --reset and explicit wipe.
Schema-incompatible stores also fail closed until an operator explicitly
resets live data.
maple stop
Stop a running maple start server (reads the PID file beside the data dir).
| Flag | Default | Description |
|---|---|---|
--data-dir <path> | ~/.maple/data | Data directory of the server to stop |
maple reset
Delete live chDB data so the next maple start bootstraps fresh. The checkpoint
registry under <data-dir>/backups is preserved. Refuses to run while a server
still owns the store.
Reset is journaled beside the data directory and removes only the chDB-owned
top-level directories produced by the bundled native build (data, metadata,
store, and tmp). If any other entry exists, reset preserves everything and
fails with the unrecognized paths so an operator can inspect them. Startup
finishes an interrupted recorded reset before it evaluates store compatibility
or cleanliness.
| Flag | Default | Description |
|---|---|---|
--data-dir <path> | ~/.maple/data | Store whose live data clears |
--yes, -y | false | Skip the confirmation prompt |
maple checkpoint
Create and validate a restorable checkpoint of the local chDB store. The running server must have been started with a chDB config that allows ClickHouse backups:
<clickhouse>
<backups>
<allowed_disk>default</allowed_disk>
<allowed_path>backups</allowed_path>
</backups>
</clickhouse>
maple start --chdb-config-file ./chdb-backups.xml
maple checkpoint
Checkpoint accepts --host, --port, and --data-dir. Wildcard hosts are
queried through matching loopback; if the server was started with one-off host
or port flags, pass the same values to maple checkpoint.
Every completed checkpoint receives an immutable UUID and is written under:
<data-dir>/backups/
state.json
snapshots/<checkpoint-id>/
backup/
manifest.json
operations/
pins/
quarantine/
retiring/
state.json is the only authority for the selected current and previous
IDs. Maple writes and syncs a strict versioned manifest only after restoring
the native backup into one sacrificial chDB and validating all six raw telemetry
tables. It then selects the snapshot with a synced atomic state-file
replacement. A third checkpoint retires the old previous snapshot only when it
is complete, compatible, unreferenced, and unpinned; uncertain state is
preserved.
The earlier unreleased backups/{building,current,previous} preview layout is
not inferred or deleted. If it is present without a valid new state pointer,
checkpoint commands fail closed and report the paths for operator inspection.
Missing, malformed, incompatible, incomplete, or symlinked checkpoint state is
also rejected rather than guessed.
maple restore
Restore the local chDB store from the last promoted checkpoint. Refuses to run while a server still owns the store. The existing store is moved aside for quarantine rather than deleted.
| Flag | Default | Description |
|---|---|---|
--data-dir <path> | ~/.maple/data | Store to restore |
--checkpoint-id <uuid> | selected current | Restore one immutable checkpoint ID |
--yes, -y | false | Skip the confirmation prompt |
Restore uses a collision-resistant working path and quarantine, and records a durable sibling transaction before changing the live directory. Reconciliation can resume the recorded quarantine, live swap, and marker-update boundaries idempotently. The displaced live store is never deleted. Unrecorded or mismatched restore-like paths fail closed without mutation.
maple restore --yes
maple restore --checkpoint-id 01234567-89ab-4cde-8fab-0123456789ab --yes
Checkpoint and restore operations share one maintenance lock. A live owner is reported as busy; uncertain ownership is preserved and blocks destructive maintenance.
Archive commands
Local mode only. Export sealed UTC-day ranges of the six raw telemetry tables from immutable checkpoints into portable Parquet, queryable independently with DuckDB. See Local telemetry archives for the full architecture, calibration, and off-happy-path reference.
maple archive create <range-date> <signal>
Seal one UTC day of one signal into a validated Parquet generation from a checkpoint. Resolves and pins the checkpoint (default: current), restores it to sacrificial scratch, exports bounded Parquet shards, validates row counts and checksums, atomically selects the generation, and releases the pin. The live store is never opened for export.
| Argument / Flag | Description |
|---|---|
<range-date> | UTC day to seal, YYYY-MM-DD |
<signal> | logs, traces, metrics_sum, metrics_gauge, metrics_histogram, or metrics_exponential_histogram |
--data-dir | Live chDB data directory (default: ~/.maple/data) |
--archive-dir | Archive root (default: ~/.maple/archive) |
--scratch-root | Restored-checkpoint scratch root (default: ~/.maple/scratch) |
--checkpoint-id | Archive from a specific checkpoint instead of the selected current |
A late-arrival re-export creates a new generation that supersedes the old one; the previous generation is retained but excluded from active listings and query paths.
maple archive list
Report active archive generations. Superseded generations are retained on disk but never listed.
| Flag | Description |
|---|---|
--archive-dir | Archive root (default: ~/.maple/archive) |
--output summary|paths|json | summary (default), paths (machine-readable active Parquet paths for DuckDB), or json |
--signal <name> | Required with --output paths; the signal whose active paths to emit |
maple archive rebuild <signal>
Rebuild a signal’s catalog.jsonl from the authoritative generation manifests,
recovering from a truncated or missing catalog without rescanning Parquet bytes.
Services
maple services
List active services with throughput, error rate, and P95 latency. Flags: --since / --start / --end, --env.
maple diagnose <service-name>
Deep-dive a service: health, top errors, recent traces and logs.
<service-name>— service to diagnose- Flags:
--since/--start/--end,--env
maple service-map
Service dependency edges (call counts, errors, latency). Flags: --since / --start / --end, --service, --env.
maple top-ops <service-name>
Top operations (span names) for a service, ranked by a metric.
<service-name>— service to inspect--metric <count|avg_duration|p50_duration|p95_duration|p99_duration|error_rate|apdex>— ranking metric (defaultcount)- Flags:
--since/--start/--end,--limit
Traces
maple traces
Search traces/spans.
| Flag | Description |
|---|---|
--span-name <substr> | Filter by span name (substring, case-insensitive) |
--errors | Only include traces with errors |
--min-duration-ms <int> | Minimum duration in milliseconds |
--max-duration-ms <int> | Maximum duration in milliseconds |
--http-method <method> | Filter by HTTP method (GET, POST, …) |
Plus --since / --start / --end, --service, --limit, --offset.
maple traces --service api --min-duration-ms 500 --errors --since 1h
maple trace <trace-id>
Inspect a trace: full span tree + correlated logs.
<trace-id>— trace ID to inspect
maple slow-traces
Find the slowest traces with duration stats. Flags: --since / --start / --end, --service, --env, --limit.
Errors
maple errors
List error groups by fingerprint (count, affected services, last seen). Flags: --since / --start / --end, --service, --env, --limit.
maple error <fingerprint-hash>
Show detail for one error group: sample traces + timeseries.
<fingerprint-hash>— error fingerprint hash (from theerrorscommand)- Flags:
--since/--start/--end,--service,--limit
Logs
maple logs
Search logs with filtering.
| Flag | Alias | Description |
|---|---|---|
--severity <level> | Filter by severity (TRACE/DEBUG/INFO/WARN/ERROR/FATAL) | |
--search <text> | -q | Search text (substring match) |
--trace-id <id> | Filter by trace ID |
Plus --since / --start / --end, --service, --limit, --offset.
maple log-patterns
Cluster logs into templates to surface the noisiest patterns. Flags: --since / --start / --end, --service, --severity, --search/-q, --limit.
Attributes
maple attributes has two subcommands for discovering attribute keys and values.
maple attributes keys
Discover available attribute keys.
| Flag | Default | Description |
|---|---|---|
--source <traces|metrics|services> | traces | Attribute source |
--scope <span|resource> | span | Attribute scope (traces only) |
Plus --service, --since / --start / --end, --limit.
maple attributes values <key>
List values for an attribute key.
<key>— attribute key to list values for- Flags: same as
attributes keys
Metrics and raw SQL
maple metrics
List available metrics. Flags: --since / --start / --end, --service, --search/-q, --limit.
maple query "<sql>"
Run raw ClickHouse SQL against the local chDB store — an escape hatch for anything the typed commands don’t cover.
<sql>— raw ClickHouse SQL
maple query "SELECT ServiceName, count() FROM traces GROUP BY ServiceName ORDER BY 2 DESC"
Local only. Raw SQL against the multi-tenant cloud warehouse would let a client read other orgs’ data, so
maple queryreturns a clear error in remote mode. Every other command works in both modes.
Analytics
maple timeseries
Time-bucketed trace metrics (count, latency quantiles, error rate, apdex emitted per bucket).
| Flag | Default | Description |
|---|---|---|
--group-by <none|service|span_name|status_code|http_method> | none | Group series by dimension |
--span-name <substr> | Filter by span name | |
--errors | false | Only include errored spans |
--bucket <seconds> | 60 | Bucket size in seconds |
Plus --since / --start / --end, --service, --env.
maple breakdown
Top-N trace breakdown by dimension (service, span, status code, http method).
| Flag | Default | Description |
|---|---|---|
--group-by <service|span_name|status_code|http_method> | span_name | Group results by dimension |
--span-name <substr> | Filter by span name | |
--errors | false | Only include errored spans |
Plus --since / --start / --end, --service, --env, --limit.
maple compare
Compare service health between two time windows (regression detection). Provide either --around or all four explicit window bounds.
| Flag | Description |
|---|---|
--around <ts> | Compare the 30m before vs. after this UTC time (YYYY-MM-DD HH:mm:ss) |
--current-start <ts> / --current-end <ts> | The “current” window |
--previous-start <ts> / --previous-end <ts> | The baseline window |
--env <name> | Filter by deployment environment |
Auth and configuration
Remote credentials live in ~/.maple/config.json (mode 0600).
maple login
Save remote workspace credentials.
| Flag | Description |
|---|---|
--api-url <url> | Maple API base URL (e.g. https://api.maple.dev) |
--token <token> | API token. If omitted, it’s read from stdin so it stays out of shell history |
maple logout
Remove the stored remote token from ~/.maple/config.json.
maple whoami
Show the resolved mode (local/remote) and target.
maple use <local|remote|auto>
Pin the default backend so commands stop auto-detecting, or restore auto-detect.
<mode>—local,remote, orauto(clear the pin)
Mode resolution, per command, in priority order:
--local/--remoteflags.defaultModepinned viamaple use.- Auto-detect — a configured token implies remote; otherwise a quick
GET /healthprobe of the local server implies local. If neither is available, the CLI prints an actionable error.
Server endpoints
maple start binds 127.0.0.1 by default. --host or
MAPLE_LOCAL_BIND_HOST may select another address; doing so exposes every route
below without application authentication. When --offline is set, the bundled
SPA is also served over GET.
| Method | Path | Purpose |
|---|---|---|
GET | /health | Liveness probe (returns OK); used by mode auto-detect |
POST | /v1/traces | OTLP traces ingest → { "accepted": <rowCount> } |
POST | /v1/logs | OTLP logs ingest |
POST | /v1/metrics | OTLP metrics ingest |
POST | /local/query | Run SQL: { "sql": "..." } → bare JSON array of rows |
OPTIONS | * | Restricted CORS/PNA preflight for the exact configured hosted UI origin |
OTLP bodies may be protobuf (default) or JSON, optionally gzip-encoded. The /local/query handler owns the output format — it strips any trailing FORMAT <ident> and re-appends FORMAT JSONEachRow, then wraps the rows into a JSON array, so clients POST their compiled SQL verbatim.
Environment variables
Runtime (CLI + server):
| Variable | Default | Purpose |
|---|---|---|
MAPLE_LOCAL_BIND_HOST | 127.0.0.1 | Server bind host and default same-machine CLI target; wildcards map to loopback |
MAPLE_LOCAL_ADVERTISE_HOST | connection-safe bind host | Host printed for clients and the bundled UI |
MAPLE_LOCAL_URL | derived bind host + 4318 | Explicit base URL override for CLI query and mode detection |
MAPLE_LOCAL_UI_URL | https://local.maple.dev | Exact separately hosted UI origin linked by maple start and allowed by CORS |
MAPLE_LIBCHDB | (auto) | Explicit path to libchdb. Otherwise resolved beside the binary (Homebrew keeps it in the same libexec dir), then ~/.maple/bin/libchdb.{so,dylib} |
MAPLE_API_URL | https://api.maple.dev | Remote API base URL |
MAPLE_API_TOKEN | Remote bearer token (overrides the stored value) | |
MAPLE_ORG_ID | Remote org override | |
MAPLE_DEBUG | Set to 1 to enable --debug | |
MAPLE_FORMAT | json | json or table — same as --format |
MAPLE_NO_UPDATE_CHECK | Set to 1 to disable startup update checks (the Homebrew wrapper sets this automatically) |
Homebrew:
brew install Makisuo/tap/maple
brew upgrade maple
brew uninstall maple
Homebrew-managed installs block maple update; use brew upgrade maple so Homebrew owns the installed version and receipt.
If Homebrew asks you to trust the third-party tap, run brew trust Makisuo/tap once and retry the install.
Manual installer (scripts/install.sh, env-only):
| Variable | Default | Purpose |
|---|---|---|
MAPLE_VERSION | latest | Release tag to install |
MAPLE_INSTALL_DIR | ~/.maple/bin | Where the 2-file bundle is installed |
MAPLE_BIN_DIR | (auto) | Where maple is symlinked onto PATH |
MAPLE_SKIP_CHECKSUM | 0 | Set to 1 to skip SHA-256 verification (air-gapped mirrors only) |
The on-disk config at ~/.maple/config.json stores apiUrl, token, orgId, and defaultMode. Env vars take precedence over stored values.
Troubleshooting
libchdb not found. The binary dlopens libchdb relative to its own path, then falls back to ~/.maple/bin. Homebrew keeps maple and libchdb together in its Cellar; the manual installer keeps them in ~/.maple/bin. If you move files by hand, keep libchdb.so/.dylib beside maple, or set MAPLE_LIBCHDB to its full path. (Running from source has no sibling library — set MAPLE_LIBCHDB or drop one in ~/.maple/bin.)
Homebrew installed but maple still runs the old binary. You probably have a manual-installer symlink earlier on PATH. Run command -v maple to confirm, then remove the old symlink or run curl -fsSL https://maple.dev/cli/uninstall | sh before reinstalling with Homebrew.
maple is already running (PID …). A server already owns this data dir. Stop it with maple stop, or start a second instance on another port and data dir: maple start --port 4400 --data-dir ~/.maple/data-2.
Incompatible store after an upgrade. If a new binary refuses to open an older store (the local store … is incompatible), explicitly clear live data with maple reset --yes, or start fresh in one step with maple start --reset. Both preserve the checkpoint registry; incompatible checkpoints remain preserved and fail closed until deliberately handled.
Browser asks to “access devices on your local network” (or CORS errors). The default dashboard at local.maple.dev is a public origin reaching your loopback server, which trips Chrome’s Private Network Access gate. Run maple start --offline to serve the dashboard same-origin — no prompt, no internet needed. For a wildcard LAN bind, also set --advertise-host to the hostname the browser will use; other browser hosts and cross-origins are rejected.
Authentication proxy blocks the bundled UI. The UI works with TLS and browser-managed authentication such as a session cookie or HTTP authentication. It does not inject a Bearer API key or copy an entry-page query parameter into /local/query and OTLP URLs.
No data appearing. Confirm your exporter points at the advertised host and port and the server is up (maple whoami, or curl <host>:4318/health). Widen the time range (--since 24h — the default is 6h). Local mode stores everything under org_id = "local"; a successful ingest responds { "accepted": <n> }.
No Maple backend found. No mode could be resolved: start local mode (maple start) or connect a workspace (maple login), or force one with --local / --remote.