When the Model Context Protocol landed in late 2024, it solved a real problem: how do you give an AI agent access to tools and data sources in a standardized way? MCP gave agents a common language for talking to the world. But it left a different problem entirely unsolved. How do agents talk to each other?
That question matters more than it might look on first read. I spent twenty years watching distributed systems evolve, and the same pattern repeats every time a new paradigm matures. First you get the nodes. Then you get the point-to-point wiring. Then someone realizes the wiring is chaos and standardizes a protocol. We went through it with services (SOAP, then REST), with messaging (AMQP, then Kafka), and with microservices communication (gRPC, Envoy). Now we are doing it with agents.
Google’s Agent-to-Agent protocol, A2A, is that standardization moment for multi-agent AI. It reached v1.0 in 2026 under Linux Foundation governance, with AWS, Microsoft, Salesforce, MongoDB, and about fifty other technology partners building native support into their platforms. Amazon Bedrock AgentCore and Azure AI Foundry both integrated A2A natively, and by July 2026 we had demonstrated cross-cloud agent calls working end-to-end: a Bedrock-hosted agent calling a Microsoft Foundry agent authenticated via Microsoft Entra. That is a genuinely remarkable thing when you think about how tangled the point-to-point alternative would have been.
This article is the practical guide I wish I had when I started building multi-agent systems on these platforms. I will cover what A2A actually does, where it fits alongside MCP, how the wire protocol works, how production deployments look across the major clouds, and where the security landmines are hiding.
What Problem A2A Actually Solves
To understand A2A you need to understand the failure mode it prevents. When I built my first multi-agent system on LangGraph about eighteen months ago, I ended up with a brittle set of custom RPC calls between agents that each lived in different processes. One agent handled document parsing. Another did web research. A third synthesized the results. The orchestration logic knew the exact API shape of every agent, which meant any change to an agent’s interface broke the orchestrator.
Now multiply that by twenty agents across three cloud accounts and two vendor frameworks. Every new agent requires new orchestration code. Every version bump requires coordinated changes. You end up with exactly the kind of tight coupling distributed systems were supposed to eliminate.
A2A addresses this with three core ideas. First, agents advertise their capabilities in a machine-readable format called an Agent Card. Second, tasks flow between agents using a standardized JSON-RPC interface with Server-Sent Events for streaming updates. Third, agents remain opaque to each other: the client agent does not need to know anything about how a remote agent is implemented internally.
The analogy I use with my teams: MCP is like REST for agent-to-tool connections. A2A is like REST for agent-to-agent connections. Both build on the same underlying HTTP and JSON primitives. Both establish conventions rather than inventing new transports. Both are deliberately simple.
The Agent Card: How Agents Discover Each Other
Every A2A-compliant agent exposes a discovery document called an Agent Card at /.well-known/agent-card.json. This is the same convention that OpenID Connect uses for its discovery document, which I suspect was intentional. The Agent Card describes what the agent can do, what inputs it accepts, what outputs it produces, what authentication mechanisms it supports, and what languages and modalities it handles.
A minimal Agent Card looks roughly like this:
{
"name": "document-summarizer",
"description": "Summarizes long documents into structured briefs",
"version": "1.2.0",
"url": "https://agents.internal.mycompany.com/summarizer",
"capabilities": {
"streaming": true,
"pushNotifications": false,
"stateTransitionHistory": true
},
"skills": [
{
"id": "summarize-document",
"name": "Summarize Document",
"inputModes": ["text", "file"],
"outputModes": ["text"]
}
],
"authentication": {
"schemes": ["bearer"]
}
}
The orchestrating agent fetches Agent Cards from a directory service or a known endpoint registry, selects the right agent for a given subtask based on skills and capabilities, and then starts a task. In a well-designed system you version these cards and cache them. In a poorly designed system you fetch them on every call and wonder why your inter-agent latency is high. I have seen both.

