Written by: Arjun Karnik, Growth Marketing Specialist

Key Takeaways

  • The Agent2Agent (A2A) protocol is an open standard that lets autonomous AI agents from different vendors securely discover each other, communicate, and delegate tasks using HTTPS, JSON-RPC 2.0, and Server-Sent Events.
  • Before A2A, multi-agent systems needed custom integrations for every agent pairing. Teams duplicated glue code, lacked discovery, and reinvented security each time.
  • Core A2A concepts include Agent Cards for capability discovery, stateful Tasks with defined lifecycles, and Artifacts as deliverables. The spec defines these in Protocol Buffers and JSON Schema.
  • A2A complements MCP by handling horizontal agent-to-agent collaboration, while MCP manages vertical agent-to-tool connections. This pairing supports layered architectures where orchestrators delegate to specialist agents.
  • Marketers who want to run A2A in production should see Arjun Karnik’s live demo and step-by-step implementation guide to see the protocol in action.

The Problem: Why Agent-to-Agent Communication Needs a Standard

Multi-agent systems previously relied on custom integrations between every pair of agents. Frameworks such as LangChain, CrewAI, AutoGen, and Google ADK lacked a shared language for task delegation. Each new pairing required fresh glue code, no discovery mechanism, no standardized task lifecycle, and bespoke security.

A2A is an open standard that enables seamless communication and collaboration between AI agents built using diverse frameworks and by different vendors. Google introduced it on April 9, 2025, and donated it to the Linux Foundation on June 23, 2025, where it reached v1.0.0 on March 12, 2026, with support from over 150 organizations including Google, Microsoft, AWS, and IBM.

A core design principle is opaque collaboration. A2A uses HTTPS for secure communication and keeps operations opaque so agents cannot see the inner workings of other agents during collaboration. Agents work together without exposing internal logic, private memory, prompts, or underlying models.

Core Concepts: Agent Cards, Tasks, and Artifacts

Agent Cards: How Agents Describe Themselves

Agent Cards are JSON discovery files that let AI agents locate, evaluate, and delegate tasks to each other without hard-coded integrations. Every A2A-compliant agent publishes its Agent Card at a well-known URL following RFC 8615 so client agents can discover it via unauthenticated HTTP GET requests, specifically at /.well-known/agent-card.json.

Required fields include name, description, version, url, skills, and protocolVersion. The capabilities object declares streaming and push-notification support. The A2A v1.0 release added cryptographically signed Agent Cards using JWS (RFC 7515) signatures over RFC 8785 canonicalized JSON, with Ed25519 (EdDSA) as one supported signing algorithm. Authenticated callers can fetch a richer card via the GetExtendedAgentCard RPC, which may expose additional skills or security requirements.

Tasks: The Stateful Unit of Work

In the A2A protocol, task IDs are server-generated when a new task is created; client-provided task IDs for creating new tasks are not supported, and a client-provided taskId must reference an existing task. Some SDKs may layer client-generated IDs on top for idempotency, but the core spec treats server-generated IDs as canonical.

The core nouns defined in the A2A protocol — AgentCard, AgentSkill, Task, Message, Part, Artifact, and Extension — are defined in Protocol Buffers and published as JSON Schema 2020-12, auto-generated from the protos. Messages are the communication units within a task. Each message has a role (user or agent) and an array of Parts (TextPart, FilePart, DataPart). Artifacts are the deliverables produced when a task completes, each with a name, description, and parts. They are distinct from messages, which represent the conversation, and a single task can produce multiple artifacts.

Transport and Message Format: HTTPS, JSON-RPC 2.0, and SSE

A2A uses existing standards like HTTP, JSON-RPC, and Server-Sent Events (SSE) to speed up developer adoption. All JSON-RPC requests route through a single endpoint, typically POST /, with methods including SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, and SubscribeToTask.

Clients include an A2A-Version header with each request to ensure protocol compatibility. Credentials travel in HTTP headers, never in the JSON-RPC payload. A2A v1.0 also ships a gRPC binding for higher-performance deployments, with a2a.proto as the normative specification.

The A2A Task Lifecycle: States and Transitions

The A2A protocol defines eight task states grouped into three categories: active (SUBMITTED, WORKING), interrupted (INPUT_REQUIRED, AUTH_REQUIRED), and terminal (COMPLETED, FAILED, CANCELED, REJECTED). The full lifecycle:

  1. Submitted: From the Submitted state, a task can transition to Working, Canceled, Rejected, or Failed, and may also transition directly to Completed (per the official SDKs) or to AuthRequired (per some SDKs), but cannot transition directly to InputRequired.
  2. Working: In the A2A protocol, the Working state can transition to Completed, Failed, Canceled, InputRequired, or AuthRequired.
  3. Input-required: The task pauses until the client responds with a new message via tasks/send using the same task ID. Multiple rounds are allowed for multi-turn negotiations.
  4. Auth-required: A dedicated interrupted state distinct from input-required, which signals that the client must complete an authentication step, typically acquiring or refreshing a credential, before resuming the same task.
  5. Completed: Terminal success state. Artifacts are available for retrieval.
  6. Failed: Terminal error state. Retrying requires creating a new task with a new ID.
  7. Canceled: Terminal state. The client, gateway, or authorized caller stopped the task.
  8. Rejected: Terminal state. The agent refused the task due to policy, capability mismatch, or authentication failure.

Handling Long-Running Tasks in A2A

A2A supports long-running tasks through streaming, push notifications, and asynchronous execution for scenarios where agents or users are not continuously connected.

Streaming via SSE: The A2A protocol supports streaming responses via Server-Sent Events over a long-lived HTTP connection, with the SendStreamingMessage operation mapping to the JSON-RPC message/stream method and returning a text/event-stream HTTP response. The server pushes TaskStatusUpdateEvent and TaskArtifactUpdateEvent objects until the task reaches a terminal state.

Push notifications: Push notifications act as a signal, not a full payload transport. The client supplies a PushNotificationConfig with an HTTPS webhook URL, optional token, and optional authentication details. On significant updates the server POSTs to the webhook and the client typically calls GetTask with the notified taskId to fetch the full updated task and artifacts.

Polling: Clients can call tasks/get at any time to retrieve the current task state.

Stream reconnection: tasks/resubscribe re-establishes a dropped SSE stream against an existing task ID.

Production pattern: Set per-hop and end-to-end timeout budgets, persist task IDs in durable storage, and implement retry with exponential backoff for transient failures.

A2A vs MCP: How the Protocols Work Together

MCP and A2A solve different problems. MCP connects an agent to its tools and data, while A2A connects independent agents to each other. This architectural difference is fundamental and shapes how you design multi-agent systems.

MCP, introduced by Anthropic, is a protocol for connecting AI or LLM applications and agents to external data sources, tools, and APIs, while A2A standardizes peer-to-peer delegation of complete autonomous tasks between agents. MCP acts as a vertical integration layer that links an agent to data. A2A acts as a horizontal collaboration layer that links agent to agent.

The interaction models differ as well. MCP uses a host-client-server model where the AI model is always the decision maker and the MCP server is a passive provider of capabilities. A2A uses a peer model where both participants are autonomous agents capable of independent reasoning. MCP tools are stateless function calls. A2A has first-class human-in-the-loop support via the INPUT_REQUIRED task state, and tasks are stateful with a defined lifecycle.

MCP interaction is hierarchical: an agent (host) creates a client that connects to a passive server, and there is no built-in runtime discovery of servers. Each client is pointed at a preconfigured server endpoint, although once connected, a client can discover a server’s capabilities via mechanisms like server/discover and tools/list. A2A agents publish Agent Cards for dynamic discovery, so orchestrators can locate new agents at runtime.

The production pattern is a layered architecture. A high-level orchestrator agent uses A2A to manage workflows and delegate to specialist agents. Each specialist agent then uses MCP internally to call its own tools, and the orchestrator only needs to know what specialists can do via their A2A Agent Cards.

The decision rule is simple. Use A2A when the other system needs to reason, plan, or make decisions. Use MCP when it needs to execute a defined operation and return a result. To see how these concepts work in practice, review the complete A2A interaction below.

A2A Protocol Example: A Complete Worked Interaction

Step 1: Discover the Agent Card

GET /.well-known/agent-card.json Host: agents.example.com

Response (abbreviated):

{ "name": "Procurement Agent", "description": "Handles supplier evaluation and purchase order creation", "version": "1.0.0", "url": "https://agents.example.com/a2a", "protocolVersion": "1.0.0", "capabilities": { "streaming": true, "pushNotifications": false }, "skills": [ { "id": "evaluate_supplier", "name": "Evaluate Supplier", "description": "Evaluates supplier quotes against criteria", "inputModes": ["text"], "outputModes": ["text"] } ], "securitySchemes": { "oauth2": { "type": "oauth2", "flows": { "clientCredentials": { "tokenUrl": "https://auth.example.com/token", "scopes": { "procurement:write": "Create purchase orders" } } } } }, "securityRequirements": [ { "oauth2": ["procurement:write"] } ] }

Step 2: Create a Task via message/send

POST /a2a Content-Type: application/json Authorization: Bearer eyJhbGciOi... A2A-Version: 1.0.0

Request:

{ "jsonrpc": "2.0", "id": "req-001", "method": "message/send", "params": { "message": { "messageId": "msg-a1b2c3d4", "role": "user", "parts": [ { "kind": "text", "text": "Evaluate supplier Acme Corp for 500 units of component X. Budget: $12,000. Delivery by March 30." } ] } } }

Response (task accepted, work in progress):

{ "jsonrpc": "2.0", "id": "req-001", "result": { "task": { "id": "task-12345", "state": "working", "status": { "state": "working", "message": "Evaluating supplier against criteria", "timestamp": "2026-09-01T14:30:00Z" } } } }

Step 3: Receive Streaming Updates via message/stream

POST /a2a Content-Type: application/json Accept: text/event-stream Authorization: Bearer eyJhbGciOi... A2A-Version: 1.0.0

Request:

{ "jsonrpc": "2.0", "id": "req-002", "method": "message/stream", "params": { "message": { "messageId": "msg-a1b2c3d4", "role": "user", "parts": [ { "kind": "text", "text": "Evaluate supplier Acme Corp for 500 units of component X. Budget: $12,000. Delivery by March 30." } ] } } }

SSE stream (each data: line is a JSON-RPC response):

data: {"jsonrpc":"2.0","id":"req-002","result":{"statusUpdate":{"status":{"state":"working","message":"Checking pricing against budget","timestamp":"2026-09-01T14:30:05Z"}}}} data: {"jsonrpc":"2.0","id":"req-002","result":{"statusUpdate":{"status":{"state":"working","message":"Verifying delivery timeline","timestamp":"2026-09-01T14:30:12Z"}}}} data: {"jsonrpc":"2.0","id":"req-002","result":{"artifactUpdate":{"artifact":{"artifactId":"art-001","name":"evaluation_result","parts":[{"kind":"text","text":"{"supplier":"Acme Corp","score":0.87,"price":"$11,850","delivery":"March 28","recommendation":"APPROVE"}"}]}}}} data: {"jsonrpc":"2.0","id":"req-002","result":{"statusUpdate":{"status":{"state":"completed","message":"Evaluation complete","timestamp":"2026-09-01T14:30:15Z"}}}}

Step 4: Handle Input-Required (Multi-Turn Negotiation)

If the agent needs clarification, the task transitions to input-required:

{ "jsonrpc": "2.0", "id": "req-002", "result": { "statusUpdate": { "status": { "state": "input-required", "message": "Supplier offers volume discount at 750 units. Proceed with 750 units or maintain 500?", "timestamp": "2026-09-01T14:31:00Z" } } } }

The client resumes the same task with a new message using the original task ID:

