Skip to content

CLI Reference

Fabrício Bracht edited this page Jul 3, 2026 · 1 revision

CLI Reference

Complete reference for the mqttv5 command-line tool.


Installation

cargo install mqttv5-cli

Commands Overview

Command Description
pub Publish messages to MQTT topics
sub Subscribe to MQTT topics
broker Start MQTT broker
bench Run performance benchmarks against a broker
acl Manage ACL file for broker authorization
passwd Manage password file for broker authentication
scram Manage SCRAM-SHA-256 credentials file

Global Flags

Global flags may appear before or after the subcommand.

Flag Description Env
--verbose, -v Enable verbose logging MQTT5_VERBOSE
--debug Enable debug logging MQTT5_DEBUG
--help, -h Show help —
--version, -V Show version —

RUST_LOG, if set, overrides --verbose/--debug and is used verbatim as the tracing filter.


Environment Variables

Every flag on the broker, pub, and sub subcommands can be set via an environment variable. The convention is the MQTT5_ prefix followed by the upper-snake-case of the long flag name (e.g. --max-clients -> MQTT5_MAX_CLIENTS), with the exceptions noted in the tables below. The bench, acl, passwd, and scram subcommands do not read environment variables.

Precedence: CLI flag > environment variable > default value.

  • Broker bind addresses use distinct names to avoid colliding with the client hostname: --host on the broker is MQTT5_BIND (not MQTT5_HOST), and the TLS/WS/QUIC bind flags use MQTT5_TLS_BIND, MQTT5_WS_BIND, MQTT5_WS_TLS_BIND, MQTT5_QUIC_BIND. On pub/sub, --host is MQTT5_HOST.
  • Repeatable flags (--host, --tls-host, --ws-host, --ws-tls-host, --quic-host, --jwt-role-map, --jwt-trusted-role-claim) accept comma-separated values when set via env var. Repeating the flag on the CLI still works.
  • Boolean flags treat any non-empty env value as true (MQTT5_ALLOW_ANONYMOUS=1 or =true).
  • Run --help on any subcommand to see the env var name for each flag (shown as [env: MQTT5_...=]).
  • When --config is provided to the broker, the config file is authoritative and the other broker flags are ignored.

The Docker image sets MQTT5_NON_INTERACTIVE=true by default:

docker run -e MQTT5_BIND=0.0.0.0:1883 \
           -e MQTT5_ALLOW_ANONYMOUS=true \
           -e MQTT5_STORAGE_BACKEND=memory \
           -p 1883:1883 \
           mqttv5 broker

mqttv5 broker

Basic Usage

mqttv5 broker --allow-anonymous
mqttv5 broker --config broker.json
mqttv5 broker generate-config > broker.json

The broker prompts for an authentication choice when none is configured; use --allow-anonymous, an auth file, or --non-interactive to avoid the prompt.

generate-config Subcommand

mqttv5 broker generate-config [--output FILE] [--format json|toml]
Flag Description Default
--output, -o <FILE> Output file path (else stdout) stdout
--format, -f <FMT> json or toml json

Network Flags

Flag Description Env Default
--config, -c <FILE> Configuration file path (JSON). Disables other flags MQTT5_CONFIG None
--host, -H <ADDR> TCP bind address (repeatable) MQTT5_BIND 0.0.0.0:1883, [::]:1883
--tls-host <ADDR> TLS bind address (repeatable) MQTT5_TLS_BIND 0.0.0.0:8883, [::]:8883 (when cert+key set)
--ws-host <ADDR> WebSocket bind address (repeatable) MQTT5_WS_BIND None
--ws-tls-host <ADDR> WebSocket TLS bind address (repeatable) MQTT5_WS_TLS_BIND None
--ws-path <PATH> WebSocket path MQTT5_WS_PATH /mqtt
--quic-host <ADDR> QUIC bind address (repeatable; requires TLS cert+key) MQTT5_QUIC_BIND None

QUIC Flags

Flag Description Env Default
--quic-delivery-strategy <S> Server delivery strategy: control-only, per-topic, per-publish MQTT5_QUIC_DELIVERY_STRATEGY per-topic
--quic-early-data Enable QUIC 0-RTT early data MQTT5_QUIC_EARLY_DATA false

TLS Flags

