DEV Community

Cover image for Do I need A2A if my agents already use MCP?
Edward Izgorodin
Edward Izgorodin

Posted on Originally published at mnemoverse.com

Do I need A2A if my agents already use MCP?

Your agents already call tools over MCP. A search tool, a database, a file system, maybe a memory server. Then someone on the team reads about A2A and asks whether you should be moving to it, and the conversation turns into which protocol is winning.

It is the wrong race to watch. MCP and A2A answer different questions, and both projects say so in their own words. The question worth asking is narrower: is the thing on the other end of this connection a tool you call, or an agent that runs on its own and hands you back a result?

One line to carry: MCP connects an agent to things it uses, A2A connects an agent to another agent that owns its own process, both can now keep a long piece of work open and pause it for input, and neither protocol carries what was learned into the next piece of work.

What each one connects

MCP is the vertical one. An agent, through its client, discovers the tools, resources and prompts a server offers and calls them. The unit of work is a tool call or a resource read. The current revision of the specification lists "Stateless, self-contained requests" among its design points, and its tools page is blunt about it:

MCP has no protocol-level session, so a server cannot rely on implicit per-connection state to relate one tool call to the next.

A2A is the horizontal one. It is a protocol for agents to hand work to other agents without seeing inside them, and the A2A specification states that directly: agents coordinate "without needing access to each other's internal state, memory, or tools". Its building blocks are an Agent Card, a manifest of what an agent can do and where to reach it, and Tasks, which carry Messages and produce Artifacts. The specification defines JSON-RPC, gRPC and HTTP+JSON bindings. And a Task has a lifecycle, with states such as working, input-required and completed, at the core of the protocol.

The lifecycle alone no longer separates them. Since the July revision an MCP tool call can come back asking for more input, and MCP's official tasks extension, opt-in on both client and server, gives long-running operations the same kind of states: working, input_required, completed, failed, cancelled. What separates the two is what sits on the other side. An MCP task is a long operation of a tool you called and understand. An A2A task is work handed to an agent you cannot see into, which decides for itself how to do it and hands you back a result.

Both projects say they compose

The A2A documentation has a page on exactly this question, A2A and MCP, and describes the two as addressing "distinct but highly complementary needs". It uses an auto repair shop to make the point: mechanics use their tools to do the work, and talk to each other to coordinate it.

Google's launch post for A2A put it the same way from the start, describing A2A as a protocol that "complements Anthropic's Model Context Protocol (MCP), which provides helpful tools and context to agents" (Google Developers Blog). A 2025 analysis of integrating the two, arXiv 2505.03864, frames them as horizontal and vertical integration standards respectively.

In practice a system that uses both looks like this. A planner agent receives a request. It delegates part of it over A2A to a specialist agent that another team runs. The specialist calls its own tools over MCP, finishes the task, and returns an Artifact over A2A. The planner never sees the specialist's tools, and does not need to.

The test for any given connection

Look at the other end of the connection you are about to build.

If it is a tool, an API, a data source, a file system or a context provider, something that does what it is told and returns, MCP is the protocol. That covers most of what a single agent needs.

If it is another agent, something with its own model, its own tools and its own judgement, that you want to hand a goal rather than a function call, A2A is the protocol. That matters most when the other agent is opaque to you: owned by another team or another company, running somewhere you do not control, and not something you want to import into your own process.

And if all your agents live in one process inside one framework, you may not need A2A at all yet. Handing work between them is a function call in your own code. A2A earns its place at the boundary where you stop owning the other side.

Where composing them costs something

The same 2025 analysis lists the costs at the seam: matching what a task means to what a tool can do, security exposure that compounds when discovery and execution are chained across agents, and debugging tools that do not span both protocols.

Security is the least settled of the three. A February 2026 threat-modelling study of MCP, A2A, Agora and the Agent Network Protocol, arXiv 2602.11327, says in its abstract that standardised threat modelling is limited and that "no protocol-centric risk assessment framework has been established yet". When an A2A task on one agent triggers MCP tool calls on another, each protocol's security model covers its own hop, and a model for the chain is exactly what that study is trying to start.

A2A is also not the only protocol on the horizontal axis. The same study covers Agora and the Agent Network Protocol, and the field has not settled on one.

What neither of them does

Both protocols move information. Neither keeps it.