{ "jsonrpc": "2.0", "id": "req-003", "method": "message/send", "params": { "message": { "messageId": "msg-b2c3d4e5", "taskId": "task-12345", "role": "user", "parts": [ { "kind": "text", "text": "Maintain 500 units. Prioritize delivery date over discount." } ] } } }

A2A Specification and AP2 Extension

A2A reached v1.0 in 2026 and is governed under the Linux Foundation. The v1.0 specification layers concepts into a canonical data model, abstract operations, and protocol bindings, which this guide has already covered.

The official A2A GitHub repository hosts the specification, SDKs in Python, Go, JavaScript, Java, and .NET, an Inspector tool, and a Test Compatibility Kit (TCK). The Agent Payments Protocol (AP2) extension enables autonomous transactions and is supported by more than 60 organizations.

Security and Authentication: Implementing A2A in Production

The A2A protocol mandates HTTPS for all production deployments, recommends TLS 1.2 or higher (with TLS 1.3+ recommended in some versions), recommends that clients validate server certificates against trusted CAs, and recommends strong cipher suites including perfect forward secrecy.

The A2A protocol specification defines five security scheme types that can be declared in an Agent Card: API keys, HTTP authentication, OAuth 2.0 with configurable flows, OpenID Connect Discovery, and mutual TLS (mTLS).

OAuth 2.0 with client credentials flow is the most common choice for enterprise deployments. It integrates with existing identity infrastructure, supports narrow scoping at the skill level, and is natively supported by the A2A v1.0 security model. Per the IETF Agent Authorization Profile (AAP) draft, the receiving resource server validates the OAuth 2.0 token’s signature, exp, aud, and iss claims, and requires a unique jti to prevent replay (confused deputy) attacks, while sub and scope are validated as part of the required AAP claims.

A2A agents MUST reject requests with invalid or missing authentication credentials and MUST NOT reveal the existence of resources the client cannot access.

The A2A protocol v1.0 specification introduced Agent Card signing using JSON Web Signature per RFC 7515, with JSON Canonicalization Scheme per RFC 8785 applied before signing. Signed cards allow clients to verify that the card content is unaltered and that it originates from the declared provider.

Push notifications require bidirectional authentication. A2A servers SHOULD NOT blindly POST to client-provided URLs to prevent SSRF and DDoS amplification, and MUST authenticate to webhooks using schemes like Bearer tokens, API keys, HMAC signatures, or mTLS. Webhook receivers MUST verify the server’s identity and prevent replay attacks using timestamps and nonces.

To prevent authorization creep in delegation chains, a recommended pattern is to use OAuth 2.0 Token Exchange (RFC 8693) to trade a user-level token for a tightly-scoped, short-lived token for the specific downstream skill, although the A2A spec itself is silent on how to downscope credentials. A2A does not natively solve the trust chain problem, where Agent A delegates to B which delegates to C and C cannot verify that A authorized the delegation. Token Exchange is the current production mitigation.

Since A2A is built on HTTP and JSON-RPC, every agent-to-agent interaction is an API call, making the API gateway the natural enforcement point for authentication, rate limiting, and observability on agent-to-agent traffic.

Implementation Considerations and Best Practices

Agents declare support for streaming via AgentCard.capabilities.streaming and for push notifications via AgentCard.capabilities.pushNotifications. Because these capabilities determine which operations are available, clients SHOULD validate them before attempting to use streaming or push-notification operations, and agents MUST return UnsupportedOperationError or PushNotificationNotSupportedError when these capabilities are false or absent. In short, always read the Agent Card before choosing an interaction mode.

Some SDKs expose client-generated task IDs to enable idempotent task submission. Resending a request with the same task ID after a timeout then returns the current state rather than creating a duplicate, even though the core protocol treats server-generated IDs as the source of truth.

The A2A protocol does not define built-in timeouts, so production systems implement their own timeout management. Teams typically configure client-side per-request timeouts and use the protocol’s task cancellation mechanism to cancel tasks that exceed a chosen duration.

The A2A spec recommends using OpenTelemetry with W3C Trace Context headers on every A2A call so a single user request can be traced across the entire agent chain. Correlate a trace ID per workflow, a task ID per agent task, and an agent ID per hop.

