TAI BUI
Back to curriculum
BuildPython

A2A — Agent-to-Agent Protocol

MCP connects an agent to tools. A2A (Agent2Agent) connects an agent to other agents, including ones built on different frameworks that you can't see inside. Google released it in April 2025 and donated it to the Linux Foundation that June. It absorbed IBM's ACP, added the AP2 payments extension, and reached v1.0 in April 2026 with 150+ supporters including AWS, Cisco, Microsoft, Salesforce, SAP, and ServiceNow. This lesson walks the Agent Card, the Task lifecycle, and the two transport bindings.

TIME: ~75 minutesPREREQUISITES: Phase 13 · 06 (MCP fundamentals), Phase 13 · 08 (MCP client)

Learning Objectives

  • Distinguish agent-to-tool (MCP) from agent-to-agent (A2A) use cases.
  • Publish an Agent Card at `/.well-known/agent.json` with skills and endpoint metadata.
  • Walk the Task lifecycle (submitted → working → input-required → completed / failed / canceled / rejected).
  • Use Messages with Parts (text, file, data) and Artifacts as outputs.

The Problem

A customer-service agent needs to hand report-writing to a specialized writer agent. Before A2A you had three options:

  • A custom REST API. It works, but every pairing is a one-off.
  • A shared codebase. Both agents have to run the same framework.
  • MCP. It doesn't fit, because MCP is for calling tools. It isn't built for two agents collaborating while each keeps its reasoning private.

A2A fills that gap. One agent sends a Task to another, and the interaction has a lifecycle, messages, and artifacts. The called agent's internal state stays opaque, so the caller sees only task state transitions and the eventual outputs.

A2A is the protocol for agents across frameworks to talk to each other. It doesn't replace MCP. The two sit side by side.

Warm-up0/3
1. In MCP, what does a client typically invoke on a server?Warm-up
A box for an MCP client with an arrow labelled client invokes to a box for an MCP server, with a dashed question box under the arrow.
2. When an MCP host's agent calls a tool, what does the host see of that call?Warm-up
An MCP host with an agent inside sends a tool call to an MCP server, and a dashed question box under the host asks what the host sees of the call.
3. A server must push progress updates to a client over one long-lived HTTP response. Which standard mechanism does that?Warm-up
A server and a client joined by one long arrow labelled one HTTP response, kept open, with three boxes marked update 1, update 2 and update 3 along it, and a dashed box asking for the mechanism.
Update labels are placeholders.
Check: The Problem0/2
1. What is A2A?Define
A customer-service agent box with an arrow labelled hand off report-writing to a specialized writer agent box, and a dashed box asking which protocol sits between them.
2. Why is a shared codebase a poor way to let one agent delegate work to another?Explain
A customer-service agent box and a writer agent box, each with an import arrow down to one shared codebase box.
Typed schematic, not captured output.

The Concept

Agent Card

Every A2A-compliant agent publishes a card at /.well-known/agent.json:

json
{
  "schemaVersion": "1.0",
  "name": "research-agent",
  "description": "Summarizes academic papers and drafts citations.",
  "url": "https://research.example.com/a2a",
  "version": "1.2.0",
  "skills": [
    {
      "id": "summarize_paper",
      "name": "Summarize a paper",
      "description": "Read a paper PDF and produce a 3-paragraph summary.",
      "inputModes": ["text", "file"],
      "outputModes": ["text", "artifact"]
    }
  ],
  "capabilities": {"streaming": true, "pushNotifications": true}
}

Discovery is URL-based: fetch the card, learn the URL of the A2A endpoint, enumerate skills.

Signed Agent Cards (AP2)

The AP2 extension (September 2025) adds cryptographic signatures to Agent Cards. A publisher signs its own card with a JWT; consumers verify. This prevents impersonation.

Task lifecycle

submitted -> working -> completed | failed | canceled | rejected
             -> input_required -> working (loop via message)

Clients initiate with tasks/send. The called agent transitions through states; clients subscribe to state updates via SSE or poll.

Messages and Parts

A message carries one or more Parts:

  • text: plain content.
  • file: base64 blob with mimeType.
  • data: typed JSON payload, used as structured input for the called agent.

Example:

