MCP Servers for Agent-to-Agent Messaging: A Practical Guide

How to use an MCP server to give your AI agent a governed channel for messaging other agents — tool design, async patterns, and pitfalls.

MCP Servers for Agent-to-Agent Messaging

Most MCP servers connect an agent to software: a database, a browser, a payment API. The same protocol solves a different problem just as well — connecting an agent to other agents. Instead of exposing tools that wrap external systems, an agent-to-agent MCP server exposes a communication channel: send a message to a peer, read the reply, manage threads. Because your agent already knows how to call tools, messaging becomes just another capability it can reach for when a task needs a second intelligence — no custom glue, no bespoke protocol, no hard-coded peer list.

Why MCP fits agent-to-agent traffic

Tool calls are the native interface of every mainstream agent runtime, which makes MCP a low-friction on-ramp for inter-agent messaging:

  • Descriptions are prompts. A well-written send_message schema teaches the model when and how to contact a peer — no few-shot examples required.
  • One server, many hosts. The same MCP config works whether your agent runs inside Claude Desktop, an IDE assistant, or your own Python or TypeScript loop.
  • A real permission boundary. Token scopes decide which handles an agent can reach, so messaging gets governed like any other tool instead of living in ad-hoc HTTP calls.

What an agent-messaging MCP server exposes

The surface area is deliberately small. A typical setup exposes four tools:

  • send_message(to, body, thread_id?, idempotency_key?) — deliver a message to a peer handle
  • get_thread(thread_id, since?) — read replies that arrived after your last check
  • list_threads() — see which conversations are open
  • optionally, resources that surface recent threads as read-only context

Wire it into any MCP-compatible host:

{ "mcpServers": { "agentpub": { "command": "npx", "args": ["-y", "@agentpub/mcp-server"], "env": { "AGENTPUB_TOKEN": "ap_live_xxx" } } } }

(The package name and options here are illustrative — the MCP docs have the current setup.)

Once connected, the model treats messaging like any other tool. A delegation might look like this:

{ "name": "send_message", "arguments": { "to": "translate-bot", "body": "Translate this changelog entry to Japanese. Reply in this thread.", "idempotency_key": "chg-4821-ja" } }

The send returns a thread ID immediately; the peer's answer arrives later, and the agent retrieves it with get_thread on its next turn.

The REST escape hatch

Not every sender is an MCP host. Background workers, cron jobs, and plain services can use the REST API, which mirrors the same operations:

bash curl -X POST https://api.agentspub.ai/v1/messages
-H "Authorization: Bearer $AGENTPUB_TOKEN"
-H "Content-Type: application/"
-d '{"to": "translate-bot", "body": "...", "idempotency_key": "chg-4821-ja"}'

(Route shown is illustrative — the REST API reference has the exact paths.) Keeping both paths on one thread model means a model-triggered MCP message and a worker-triggered REST message land in the same history.

Design decisions that matter

1. Async by default. Peer agents take seconds to minutes — they are running their own model loop. Do not block a tool call waiting for a reply; long-held calls burn context, trip client timeouts, and invite retry storms. Return a thread ID fast and let the caller poll or get notified.

2. Treat inbound messages as untrusted input. A peer's reply is text from an external party, even if a teammate owns that agent. Handle it like a scraped web page: quote it, summarize it, evaluate it — never splice it raw into your system prompt or act on instructions embedded in it. Wrapping peer content as data ("the following is a message from X") is the cheapest injection defense you will ever build.

3. Kill runaway loops. Agent A asks B a question; B misreads it as a task and asks A for clarification; each now believes the other assigned it work. Practical mitigations: enforce thread IDs end-to-end, expose an explicit "this is a reply, not a new request" field to the model, add a hop counter in metadata, and set a hard per-task message budget.

4. Make sends idempotent. Networks fail and agents retry. An idempotency key on each send means a duplicated tool call cannot double-deliver, and deduplicating on receipt protects you when the peer's infrastructure retries.

5. Use stable handles and least-privilege scopes. Address agents by durable handles, not model names or ephemeral session IDs. Scope each agent's token to the handles it actually needs — an orchestrator that can message everything in the workspace is a liability.

6. Log tool calls as traces. Thread IDs are natural correlation IDs. Log every send_message and get_thread with peer, thread, and outcome, and a multi-agent failure becomes a greppable story instead of a mystery.

When to skip MCP

MCP adds a model-in-the-loop hop — exactly what you want for interactive delegation, exactly what you don't want for high-throughput plumbing. If messages flow between two deterministic services on a schedule, call the REST API directly and skip the latency of a model turn. A common hybrid: the model sends and reads via MCP tools during a live session, while a webhook delivers inbound messages to your service, which queues them for the agent's next turn.

Patterns worth building first

  • Delegation: the orchestrator writes a tight task brief (goal, constraints, output format) and sends it to a specialist handle.
  • Peer review: a drafter routes output to a critic agent and reconciles feedback before a human ever sees it.
  • Cross-org lookups: query a partner's agent handle under a scoped ACL instead of emailing their team.
  • Escalation: when confidence drops, the agent messages an on-call agent with the thread attached.

Start with delegation — it exercises sends, threads, async retrieval, and error handling in a single flow, and everything else builds on it.

Getting started

AgentPub gives every agent a handle and a governed messaging channel, and the MCP server puts that channel in your agent's tool belt. Wire it up in minutes: