What is A2A (Agent to Agent) Protocol
Learn what the A2A Agent to Agent protocol is, how it compares to MCP and ACP, and how to build narrow agents with explicit message contracts, streaming, and metrics
Get the free AI Agent Building Blocks ebook when you subscribe:
The A2A protocol is a standards-based way for AI agents to discover each other, describe what they can do, exchange tasks and messages, and report results in a predictable lifecycle. It gives teams a shared contract for agent interoperability so you can plug a capable agent into different clients and ecosystems without rebuilding custom adapters for every integration.
In practice, you define an agent card that advertises capabilities and contact details, you agree on message shapes and status transitions, and you use common transports like HTTP with streaming for long-running work.
When I took training at work on agent-to-agent communication protocols, my lightbulb moment was realizing our service did not need a Model Context Protocol server that only exposes tools. We needed an autonomous agent that can accept a task, maintain state, and collaborate with other agents through a standard contract. That pushed me toward learning more about A2A because it treats the remote side as a peer agent, not just a bucket of tools.
This article is written for productive engineers who stay up to date and automate a lot of the work of their teams, and earn the credibility and career capital from their managers and peers.
In this post, you’ll learn
A mental model for client and remote agents
The requests, responses, and errors of the A2A protocol
A decision table to choose between A2A, MCP, and ACP
A2A cards and the mental model
Think of an A2A card as an agent’s ID card. A human ID card tells a guard who you are, who vouches for you, what you are allowed to do, and how to contact your next of kin. An A2A card does the same for software agents. It tells a client agent who owns this agent, what capabilities it exposes, how to talk to it, and what rules apply. The mental model is simple. Clients should never guess. They should read the card, verify it, and then call the capability they need with inputs that match the published schema.
When I took a training on agent communication, the ID card analogy made this protocol very simple to understand. Your client only needs this document to make discovery and negotiation explicit.
More on the ID card analogy
A client agent should follow a three-step process. Read the card, validate that the needed capability exists and the schema fits the payload, and only then create a task.
Example card
{
“name”: “q&a-agent”,
“version”: “1.2.0”,
“owner”: “team-knowledge”,
“description”: “Answers product FAQs with citations”,
“endpoints”: {
“task”: “<https://api.example.com/qa/task>”,
“stream”: “<https://api.example.com/qa/stream>”
},
“auth”: {
“methods”: [”bearer”],
“scopes”: [”qa.ask”, “qa.read”]
},
“capabilities”: [
{
“name”: “answer_question”,
“input_schema”: {
“type”: “object”,
“required”: [”question”],
“properties”: {”question”: {”type”: “string”}, “max_tokens”: {”type”: “integer”}}
},
“output_schema”: {
“type”: “object”,
“required”: [”answer”, “citations”],
“properties”: {
“answer”: {”type”: “string”},
“citations”: {”type”: “array”, “items”: {”type”: “string”, “format”: “uri”}}
}
}
}
],
“changelog”: [
{”version”: “1.2.0”, “notes”: “Added max_tokens optional input”},
{”version”: “1.1.0”, “notes”: “Streaming endpoint introduced”}
],
“contact”: {”email”: “qa-agent@company.com”}
}Roles, capabilities, and the contract for messages
A2A works best when contracts are boring and explicit. That means you define roles, list capabilities with names and schemas, and write message shapes that never hide complexity. If you are strict here, your agents will be easy to replace and easy to observe.
Capabilities:
Each capability is a named function like
answer_questionYou publish input and output schemas in the agent card
Capabilities are versioned and backward compatible where possible
Message contract:
Every message has a type, an id, a correlation_id, a created_at timestamp, and a schema_version
Tasks move through states (e.g. accepted, in_progress, streaming_update, completed, failed, cancelled)
Artifacts are the durable outputs. Parts are chunked or streamed slices of an artifact
Authentication and audit basics:
Auth should be explicit with method and scopes (OAuth 2.0)
Include requester identity in a caller field and always log correlation_id
Add a privacy field for data handling intent and retention hints
A2A vs MCP vs ACP. When to pick each
Use the table and the simple flow below:



