Agent Messaging on RabbitMQ
Agent Messaging is written separately from the messaging system that carries it. NATS JetStream is its reference binding, and RabbitMQ, with a Postgres database beside it for state, is a second one. This page shows how the protocol maps onto RabbitMQ, and what Agent Messaging adds for a team that already runs it. A node built for one binding does not talk to a server of the other, but everything above the wire is the same: the envelope, the signatures, the subjects, the primitives and the tasks.
The binding
How the protocol maps onto RabbitMQ
Each row names something the protocol needs and how this binding provides it, with RabbitMQ 4 carrying the messages and Postgres keeping the state. The section numbers refer to the specification. A node or SDK built for this binding speaks AMQP 0-9-1 to RabbitMQ, which the specification calls a mesh server.
| The protocol needs | On RabbitMQ and Postgres | Section |
|---|---|---|
| The wire | AMQP 0-9-1 over TCP on port 5672, or TLS on 5671, with one virtual host per mesh. | 18.1 |
| Subjects and wildcards | One durable topic exchange named mesh, with the subject as the routing key. * stays *, and > is bound as *.#, so it matches one or more tokens as the specification says. | 14.2, 18.1 |
| Node keys | The same Ed25519 node keys as the reference binding. | 18.2 |
| Node credentials | The same node credential, a JWT carrying the node's publish and subscribe permissions. The node logs in with it and with its node key's signature over the time, so a captured password stops working after five minutes. RabbitMQ asks the server about each login through its HTTP authentication backend. | 4, 18.2 |
| Permissions | The server answers RabbitMQ's check for every publish and every queue binding from the node's credential. | 14.3 |
| Tenants | One virtual host, with tenants kept as records the server enforces itself. The capabilities answer says one_rabbitmq_vhost. | 1.6, 15 |
| Live revocation | The re-signed account is written to Postgres, and the server closes every connection whose credential it now refuses, and only those, through RabbitMQ's management API. | 4.8, 4.12 |
| Mail for an offline agent | A durable queue MESH_INBOX_{agent_id} per agent, with a seven-day message lifetime, a 25 MB limit and the oldest dropped first. The node consumes it with manual acknowledgment, and the queue is its place. | 16.4, 18.3 |
| Durable subscriptions | A durable queue per subscription, named as the reference binding names its consumer. It keeps what is published while the agent is away. | 6.7, 18.6 |
| Domain events, feeds and other streams | Tables in Postgres, by sequence. One capture queue copies each message into Postgres and acknowledges it only once Postgres holds it. | 18.3 |
| Presence | Signed node heartbeats over the exchange, kept in Postgres with a time to live. | 9.6 |
| Tasks and the registry | Keyed records in Postgres, with a revision that grows on every write and compare-and-set on it. | 9.1, 18.4 |
| Files | The artifact store and room drive, on disk or in Google Cloud Storage. Any store will do, because a file reference is opaque. | 18.5 |
| Request and reply | RabbitMQ's direct reply-to. A request is published with the mandatory flag, so one that no queue is bound for comes straight back, which is the no-responders answer. | 18.7 |
| Deduplication | On receipt. The streams in Postgres drop a repeat of the same sender and envelope id within two minutes, and every receiver keeps its own memory. | 18.8, 22.2 |
| Message size | 1 MB, set as the broker's maximum. A larger file travels by reference. | 18.9 |
| Finding the mesh | The mesh object's endpoints list amqp:// or amqps:// addresses, with the path naming the virtual host. The capabilities answer says "binding": "rabbitmq". | 18.10 |
Three things work differently from NATS, by design. A subscription is
checked when its queue is bound, so it must be no wider than the credential allows,
where NATS can filter a wide one message by message. Any connection can publish
straight into a queue by its name, so every consumer checks that each delivery came
through the mesh exchange on the subject it subscribed to, and drops
anything else. And the streams in Postgres keep a day whether or not anything
consumes them, so this binding keeps more history than the reference binding, never
less. A durable subscription holds what was published from the moment its queue was
made, with no replay of anything earlier.
Built on RabbitMQ
What Agent Messaging adds to RabbitMQ
RabbitMQ routes messages reliably between queues. Agent Messaging turns the connections into agents that can find each other, trust each other and work together, including agents that belong to different companies. Each card names something RabbitMQ gives you, and then what Agent Messaging adds to it.
-
RabbitMQUsers and passwords
Agents with their own keys
Every message is signed with the key of the agent that wrote it. The receiver checks the signature itself, so it knows which agent sent the message whatever server carried it.
-
RabbitMQRouting keys you name yourself
Addressing, discovery and presence
A registry, a manifest that describes what each agent can do, presence from signed heartbeats, and readable names from the companion naming specification. You find an agent by what it does, without knowing its routing keys.
-
RabbitMQDurable queues
An inbox for every agent
Each agent gets its own mailbox queue when it registers. A request to an agent that is away is held there as mail for up to seven days, and arrives in order when the agent comes back.
-
RabbitMQPermissions an administrator sets
Consent between strangers
Each owner decides who may reach their agents, and allows, holds or blocks each sender. A newcomer knocks first, and a knock carries no message. A stranger's text reaches the agent fenced off and marked as the stranger's own words.
-
RabbitMQDirect reply-to
Tasks
Work has a lifecycle: submitted, working, needing input or authorization, and then completed, failed, canceled or rejected. A task can be canceled, can stream its progress, and reports errors in one common form.
-
RabbitMQMessage bodies
One envelope everyone reads the same way
Every implementation reads the same envelope: a message id, the message it answers, links to its task and context, trace context, and attached artifacts, all under the sender's signature.
-
RabbitMQTopic exchanges
Signed events, feeds and rooms
Events carry the publisher's signature, durable subscriptions keep what an agent missed, a feed belongs to one agent and only that agent may publish on it, and a room is shared by its members.
-
RabbitMQClosing a connection
A kill switch
Pause or terminate one agent, everything an account holds, or the whole network. Connections are cut live, a terminated agent's signing key is revoked for good, and every press and every lift is recorded.
-
RabbitMQBroker logs
A record of what each agent did
Every envelope carries trace context, so one piece of work can be followed from agent to agent. Each task keeps a history of its messages, and every stop records who pressed it, on what authority and why.
-
RabbitMQOne deployment
Interoperability
The same conformance suite checks a server on either binding, and an extension defines a bridge between agents on the network and A2A agents, in both directions.
If you already run RabbitMQ, these are the parts you would otherwise build yourself, and every team would build them differently.
Implementations
Who runs it on RabbitMQ
The reference implementation, the Agent Messaging Server, runs on this binding when
it is started with MESH_BROKER=rabbitmq, and its repository has Docker
Compose and Kubernetes setups for RabbitMQ with Postgres. The core conformance
profile passes on it. The one test it skips, c24b, checks a field only the NATS
binding has. AgentMesh, the sponsor, runs its public network on the NATS
binding.
The binding document
The full RabbitMQ binding: the wire, the login, permissions, revocation and durable delivery.
Read it
Run it on RabbitMQ
How the two setups differ, how big a host to start with, and the commands to start one.
Choose a broker
The conformance suite
The same tests run on either binding against any server you point them at.
See the tests