The agent registry question is worth thinking through carefully. A2A does not specify a central registry; it leaves that to the platform. Bedrock AgentCore maintains its own registry. Azure AI Foundry has its own. If you are building across clouds you will need a broker layer, which is where tools like the Bedrock AgentCore Gateway start earning their complexity cost.
The Wire Protocol: JSON-RPC Over HTTP With SSE Streaming
The actual communication between agents uses JSON-RPC 2.0 over HTTPS. If you have worked with any modern API, this is not a foreign concept. A client agent sends a JSON-RPC request to a remote agent’s endpoint. The remote agent processes it and returns a response.
What makes A2A more interesting than a plain REST call is the task lifecycle and the streaming model. A task transitions through states: submitted, working, input-required, auth-required, and then terminal states of completed, failed, canceled, or rejected. The two interrupt states are particularly important for real production workflows. input-required pauses a task when the remote agent needs clarification without killing it. auth-required handles credential escalation mid-task.
For long-running tasks, A2A uses Server-Sent Events to push updates back to the client agent without requiring polling. The client opens an SSE stream after submitting a task and receives status transitions and partial results as they are produced. For short tasks, a synchronous response is perfectly acceptable and simpler.
The key RPC methods in the spec:
tasks/send- submit a new task or send a follow-up message to a waiting tasktasks/get- retrieve the current state and results of a tasktasks/cancel- request cancellation of an in-progress tasktasks/sendSubscribe- submit a task and immediately subscribe to SSE updates in one call
That last method matters more than it looks. In practice most agent interactions want streaming, so tasks/sendSubscribe is what you reach for first. The separation only exists for cases where you genuinely want fire-and-forget submission with separate status polling.
How A2A Relates to MCP (and Why You Need Both)
This is the question I get most often, so let me be direct about it. MCP gives an agent access to tools, databases, APIs, and file systems. A2A gives an agent the ability to delegate tasks to other agents. They operate at different layers of the stack and are designed to work together.
In a typical multi-agent architecture, an orchestrator agent uses MCP to access its own tools (web search, code execution, database queries) and uses A2A to hand work off to specialized subagents. Those subagents in turn use their own MCP connections to whatever tools they need. The orchestrator never needs to know whether a remote agent is calling a database or running Python or hitting a third-party API. It only knows the task interface.

The confusion comes from the fact that some vendors market MCP as sufficient for everything. It is not. If you have tried to build a complex agent orchestration system with only MCP, you have probably hit the point where you wanted a remote agent to stream partial results back, handle retries with state preservation, or authenticate with a different identity provider mid-task. Those are A2A problems.
The practical rule I use: if you are connecting an agent to a data source or an API, use MCP. If you are connecting an agent to another agent, use A2A.
Production Deployment Across Cloud Platforms
AWS, Microsoft, and Google all have native A2A support, but the integration points differ significantly.
Amazon Bedrock AgentCore treats A2A as a first-class runtime primitive. Agents deployed to AgentCore automatically get an A2A endpoint at the platform level. The AgentCore Gateway provides the agent registry, handles authentication via IAM and Cognito, and routes inter-agent calls. If you are building a Strands agent, a LangGraph agent, or an OpenAI Agents SDK agent on Bedrock, A2A just works between them without custom glue code. The cross-cloud story is where it gets interesting: the July 2026 demonstration showed an AgentCore agent calling a Microsoft Foundry agent using Microsoft Entra tokens exchanged via OAuth 2.0. That handshake used the A2A spec’s bearer token authentication directly.
Azure AI Foundry integrates A2A at the Copilot Studio layer, making it accessible to non-engineers through a visual interface while still exposing the raw protocol for custom implementations. The Entra integration is tight: agents authenticate to each other using the same enterprise identity fabric that governs human access, which is the right design decision for enterprise deployments.
Google Cloud has A2A support in Vertex AI Agent Builder and in the Agent Development Kit (ADK). Since Google authored the protocol, the tooling here is predictably more mature, but the advantage is narrowing as the Linux Foundation governance body standardizes behavior across implementations.
If you are building for a single cloud, lean on the native platform support. If you are building cross-cloud or need framework portability, you will want to implement A2A at the framework layer rather than relying on platform-specific wrappers. The spec is simple enough that a direct implementation is not particularly painful.

