Skip to content
advanced

A2A Explained: How Agent-to-Agent Communication Differs from MCP

MCP answers "what can I call?" A2A answers "who can I hand this to?" Different questions, different failure modes.

Published 2026-09-11Updated 2026-09-1214 min read
A breathtaking mountain landscape under dramatic cloud cover, ideal for nature photography.
A breathtaking mountain landscape under dramatic cloud cover, ideal for nature photography. Photo by Tudor S on Pexels.

MCP answers "what can I call?" A2A answers "who can I hand this to?" Different questions, different failure modes.

Picture a support agent that needs to hand a refund dispute to a billing agent. The billing agent may need to ask a follow-up question. The whole exchange may need to survive a restart. The obvious move is to wrap the billing agent as an MCP tool. It works in the demo. Then it rots in production, and the rot is structural rather than a bug.

Here is the failure sequence I use to teach this distinction. The wrapped agent has no task identity, so a retry after a timeout re-runs the entire dispute from scratch. It has no channel to ask a clarifying question mid-call, so it either guesses or fails. When the process dies halfway through, the half-finished job evaporates because there is nowhere to park it. The team built a stateful delegation problem on top of a call contract, and the contract lost.

That failure is worth understanding precisely, because it is the difference between two protocols people keep treating as competitors.

The Layer Mistake Behind Most A2A vs MCP Debates

A sparse architecture diagram shows an orchestrating agent sending a goal-level task across an A2A boundary to a billing agent. Inside the billing agent, an MCP boundary connects to ledger-read and refund-execution tools. The diagram distinguishes the external responsibility-transfer boundary from the internal capability-exposure boundary.
A2A can connect agents at a goal-and-responsibility boundary while MCP remains an internal contract for calling concrete tools.

The recurring question — "should we use A2A or MCP?" — is malformed. It assumes both protocols occupy the same slot and you pick one. They occupy different layers, and the real question is which boundary your integration crosses.

MCP is a client-server contract for exposing tools, resources, and prompts to a model-driven client. The unit of interaction is a call with a schema-defined shape. The client learns what it can invoke and with what arguments, then invokes it. That is capability exposure.

A2A is a peer-style contract for one agent to delegate work to another agent. The unit of interaction is a task with a lifecycle. The caller describes intent; the remote agent decides method. That is agent collaboration.

The asymmetry that matters is not features. It is opacity. An MCP tool is expected to be deterministic and inspectable — you can read its schema and predict its behavior. An A2A remote agent is deliberately opaque. It decides its own method, runs its own model, and may change its internals without telling you. That opacity is a design choice, not a limitation. It is what lets a remote agent evolve without breaking callers.

The two compose rather than substitute. An agent's advertised A2A capability can be implemented internally with MCP tools, and the caller never needs to know. A billing agent that exposes "resolve dispute" over A2A might internally call an MCP server for ledger reads and another for refund execution. The peer on the other side of the A2A boundary sees a goal-level capability. The tools stay private.

The decision axis is what crosses the boundary: a typed call, or a goal plus responsibility for finishing it.

Knowledge check

Check your understanding

Answer this question before you continue.

A billing agent owns the method for resolving a dispute, may ask follow-up questions, and can change its internal model without changing the caller's goal. Which boundary best fits this interaction?
Comparison Reasoning

Focus: Distinguish capability exposure from responsibility transfer when selecting between MCP and A2A.

What Actually Crosses the Wire in Each Protocol

Make the interface concrete and the layer distinction stops being abstract.

On the MCP side, you get JSON-RPC primitives, tool schemas, resource reads, and a client that must understand the schema to call correctly. The caller is coupled to an input/output contract. If the tool changes its arguments, callers break loudly at the type level.

On the A2A side, the transport is HTTP and JSON-RPC 2.0, with Server-Sent Events for streaming. Messages are composed of parts — text, structured JSON, files, URLs — and results come back as artifacts. The caller is coupled to a task contract and a natural-language description of intent, not to a function signature.

DimensionMCPA2A
Unit of workA callA task with a lifecycle
Caller couplingInput/output schemaTask contract plus intent
DiscoveryTool schemasAgent Cards
Stateful semanticsNot standardized across callsTask lifecycle is part of the protocol
StreamingTransport-dependentServer-Sent Events
Result shapeSchema-defined returnArtifacts composed of parts
Execution visibilityInspectable, deterministicOpaque, agent-chosen