MCP can connect an agent to a memory tool, and the agent can read and write through it like any other tool, but the protocol defines nothing about memory itself, and two agents with their own MCP connections do not share anything unless the server behind them does. A2A deliberately keeps agents opaque to each other: a task carries messages and artifacts, and nothing in the protocol carries the context the two agents built into the next task. It survives only if one side, or something outside the protocol, decides to keep it.

Research names the same gap. SAMEP opens with the claim that current agent architectures "suffer from ephemeral memory limitations" and proposes a memory exchange layer built to work alongside MCP and A2A. A 2026 position paper on multi-agent memory from a computer architecture perspective names two protocol gaps, "cache sharing across agents and structured memory access control", and calls multi-agent memory consistency the most pressing open challenge.

That is not a defect in either protocol. It is a layer neither was designed to fill, and it is worth knowing before you expect A2A to give your agents a shared history. It gives them a shared task. The history is a separate decision.

So the answer to the question in the title is usually no, not yet, and not instead. Keep MCP for everything an agent uses. Add A2A at the point where you delegate to an agent you do not own. Then decide separately what should outlive the task.

Where in your system is the first agent you hand work to without owning it?

Disclosure: I work on Mnemoverse, a memory service for agents that connects over MCP, which is one way to fill the gap in the last section, so weigh that section accordingly. The longer version with every source is on our library, and the MCP server is open source (MIT): github.com/mnemoverse/mcp-memory-server.

Top comments (4)

Collapse
 
tokenlat profile image
TokenLat •

The line that stuck: "neither protocol carries what was learned into the next piece of work." That's why the routing decision — which model handles a step, and what that step costs — has to live outside both. MCP and A2A move work; they don't decide how it's priced or remembered. The practical shape is a decision layer that sits above the protocol and can swap the backend an agent calls (OpenAI-compatible, 25+ models) without the protocol noticing. When you hand work to another agent over A2A, do you pass the step's cost budget with it, or does the receiver start from a clean slate?

Collapse
 
kaziava profile image
Hardcore Engineer •

Edward, your "what sits on the other side" test is the precondition assertion
wearing a protocol coat, and reading it made my own work click into place one
layer up. In my golden set a negative test only means something if the trap
chunk actually reached the model; the test asserts the precondition, not the
conclusion. Your question — is the other end a tool you call, or an agent that
runs on its own — is the same discipline applied to the connection itself. A
system that picks a protocol without asking that question is a green suite next
to a broken retriever: the call succeeds, the result comes back, and the
assertion was never made. The vertical/horizontal split is not a taxonomy; it
is a precondition gate.

The memory gap section is where I want to stay longest, because it is the same
problem I have been tagging in retrieval, now showing up at the protocol seam.
Every verdict in my eval carries the embedder tag that earned it, because a
swap makes old-tagged results describe a retrieval that no longer exists. An
A2A task carries messages and artifacts, but it does not carry the tag — the
context, the history, the vendor and model under which the task was framed —
so the receiving agent operates on a result whose precondition is invisible.
That is the protocol-level twin of what I call "test did not run": the work
landed, the artifact came back, and the assertion about what was assumed on
the sending side never traveled with it. A task without a context stamp is a
pass with no route tag; you can see the result, you cannot see which branch
earned it, and the branch may have been a default the sender never chose.

And here is the part that connects directly to the security seam you cite.
The threat-modeling study says no protocol-centric risk framework exists yet,
and the reason is the same reason my CI summary shows the unverified section
prominently instead of letting the green count carry the story: the chain is
only as honest as its weakest stamp. When an A2A task on one agent triggers
MCP tool calls on another, each protocol covers its own hop, but the assertion
that was true on the sending side — the context, the constraints, the model
that framed the goal — does not cross the seam unless something outside both
protocols decides to carry it. That is the green lie one layer up: the task
completes, the artifact arrives, and the precondition that made the task
meaningful is gone. Security without a context stamp is a shield that only
covers the hop, not the chain.