The Memory Question
One thing A2A does not solve: agent memory across sessions. A2A handles the communication of tasks, not the persistence of context. When a remote agent completes a task and the connection closes, any state that agent held is gone unless the agent itself persists it.
This matters for multi-agent workflows where a subagent needs to remember context from previous interactions with the same orchestrator. The answer is not to stuff everything into every A2A message; that is expensive and ugly. The answer is to build your agents against a memory layer (Mem0, Zep, or Bedrock AgentCore’s memory service) that is independent of the communication protocol. The orchestrator and the subagent both write to and read from that memory layer using keys that identify the session.
I have seen teams make the mistake of treating A2A messages as the state store, stuffing enormous context windows into the task payload to preserve continuity. It works until you are paying for the token cost of that context on every call, at which point the economics break down quickly.
Security Architecture for A2A Systems
This is where I see the most dangerous gaps in production deployments. A2A adds a new attack surface that most security teams have not started thinking about.
The first issue is agent impersonation. Any system that can send a valid JSON-RPC request to your agent endpoint can impersonate an orchestrator. The spec supports OAuth 2.0 bearer tokens, and you need to enforce this. Every A2A endpoint should validate the caller’s token against a known issuer before processing any task. The AgentCore and Azure implementations handle this at the platform layer, but if you are running a self-hosted agent, you own this entirely.
The second issue is prompt injection via A2A. When a remote agent sends a task payload to your agent, that payload might contain adversarial content designed to manipulate your agent’s behavior. I wrote about prompt injection and AI agent security in detail elsewhere, but the A2A context adds a dimension: you now have to treat task payloads from other agents as untrusted input, even when the agent that sent them is authenticated. Authentication proves the sender is who they say they are. It does not prove the content of their task is safe.
The third issue is lateral movement. In a multi-agent system, a compromised agent can use its legitimate A2A credentials to call other agents and exfiltrate data or take unauthorized actions. The mitigation is strict scoping of what each agent is allowed to call and what operations it can request. This is not different in principle from Kubernetes RBAC or IAM least privilege; it is just applied to agent-to-agent communication rather than human-to-resource access.
My recommendation is to build an agent mesh policy layer, similar in concept to a service mesh authorization policy, that defines what agents can call what other agents with what permissions. This is admittedly an immature space in 2026 and most teams are still hand-rolling these policies. The tooling will catch up; for now, document your agent communication graph and enforce it at the API gateway layer.
When to Use A2A vs a Pure Orchestration Framework
A2A is not the right answer for every multi-agent use case. Here is how I think about the decision.
Use A2A when your agents are independently deployable services that might be built by different teams or run on different platforms. Use A2A when you need agents to be discoverable without hard-coded endpoints. Use A2A when you want cross-vendor interoperability, for example mixing a LangGraph agent with a CrewAI agent without writing custom integration code.
Stay with a pure framework like LangGraph or CrewAI in-process orchestration when all your agents run in the same process, when you need sub-millisecond latency between agent calls, or when your agent graph is simple enough that the discovery and task lifecycle overhead is not worth the abstraction.
The failure mode I see most often is teams adopting A2A for everything, including agents that are fundamentally just helper functions dressed up with an LLM. If an “agent” does a single deterministic thing and never needs to stream partial results or pause for input, it is not really an agent in the A2A sense. Call it synchronously through a normal function or a tool call.
The Governance and Versioning Problem
One underappreciated challenge in A2A deployments is Agent Card versioning. When a remote agent changes its capabilities, the clients that depend on that agent need to know. The protocol itself does not solve this. The Agent Card has a version field, but the spec does not define how changes should be communicated or how clients should handle deprecations.
For production systems I recommend treating Agent Cards the same way you would treat an OpenAPI schema: semantic versioning, a changelog, and a deprecation policy with timelines. Expose v1 and v2 of your agent concurrently during transitions rather than forcing all callers to upgrade simultaneously. The operational discipline here is the same as API versioning for REST services; the context is just new.
The Linux Foundation governance body has indicated that A2A v1.1 will include guidance on schema evolution and deprecation, which is a welcome development. For now you are on your own.
Observability in A2A Systems
Distributed tracing for agent-to-agent calls is essentially the same problem as distributed tracing for microservices, with the added complexity that agent reasoning is non-deterministic and the interesting failures are often semantic rather than structural. A call can succeed at the HTTP layer and still produce a completely wrong result.
Instrument your A2A endpoints with OpenTelemetry. Propagate trace context in the A2A request headers so that a single orchestrator call produces a complete trace spanning every remote agent invocation. Add semantic spans for the agent reasoning steps, not just the transport. The task ID from A2A is a natural correlation key; log it everywhere.
For LLM-specific observability layered on top of A2A, the tools I use in production are Langfuse for trace collection and Arize Phoenix for evaluation. Neither is specific to A2A, but both understand the multi-step, multi-agent shape of these systems better than generic APM tools.
What the Ecosystem Looks Like in 2026
The fifty-plus partners that contributed to A2A during its development have all shipped or announced integrations. The pattern that is emerging is a two-tier ecosystem: platform-level integrations (Bedrock AgentCore, Azure AI Foundry, Google Cloud Vertex AI) handle the registry, authentication, and routing concerns at the infrastructure layer, and framework-level integrations (LangGraph, CrewAI, OpenAI Agents SDK, Google ADK) handle the agent implementation and task management.
The interesting competition is not between A2A and MCP; they are genuinely complementary. The competition is between A2A and vendor-specific orchestration protocols. Every cloud provider has financial incentives to make you use their proprietary agent communication layer, which would lock your agents into their platform. A2A, under Linux Foundation governance, is the counterweight to that. The more you build on A2A, the more freedom you have to move agents between platforms and vendors.
Twenty years in this industry has taught me to be skeptical of standards that arrive too early and skeptical of vendor-specific solutions that arrive too late. A2A landed at the right time: the multi-agent pattern is real and growing, the failure modes of point-to-point custom protocols are already visible, and the spec is simple enough to actually implement. The FinOps implications are also real: when you can route subtasks to the cheapest capable agent across clouds without custom integration work, the economics of large multi-agent systems start to look meaningfully different.
If you are building AI infrastructure in 2026 and you have more than two agents talking to each other, you should be evaluating A2A. Not because it is the only option, but because the alternative is a custom protocol that will look embarrassingly ad hoc in eighteen months when your agent graph is three times larger and every cross-team integration requires a coordination meeting.
The standard exists. The platforms support it. Use it.
Get Cloud Architecture Insights
Practical deep dives on infrastructure, security, and scaling. No spam, no fluff.
By subscribing, you agree to receive emails. Unsubscribe anytime.