The schema-coupling difference has a sharp consequence. With MCP, you can statically validate that a call is well-formed before you make it. With A2A, you cannot statically validate that a remote agent will do the right thing. You can only check the outcome.

That does not mean you throw away contract testing at the A2A boundary. It means verification splits into two layers, and both are required:

  1. Envelope and lifecycle conformance. Validate the message shape, the task state transitions, the authorization scope, and the artifact structure mechanically. These are still assertions, not vibes.
  2. Domain outcome and policy evaluation. Evaluate whether the artifact actually satisfies the goal, respects policy, and is safe to act on. This is where an eval suite replaces a unit test.

The mistake is treating these as either/or. Envelope checks catch malformed delegation before it wastes a remote agent's time. Outcome evaluation catches a well-formed task that produced the wrong answer. You need both, and they fail differently.

Discovery: Tool Schemas vs Agent Cards

Discovery is the first real architectural divergence, and it changes how you deploy and version systems.

MCP discovery is registration and schema lookup. The client learns what it can call and with what arguments. Selection is a type match: does this tool accept the arguments I have?

A2A discovery is capability advertisement. An Agent Card — typically served at a well-known path — describes identity, endpoint, skills, supported modalities, streaming and push-notification support, and authentication requirements. The client fetches the card and decides whether this agent fits the job.

That changes routing. With MCP you select a function. With A2A you select an agent, which means selection logic becomes a judgment about fit, trust, and cost rather than a type match. You are no longer asking "does this signature match?" You are asking "is this the right party to own this work, and do I trust its output enough to act on it?"

Versioning and drift diverge too. A changed tool schema breaks callers loudly — usually at compile time or first call. A changed remote agent can degrade quality silently while the card still looks valid. The card says "handles refund disputes." It does not say the remote agent swapped models last Tuesday and now resolves edge cases differently.

Treat an Agent Card as a contract, with the same review discipline you would apply to a public API description. It is a discovery surface, and discovery surfaces drift.

The honest limit: card contents and discovery conventions vary across implementations. Verify against the specific runtime you are integrating rather than assuming a universal shape. The concept is stable; the exact fields are not.

Knowledge check

Check your understanding

Answer this question before you continue.

An orchestrator must choose among several remote agents that all advertise refund-dispute skills. What additional judgment does A2A discovery require beyond checking whether an input signature matches?
Scenario Interpretation

Focus: Apply the distinction between schema-based tool selection and judgment-based agent selection.

Task State: The Part MCP Was Never Designed to Hold

This is where delegation stops being a fancy call and becomes a different kind of system.

A2A tasks move through an explicit lifecycle: submitted, working, then terminal or blocked states such as input-required, auth-required, completed, failed, canceled, or rejected.

The input-required state is the mechanism that enables multi-turn clarification. The remote agent can ask a question mid-task instead of failing or guessing. That single state is why the wrapped-agent-as-MCP-tool approach rots: a basic MCP tool call has no standardized place to return "I need more information and I am holding your job open while I wait." You can build that loop in your own client, but you are now inventing a task protocol on top of a tool protocol, and every caller has to reinvent it.

Long-running work is first-class in A2A. Tasks can outlive a single request, stream progress, and deliver artifacts on completion. In MCP, cross-request state lives in the calling agent's own loop, not in the protocol. That is the precise difference: not that MCP forbids state, but that MCP does not standardize task identity, lifecycle, or reconciliation across calls. A wrapped agent-as-tool has nowhere protocol-defined to park a half-finished job.

Here is the invariant that makes recovery safe, and the one most teams miss:

A visible task state is not proof that a side effect did or did not happen. Safe recovery requires that a task id maps to durable, authoritative state, and that every side effect is correlated with that state through an idempotency key or a reconciliation query.

Without that invariant, task lifecycle visibility is theater. You can see the task moved to completed and still not know whether the refund executed once, twice, or not at all.