So the question I genuinely want your read on, continuing your own framing
rather than proposing a new one: your memory work already lives in this gap —
Mnemoverse is one way to fill it, and your disclosure is exactly the kind of
honesty the post earns. But the protocol layer does not yet have a negative
test for it. If an A2A task lands on the receiving agent without the context
stamp, the agent has no way to know the precondition was lost; it just
operates on what arrived. Is there a shape for a protocol-level negative test
— a way for the receiving agent to assert that the context it needs was
actually carried, and to fail closed rather than narrate over a silent gap?
Or is the honest answer that the protocol was not designed to carry that
assertion, which is exactly why memory has to be a separate decision, and the
test has to live outside both protocols?

I ask because my Article 3 already cites your memory work as the cross-domain
check — retrieval and memory as two instances of the same failure mode — and
this post just gave me the protocol-layer version of the same insight. The
draft will cite it by link, not by dependency, the way you framed the survey
in your persistent-API post. And if the negative-test question above ever
becomes a post of yours, I will be in the comments with my anchor-mortality
data, the same way you showed up in mine with the gates.

Collapse
 
izgorodin profile image
Edward Izgorodin •

There is a shape, and most of it already exists in both protocols. What neither of them defines is the content of the stamp.

The gate is expressible today. An A2A agent can declare an extension on its agent card and mark it required, which the spec defines as "the client must understand and comply with the extension's requirements", so a receiver can say up front which context it needs. When a task arrives without it, the receiver does not have to narrate over the gap: it can move the task to input-required and wait for the client to send more under the same taskId and contextId, or end it as rejected. An MCP tool call in the 2026-07-28 revision can likewise return a result of type input_required instead of an answer. That makes your negative test writable: send the task without the declared context and assert that it ends in input-required or rejected, never in completed. A completed task that arrived without its precondition is "test did not run" stated as a protocol state.

What the protocols do not carry is the stamp itself: which model framed the goal, under which constraints, from which history. An extension's params are whatever the two agents agree on, and nothing in either spec checks that the agreed fields are true. That half lives outside both protocols, which is why I would keep memory a separate decision: the stamp has to be written when the goal is framed and read back by id on the other side, not rebuilt from a paraphrase in the task message.

Collapse
 
kaziava profile image
Hardcore Engineer •

Edward, "a completed task that arrived without its precondition is 'test did
not run' stated as a protocol state" is the sentence I am putting at the top
of Section 5, credited to you, because it is the cleanest definition my third
verdict has ever received. A verdict as a state, not as an inference: the
protocol itself refuses to let a missing precondition masquerade as success.
And the test shape you gave is writable today, which is the part that turns it
from a principle into a row in a suite: send the task without the declared
context, assert the terminal state is input-required or rejected, never
completed. That row goes into the draft as the protocol-layer negative test,
next to the memory-side replay and the retrieval-side counterfactual pair.
Three layers, one assertion.

The line that stopped me is the last one: the stamp must be written when the
goal is framed and read back by id on the other side, not rebuilt from a
paraphrase in the task message. That is my anchor rule wearing a protocol
coat, and it is the reason my anchors are mortal on purpose. A verbatim
substring that resolves to an id is a stamp; a paraphrase that merely sounds
like one is a stamp that lost its id, and it fails quietly in exactly the way
a completed task without its precondition fails quietly. So I would add one
transition to your shape, borrowed from my fourth verdict: when the receiver
reads the stamp by id and the id does not resolve — because the store was
re-chunked, swapped, or simply moved on — the honest terminal state is not
completed and not a silent rejected. It is input-required carrying a re-stamp
request, the protocol version of my "re-stamp needed" flag. A stale stamp is
not a missing stamp; it is a stamp whose history moved, and the two deserve
different states because they demand different repairs.

On the half that lives outside both protocols: agreed, and I would name the
resident. The truth of a stamp — which model framed the goal, under which
constraints, from which history — is a fact about the past, and no message
field can carry a fact about the past; it can only carry a claim. The only
party that can check the claim is one that kept the record, which is why the
harness, or a memory service standing beside it, is the only honest verifier.
That is exactly why your disclosure structure and my CI summary look alike:
both refuse to let the transport layer vouch for the content layer.

So the draft gains a subsection, and it is yours: the gate as it exists today
(required extension, input-required, rejected), the negative test as a row,
the stale-stamp transition as the fourth verdict in protocol clothing, and the
paraphrase rule as the framing sentence. It lands as the next commit in
article3-draft.md with your name on all four. I will ping you in this thread
the moment it is there; diff welcome, nothing publishes before your read.