mq9: What It Is
One Line
mq9 is RobustMQ's communication layer designed specifically for AI Agents. It gives Agents mailboxes — send it out, the other party receives it when they come online.
What Problem It Solves
Agents need to communicate. But Agents are not services — they are ephemeral, going online and offline at any time, with a lifecycle that may be only a few seconds.
Agent A sends a message to Agent B; B is offline, and the message is gone. Every team works around this problem with HTTP callbacks, Redis, database polling, or homegrown queues.
mq9 solves it directly: messages are written to storage first; if the other party is online, they are pushed in real time; if offline, the messages wait and are delivered in full when they come online.
mq9 only handles communication — how to reliably deliver messages. What the message contains and what the business semantics are — mq9 does not care.
Core Concept: Mailbox
mq9 has a single core abstraction: Mailbox (MAILBOX).
I know the other party's address; I compose a message and drop it in. Whether they are home or not doesn't matter — the message waits in their mailbox. Messages carry one of three priority levels: critical, urgent, or normal (default). When they get home, they open the mailbox and read critical messages first, then urgent, then normal.
A mailbox has a TTL — it is automatically destroyed on expiry, along with all messages inside. No manual deletion needed. One Agent can hold multiple mailboxes simultaneously; leave them alone when done, TTL handles cleanup.
mail_id unguessability is the security boundary. mail_id is a system-generated unguessable string. Knowing the mail_id lets you send messages and subscribe; without it, you can't interact with the mailbox. No token, no ACL.
Mailboxes come in two kinds:
| Private mailbox | Public mailbox | |
|---|---|---|
| mail_id | System-generated, unguessable | User-defined, meaningful name |
| Discoverability | Private | Auto-registered to PUBLIC.LIST |
| Use cases | Point-to-point messaging, result delivery | Task queues, public channels |
A public mailbox's mail_id is its address — choose a meaningful name like task.queue or analytics.result rather than a UUID, making it easier for other Agents to discover and understand.
Subscription semantics: Every subscription delivers all non-expired messages in full, with new messages pushed in real time afterward. No read/unread tracking, no consume offset, no QUERY command.
CREATE is idempotent. Creating again does not error; TTL is fixed by the first creation.
Three Operations
| Operation | Description |
|---|---|
MAILBOX.CREATE | Create a mailbox |
MAILBOX.MSG.{mail_id}.{priority} | Send a message to a mailbox |
MAILBOX.MSG.{mail_id}.* | Subscribe to a mailbox; receive all non-expired messages in full |
No QUERY — subscribing is querying. No DELETE — TTL handles cleanup automatically.
Three priority levels:
| Level | Semantics | Typical use |
|---|---|---|
| high | Urgent, processed first | Task interrupts, emergency commands |
| normal | Routine communication | Task dispatch, result delivery |
| low | Background, not urgent | Logs, status reports |
The storage layer guarantees priority ordering; consumers need not sort themselves.
For detailed protocol design, see the [$mq9.AI.* Protocol Design Document].
Public Mailbox Discovery
$mq9.AI.PUBLIC.LIST is a system-managed address maintained by the broker. Does not accept user writes. Never expires.
Public mailboxes are automatically registered on creation and removed when their TTL expires. No manual registry maintenance.
nats sub '$mq9.AI.PUBLIC.LIST'Subscribing delivers all current public mailboxes immediately, then streams additions and removals in real time. No registry service needed — PUBLIC.LIST is the directory.
Key Design Decisions
- Store first, then push. Persistence is the default behavior, not an option.
- mail_id is not bound to Agent identity. One Agent, multiple mailboxes; leave them alone when done; TTL handles cleanup.
- Client-side deduplication. Every message has a msg_id; the server maintains zero consumer state.
- CREATE is idempotent. Creating again silently succeeds; TTL is fixed by the first creation. No state query interface.
- Wildcard subscriptions across all mailboxes are prohibited. Subscriptions must specify an exact mail_id; the broker enforces this.
Relationship with RobustMQ
mq9 is RobustMQ's fifth native protocol layer, alongside MQTT, Kafka, NATS, and AMQP, sharing the unified storage layer. Deploy one RobustMQ; all mq9 capabilities are ready.
docker run -d -p 4222:4222 robustmq/robustmq:latestIoT devices send data via MQTT, analytics systems consume via Kafka, Agents collaborate via mq9 — the same broker, the same storage.
Relationship with NATS
mq9 is compatible with the NATS protocol; all language NATS clients work out of the box, with zero ecosystem cost.
mq9 is not NATS — it is an independent broker. It occupies a middle ground between Core NATS (too lightweight, no persistence) and JetStream (too heavy, stream/consumer/offset) — adding persistence, priority, and TTL, without adding streams and consumer groups. Designed only for Agent communication, not a general messaging system.