Flag Description Env Default
--tls-cert <FILE> TLS certificate (PEM) MQTT5_TLS_CERT None
--tls-key <FILE> TLS private key (PEM) MQTT5_TLS_KEY None
--tls-ca-cert <FILE> CA cert for client verification (enables mTLS) MQTT5_TLS_CA_CERT None
--tls-require-client-cert Require client certificates (needs --tls-ca-cert) MQTT5_TLS_REQUIRE_CLIENT_CERT false

--tls-cert and --tls-key must be supplied together.

Authentication Flags

Flag Description Env Default
--allow-anonymous [BOOL] Allow anonymous connections (bare flag = true) MQTT5_ALLOW_ANONYMOUS Unset (prompts; errors under --non-interactive)
--auth-password-file <FILE> Password file MQTT5_AUTH_PASSWORD_FILE None
--acl-file <FILE> ACL file MQTT5_ACL_FILE None
--auth-method <METHOD> password, scram, jwt, jwt-federated MQTT5_AUTH_METHOD None
--scram-file <FILE> SCRAM credentials file MQTT5_SCRAM_FILE None

Providing a password/SCRAM/JWT file disables anonymous access by default.

JWT Flags

Flag Description Env Default
--jwt-algorithm <ALG> hs256, rs256, es256 MQTT5_JWT_ALGORITHM None
--jwt-key-file <FILE> JWT secret (HS256) or public key (RS256/ES256) MQTT5_JWT_KEY_FILE None
--jwt-issuer <ISS> Required JWT issuer MQTT5_JWT_ISSUER None
--jwt-audience <AUD> Required JWT audience MQTT5_JWT_AUDIENCE None
--jwt-clock-skew <SECS> Clock skew tolerance (e.g. 60, 1m) MQTT5_JWT_CLOCK_SKEW 60
--jwt-jwks-uri <URL> JWKS endpoint (federated) MQTT5_JWT_JWKS_URI None
--jwt-fallback-key <FILE> Fallback key when JWKS unavailable (required with --jwt-jwks-uri) MQTT5_JWT_FALLBACK_KEY None
--jwt-jwks-refresh <SECS> JWKS refresh interval MQTT5_JWT_JWKS_REFRESH 3600
--jwt-role-claim <PATH> Claim path for roles (e.g. realm_access.roles) MQTT5_JWT_ROLE_CLAIM None
--jwt-role-map <MAP> claim_value:mqtt_role (repeatable) MQTT5_JWT_ROLE_MAP None
--jwt-default-roles <ROLES> Default roles for authenticated JWT users (comma-separated) MQTT5_JWT_DEFAULT_ROLES None
--jwt-role-merge-mode <MODE> merge or replace (deprecated, use --jwt-auth-mode) MQTT5_JWT_ROLE_MERGE_MODE merge
--jwt-auth-mode <MODE> identity-only, claim-binding, trusted-roles MQTT5_JWT_AUTH_MODE None
--jwt-trusted-role-claim <PATH> Trusted role claim paths (repeatable) MQTT5_JWT_TRUSTED_ROLE_CLAIM None
--jwt-session-scoped-roles [BOOL] Clear JWT roles on disconnect MQTT5_JWT_SESSION_SCOPED_ROLES Unset
--jwt-issuer-prefix <PREFIX> Custom issuer prefix for user-ID namespacing MQTT5_JWT_ISSUER_PREFIX None
--jwt-config-file <FILE> Multi-issuer federated JWT config (JSON) MQTT5_JWT_CONFIG_FILE None

Storage Flags

Flag Description Env Default
--storage-backend <TYPE> file or memory MQTT5_STORAGE_BACKEND file
--storage-dir <DIR> Storage directory MQTT5_STORAGE_DIR ./mqtt_storage
--no-persistence Disable persistence MQTT5_NO_PERSISTENCE false

Broker Settings

Flag Description Env Default
--max-clients <N> Maximum concurrent clients MQTT5_MAX_CLIENTS 10000
--session-expiry <SECS> Default session expiry (e.g. 3600, 1h) MQTT5_SESSION_EXPIRY 3600
--max-qos <0|1|2> Maximum QoS MQTT5_MAX_QOS 2
--keep-alive <SECS> Server keep-alive (e.g. 60, 2m) MQTT5_KEEP_ALIVE None
--response-information <STR> Response information sent to clients that request it MQTT5_RESPONSE_INFORMATION None
--no-retain Disable retained messages MQTT5_NO_RETAIN false
--no-wildcards Disable wildcard subscriptions MQTT5_NO_WILDCARDS false
--non-interactive Skip interactive prompts MQTT5_NON_INTERACTIVE false

Inbound/rate limits (max_packet_size, server_receive_maximum, max_subscriptions_per_client, max_message_rate_per_client, etc.) are configuration-file fields only and have no dedicated CLI flags. See the Broker Guide.

OpenTelemetry Flags

Only present when the binary is built with the opentelemetry feature.

Flag Description Env Default
--otel-endpoint <URL> OTLP endpoint MQTT5_OTEL_ENDPOINT None
--otel-service-name <NAME> Service name MQTT5_OTEL_SERVICE_NAME mqttv5-broker
--otel-sampling <0.0-1.0> Sampling ratio MQTT5_OTEL_SAMPLING 1.0

Examples

# Anonymous broker
mqttv5 broker --allow-anonymous

# Multi-transport
mqttv5 broker \
  --host 0.0.0.0:1883 \
  --tls-host 0.0.0.0:8883 \
  --tls-cert server.pem \
  --tls-key server-key.pem \
  --ws-host 0.0.0.0:8080

# QUIC (requires TLS cert+key)
mqttv5 broker \
  --host 0.0.0.0:1883 \
  --quic-host 0.0.0.0:14567 \
  --tls-cert server.pem --tls-key server-key.pem

# Password + ACL
mqttv5 broker \
  --auth-password-file passwd.txt \
  --acl-file acl.txt \
  --allow-anonymous=false

# SCRAM
mqttv5 broker --auth-method scram --scram-file scram.txt --allow-anonymous=false

# JWT
mqttv5 broker \
  --auth-method jwt --jwt-algorithm rs256 \
  --jwt-key-file public.pem \
  --jwt-issuer "https://auth.example.com" --jwt-audience "mqtt-broker"

# Federated JWT (trusted roles / Keycloak)
mqttv5 broker \
  --auth-method jwt-federated \
  --jwt-jwks-uri "https://keycloak.example.com/realms/mqtt/protocol/openid-connect/certs" \
  --jwt-fallback-key fallback.pem \
  --jwt-issuer "https://keycloak.example.com/realms/mqtt" \
  --jwt-auth-mode trusted-roles \
  --jwt-trusted-role-claim "realm_access.roles"

mqttv5 pub

Basic Usage

mqttv5 pub -t <TOPIC> -m <MESSAGE>
mqttv5 pub -t <TOPIC> -f <FILE>
mqttv5 pub -t <TOPIC> --stdin

Connection Flags