The operational consequences land on you, not the protocol:

  • Task persistence. If your orchestrator restarts, in-flight tasks need to survive or be reconciled against durable state.
  • Idempotency on retry. Retrying a task id must not duplicate a non-idempotent action. The remote agent must honor an idempotency key, or you must reconcile before retrying.
  • Cancellation semantics. A canceled task whose side effects already landed is a real state, and you need to detect it.
  • Timeouts that do not orphan work. A timeout on your side does not stop the remote agent.
  • Reconciliation after a crash. You need to query task state and decide whether to resume, retry, or abandon.

Name the failure paths before they page you. A task stuck in working with no heartbeat. A canceled task whose refund already executed. A retry that charges the customer twice because the first attempt succeeded but the response was lost. These are not exotic. They are the ordinary weather of distributed systems, and A2A hands you the same weather microservices handed you a decade ago.

Knowledge check

Check your understanding

Answer this question before you continue.

A task is visibly marked completed after a timeout and restart. Which conclusion is safe according to the article?
Misconception Check

Focus: Explain why visible A2A task states are insufficient for safe recovery from retries and crashes.

Delegation, Trust, and the Security Boundary

Authentication is not the hard part. Authorization scope is.

A delegated task may need credentials the caller should not hand over directly. The auth-required state exists precisely because a remote agent may need to obtain its own authorization mid-task rather than receiving it up front. That is a meaningful design choice: the caller delegates the goal, and the remote agent negotiates its own access.

The trust asymmetry is the part architects underestimate. An MCP tool runs where you put it, under your policy, your logging, your model version. A remote A2A agent runs under someone else's policy, logging, and model version. You are not calling a function. You are handing work to a party whose internals you cannot see and whose behavior can change without a schema diff.

Prompt-injection and instruction-confusion risk grows when a remote agent's natural-language output is fed back into your orchestrator's reasoning loop. The remote agent's artifact is untrusted input. Treat it that way.

Practical controls I would put in place before shipping a cross-org delegation:

  • Constrain what a delegated task may touch. Scope the remote agent's authority, not just its endpoint.
  • Treat remote artifacts as untrusted input. Validate before they enter your reasoning loop.
  • Log the full task transcript — every message, every state transition, every artifact.
  • Keep a human-approval gate on irreversible actions. Refunds, deploys, deletions, payments.

Where this is heading in the wider ecosystem: agent registries and identity schemes are being built because "who is this agent and who is liable" is unresolved. Payments authorities and platform vendors are experimenting with registries that vet agents before they transact. Treat registry and liability questions as open, not settled. If your architecture assumes a solved identity layer, you are building on sand.

Knowledge check

Check your understanding

Answer this question before you continue.

A remote agent returns an artifact that the orchestrator will use to decide whether to issue a refund. Which control best follows the article's security boundary guidance?
Scenario Interpretation

Focus: Identify the security controls required when an orchestrator consumes output from a remote A2A agent.

When to Use Which — and When to Use Neither

Convert the comparison into a rule you can apply this week.

Use MCP when the boundary is capability exposure: a database, an API, a file system, a deterministic operation with a describable contract. The caller knows what it wants and the tool knows how to do it. Schema coupling is a feature here, not a cost.

Use A2A when the boundary is responsibility transfer: the other side owns a domain, its method is not your business, and the work may take multiple turns or a long time. You are handing over a goal, not a call.

Use both when a domain agent exposes a goal-level capability to peers while internally calling MCP tools. This is the common production shape, not an exotic one. The billing agent speaks A2A to its peers and MCP to its ledger.

Use neither when a single agent with a handful of tools already solves the problem. A mesh of agents adds discovery, auth, monitoring, and resilience work that small workflows do not repay. This is the same economics as MCP itself: MCP pays off when you have many tools and contexts. A2A pays off when you are stitching together many agents with genuinely different capabilities and owners. Below that threshold, you are paying microservices tax for a script.

The migration path I would follow: start with MCP for tools, add A2A only at the seams where a second team or vendor owns the work, and keep the orchestrator thin. Every agent you add to the mesh is a service you now have to discover, authenticate, monitor, and reconcile.

A Minimal Delegation Trace to Build Against

Abstract lifecycles become real when you can run one and break it. Here is the smallest observable target.

Step one: prove discovery. Publish an Agent Card for a trivial remote agent and fetch it from a client. Confirm you can read its skills and endpoint before adding any reasoning.

