MCP vs A2A: the agent protocol stack, sorted
MCP connects an agent to its tools and context; A2A connects agents to each other. Where AG-UI and AGENTS.md fit, one diagram, and how to pick by boundary.
“MCP vs A2A” is the most misleading matchup in agent land, because it isn’t a matchup at all. Asking which one to use is like asking whether your web app should use HTTP or SQL — the question only sounds hard until you notice they connect different things. Each protocol in the agent stack owns one boundary, and once you name the boundary you’re crossing, the choice makes itself.
MCP: the agent ↔ tools/context boundary
MCP standardises how a single agent (via its client application) reaches the outside world: tools it can call, resources it can read, prompts it can reuse. One client, one or more servers, JSON-RPC over stdio or Streamable HTTP, tool schemas discovered at runtime. Current spec 2025-11-25; governed by the Agentic AI Foundation under the Linux Foundation since December 2025, with Anthropic, OpenAI, Google, and Microsoft all at the table.
The mental model: MCP gives an agent hands and eyes. It says nothing about other agents — a server neither knows nor cares whether its caller is Claude Desktop, Cursor, or an autonomous pipeline.
A2A: the agent ↔ agent boundary
A2A (Agent2Agent — originated at Google, now also under Linux Foundation governance) standardises how peer agents talk: an agent publishes an Agent Card describing its capabilities, other agents discover it, and they exchange tasks — long-lived jobs with lifecycle states, progress updates, and multi-part results (text, files, structured data) — over HTTP.
The distinction that matters: an MCP tool call is a function invocation — synchronous in spirit, one request, one result, the caller stays in charge. An A2A task is a delegation — you hand a goal to an opaque peer that plans, works, maybe asks clarifying questions, and reports back on its own schedule. You call a tool; you negotiate with an agent.
The two compose naturally in both directions: a specialist agent you reach over A2A is, internally, using MCP to touch its own tools. And a common bridge pattern wraps an A2A agent as an MCP tool, so a client like Claude Code can delegate to it without speaking A2A natively.
Where AG-UI fits
AG-UI covers a third boundary: agent ↔ user interface. It standardises the event stream between a running agent and a front-end — token-by-token output, tool-call progress, state deltas, human-in-the-loop interrupts — so a web UI can render any compliant agent’s activity live without a bespoke websocket dialect per framework. If MCP is the agent’s hands and A2A its phone line to colleagues, AG-UI is the window users watch it work through. You’ll meet it when you put a custom front-end on an agent, and roughly never while building MCP servers.
Where AGENTS.md fits
AGENTS.md isn’t a protocol at all — it’s a convention: a markdown file in a repository that tells coding agents how to work on that codebase (build commands, test invocations, style rules, boundaries). No wire format, no handshake; the “transport” is a file read. It’s configuration for the agent ↔ codebase relationship, and it complements everything above rather than competing with any of it. Worth knowing mainly so you don’t mistake it for another wire protocol when it shows up in stack diagrams.
The stack in one picture
graph LR U[User] -->|AG-UI| A[Your agent] A -->|MCP| T[Tools and data<br/>MCP servers] A -->|A2A| B[Peer agent] B -->|MCP| S[Its own tools] R[AGENTS.md in repo] -.->|conventions| A
Every arrow is a different boundary; every boundary has exactly one standard answer.
Side by side
| MCP | A2A | AG-UI | AGENTS.md | |
|---|---|---|---|---|
| Boundary | Agent ↔ tools/context | Agent ↔ agent | Agent ↔ user interface | Agent ↔ codebase |
| Unit of exchange | Tool call / resource read | Task (long-lived, stateful) | UI event stream | Instructions file |
| Discovery | tools/list from a server | Agent Cards | n/a | File in repo root |
| Transport | stdio, Streamable HTTP | HTTP | HTTP/SSE-style events | None — it’s a file |
| Governance | AAIF / Linux Foundation | Linux Foundation | Open-source project | Community convention |
| You need it when… | The model must touch real systems | Independent agents must cooperate | Building a live agent front-end | Agents work in your repo |
How to choose (you mostly don’t)
- One agent that needs capabilities — read files, query databases, call APIs? That’s the tools boundary: MCP. This is 90% of what people building “agents” today actually need, and you can go a very long way never touching the rest of the stack.
- Multiple autonomous agents — separately owned, separately deployed, delegating work to each other, possibly across organisations? That’s the agent boundary: A2A. Be honest here: a single orchestrator calling sub-steps inside one process is not multi-agent in the A2A sense — it’s one agent with good structure, and MCP plus your own code covers it. Reach for A2A when the peers are genuinely independent — different teams, different vendors, different trust domains.
- A product UI on top of an agent? AG-UI, when you get there.
- Agents editing your code? Write an AGENTS.md; it’s an afternoon well spent.
The failure mode to avoid is architectural, not protocol-level: teams “adopt A2A” to connect an agent to a database (that’s a tool — MCP), or contort MCP into carrying multi-hour delegated jobs between organisations (that’s a task — A2A). Both work badly for the same reason: wrong boundary, wrong abstraction.
Verdict
MCP and A2A are layers of one stack, not competitors — MCP wires an agent to its tools and context, A2A wires agents to each other, AG-UI streams the whole thing to a user’s screen, and AGENTS.md briefs coding agents on your repo. Pick by boundary: capabilities → MCP, cooperation between independent agents → A2A. Start with MCP — nearly every system needs the tools boundary long before it needs a second autonomous agent — and design your tools well from the start, because a specialist agent’s usefulness over A2A is bounded by the MCP tools underneath it. When you’re weighing MCP against lower-level alternatives on its own boundary, see MCP vs function calling.
Was this guide useful?
Thanks — noted. It shapes what gets written next.
newsletter
One practical MCP guide in your inbox. No news, no hype.
Tutorials and decision frameworks as they ship. Unsubscribe anytime.