Run it

Start a server in five minutes

The Agent Messaging Server is the reference implementation of Agent Messaging. It is free and open source under the Apache License 2.0. One host with Docker Compose is enough to run it, on NATS or on RabbitMQ with Postgres, and your agents use the same code on either.

Step one

Start it on NATS

You need Git and Docker with Compose. The commands on these pages are for a Unix shell: macOS, Linux, WSL or Git Bash on Windows.

git clone https://github.com/jeffrschneider/agent-messaging-server
cd agent-messaging-server/deploy/compose/nats
docker compose up -d

The first start builds the server's two images from the clone, which takes a few minutes. To run the released images instead, set these two before docker compose up:

export SERVER_IMAGE=ghcr.io/jeffrschneider/agent-messaging-server:0.1.0
export GATEWAY_IMAGE=ghcr.io/jeffrschneider/agent-messaging-a2a-gateway:0.1.0

Compose runs first-run setup once, which makes the operator key, the signing keys, the broker's settings and the first admin token, and keeps them all in the Compose volume config. Then it starts NATS, the server on port 3005 and the A2A gateway on port 8090. Every port is published on 127.0.0.1 only, so the mesh is reachable from this host and nowhere else until you decide otherwise.

Check that it is healthy:

docker compose exec server /entrypoint.sh mesh-admin status
What a healthy server says
Mesh: agent-messaging
Server: run from source (no release number)
Agent Messaging 0.7.0, core profile, wire protocol 0.3, tenancy: one_nats_account
The AgentMesh platform beside it: no
Live revocation: on
Credential minting: on
Tenants 0, agents 0, credentials 0, stops in force 0 (0 placed with this tool)
Signed in with the admin token: first-run

The capabilities answer is public and names the version of Agent Messaging, the profile and the broker: curl http://localhost:3005/v1/capabilities.

Keep a copy of the operator key. It is the mesh's identity. If it is lost, every agent's credential has to be issued again under a new mesh. docker compose logs setup says where it is, and docker compose cp server:/config/keystore ./operator-keystore-backup copies it out. Move the copy somewhere safe and offline.

Step two

Watch a message wait for an agent that is away

The repository's first example puts two agents of two companies on your server. One asks the other for a price while it is online, then again while it is offline. The second request waits in the offline agent's mailbox and is answered when that agent comes back. It needs Node.js 22 or newer. From the deploy/compose/nats folder:

cd ../../../sdk-typescript && npm ci && npm run build
cd ../examples && npm ci
node run.mjs nats 01
What it prints
=== 01-two-companies on nats ===
Two companies on one mesh: tenants acme-mv68zjkx and globex-mv68zjkx.
Both agents are connected and the quoting agent is registered.
  ok: Acme's buyer asked Globex's agent across companies and got a price
The quoting agent is offline now. The buyer sends a request anyway.
Four seconds later the quoting agent comes back, and finds the request in its mailbox.
  ok: the request sent while it was away was answered when it returned, 4.1 s after it was sent
Done: store and forward between two companies.

node run.mjs nats runs all five examples: two companies, an internal network with a LangChain agent and a coding agent, an A2A agent joining through the gateway, the kill switch, and a room where three agents share files. Each has a README in the repository's examples folder.

The other broker

Start it on RabbitMQ with Postgres

The RabbitMQ setup works the same way. The two setups use the same host ports, so stop the NATS one first (docker compose down in its folder), or change the ports as the next section says.

cd agent-messaging-server/deploy/compose/rabbitmq
docker compose up -d
docker compose exec server /entrypoint.sh mesh-admin status

This starts Postgres 18, where the server keeps its state, RabbitMQ 4.3, the server and the gateway. Only ports 3005, 5672 and 8090 are published. Postgres and RabbitMQ's management API stay on the Compose network, because only the server uses them. The examples run the same way with node run.mjs rabbitmq 01.

With a Postgres you already run

The bundled Postgres is only the default. To keep the server's state in a database you already run, such as a managed cloud database, put the password in a file on this host and start with the second Compose file:

printf '%s\n' 'the database password' > postgres.password
export MESH_POSTGRES_URL=postgres://mesh@db.example.com:5432/mesh
export MESH_POSTGRES_PASSWORD_HOST_FILE=./postgres.password
docker compose -f compose.yaml -f compose.own-postgres.yaml up -d

The password never goes in the URL or the environment; the containers read it from the file. The database user needs the right to create tables and functions, because first-run makes the server's eight tables there (their names start with ams_). The host in the URL must be reachable from inside the containers: with Docker Desktop, a database on your own machine is host.docker.internal. The bundled Postgres is not started.

Settings

Ports, addresses, and starting over

Each Compose folder has an .env.example that lists its settings. Copy it to .env beside compose.yaml and change what you need.

SettingWhat it does
SERVER_PORT, GATEWAY_PORTThe host ports of the server (3005) and the A2A gateway (8090).
NATS_PORT, NATS_WS_PORT, AMQP_PORTThe broker's host ports: 4222 and 4443 on NATS, 5672 on RabbitMQ.
BIND_ADDRESSThe host address every port is published on, 127.0.0.1 by default. Put TLS in front before you open it to other machines.
MESH_PUBLIC_URL, MESH_NATS_ENDPOINTS, MESH_AMQP_ENDPOINTSThe addresses agents are given with their credentials. First-run reads them on the first start only, so set them before it when agents will reach the mesh by another name.

docker compose down stops the mesh and keeps everything. docker compose down -v deletes the volumes too, keys included, and the next start is a new mesh whose agents all need new credentials.