Step two: send one task. Observe the submitted-to-working transition and confirm the artifact arrives in a predictable shape. Log the task id.

Step three: force the input-required path. Have the remote agent ask a clarifying question. Answer it. Let the task complete. This is the path a wrapped MCP tool cannot express without you building the loop yourself, so prove it works before you rely on it.

Step four: break it deliberately. Kill the remote agent mid-task. Retry the same task id. Inspect whether you get duplication, an orphan, or a clean failure. Then cancel a task whose side effects already landed and see whether your system notices.

What to instrument for every delegation:

{
  "task_id": "tsk_8f2a",
  "idempotency_key": "refund-dispute-4471",
  "transitions": [
    {"state": "submitted", "at": "2026-01-14T10:02:11Z"},
    {"state": "working",   "at": "2026-01-14T10:02:12Z"},
    {"state": "input-required", "at": "2026-01-14T10:02:19Z"},
    {"state": "working",   "at": "2026-01-14T10:03:02Z"},
    {"state": "completed", "at": "2026-01-14T10:03:41Z"}
  ],
  "artifacts": [{"id": "art_01", "provenance": "remote-agent"}],
  "transcript_ref": "trace://delegation/tsk_8f2a"
}

Task id, idempotency key, state transitions with timestamps, artifact provenance, and the full message transcript. If you cannot reconstruct what happened from those five things, you cannot debug a delegation failure.

Now make the drill falsifiable. For each perturbation, write the predicate your system must satisfy:

PerturbationExpected observationPredicate that must hold
Retry same task id after timeoutRemote agent reports the original task already completedNo second side effect; artifact identical to first
Retry same task id, response lostRemote agent returns the same artifact, not a new oneIdempotency key maps to one side effect
Remote agent dies mid-taskTask stuck in working, no heartbeatReconciliation query resolves to resume, retry, or abandon
Cancel after side effect landedTask reaches canceled, but refund already executedSystem flags the orphaned side effect for review
Malformed artifact returnedEnvelope validation fails before reasoningArtifact rejected; task marked failed, not completed

The drill: run this trace once with a local agent wrapped as an MCP tool and once over A2A. Write down which failure modes each one cannot express. The MCP version will not hold a task open for clarification without custom client logic, and it will not have a protocol-standard task id to reconcile against after a crash. That gap is the whole argument.

The Seam You Cannot Observe

Name the boundary first, then pick the protocol. Capability exposure is a call contract; agent collaboration is a delegation contract with standardized task state. They fail in different ways, and the failure modes tell you which one you actually needed.

Protocols do not make agents collaborate. They make the seams between them inspectable. The seam you cannot observe is the one that will page you at 3 a.m.

Your next action: instrument a single delegation trace with task-id logging, an idempotency key, and state transitions. Run the same job through an MCP-wrapped agent. Then run the perturbation table above and record which predicates your system can actually satisfy. The failure modes the call contract cannot express are the ones that tell you where A2A belongs in your stack.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

A billing agent owned by one team exposes dispute resolution to peer agents, while internally it calls a ledger API and refund operation with fixed schemas. Which architecture matches the article's recommendation?
Question 1 of 2Comparison Reasoning

Focus: Choose MCP, A2A, both, or neither based on ownership, interaction shape, and workflow complexity.

A refund delegation times out after the remote agent may have executed the refund. The orchestrator creates a new task id and retries without checking durable state or reusing an idempotency key. What is the primary defect?
Question 2 of 2Debugging

Focus: Diagnose a delegation retry design that can duplicate a side effect after a lost response.

Related sites

Build the foundations behind advanced AI systems

Use LearnLLMFast for practical LLM application foundations and LearnPyFast for the Python mechanisms that support implementation work.

LLM tutorialstutorial

LearnLLMFast

Practical LLM tutorials for builders who want to understand prompting, workflows, agents, and AI applications.

LLMAIBuilders
Visit LearnLLMFast
Python tutorialstutorial

LearnPyFast

Beginner-friendly Python tutorials, examples, and learning paths for practical programming foundations.

PythonProgrammingBeginners
Visit LearnPyFast

Keep exploring

Related AI engineering tutorials

Continue with adjacent system layers, implementation patterns, and current AI engineering ideas.