json
{
  "role": "user",
  "parts": [
    {"type": "text", "text": "Summarize this paper."},
    {"type": "file", "file": {"name": "paper.pdf", "mimeType": "application/pdf", "bytes": "..."}},
    {"type": "data", "data": {"targetLength": "3 paragraphs"}}
  ]
}

Artifacts

Outputs are Artifacts, not raw strings. An Artifact is a named, typed output:

json
{
  "name": "summary",
  "parts": [{"type": "text", "text": "..."}],
  "mimeType": "text/markdown"
}

Artifacts can be streamed as chunks. The caller accumulates.

Two transport bindings

  1. JSON-RPC over HTTP. /a2a endpoint, POST for requests, optional SSE for streaming. Default binding.
  2. gRPC. For enterprise environments where gRPC is native.

Both bindings carry the same logical message shape.

Opacity preservation

A key design principle: the called agent's internal state is opaque. The caller sees task state and artifacts. The called agent's chain-of-thought, its tool calls, and its sub-agent delegation are all invisible. MCP is the opposite: tool calls there are transparent.

The reason is that competitors can collaborate without revealing internals. "Call this customer-service agent" works without the caller learning how that agent implements the service.

Timeline

  • 2025-04-09. Google announces A2A.
  • 2025-06-23. Donated to Linux Foundation.
  • 2025-08. Absorbs IBM's ACP.
  • 2025-09. AP2 extension (Agent Payments) ships.
  • 2026-04. v1.0 released with 150+ supporting organizations.

Relationship to MCP

DimensionMCPA2A
Use caseAgent-to-toolAgent-to-agent
OpacityTransparent tool callsOpaque inner reasoning
Typical callerAgent runtimeAnother agent
StateTool-call resultTask with lifecycle
AuthorizationOAuth 2.1 (Phase 13 · 16)JWT-signed Agent Cards (AP2)
TransportStdio / Streamable HTTPJSON-RPC over HTTP / gRPC

Use MCP when you want to invoke a specific tool. Use A2A when you want to delegate a whole task to another agent. Many production systems use both: an agent uses MCP for its tool layer and A2A for its collaboration layer.

Check: The Concept0/23
1. Where does an A2A-compliant agent publish its Agent Card?Define
A caller box and a research-agent box with an arrow labelled wants its Agent Card, a URL bar showing https://research.example.com followed by a dashed box for the path, and a two-field excerpt of the card.
Card excerpt is the lesson's research-agent example.
2. What is a skill in A2A?Define
An abridged block of the writer agent's published metadata with one list entry holding an id draft_report, a name Draft report and a description, with a dashed box asking what this entry is.
Abridged from main.py; the list's key name is hidden here.
3. What is a Task in A2A?Define
A customer-service agent box and a writer agent box with a dashed question box between them on the arrow that carries the report job.
Typed schematic, not captured output.
4. What is a Message in A2A?Define
A research agent box and a writer agent box with a dashed question box on the arrow between them, for what is sent to start a paper summary.
Typed schematic, not captured output.
5. Which three Part types can an A2A Message carry?Define
One message box holding three dashed slots, each labelled part with a number and a type marked by a question mark.
6. How are outputs of a Task represented in A2A?Define
A writer agent box marked task finished and a research agent box, with an arrow from the writer box to the research agent box passing through a dashed box that asks what output is returned.
7. What does the AP2 extension add to Agent Cards?Define
An abridged Agent Card with name, url and version fields, and a dashed box below it asking what the AP2 extension adds.
Card fields are from main.py.
8. What does A2A's opacity preservation mean for the caller?Define
A caller box with an arrow labelled task to a called agent box that has a dashed inner area labelled inside the agent, and a dashed question box asking what the caller can see of the inside.
9. Which Task state means the called agent needs more information before it can continue?Define
A caller box and a called agent box working on a task, a quoted line from the called agent saying it needs more information before it can continue, and a dashed box asking for the task state.
Typed schematic, not captured output.
10. Which event in A2A's history is dated April 2026?Define
A time axis from 2025-01 to 2026-07 with a highlighted marker at 2026-04 and a dashed box asking which event it is.
Axis ticks are evenly spaced six months apart; the marker sits at April 2026.
11. Which two transport bindings does A2A define?Explain
A caller box and a writer-agent box with its endpoint address, joined by two arrows each carrying a dashed box labelled binding with a question mark.
12. Why does A2A keep the called agent's chain-of-thought and tool calls hidden from the caller?Explain
A quoted request, call this customer-service agent, a caller box with an arrow to a customer-service agent box whose inner dashed area is labelled inside the agent, and a dashed box asking why the inside stays hidden.
Typed schematic, not captured output.
13. Why does the caller send targetLength as a data part instead of writing it into the text part?Explain
A code card showing a message whose only visible part is a text part reading Summarize this paper, a chip for targetLength with the value 3 paragraphs, and a dashed box asking where it goes.
Message code is typed to match the lesson's example.
14. How does a caller keep track of a Task's progress while the called agent works?Explain
A caller box and a called agent box with a task in progress, an arrow labelled task sent earlier, and a dashed box asking how the caller follows progress.
Typed schematic, not captured output.
15. Why does the clarification travel as another Message on the same Task instead of starting a new Task?Explain
A paused writer agent box asking a research agent box for the length, and a dashed box asking how the answer travels.
Typed schematic, not captured output.
16. According to the Relationship to MCP table, how does authorization typically differ between the two protocols?Explain
A three-column table with headings Dimension, MCP and A2A, and a single Authorization row with question marks in the MCP and A2A cells.
17. According to the Relationship to MCP table, what are the typical caller and state model for each protocol?Explain
A three-column table with headings Dimension, MCP and A2A, and two rows, Typical caller and State, with question marks in the MCP and A2A cells.
18. A travel agent delegates "book the trip" to a booking agent, which midway needs the traveler's passport country. What should the booking agent do under A2A?Apply
A travel agent box delegating book the trip to a booking agent box, a note that the booking agent needs the traveler's passport country, and a dashed box asking what it does next.
Typed schematic, not captured output.
19. A developer wants to know why a vendor agent's summary missed a section, so she looks for the vendor's tool calls in the task response and finds only a state and an artifact. What explains this?Analyze
A developer's question about a missed section, a task response panel with a state line and an artifact line holding the summary, a dashed red area where the vendor's tool calls were looked for and not found, and a dashed box asking why.
Typed schematic, not captured output.
20. An attacker hosts a lookalike card at a similar domain and claims to be a payments agent. Which A2A mechanism lets consumers detect that it was not published by the real agent?Analyze
Two side-by-side card boxes for a payments-agent with the domains payments.example.com and payments-example.com, and a dashed box asking which one the real agent published.
Domains are illustrative.
21. A team wants its agent to run a PDF-to-text function, and also to hand a whole "write the quarterly report" job to a vendor agent it cannot inspect. Which pairing fits?Design
A team's agent box with arrows to two job cards, run a PDF-to-text function, and hand write the quarterly report to a vendor agent it cannot inspect, each with a dashed protocol box marked with a question mark.
Typed schematic, not captured output.
22. You are shipping an agent that unknown partner agents will call. They must find its skills and endpoint from a URL alone and be able to verify the card is genuine. Which design fits?Design
Unknown partner agents and your agent joined by an arrow labelled only a URL known, a panel listing that partners must find skills and endpoint from the URL alone and verify the result, and a dashed box asking for the design.
Typed schematic, not captured output.
23. Your company runs gRPC everywhere and wants to offer an agent to partners through A2A. Which choice keeps you inside the protocol?Design
A company box whose services talk gRPC and a partner agents box joined by an arrow labelled agent offered through A2A, and a dashed box asking for the choice that stays inside A2A.
Typed schematic, not captured output.

Use It

code/main.py is a minimal A2A harness. A writer agent publishes its card, and a research agent fetches it and sends a task with a text part and a PDF file part. The writer pauses in input_required because the message has no data part with targetLength. The research agent replies with one, the task goes back to working, and it finishes with a text artifact. It's all stdlib and uses an in-process transport, so the focus stays on message shapes.

What to look at:

  • The Agent Card JSON shape.
  • Task id assignment and state transitions.
  • Messages with mixed-type parts.
  • The input-required branch mid-task.
  • The artifact returned on completion.
Check: Use It0/7
1. In main.py, the research agent calls writer_tasks_send with a text part and a PDF file part and no data part. What is the task state when the call returns?Apply
A code card for the research agent's writer_tasks_send call with a text part and a file part for paper.pdf, and a dashed box asking for the task state when the call returns.
Abridged from main.py; file mimeType and bytes omitted.
2. In main.ts, the first message has text and file parts. The writer pauses, the caller replies with one data part, and the task completes. How many messages does the task hold at the end?Apply
Four stacked steps: the caller sends a text part and a file part, the writer pauses the task, the caller replies with one data part, and the task completes. A dashed box asks how many messages the task holds at the end.
Typed schematic, not captured output.
3. In main.py, the caller replies with a data part {"targetLength": "3 paragraphs"}. Which text does the final artifact's first part contain at its start?Apply
A code card for the caller's reply carrying a data part with targetLength 3 paragraphs, and a dashed box asking how the first part of the final artifact's text begins.
Reply code is taken from main.py.
4. In main.py, the task is in input_required and the caller replies with a data part {"unit": "words"} that has no targetLength key. What happens?Apply
A box showing the task state input_required, a code card for the caller's reply with a data part holding unit words, and a dashed box asking what happens to the task.
Reply code is taken from the stem and main.py.
5. In main.ts, the first message already contains a data part {targetLength: "1 page"}. What does the call return?Apply
A code card for the first message in main.ts with a text part, a file part and a data part holding targetLength 1 page, and a dashed box asking what writerTasksSend returns.
Abridged from main.ts, with the data part added as the stem says.
6. A task is stuck in input_required after the research agent answered the writer's question with a text part reading "3 paragraphs". What is the cause?Analyze
A box showing the task state input_required, a code card for a reply carrying only a text part reading 3 paragraphs, a note that the state is still input_required afterwards, and a dashed box asking for the cause.
Reply code is taken from the stem.
7. A caller reads "streaming": true on the writer's Agent Card and waits for incremental artifact chunks, but receives only one final artifact. Why?Analyze
The writer's capabilities line with streaming true and pushNotifications false, a box for a caller waiting for incremental artifact chunks, a box for receiving one final artifact named summary, and a dashed box asking why no chunks arrive.
Card line is taken from main.py.

Ship It

This lesson produces outputs/skill-a2a-agent-spec.md. Given a new agent that should be callable by other agents, the skill produces the Agent Card JSON, skills schema, and endpoint blueprint.

Author's Note

I'd run main.py first and read the output top to bottom. It prints the writer's card, sends a message with no data part, and shows the task stopping in input_required until the research agent follows up with targetLength. The final line counts the messages on the task, so you can see that the clarification lived in the same task instead of starting a new one.

The part I'd spend time on is how little the caller learns. It gets a state string and an artifact back, and nothing about how the writer produced the summary. That's the opacity argument from the body made concrete. The cost is that the research agent can't inspect or correct the writer's reasoning, only answer the question it's asked.

Keep the toy in proportion. The transport is a function call, the writer's finish just formats a string, and nothing is signed or streamed. The card declares streaming: True, but the code never uses it. The signing and SSE parts are the two exercises I'd do before trusting this shape in anything real.

Exercises

  1. Run code/main.py. Trace the full Task lifecycle, including the input-required pause where the called agent asks for a clarification.

  2. Add a signed Agent Card. Sign with HMAC over the card's canonical JSON. Write a verifier and confirm it fails on a mutated card.

  3. Implement task streaming: the writer agent emits three incremental artifact chunks over SSE and the caller accumulates them.

  4. Design an A2A agent that wraps an MCP server. Map each MCP tool to an A2A skill. Note the trade-offs. What opacity is lost?

  5. Read the A2A v1.0 announcement and identify the one feature that is not yet implemented by any framework as of April 2026. (Hint: it relates to multi-hop task delegation.)

Key Terms

TermWhat people sayWhat it actually means
A2A"Agent-to-Agent protocol"Open protocol for opaque agent collaboration
Agent Card".well-known/agent.json"Published metadata describing an agent's skills and endpoint
Skill"A callable unit"A named operation the agent supports (analog to MCP tool)
Task"Unit of delegation"A work item with a lifecycle and final artifact
Message"Task input"Carries Parts (text, file, data)
Part"Typed chunk"text / file / data element of a message
Artifact"Task output"Named, typed output returned on completion
AP2"Agent Payments Protocol"Signed Agent Cards extension for trust and payments
Opacity"Black-box collaboration"Called agent's internals are hidden from caller
Input-required"Task pause"Lifecycle state when the agent needs more info

Further Reading

Code

Ships With