Generated from mqlite main · docs/cli.md — source v0.3.3; latest release: v0.3.3. These docs track main; check release notes for published artifacts. Edit the canonical Markdown and re-run tools/build.mjs.

CLI reference (mqlite)

One binary, two modes — the same commands work against a local SQLite DB (embedded) or a running broker (client), chosen by environment:

mqlite <command> [flags] [args]

Connection (environment)

Env Meaning
MQLITE_DB embedded DB DSN: file:./mq.db / :memory: / libsql://<db>.turso.io
MQLITE_DB_AUTH_TOKEN auth token for a remote libSQL/Turso DSN
MQLITE_ENDPOINT + MQLITE_TOKEN client mode: a running broker + its Bearer token
MQLITE_MONITOR_TOKENS optional comma-separated read-only credentials for observe and /metrics; requires administrator auth and credentials distinct from administrators
MQLITE_TOKENS broker (serve) administrator Bearer tokens; unset → a mqk_… token is generated + printed, =off disables auth; additional managed keys live in the database
MQLITE_METRICS authenticated Prometheus /metrics on the API port; on/true/1 enables, off/false/0 disables (default); requires administrator auth
MQLITE_DIAGNOSTIC_LOG optional private rotating JSONL failure/recovery log path for serve; parent must exist; use persistent storage
MQLITE_SYNC NORMAL (default) / FULL / OFF / EXTRA durability (embedded/serve). An unrecognized value is rejected at startup — a typo never silently downgrades to NORMAL.
MQLITE_DLQ_MAX_AGE · MQLITE_DLQ_MAX_COUNT · MQLITE_DLQ_MAX_BYTES broker DLQ retention (serve); on by default, disable with MQLITE_DLQ_RETENTION=off

The DB string is never compiled in — it comes from the environment. The endpoint comes from the environment too, or from --endpoint (below), which overrides it.

Global flags (data + admin commands)

Flag Meaning
--endpoint <url> client mode: a running broker (overrides MQLITE_ENDPOINT)
--token <bearer> Bearer token for --endpoint (overrides MQLITE_TOKEN)
--output text|json text (default, human) or json (machine-readable, for scripting)

They apply to the data and admin commands. serve, version and help take none of them (a broker is not a client), and vacuum is local-only — it rejects --endpoint outright, because reclaiming pages means opening the DB file directly.

