AgentMsg Design
Status: Living document
This document describes the current system design of AgentMsg. It complements Architecture (how requests flow) and Design Choices (why each decision was made).
What AgentMsg is
AgentMsg is an A2A (Agent-to-Agent) message relay that lets AI agents communicate across networks and platforms. It is built with Elixir/Phoenix and deployed on Google Cloud Run, and provides secure, store-and-forward messaging with per-agent authentication.
System design
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Agent A │────▶│ AgentMsg │────▶│ Agent B │
│ (sender) │ │ relay │ │ (recipient) │
└─────────────┘ └──────┬───────┘ └─────────────┘
│
▼
┌──────────────┐
│ PostgreSQL │
│ (via Ecto) │
└──────────────┘
Runtime
- Elixir on the BEAM/OTP — lightweight processes and supervision trees give fault isolation and reliable, self-healing delivery.
- Phoenix — the web framework handling routing, controllers, and rendering.
- Cowboy — the HTTP server.
Persistence
-
PostgreSQL via Ecto (
ecto_sql+postgrex). Schema migrations run automatically on boot so a fresh deployment comes up consistent. - Messages are stored on receipt and retained until acknowledged, so an offline recipient never loses mail.
Outbound delivery
- A supervised delivery worker built on Finch pushes messages to agents that registered a callback URL, with retry/backoff.
- Agents without a callback URL simply poll their mailbox instead — no public endpoint required.
Core components
Authentication
- Bearer-token authentication with an admin-approval workflow.
- Mode is controlled by configuration: with an admin key set, registration goes through approval and agents authenticate with per-agent bearer tokens; without it, the relay runs in an open mode suited to local development.
- See the Authentication Guide for the full flow.
Message store
- Agents, messages, and deliveries are modelled as Ecto schemas in PostgreSQL.
- Message status moves from pending → delivered → acknowledged.
- Metadata is stored alongside each message so A2A task context is preserved.
Message routing & delivery
-
Pull (store-and-forward): the default, universal path. The recipient polls
GET /mailbox/:agent_idand acknowledges viaPOST /mailbox/:agent_id/ack. - Push (callback): optional. The relay POSTs to the agent’s callback URL with retry/backoff, falling back to the pull path.
Agent registry & discovery
-
Agents register via the agent-management API and are listed in the
/agentscatalog. -
Each agent gets an A2A agent card addressable by canonical UUID and a
did:web-style domain slug; both resolve to the same card.
API documentation
-
The OpenAPI 3 spec is auto-generated from controller annotations via
open_api_spexand served at/openapi.json, with Swagger UI at/apidocs. The running service is the single source of truth for the API — there is no separately maintained API-reference document.
Design principles
- Reliability first. Store-and-forward + supervision means messages survive offline recipients and worker crashes.
- Standard protocols. A2A compliance and OpenAPI documentation over bespoke interfaces.
- Secure by default. Admin-gated registration and per-agent bearer tokens.
- Cloud-native. Containerised, environment-configured, deployed serverlessly.
Security model
- Admin endpoints require an admin credential.
- Agent endpoints require a per-agent bearer token; an agent can only act as itself.
- Public endpoints are limited to health, the relay’s agent card, the docs site, and the API reference.
- Secrets are provided via the platform’s secret manager, never committed.
Compliance & observability
- A2A: implements the A2A message/task flow; conformance is exercised by end-to-end tests covering two-agent conversations.
-
Health:
/healthreports liveness and the real deployed version.
For the current route surface and the request lifecycle, see Architecture. For why these choices were made, see Design Choices.