Agent-to-Agent Protocols in 2026: A2A Reached 1.0, Three ACPs Died or Merged, and MCP Learned to Do Most of the Same Job

Sep 9, 2026 · 14 min · Ajay Kumar

PandaStack's SDK exposes an MCP server, because that is what every agent host on earth can talk to. It does not publish an A2A agent card, and every few weeks someone asks me why. This post is my working-out of the answer, which turned into a survey of where agent-to-agent protocols actually stand seventeen months after Google announced one: what the specification says now that it has a 1.0, who has shipped it as opposed to signed a press release, what MCP did in July that makes the question harder, and what the production telemetry says about how many systems need any of this.

What A2A is, as of 1.0.1

Google announced A2A on 9 April 2025 with fifty-odd partners, donated it to the Linux Foundation on 23 June 2025, and the project tagged v1.0.0 on 12 March 2026 and v1.0.1 on 28 May. On 17 August it became a hosted project of the Agentic AI Foundation, the Linux Foundation body formed last December around MCP, Block's goose and OpenAI's AGENTS.md, whose platinum members include AWS, Anthropic, Google, Microsoft and OpenAI. So MCP and A2A now live under the same roof, which the foundation illustrates with a stack diagram, "agent to tool" for one and "agent to agent" for the other, and no further comment.

The specification has three layers: a data model, a set of operations, and bindings, of which there are three (JSON-RPC 2.0, gRPC, and HTTP+JSON). A server publishes an Agent Card at /.well-known/agent-card.json describing its skills, its supported interfaces, its authentication schemes and its capabilities. A client sends a message; the server either replies with a message or opens a task, which moves through submitted, working, input-required, auth-required, completed, failed, canceled or rejected. Updates arrive by server-sent events, by a webhook the client registers, or by polling. Version 1.0 added signed agent cards (a JWS over a canonicalised card), multi-tenancy through a scope field, ListTasks, and a cleaned-up OAuth profile that removed the implicit and password flows and added device code with PKCE. It also flattened the Part type, renamed the card path from the older agent.json, and broke every SDK, which I will get to.

The card is the interesting design decision. It is a DNS-like discovery document for a piece of software that claims to be able to do things, served over HTTPS, and everything downstream trusts it. The first published attack on A2A, from SpiderLabs in April 2025, was exactly that: a malicious agent publishes a card that exaggerates its skills so an orchestrator using a model to route tasks sends everything to it. Signed cards in 1.0 authenticate the card's author. They do not make the author honest, which is the same gap I described for MCP tool descriptions.

The three ACPs, for the record

If you searched for "ACP" this year you found three unrelated things, two of which are dead. IBM's Agent Communication Protocol, built for BeeAI, wound down on 25 August 2025 and its team joined A2A's technical steering committee, which now lists IBM, Google, Microsoft, AWS, Cisco, Salesforce, ServiceNow and SAP. Cisco's AGNTCY project had its own Agent Connect Protocol, and its repository was archived on 11 April 2026 pointing users at A2A; the rest of AGNTCY, the directory, the OASF schema and the SLIM transport, is still shipping releases as of this month under the Linux Foundation. OpenAI's Agentic Commerce Protocol is about checkout and has nothing to do with either. The consolidation is real: for agent-to-agent wire protocols there is A2A, there is the Agent Network Protocol with 1,400 stars and a DID-based identity scheme, and there is MIT's NANDA index proposal. In practice there is A2A.

Who shipped it

The Linux Foundation's one-year release says 150-plus supporting organisations and five SDK languages. I checked the second claim against the package registries this morning and the vendor claims against their own documentation, because "supporting" and "shipped" are different words.

Where Status Evidence, date
Microsoft Copilot Studio GA: connect to external agents over A2A What's New, April 2026; the how-to still points users at the old agent.json path
Microsoft Foundry Agent Service outbound A2A shipped; inbound (expose an agent by card) public preview Build, 2 June 2026
AWS Bedrock AgentCore Runtime A2A servers on port 9000, card at the well-known path, JWT or SigV4 auth 11 November 2025
Google ADK Python RemoteA2aAgent with native task mode v2.8.0, 26 August 2026
Google Cloud Marketplace registration flow for A2A agents into Gemini Enterprise docs; no count published
LangChain Agent Server A2A 1.0 JSON-RPC endpoint per assistant, no gRPC or REST docs, requires langgraph-api 0.13
Salesforce "general availability" claimed in the June 2025 Agentforce 3 post no 2026 primary source for the TDX claims
SAP sample toolkit for A2A agents into Joule; policy reportedly requires it Q2 release notes mention MCP, not A2A
OpenAI Agents SDK MCP and in-process handoffs; no A2A README, 29,300 stars
Anthropic no public position; Claude Agent SDK agents appear in AWS's demo wrapped in an A2A server nothing found either way