An ambient MQLITE_TOKEN is sent only to the endpoint that environment names. If --endpoint points at a different broker, the token is withheld (with a warning) rather than leaked to another host — pass --token to authenticate there. --token= (empty) explicitly sends no credential at all. Two spellings of the same broker (a trailing slash, mqlite://h vs http://h:6754) are the same target and keep the token.

--output json uses the wire's field names

Every message the CLI emits in --output json is the HTTP API's message object — the same struct, so the same field names and encodings (seq_number, body base64, epoch-ms timestamps). The CLI never invents or renames a key.

Two things are the CLI's own, and are not claims about the HTTP response:

The CLI also doesn't expose every HTTP operation (batch send, attempt ids). For the complete contract — all routes, all fields — see api-reference.md.

Settling across invocations needs a broker. receive --no-ack locks a message and prints its lock-token; you settle it later with complete/abandon/reject/defer/renew <queue> <seq> <token>. This works against a running broker (client mode), which holds the lock between calls. In embedded mode each invocation opens the DB fresh and reclaims orphaned locks, so a --no-ack lock does not survive to the next command — use a broker (mqlite serve + --endpoint) when you need manual settle-later.

Commands

serve — run the broker

MQLITE_DB=file:/data/mq.db MQLITE_TOKENS=mqk_dev mqlite serve --addr :6754
Flag Default
--addr :6754 listen address
--diagnostic-log <path> MQLITE_DIAGNOSTIC_LOG (otherwise disabled) private failure/recovery log; 4 MiB × 4 files; see diagnostics
--metrics false enable authenticated /metrics on the API port; overrides MQLITE_METRICS; --metrics=false disables
--insecure-allow-remote false with auth disabled, allow a non-loopback bind (otherwise refused)

The listen address may also come from MQLITE_ADDR (precedence: --addr > MQLITE_ADDR > :6754; a blank value is rejected). With auth disabled (MQLITE_TOKENS=off) the broker refuses a non-loopback bind unless --insecure-allow-remote is passed, and MQLITE_CORS defaults to off.

Serves the RPC API, the open / + /healthz, and — unless MQLITE_UI=off — the embedded admin console at /ui. Enable Prometheus on the same API port with one flag:

MQLITE_DB=file:./mq.db MQLITE_TOKENS=mqk_dev mqlite serve \
  --addr 127.0.0.1:6754 --metrics

Equivalent environment configuration is MQLITE_METRICS=on. Values on/true/1 enable metrics; off/false/0 disable it. Values are case-insensitive; unset or empty disables metrics. Invalid values fail startup. --metrics=false overrides an environment-provided enabled value. Administrator auth must remain enabled. Scrapes accept configured administrators, managed manage keys, or configured monitor credentials; send/listen keys cannot scrape metrics.

When enabled, the open discovery card includes "metrics":"/metrics", which resolves against the same origin. When disabled, the field is omitted and the route returns 404 even with valid credentials. No separate address or URL configuration is needed. If the API is publicly reachable, so is this route; keep metrics off public ingress with path filtering or a private-only broker.

key create|list|revoke — manage persistent access keys

Available in v0.3.1 and later. In client mode, use an environment administrator or a managed manage key as MQLITE_TOKEN. The broker can keep running while keys are created or revoked. Embedded mode directly manages the configured database and requires exclusive ownership; it cannot open a running local broker's DB.

# MQLITE_ENDPOINT and MQLITE_TOKEN already select the broker and administrator.
mqlite key create --name producer --permissions send --output json
mqlite key create --name worker --permissions listen --output json
mqlite key create --name processor --permissions send,listen --output json
mqlite key create --name operator --permissions manage --output json
mqlite key list --limit 100 --output json
mqlite key list --sort created_desc --limit 25 --output json
mqlite key revoke --id <public-key-id>
Subcommand Flags Result
create required --name, --permissions; optional --id, --expires-at-ms key metadata plus its one-time secret
list optional --after-id, --limit (default 100, maximum 1000), --sort id_asc|created_desc (default id_asc) metadata and a continuation cursor; no secrets or digests
revoke required --id idempotently revokes an existing database key

--id is a public 32-character lowercase hex ID; when omitted, the CLI generates it before contacting the broker. Creation failures report that ID so an ambiguous result can be reconciled without guessing from a name. The secret is a separate mqk_ token with 64 lowercase hex characters. Save it securely when returned; it cannot be retrieved again. --expires-at-ms uses epoch milliseconds; zero (the default) means no expiry. Key names need not be unique.

Lists default to ascending public ID order. --sort created_desc lists the newest-created keys first across all pages, with descending ID as the tie-breaker for identical creation timestamps. Pass next_after_id as --after-id and keep the same --sort on every page; text output includes the full continuation command. In creation order, the cursor must be an existing key ID (revoked and expired keys remain valid cursors). ID order also accepts absent predecessor IDs for reconciling a lost create response.

send permits sending, scheduling and cancelling scheduled messages; listen permits consumption, settlement, renewal, peek and queue stats; manage includes both and all administration, including issuing other manage keys. Permissions apply to the whole broker. A 403 is a permission failure, not an invalid token; ordinary send/listen keys cannot use key, list, status or the admin console. Existing configured administrator tokens retain their original format and rights.

To rotate a managed key, create its replacement, move the application to the new token, then revoke the old ID. No broker restart is needed. See the authentication contract and backup/restore implications.

create-queue <name> — create/update a queue

mqlite create-queue orders --lock 30s --max-delivery 5 --dedup 10m --ordering strict_fifo
Flag Default
--lock 0 → 30s Peek-Lock duration (0 inherits the engine default, 30s)
--max-delivery 0 → 10 deliveries before a message goes to the DLQ (0 inherits 10)
--ttl 0 (unlimited) default message TTL
--dedup 0 (off) dedup window
--ordering standard standard / group_fifo / strict_fifo
--dlq-max-age 0 (inherit) per-queue DLQ retention: drop dead letters older than this
--dlq-max-count 0 (inherit) per-queue: keep at most N dead letters (-1 = unbounded)
--dlq-max-bytes 0 (inherit) per-queue: cap dead-letter body bytes (-1 = unbounded)

subscribe <topic> <name> — create a subscription

(alias: create-subscription)

mqlite subscribe orders eu-orders --expr 'subject_parts[0]=="orders" && properties["region"]=="eu"'
Flag
--expr "" subscription filter — an expr boolean predicate; empty = match all

send <queue> <body> — enqueue a message

body of - reads stdin; or use --file.

mqlite send orders '{"id":1}' --group order-1 --message-id m1
echo '{"id":2}' | mqlite send orders -
Flag
--file read body from a file
--message-id dedup / idempotency key
--group group id (ordering / session key)
--subject subject (label)
--reply-to reply-to address
--ttl per-message TTL

receive <queue> — consume (Peek-Lock)

By default it receives and auto-Completes. Use --no-ack to leave messages locked and print each lock-token (settle them later — see settlement commands below), or --delete for at-most-once.

mqlite receive orders --max 10 --wait 5s
Flag Default
--max 1 max messages
--wait 0 long-poll wait (e.g. 5s)
--no-ack false leave messages locked (don't Complete)
--delete false receive-and-delete (at-most-once, no lock)

Auto-ack never acknowledges output you can't see. A message is only Completed after its body is written to stdout successfully. If the write fails (broken pipe) the message is left locked and redelivered; if stdout cannot deliver at all (closed at exec, or /dev/null) the command refuses up front — nothing is claimed. Use --delete to drain explicitly, or --no-ack if you only want the lock tokens.

peek <queue> — browse without locking

mqlite peek orders --state dead_lettered --max 20
Flag Default
--state "" active/locked/deferred/scheduled/dead_lettered
--from 0 start sequence number
--max 16 max messages

metrics <queue> — queue counters

Prints a human line by default; use --output json for the JSON object. (Changed in 0.3.0: metrics previously printed JSON unconditionally — scripts that parsed the old default must add --output json.)

mqlite metrics orders                 # active / locked / deferred / scheduled / dead_lettered / total
mqlite metrics orders --output json   # machine-readable

list — list queues & subscriptions

mqlite list

redrive <queue> — move dead letters back to active

mqlite redrive orders --max 100              # back to source
mqlite redrive orders --to orders-replay     # to another queue
Flag Default
--to "" target queue (default: back to source)
--max 0 (all) max messages
--older-than 0 only messages older than this

purge-dlq <queue> — delete dead letters

Destructive. An unbounded purge requires an explicit --all; otherwise pass a bound (--max/--older-than). Negative bounds are rejected (they would otherwise mean "no limit"). Exactly one positional <queue> — a stray argument is an error, not ignored.

mqlite purge-dlq orders --older-than 24h    # bounded
mqlite purge-dlq orders --all               # delete the entire DLQ (explicit)
Flag Default
--max 0 max messages to delete (0 = unbounded → --all required)
--older-than 0 only delete messages older than this (minimum 1ms — a sub-millisecond value would round to "no bound")
--all false delete the entire DLQ (required to run unbounded)

vacuum — reclaim free DB pages to the OS

Local maintenance (embedded; stop the broker first — the single-writer lock will reject it otherwise). New local DBs use auto_vacuum=INCREMENTAL, so the default is a no-lock PRAGMA incremental_vacuum; --full runs a full VACUUM (rewrites the file, global lock). Not applicable to a remote Turso/libSQL store.

MQLITE_DB=file:/data/mq.db mqlite vacuum          # incremental
MQLITE_DB=file:/data/mq.db mqlite vacuum --full   # full rewrite

complete / abandon / reject / defer / renew — settle a message

Settle a message received earlier with receive --no-ack (which printed its lock-token). Positional args are always <queue> <seq> <lock-token>. Client mode only in practice (a broker holds the lock between calls — see the note under Global flags).

mqlite complete orders 42 lt_9f3a…                 # done
mqlite abandon  orders 42 lt_9f3a… --delay 60s     # release for retry, after a backoff
mqlite reject   orders 42 lt_9f3a… --reason bad    # dead-letter it (--detail …)
mqlite defer    orders 42 lt_9f3a…                 # set aside for receive-deferred
mqlite renew    orders 42 lt_9f3a…                 # extend the lock lease

schedule <queue> <body> — enqueue for future delivery

mqlite schedule orders '{"id":1}' --at 30m                     # a duration from now
mqlite schedule orders '{"id":1}' --at 2027-01-02T15:04:05Z    # or an absolute RFC3339 time (must be future)
Flag
--at required delivery time: RFC3339 or a duration (30m, 2h)
--file · --message-id · --group · --subject same as send

Cancel a scheduled message before it activates with cancel <queue> <seq>.

receive-deferred <queue> --seq … — fetch deferred messages by seq

mqlite receive-deferred orders --seq 42,57      # re-locks them and prints tokens to settle

observe — canonical observation

Available in v0.3.2 and later. Remote mode requires a v0.3.2 or later broker; configured monitor credentials are also new in v0.3.2.

mqlite observe --output json
MQLITE_ENDPOINT=http://127.0.0.1:6754 MQLITE_TOKEN="$MONITOR_TOKEN" mqlite observe

Both output modes print the complete canonical JSON snapshot, including collection availability/freshness, queue gauges, committed message effects, storage operations, maintenance, filter failures, and HTTP request/authentication measurements. It is the same data contract as SDK Observe, MCP observe, and the HTTP Observe route; /metrics serializes these measurements for Prometheus.

Check collection.state before interpreting queue counts. An unavailable collection has queues: null, not zero messages; process counters remain usable when the configured credential can authenticate. Durations use seconds, timestamps use epoch milliseconds, and process counters reset on restart. Embedded mode marks HTTP as not_applicable. Runtime read_available and db_size_available distinguish unknown or unsupported measurements from real zeroes. See observability.md.

A configured MQLITE_MONITOR_TOKENS credential can call only observe and /metrics. It also opens the console's read-only overview/metrics views. manage includes observation; managed send/listen keys do not gain broker-wide monitoring. Monitor credentials are configured at startup and cannot be created through key create.

status — backend snapshot

mqlite status                 # backend, location, schema, ping, size, queue/subscription counts

list-subscriptions — subscriptions with topic + filter

mqlite list-subscriptions

test-filter <expr> — dry-run a subscription filter

Compiles the expression and, with a sample, reports whether it would match (nothing is enqueued).

mqlite test-filter 'subject == "ord.created"'                       # just validate
mqlite test-filter 'subject == "ord.created"' --subject ord.created # validate + test a sample
Flag
--subject · --group · --prop k=v,k=v · --file build the sample message

version / help

mqlite version
mqlite help

Examples end to end

# embedded: produce + consume against a local file, no broker
export MQLITE_DB=file:./mq.db
mqlite create-queue jobs
mqlite send jobs "hello"
mqlite receive jobs --wait 2s

# client: same commands against a running broker
export MQLITE_ENDPOINT=https://your-mqlite.fly.dev MQLITE_TOKEN=mqk_prod_xxx
mqlite list
mqlite metrics jobs

See also: api-reference.md (HTTP), mcp.md (agents), examples.md (Go SDK).