What is A2A (Agent-to-Agent)?
What is the A2A protocol?
According to google, A2A is "An open protocol enabling communication and interoperability between opaque agentic applications.". This means that multiple agents distributed across different platforms, devices and organizations can communicate with each other, sharing information and performing tasks in a decentralized manner. It helps to bridge the gap between service providers and consumers by allowing agent handoff between different systems.
Overview
Actors
User
You are the user. You interact with a host agent via a chat system or some other human friendly interface.
Host Agent
The host agent is responsible for orchestrating the entire interaction between the agents. It receives requests from the user, delegates requests to remote agents (via agent handoff) and manages the communication between agents. In terms of the protocol, the host agent is implemented as an A2A client that connects to remote agents (A2A servers) via a transport layer.
Remote Agent
Remote agents are agents provided by external parties, and are accessed via the host agent. They are implemented as A2A servers that listen for requests from the host. These are typically designed to perform a specific task and are specialized for a particular domain or use case. For example google might implement a remote agent to perform research tasks.
Transports
Unlike MCP, A2A is exclusively standardized on HTTP SSE, with support for external extensions. This means that A2A servers can be implemented using any HTTP server framework, such as Express, Fastify, or NestJS.
Authentication
A2A has launch parity with openapi, meaning that any type of authentication supported by openapi can be used with A2A. This includes:
- HTTP Basic authentication
- HTTP Bearer authentication
- API keys in headers, query strings or cookies
- OAuth 2.0 authorization
- OpenID Connect
This means that A2A servers can be plugged into any existing API gateway and utilize existing authentication and authorization mechanisms.
Agent Card
Agent cards document the capabilities of an agent. They allow for automated discovery and registration of agents.
export interface AgentCard {
name: string;
description?: string | null;
url: string;
provider?: AgentProvider | null;
version: string;
documentationUrl?: string | null;
capabilities: AgentCapabilities;
authentication?: AgentAuthentication | null;
defaultInputModes?: string[];
defaultOutputModes?: string[];
skills: AgentSkill[];
}
The AgentCard
object contains information about the agent, such as its name, description, URL, version, and capabilities. A single agent card can be exposed at the .well-known/agent.json
endpoint to enable domain driven autodiscovery.
Core Objects
Task
A Task
represents a unit of work that an agent processes. This might be a request like "Book a flight to New York", or a task like "Summarize the top reddit posts for the day".
export interface Task {
id: string;
sessionId?: string | null;
status: TaskStatus;
artifacts?: Artifact[] | null;
history?: Message[] | null;
metadata?: Metadata;
}
Each task has a unique ID, which can be used to identify and manage the task, and the session ID determines a single login session. The status is an object that contains information about the task.
export interface TaskStatus {
state: TaskState;
message?: Message | null;
timestamp?: string; // ISO 8601 date-time string
}
The TaskState
is an enum that represents the current state of the task. The message
is an optional field that can be used to provide additional context or information about the task.
export type TaskState =
| "submitted"
| "working"
| "input-required"
| "completed"
| "canceled"
| "failed"
| "unknown";
Artifacts
Artifacts are the output of a task. They can be files, text, or other types of data.
export interface Artifact {
name?: string | null;
description?: string | null;
parts: Part[];
index?: number;
append?: boolean | null;
lastChunk?: boolean | null;
metadata?: Metadata;
}
Each artifact has a name
, description
, and parts
. The name
and description
provide context for the artifact, allowing it to be used with search and retrieval (RAG) systems. The parts
are the actual data, which can be text, files, or other types of data.
Parts
export type Part = TextPart | FilePart | DataPart;
export interface TextPart {
type: "text";
text: string;
metadata?: Metadata;
}
The TextPart represents a piece of text. It has a type
of 'text'
and a text
property containing the actual text.
export interface FilePart {
type: "file";
file: FileContent;
metadata?: Metadata;
}
The FilePart
represents a file. It has a type
of 'file'
and a file
property containing the file content.
export interface FileContent {
name?: string | null;
mimeType?: string | null;
bytes?: string | null;
uri?: string | null;
}
The FileContent
represents the content of a file. It has a name
for the file name, mimeType
for the MIME type, and bytes
or uri
for the file content.
export interface DataPart {
type: "data";
data: Record<string, any>;
metadata?: Metadata;
}
The DataPart represents an unstructured piece of data. It has a type
of 'data'
and a data
property containing a json object.
Messages
export interface Message {
role: "user" | "agent";
parts: Part[];
metadata?: Metadata;
}
The Message
represents a message exchanged between the agent and the user. It has a role
of either 'user'
or 'agent'
, and a parts
array containing the actual message content. The user role is shared between the host agent and the end user, since both actors interact with the remote agent via the same interface. We have already covered the Part
type in the previous section.
Push Notifications
Push notifications are a way for the agent to notify the user about the status of a task. They reuse the same response types as the requests but with a different method name.
Supported Frameworks
The A2A spec repo contains a number of examples for different frameworks and languages. These include:
Framework | Language | Example |
---|---|---|
Genkit | JavaScript | Movie Agent |
Genkit | JavaScript | Coder Agent |
Google ADK | Python | expense report agent |
LangGraph | Python | Currency Converter Agent |
CrewAI | Python | Image Generation Agent |
LlamaIndex | Python | file parsing agent |
Conclusion
A2A (Agent-to-Agent) represents a critical evolution in how autonomous agents interoperate across organizational and technical boundaries. By standardizing communication A2A enables robust, secure, and scalable interactions between distributed systems. Its core abstractions create a clear and extensible protocol for web scale agent orchestration and delegation.