A2A 1.0 for agent builders: when your agent should call another agent instead of a tool
The Agent2Agent protocol reached its first stable release this year. Here is how its Agent Cards, tasks, and update channels work, how it differs from MCP, and when it is worth adding to a system you already run.
Most agent stacks start with one model and a growing pile of tools. Sooner or later someone asks a different question: what if the thing on the other end of the call is not a database or an API, but another agent, built by another team, running on another framework, and holding its own tools and memory? You can wrap that agent as a tool and hope for the best, or you can use a protocol designed for the job. The Agent2Agent protocol, usually shortened to A2A, is that protocol. This article explains what it standardizes, how a real exchange looks on the wire, how it sits next to the Model Context Protocol, and when it is worth the extra moving parts.
Where A2A stands in late 2026
A2A started at Google and is now a Linux Foundation project. Its 1.0.0 release on March 12, 2026 was the first stable specification, and it came with a long list of breaking changes from the 0.3 line: renamed fields, a new tasks/list method with filtering and pagination, OAuth flows modernized to drop the implicit and password grants in favor of device code and PKCE, and a large refactor that separates the abstract protocol from its mappings to specific transports. A 1.0.1 patch followed on May 26 with fixes to content types and task status values.
Adoption has moved quickly. In an April 9, 2026 announcement, the Linux Foundation said more than 150 organizations support the standard, including AWS, Cisco, Google, IBM, Microsoft, Salesforce, SAP, and ServiceNow, and that the SDK ecosystem had grown from a single Python implementation to five production languages including JavaScript, Java, Go, and .NET. The same release describes A2A as complementary to MCP, which is also a Linux Foundation project: A2A covers how agents talk to each other across organizational boundaries, and MCP covers how an agent connects to its own tools and data.
The core idea: agents stay opaque
The A2A specification lists "opaque execution" as a guiding principle. Agents collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations. That single design choice explains most of the protocol. When you call an MCP tool, you see its input schema and you get back a result for that one call. When you hand work to an A2A agent, you see a description of what it is good at, you send it a message, and you get back a task that moves through states while the remote agent does whatever it does internally. You never see its prompts, its tool list, or its chain of reasoning, and you do not need to.
The spec also calls itself "async first," designed for potentially very long-running tasks and human-in-the-loop interactions. A tool call that takes forty minutes is an awkward fit for most tool-calling loops. A delegated task that takes forty minutes and pauses once to ask for approval is exactly what A2A was built to model.
Discovery starts with the Agent Card
Every A2A server publishes an Agent Card, a JSON document that describes the agent's name, description, version, capabilities, skills, supported input and output media types, and security requirements. The spec's section on discovery names three ways to find one: a well-known URI at https://{server_domain}/.well-known/agent-card.json, a curated registry or catalog, or direct configuration where you already know the URL.
Two details in the card matter more than they first appear. The first is supportedInterfaces, an ordered list of endpoints, each naming a URL and a protocol binding. The core bindings are JSON-RPC, gRPC, and HTTP+JSON, and a client must pick the first entry it supports, so the agent author controls which transport is preferred. The second is skills, which the spec describes as "largely a descriptive concept," a focused set of behaviors the agent is likely to succeed at. Skills are not callable functions with schemas. They are the A2A equivalent of a good tool description, and everything we wrote about writing tool descriptions applies to them, because your client model will read them to decide whether to delegate.
Cards can be signed. The spec lets an Agent Card carry JSON Web Signatures per RFC 7515, computed over a canonical form produced with the JSON Canonicalization Scheme in RFC 8785, and it says clients should verify at least one signature before trusting a card. If you plan to discover agents from a public registry rather than a list you maintain yourself, that check is the difference between delegating to the vendor you meant and delegating to whoever registered a lookalike. Cards can also have an authenticated extended version, fetched with a bearer token, that lists extra skills only signed-in callers should see.
What an exchange looks like
Over the JSON-RPC binding, a client starts work with the SendMessage method. The message has a client-created messageId, a role of ROLE_USER, and one or more parts. A part holds exactly one of text, raw bytes, a file URL, or structured JSON data, plus an optional media type. A minimal request to a hypothetical invoice-checking agent looks like this:
{
"jsonrpc": "2.0",
"id": 1,
"method": "SendMessage",
"params": {
"message": {
"messageId": "9f1c2b7e-4c1a-4d0e-9a51-2a6f0c8e1d33",
"role": "ROLE_USER",
"parts": [
{ "text": "Check invoice INV-2291 against PO-118 and flag mismatches." }
]
},
"configuration": { "returnImmediately": true }
}
}
The agent can answer with a plain message, or with a task. A task has a server-generated ID, a contextId that groups related tasks and messages into one conversation, a status, and artifacts, which are the outputs. The task states are the heart of the protocol. A task begins as submitted, moves to working, and ends in one of four terminal states: completed, failed, canceled, or rejected. Two more states are "interrupted" rather than terminal: input-required, when the agent needs more from the caller, and auth-required, when it needs credentials it does not have. A client continues an interrupted task by sending a new message with the same taskId and contextId.
That returnImmediately flag is worth understanding. By default, SendMessage blocks until the task reaches a terminal or interrupted state. With the flag set, the call returns as soon as the task exists, and the caller is responsible for getting updates. Everything else follows from that choice: GetTask for polling, CancelTask to stop work, ListTasks with cursor pagination to find tasks in a context, and the rest of the method table, which is identical in name across JSON-RPC and gRPC and maps to REST paths like POST /message:send and GET /tasks/{id}.
Three ways to hear back
A2A defines three update channels, and picking the right one is mostly a question of where your client runs. Polling with GetTask works with every binding and suits simple integrations or clients behind restrictive firewalls, at the cost of latency and wasted requests. Streaming through SendStreamingMessage or SubscribeToTask delivers status and artifact events in order over Server-Sent Events on the HTTP bindings, and only works when the Agent Card sets capabilities.streaming to true. A subscription always starts with the current task object, which closes the gap between a status check and the moment the stream opens. Multiple clients can stream the same task at once, and closing one stream does not cancel the task, so a dropped connection is recoverable by subscribing again.
Push notifications are the third channel: the agent sends HTTP POST requests to a webhook the client registered, which suits server-to-server work and tasks that run for hours. They require capabilities.pushNotifications, and the spec's security section is specific about both sides. Agents should validate webhook URLs against server-side request forgery by rejecting private ranges such as 10.0.0.0/8 and 192.168.0.0/16 as well as localhost and link-local addresses, use timeouts in the 10 to 30 second range, and retry with exponential backoff. Receivers must check the webhook's credentials, should confirm the task ID is one they created, and should process deliveries idempotently because duplicates can happen. If you already handle Stripe or GitHub webhooks, this is familiar ground.
A2A next to MCP
The A2A project's own comparison page puts it neatly: MCP is vertical and deepens a single agent by handing it more tools, while A2A is horizontal and connects agents across team, department, or company boundaries. Its worked example is an auto repair shop where a customer talks to a shop manager agent over A2A, a mechanic agent uses MCP to call a diagnostic scanner and a repair manual database, and the mechanic then uses A2A again to order a part from a supplier's agent.
The line has blurred a little. The MCP specification added tasks in its 2025-11-25 revision, still marked experimental, which let a client wrap a tool call in a durable state machine and poll for the result later. That covers the long-running-tool case without A2A. What MCP tasks do not give you is the rest of the A2A model: a public card describing an agent's skills, multi-turn conversations grouped by context, artifacts streamed as they are produced, and a design that assumes the other side is an autonomous peer you do not control. The comparison page itself suggests an A2A server can expose some well-defined, stateless skills as MCP-compatible resources that another agent discovers through an MCP-style tool description, which is a reasonable way to offer both.
When to reach for it
A useful test is ownership. If the capability you need lives in your own codebase and you can describe it with an input schema, keep it as a tool, local or over MCP. If it is another team's or another company's agent, it has its own tools and model, it may run for minutes or hours, and it may need to come back and ask a question, A2A gives you a contract for all of that instead of a custom wrapper you will maintain alone.
Treat delegation like any other untrusted input, too. Text and artifacts coming back from a remote agent can carry the same kinds of injected instructions we covered in our piece on prompt injection defenses, and a remote agent that reaches the auth-required state is asking your system for credentials, which deserves the same scrutiny as any approval gate. Pin the protocol version with the A2A-Version header, since the spec says an empty header is treated as 0.3 and agents may serve different versions on different interfaces. Prefer signed cards from sources you can verify, and log task IDs on both sides so a failed handoff can be traced.
A2A will not replace your tool layer, and it should not. It solves a narrower problem well: letting agents built by different people hand work to each other, track it, and talk it through, without either side opening its internals. If your roadmap includes partner integrations or a second team's agent, it is worth reading the spec before you invent your own version of it.
Sources
A2A Protocol specification, latest release
A2A and MCP: detailed comparison