The SDKs: Python a2a-sdk is at 1.1.2 with 14 million downloads a month according to pypistats, which is a large number until you notice Google's ADK depends on it. JavaScript reached 1.0 on 22 July and 1.1.0 on 26 August. Java is at 1.0.0.Final since June, Go at v2.5.0. The .NET package is still 1.0.0-preview2 from April, so "five production-ready SDKs" is four. Copilot Studio's April GA and AgentCore's support are the two shipped surfaces that matter; the rest is samples, previews and claims I could not trace to a vendor page.

What MCP did in July

The reason the A2A question got harder is the MCP revision of 28 July 2026, which I covered from the security side last week and which matters here for a different reason. That revision made the protocol stateless, removed the initialise handshake and session IDs, and moved long-running work into an official Tasks extension with states working, input-required, completed, failed and cancelled, polled through tasks/get and fed through tasks/update. It replaced server-initiated sampling and elicitation with "multi round-trip requests", where a server answers input_required and the client retries with the input. And it deprecated Sampling, Roots and Logging outright with a twelve-month window.

Put the two lifecycles side by side and the overlap is nearly total.

A2A v1.0 task lifecycle submitted working input-required auth-required completed failed canceled rejected updates: SSE stream · push webhook (registered config) · polling GetTask bindings: JSON-RPC 2.0 · gRPC · HTTP+JSON discovery: /.well-known/agent-card.json, optionally JWS-signed MCP Tasks extension, 2026-07-28 working input_required MRTR: server returnsinputRequests; clientretries with responses completed failed cancelled updates: poll tasks/get · input via tasks/update · tasks/list removed transport: stateless Streamable HTTP; sampling, roots, logging deprecated A2A has, MCP lacks: agent card discovery and JWS-signed cards · push-notification config · multi-tenancy scope · gRPC binding · auth-required state MCP has, A2A lacks: 10,000+ public servers (Dec 2025) · ~500M monthly SDK downloads · a host inside every agent client · 12 months of production scar tissue Neither foundation has published a position on whether both are needed.
The two task lifecycles after MCP's July revision. A2A keeps discovery, signing and push; MCP keeps the installed base.

There is a subtlety that cuts the other way. The pattern people used to argue A2A was unnecessary, "just expose your agent as an MCP server and let the host call it as a tool", relied on Sampling so the wrapped agent could ask the host's model for completions. Sampling is now deprecated. An agent behind an MCP server in 2027 will bring its own model or use multi round-trip requests to ask the client for input, which is a task-shaped interaction and looks a great deal like A2A's. Both protocols are converging on the same thing from opposite ends, and the foundation hosting both has not said which end wins. My guess, and it is only that, is that the answer will be "A2A cards for discovery and auth between organisations, MCP tasks inside them", which is roughly what Microsoft's Copilot Studio documentation already describes in practice.

The first CVE on an A2A surface

There are no published advisories on the Python or JavaScript SDKs. There is, since 28 August, CVE-2026-19286: an unauthenticated remote code execution through the public A2A endpoint in Langflow open source versions 1.0.0 to 1.11.1, CVSS 9.8, with an authenticated companion at 9.9. It is an implementation bug in Langflow's server, not a flaw in the protocol. It is also exactly the class of bug the protocol invites, because an A2A endpoint is by construction a public HTTP surface that accepts natural-language instructions and turns them into work, and the auth schemes in the card are a menu the server author may leave empty. The academic literature has been saying this for a year: Habler and colleagues' MAESTRO threat model in April 2025, a comparative analysis of MCP, A2A, Agora and ANP in February with twelve protocol-level risks, and a June governance-gaps paper noting that none of the five protocols it examined can express dissent or voting, which sounds abstract until your orchestrator has three workers disagreeing. NIST launched an AI Agent Standards Initiative in February whose announcement names neither protocol; OWASP's Agentic Top 10 for 2026 covers the attacks. The identity layer that would let a receiving agent know who delegated what to whom is still being assembled from OAuth extensions and SPIFFE, and A2A's card auth schemes are the place it plugs in.

How many systems need this at all

This is the part I wanted before deciding about my own SDK. Datadog's State of AI Engineering, from telemetry through March 2026, found that 59 percent of agentic requests made a single service call and only 18 percent made three or more; the report does not mention MCP or A2A. LangChain's survey of 1,340 engineers found 57 percent with agents in production and quality and latency as the top barriers, with no protocol breakdown. Anthropic's multi-agent research system runs an orchestrator with three to five parallel subagents, in process, at fifteen times the tokens of a chat, and hands results back through return values and a shared filesystem, not a wire protocol. Cognition's "Don't Build Multi-Agents" argues that parallel subagents fail because actions carry implicit decisions that do not survive a context boundary. Microsoft's own Copilot Studio guidance says to split into connected agents only past thirty or forty available actions, or at a team boundary, and warns that each hop adds latency. And the MAFBench paper measured framework overhead alone raising latency more than a hundredfold and dropping coordination success from over ninety percent to under thirty.