Flag Description Env Default
--url, -U <URL> Broker URL (mqtt://, mqtts://, ws://, wss://, quic://, quics://); conflicts with --host/--port MQTT5_URL None
--host, -H <HOST> Broker hostname MQTT5_HOST localhost
--port, -p <PORT> Broker port MQTT5_PORT 1883
--client-id, -c <ID> Client ID MQTT5_CLIENT_ID Auto-generated
--username, -u <USER> Username MQTT5_USERNAME None
--password, -P <PASS> Password MQTT5_PASSWORD None
--auth-method <METHOD> password, scram, jwt MQTT5_AUTH_METHOD password
--jwt-token <TOKEN> JWT token (for --auth-method jwt) MQTT5_JWT_TOKEN None
--non-interactive Skip interactive prompts MQTT5_NON_INTERACTIVE false

Message Flags

Flag Description Env Default
--topic, -t <TOPIC> MQTT topic (required; prompted if omitted) MQTT5_TOPIC None
--message, -m <MSG> Message payload MQTT5_MESSAGE None
--file, -f <FILE> Read message from file MQTT5_FILE None
--stdin Read message from stdin MQTT5_STDIN false
--qos, -q <0|1|2> QoS level MQTT5_QOS 0
--retain, -r Retain message MQTT5_RETAIN false
--message-expiry-interval <SECS> Message expiry (0 = no expiry) MQTT5_MESSAGE_EXPIRY_INTERVAL None
--topic-alias <N> Topic alias (1-65535) MQTT5_TOPIC_ALIAS None
--response-topic <TOPIC> Response topic (request/response) MQTT5_RESPONSE_TOPIC None
--correlation-data <HEX> Correlation data, hex-encoded MQTT5_CORRELATION_DATA None
--wait-response Wait for response (needs --response-topic) MQTT5_WAIT_RESPONSE false
--timeout <SECS> Timeout while waiting for response MQTT5_TIMEOUT 30
--response-count <N> Responses to wait for (0 = until timeout) MQTT5_RESPONSE_COUNT 1
--output-format <FMT> Response output: raw, json, verbose MQTT5_OUTPUT_FORMAT raw
--delay <SECS> Delay before publishing (conflicts with --at) MQTT5_DELAY None
--repeat <N> Publish N times (0 = infinite) MQTT5_REPEAT None (once)
--interval <MS> Interval between repeats in ms (requires --repeat) MQTT5_INTERVAL 1000
--at <TIME> Schedule publish (14:30, 2025-01-15T14:30:00) MQTT5_AT None

Session Flags

Flag Description Env Default
--no-clean-start Resume existing session MQTT5_NO_CLEAN_START false
--session-expiry <SECS> Session expiry (0 = on disconnect) MQTT5_SESSION_EXPIRY None (0)
--keep-alive, -k <SECS> Keep-alive interval MQTT5_KEEP_ALIVE 60
--protocol-version <VER> 3.1.1/311/4 or 5/5.0 MQTT5_PROTOCOL_VERSION 5
--auto-reconnect Enable automatic reconnection MQTT5_AUTO_RECONNECT false

Will Message Flags

Flag Description Env Default
--will-topic <TOPIC> Will topic MQTT5_WILL_TOPIC None
--will-message <MSG> Will payload MQTT5_WILL_MESSAGE None
--will-qos <0|1|2> Will QoS MQTT5_WILL_QOS 0
--will-retain Will retain MQTT5_WILL_RETAIN false
--will-delay <SECS> Will delay MQTT5_WILL_DELAY None

TLS Flags

Flag Description Env Default
--cert <FILE> Client certificate MQTT5_CERT None
--key <FILE> Client private key MQTT5_KEY None
--ca-cert <FILE> CA certificate MQTT5_CA_CERT None
--insecure Skip TLS/QUIC verification MQTT5_INSECURE false

QUIC Flags

Flag Description Env Default
--quic-stream-strategy <S> control-only, per-publish, per-topic, per-subscription MQTT5_QUIC_STREAM_STRATEGY control-only
--quic-flow-headers Enable flow headers for stream state tracking MQTT5_QUIC_FLOW_HEADERS false
--quic-flow-expire <SECS> Flow expiry MQTT5_QUIC_FLOW_EXPIRE 300
--quic-max-streams <N> Max concurrent streams MQTT5_QUIC_MAX_STREAMS None
--quic-datagrams Use QUIC datagrams (unreliable transport) MQTT5_QUIC_DATAGRAMS false
--quic-connect-timeout <SECS> Connection timeout MQTT5_QUIC_CONNECT_TIMEOUT 30
--quic-early-data Enable QUIC 0-RTT early data MQTT5_QUIC_EARLY_DATA false

Codec Flags

Only present with the codec feature.

Flag Description Env Default
--codec <CODEC> Compress payload: gzip, deflate MQTT5_CODEC None
--codec-level <0-9> Compression level (requires --codec) MQTT5_CODEC_LEVEL 6
--codec-min-size <BYTES> Minimum payload size to compress (requires --codec) MQTT5_CODEC_MIN_SIZE 128

OpenTelemetry Flags

Only present with the opentelemetry feature. Same as broker, except the default service name is mqttv5-pub.

Examples

mqttv5 pub -t test/topic -m "Hello"
mqttv5 pub -t status/online -m "true" -q 1 -r

# TLS
mqttv5 pub --url mqtts://broker.example.com:8883 --ca-cert ca.pem -t test -m "Secure"

# QUIC multistream
mqttv5 pub --url quic://broker:14567 --ca-cert ca.pem \
  --quic-stream-strategy per-publish -t sensors/data -m '{}' -q 1

# Repeated publishing every 500ms, 100 times
mqttv5 pub -t sensors/data -m "reading" --repeat 100 --interval 500

# Scheduled publish
mqttv5 pub -t alerts/scheduled -m "wake up" --at 14:30

# Request/response
mqttv5 pub -t commands/request -m '{"action":"status"}' \
  --response-topic commands/response --wait-response --timeout 10 -q 1

mqttv5 sub

Basic Usage

mqttv5 sub -t <TOPIC>
mqttv5 sub -t "sensors/#" -v

sub subscribes to a single topic filter per invocation (--topic is not repeatable). To watch several filters, run multiple sub processes.

Subscription Flags

Flag Description Env Default
--topic, -t <TOPIC> Topic filter (required; prompted if omitted) MQTT5_TOPIC None
--qos, -q <0|1|2> Subscription QoS MQTT5_QOS 0
--verbose, -v Include topic names in output — (global --verbose) false
--count, -n <N> Exit after N messages (0 = infinite) MQTT5_COUNT 0
--no-local Don't receive own messages MQTT5_NO_LOCAL false
--retain-handling <0|1|2> 0=send, 1=send if new, 2=don't send MQTT5_RETAIN_HANDLING 0
--retain-as-published Keep original retain flag on delivery MQTT5_RETAIN_AS_PUBLISHED false
--subscription-identifier <ID> Subscription ID (1-268435455) MQTT5_SUBSCRIPTION_IDENTIFIER None

Connection, Session, Will, TLS, QUIC Flags

Identical names, env vars, and defaults to pub (except --otel-service-name defaults to mqttv5-sub). sub does not have the publish-only flags (--message, --file, --stdin, --retain, --message-expiry-interval, --topic-alias, response/request flags, --repeat, --interval, --at, --delay).

Codec Flag

Only present with the codec feature.

Flag Description Env Default
--codec <CODEC> Decode incoming messages: gzip, deflate, all MQTT5_CODEC None

Examples

mqttv5 sub -t "sensors/#" -v
mqttv5 sub -t "data/#" -q 1 --no-local
mqttv5 sub -t "events/#" -n 10 -v

# Persistent session
mqttv5 sub -t "data/#" --client-id my-sub --no-clean-start --session-expiry 3600 -q 1

# QUIC per-subscription streams
mqttv5 sub -t "sensors/#" --url quic://broker:14567 --ca-cert ca.pem \
  --quic-stream-strategy per-subscription --quic-flow-headers -v

mqttv5 bench

Benchmarks against a running broker. The bench subcommand does not read MQTT5_* environment variables.

Basic Usage

mqttv5 bench
mqttv5 bench --mode latency
mqttv5 bench --mode connections
mqttv5 bench --mode hol-blocking --trace-dir ./traces

Flags

Flag Description Default
--mode <MODE> throughput, latency, connections, hol-blocking throughput
--duration <SECS> Test duration 10
--warmup <SECS> Warmup period 2
--payload-size <BYTES> Message size (raw payloads are padded to at least 12 bytes) 64
--topic, -t <TOPIC> Publish topic bench/test
--filter, -f <FILTER> Subscription filter Same as topic
--qos, -q <0|1|2> QoS level 0
--url, -U <URL> Broker URL; conflicts with --host/--port None
--host, -H <HOST> Broker hostname localhost
--port, -p <PORT> Broker port 1883
--client-id, -c <ID> Client ID prefix Auto-generated
--publishers <N> Number of publisher clients 1
--subscribers <N> Number of subscriber clients 1
--concurrency <N> Concurrent connections (connections mode) 10
--topics <N> Number of topics (hol-blocking mode) 4
--rate <N> Publish rate in msg/s (0 = unlimited) 0
--payload-format <FMT> raw, json, bebytes, compressed-json raw
--trace-dir <DIR> Directory for per-topic trace CSV (hol-blocking mode) None
--pub-url <URL> Separate publisher URL for HOL mode None
--insecure Skip TLS certificate verification false
--ca-cert <FILE> CA certificate (PEM) None
--cert <FILE> Client certificate (PEM) None
--key <FILE> Client private key (PEM) None
--quic-stream-strategy <S> control-only, per-publish, per-topic, per-subscription control-only
--quic-flow-headers Enable QUIC flow headers false
--quic-flow-expire <SECS> Flow expiry 300
--quic-max-streams <N> Max concurrent QUIC streams None
--quic-datagrams Use QUIC datagrams false
--quic-connect-timeout <SECS> QUIC connection timeout 30
--quic-early-data Enable QUIC 0-RTT early data false

Examples

mqttv5 bench --duration 30 --subscribers 10
mqttv5 bench --mode latency --duration 10
mqttv5 bench --mode connections --concurrency 50

# Head-of-line blocking with trace output
mqttv5 bench --mode hol-blocking --topics 4 --rate 500 --duration 60 --trace-dir ./traces

# HOL with split transports (QUIC sub, TCP pub)
mqttv5 bench --mode hol-blocking --topics 4 --rate 500 --duration 60 \
  --url quic://localhost:14567 --pub-url mqtt://localhost:1883 \
  --quic-stream-strategy per-topic --ca-cert ca.pem --trace-dir ./traces

mqttv5 passwd

Passwords are hashed with Argon2id.

Usage

mqttv5 passwd [OPTIONS] <USERNAME> [FILE]

The username is the first positional argument and the file the second. Batch mode passes the password as the value of -b, so the username still comes first: mqttv5 passwd alice -b secret passwords.txt.

Flags

Flag Description
--create, -c Create new file (overwrites if exists)
--batch, -b <PASS> Password on command line (visible in process list)
--delete, -D Delete user (conflicts with --batch)
--stdout, -n Output hash to stdout (conflicts with <FILE>, --create, --delete)

Examples

mqttv5 passwd -c alice passwords.txt        # create file, add user (prompts)
mqttv5 passwd bob passwords.txt             # add to existing file
mqttv5 passwd alice -b mypassword passwords.txt   # batch mode
mqttv5 passwd -D alice passwords.txt        # delete user
mqttv5 passwd -n testuser                   # print hash to stdout

mqttv5 scram

Manage SCRAM-SHA-256 credentials (PBKDF2-HMAC-SHA256).

Usage

mqttv5 scram [OPTIONS] <USERNAME> [FILE]

Flags

Flag Description Default
--create, -c Create new file (overwrites if exists) false
--batch, -b <PASS> Password on command line (conflicts with --delete) None
--delete, -D Delete user false
--stdout, -n Output to stdout (conflicts with <FILE>, --create, --delete) false
--iterations, -i <N> PBKDF2 iteration count (minimum 10000) 310000

File Format

One line per user, five colon-separated fields:

username:salt:iterations:stored_key:server_key

salt, stored_key, and server_key are Base64-encoded.

Examples

mqttv5 scram -c alice scram.txt
mqttv5 scram bob scram.txt
mqttv5 scram alice -b mypassword scram.txt
mqttv5 scram -D alice scram.txt
mqttv5 scram -n testuser
mqttv5 scram -i 500000 alice scram.txt

mqttv5 acl

Every ACL subcommand takes a required --file, -f <FILE> argument.

Commands

Command Description
add <user> <topic> <perm> -f FILE Add user rule
remove <user> [topic] -f FILE Remove rule(s) for user
list [user] -f FILE List rules (all or for a user)
check <user> <topic> <action> -f FILE Check permission (read/write)
role-add <role> <topic> <perm> -f FILE Add role rule
role-remove <role> [topic] -f FILE Remove role rule(s)
role-list [role] -f FILE List role definitions
assign <user> <role> -f FILE Assign role to user
unassign <user> <role> -f FILE Remove role from user
user-roles <user> -f FILE List roles assigned to a user

Permissions: read (subscribe), write (publish), readwrite, deny. Topic patterns support +/# wildcards and %u (authenticated username) substitution.

Examples

mqttv5 acl add alice "sensors/#" readwrite -f acl.txt
mqttv5 acl add "*" '$DB/u/%u/#' readwrite -f acl.txt
mqttv5 acl role-add admin "#" readwrite -f acl.txt
mqttv5 acl assign alice admin -f acl.txt
mqttv5 acl check alice "sensors/temp" write -f acl.txt
mqttv5 acl list -f acl.txt
mqttv5 acl user-roles alice -f acl.txt
mqttv5 acl remove alice "sensors/#" -f acl.txt

Configuration File Schema

See the Broker Guide for the complete JSON/TOML configuration reference. Generate a fully-populated example with:

mqttv5 broker generate-config --format json
mqttv5 broker generate-config --format toml --output broker.toml

Clone this wiki locally