Task state and artifacts should survive process restarts. If your agent runs in Kubernetes, assume pods die mid-task and back task records and artifact blobs to a store the agent container does not own exclusively.

When an upstream user aborts, you should cancel downstream tasks to avoid wasted work. A delegation graph helps propagate the cancellation across the chain, and logging canceled tasks that already incurred cost gives you visibility into resource usage.

Frequently Asked Questions

How does the A2A protocol work?

The A2A protocol uses a client-server model where one agent (the client) discovers another agent’s capabilities via its Agent Card, then delegates work as a Task. The task progresses through a defined lifecycle of submitted, working, input-required, auth-required, completed, failed, canceled, or rejected, with messages exchanged as JSON-RPC 2.0 requests over HTTPS. For long-running tasks, the server streams status and artifact updates via Server-Sent Events or sends push notifications to a registered webhook. Some SDKs support client-generated task IDs to make submission idempotent, so retries after network failures are safe. The Agent Card, served at /.well-known/agent-card.json, tells the client everything it needs before sending the first request, including the agent’s skills, supported interaction modes, and authentication requirements.

What are the key differences between A2A and MCP?

MCP (Model Context Protocol) standardizes agent-to-tool communication, which covers how a single agent connects to external data sources and APIs. A2A standardizes agent-to-agent communication, which covers how autonomous agents discover each other, delegate tasks, and coordinate work. MCP acts as a vertical integration layer that connects an agent to data, while A2A acts as a horizontal collaboration layer that connects agent to agent. In MCP, the LLM is always the decision-maker and the MCP server is a passive capability provider. In A2A, both participants are autonomous agents capable of independent reasoning. MCP tools are stateless function calls. A2A tasks are stateful with a defined lifecycle that includes human-in-the-loop pauses via the input-required state. MCP requires preconfigured server endpoints, while A2A agents publish Agent Cards for dynamic discovery. Production multi-agent systems typically use both, with A2A for inter-agent coordination and MCP for each agent’s tool access.

Is agent-to-agent communication a protocol?

Yes. The Agent2Agent (A2A) protocol is an open standard introduced by Google in April 2025 and donated to the Linux Foundation in June 2025. It reached v1.0.0 in March 2026 with support from over 150 organizations including Google, Microsoft, AWS, Salesforce, SAP, ServiceNow, and IBM. It defines how autonomous AI agents discover each other, delegate tasks, and coordinate work using HTTPS, JSON-RPC 2.0, and Server-Sent Events. The specification is maintained under the Linux Foundation and is available in the official A2A GitHub repository, with production-ready SDKs in Python, Go, JavaScript, Java, and .NET.

How does agent-to-agent communication work step by step?

Agent-to-agent communication in A2A works through four steps:

  1. Discovery: The client fetches the remote agent’s Agent Card at /.well-known/agent-card.json to learn its capabilities, skills, and authentication requirements. In v1.0, the client can verify the card’s JWS signature to prevent tampering.
  2. Task creation: The client sends a JSON-RPC message/send or message/stream request to create a Task. The server returns a task ID and initial state.
  3. Execution: The server processes the task, potentially streaming updates via SSE, requesting more input via the input-required state, or requiring additional authentication via the auth-required state.
  4. Completion: The task reaches a terminal state of completed, failed, canceled, or rejected, and artifacts are retrieved via tasks/get.

What should I check before implementing A2A in production?

Five checks make a production A2A deployment reliable. First, verify the Agent Card’s capabilities object before choosing an interaction mode, because streaming requires capabilities.streaming: true and push notifications require capabilities.pushNotifications: true. Second, confirm whether your chosen SDK supports client-generated task IDs for idempotent submissions, even though the core protocol uses server-generated IDs. Third, ensure that task state and artifacts are persisted outside the agent container. Fourth, implement OpenTelemetry tracing with W3C Trace Context headers. Fifth, validate that OAuth 2.0 Token Exchange is configured to prevent authorization creep in delegation chains.