So the honest reading is that true multi-hop, multi-vendor agent systems are rare, the ones that exist are mostly single-vendor and in-process, and the wire protocol matters at organisational boundaries: your agent calling a supplier's, a Copilot Studio agent calling one in Foundry, a marketplace. That is a real use, it is where signed cards and OAuth device flows earn their keep, and it is not most systems.

A working pair on the 1.1 SDK

Every A2A Python tutorial written before April is wrong now, because 1.0 removed A2AStarletteApplication, A2AClient and ClientFactory, replaced Pydantic types with protobuf-generated classes, uppercased the enums, moved the URL out of the card into supported_interfaces, and requires an executor to emit either exactly one message or a task first. The migration guide lists all of it. This is what the minimum looks like on a2a-sdk 1.1.2, adapted from the official hello-world sample.

pip install "a2a-sdk[http-server]==1.1.2" uvicorn httpx
# server.py
import uvicorn
from starlette.applications import Starlette
from a2a.helpers import get_message_text, new_task_from_user_message, new_text_message, new_text_part
from a2a.server.agent_execution import AgentExecutor, RequestContext
from a2a.server.events import EventQueue
from a2a.server.request_handlers import DefaultRequestHandler
from a2a.server.routes import create_agent_card_routes, create_jsonrpc_routes
from a2a.server.tasks import InMemoryTaskStore, TaskUpdater
from a2a.types import AgentCapabilities, AgentCard, AgentInterface, AgentSkill, TaskState

class EchoExecutor(AgentExecutor):
    async def execute(self, ctx: RequestContext, q: EventQueue) -> None:
        task = ctx.current_task or new_task_from_user_message(ctx.message)
        if not ctx.current_task:
            await q.enqueue_event(task)                     # task-first stream, required in 1.x
        u = TaskUpdater(event_queue=q, task_id=task.id, context_id=task.context_id)
        await u.update_status(state=TaskState.TASK_STATE_WORKING, message=new_text_message("working"))
        await u.add_artifact(parts=[new_text_part(text=f"echo: {get_message_text(ctx.message)}",
                                                  media_type="text/plain")])
        await u.update_status(state=TaskState.TASK_STATE_COMPLETED)
    async def cancel(self, ctx, q): raise NotImplementedError

card = AgentCard(
    name="Echo Agent", description="Minimal A2A 1.0 agent", version="0.1.0",
    default_input_modes=["text/plain"], default_output_modes=["text/plain"],
    capabilities=AgentCapabilities(streaming=True),
    supported_interfaces=[AgentInterface(protocol_binding="JSONRPC", protocol_version="1.0",
                                         url="http://127.0.0.1:9999")],
    skills=[AgentSkill(id="echo", name="Echo", description="Echoes text", tags=["demo"])],  # tags required
)
handler = DefaultRequestHandler(agent_executor=EchoExecutor(), task_store=InMemoryTaskStore(), agent_card=card)
app = Starlette(routes=[*create_agent_card_routes(card), *create_jsonrpc_routes(handler, "/")])
uvicorn.run(app, host="127.0.0.1", port=9999)
# client.py
import asyncio, httpx
from a2a.client import A2ACardResolver, ClientConfig, create_client
from a2a.helpers import new_text_message
from a2a.types import Role, SendMessageRequest

async def main():
    async with httpx.AsyncClient() as http:
        card = await A2ACardResolver(httpx_client=http, base_url="http://127.0.0.1:9999").get_agent_card()
    client = await create_client(agent=card, client_config=ClientConfig(streaming=True))
    async for resp in client.send_message(SendMessageRequest(message=new_text_message("hello", role=Role.ROLE_USER))):
        print(resp)                                         # StreamResponse; inspect with HasField()
    await client.close()

asyncio.run(main())

The card is served at /.well-known/agent-card.json. Note that the Copilot Studio documentation, dated 26 August, still tells its users to look for agent.json; if you are exposing an agent to it, serve both paths.

What I decided

I am not adding an A2A card to PandaStack's SDK this quarter. The customers I serve run agents that call tools, and tools are MCP; where they run several agents, those agents are in one process or one repository and the data says that is the norm. The case for a card arrives when a customer wants an agent of theirs, running in one of my sandboxes, to be discoverable and callable by a Copilot Studio or Foundry agent in another company, with a signed card and an OAuth device flow, and I expect that customer to exist within a year. When they do, the SDK is four packages and a well-known path, and I would rather build it against a 1.x that has stopped moving. The thing to watch is not A2A's adoption count, which will keep rising as long as Google's ADK depends on it. It is whether the foundation that now owns both protocols says out loud what each one is for.


Related: MCP Security in 2026, Who Is This Agent? Non-Human Identity in 2026 and Agent Observability in 2026.

I'm Ajay Kumar — I build and operate PandaStack, an open-source Firecracker microVM cloud for AI agents. Everything above comes from running it in production.

Need this kind of infrastructure work? See what I do or email hello@ajayk.sh.


Related