On this page
- Why this matters now
- The production boundary: agent as service
- Do not confuse A2A with MCP
- A minimal contract-first implementation
- Streaming and push are reliability features, not UI decoration
- Security model: keep identity out of the payload
- Observability: trace the delegation, not just the model call
- Versioning and compatibility will hurt first
- A rollout plan that will survive contact with production
- Phase 1: private delegation
- Phase 2: governed discovery
- Phase 3: external interoperability
- Common mistakes
- The practical takeaway
- References
The next production problem for agent systems is not whether one agent can call one more tool. Teams already have tool calling, MCP servers, retrieval pipelines, sandboxes, and workflow engines. The harder problem is what happens when useful agents live behind different runtime boundaries: one in a vendor platform, one in a customer support system, one in a data platform, one in an internal automation service, and one in a partner environment.
At that point, pretending every remote capability is a function call breaks down. A remote agent may need to run for minutes, ask follow-up questions, stream partial artifacts, enforce its own policy, hide proprietary tools, or operate under a different identity boundary. That is the gap the Agent2Agent protocol, usually shortened to A2A, is trying to fill.
A2A reached a 1.0 specification line in 2026 and is now hosted as a Linux Foundation project after Google's contribution of the protocol, SDKs, and tooling. The important engineering shift is not the governance announcement by itself. It is the boundary A2A draws: agents should be able to collaborate as opaque network services without exposing their internal memory, tool graph, prompts, or vendor-specific runtime.
If MCP is the tool boundary, A2A is the delegation boundary.
Why this matters now
Most early agent architectures have a single control plane. One orchestrator owns the model call, tool list, state store, policy checks, and UI. That model is simpler to debug, but it does not match how enterprises buy and deploy software. Real systems already have multiple owners:
- A CRM team owns customer operations agents.
- A data platform team owns warehouse and BI agents.
- A security team owns incident triage agents.
- A finance team owns approval and procurement agents.
- A platform team owns the generic assistant shell.
You can integrate all of those as tools only if each capability is narrow, stateless, and safe to expose as a schema. Many agent capabilities are not like that. They are long-running services with their own context, internal tools, permissions, and audit requirements.
A2A gives teams a vocabulary for this shape of integration. A client agent sends a message to a remote A2A server. The remote server can return a direct message or a stateful task. The task can stream status updates and artifacts, move through a lifecycle, require more input, or complete asynchronously. The client does not need to know which model, workflow engine, tools, or memory system the remote agent used.
That opacity is not a weakness. It is the feature that lets agent platforms become deployable services instead of prompt folders wired together by private SDK calls.
The production boundary: agent as service
A useful mental model is to treat an A2A server like a specialized application service, not like a library. It publishes a contract. It authenticates callers. It authorizes operations. It emits traces and audit records. It owns its internal implementation.
flowchart LR
U["User or workflow"] --> C["Client agent"]
C -->|"discover"| R["Agent registry or .well-known card"]
R --> C
C -->|"A2A message"| G["A2A gateway"]
G --> P["policy and identity checks"]
P --> S["Remote agent service"]
S --> T["private tools and memory"]
S -->|"task status"| C
S -->|"artifact"| C
S -->|"trace and audit"| O["observability stack"]
The core A2A objects map cleanly to service design:
| A2A object | Production role | Engineering question |
|---|---|---|
| Agent Card | Service contract and discovery document | Who is this agent, what skills does it offer, which endpoint and auth scheme should clients use? |
| Message | One conversational or command turn | What is the client asking the remote agent to do now? |
| Task | Stateful unit of delegated work | How do we track progress, retries, interruption, and final state? |
| Part | Typed content inside messages or artifacts | Is this text, structured JSON, a file reference, or binary content? |
| Artifact | Concrete output of the task | What deliverable should downstream systems persist, review, or pass forward? |
| Extension | Capability beyond the base protocol | Which non-portable behavior are we intentionally depending on? |
This is a better abstraction for serious agent delegation than function calling. A function call is usually a synchronous operation with a clear input and output. An agent service often needs task state, identity propagation, partial progress, human input, and a durable audit trail.
Do not confuse A2A with MCP
A2A and MCP are complementary, but they solve different problems.
MCP standardizes how an agent connects to tools, APIs, files, databases, and other resources. It is the right boundary for discrete capabilities with structured inputs and outputs. A remote database query, a ticket lookup, a code search, and a deployment API are good MCP-shaped capabilities.
A2A standardizes how independent agents collaborate with each other. It is the right boundary when the other side is itself an agentic system: it may plan, call tools, maintain task state, request more input, and return multiple artifacts over time.
A practical rule:
- If the remote capability should be invoked like
get_customer_invoice(id), expose a tool. - If the remote capability should be asked to
resolve this billing dispute and return the final explanation, evidence, and approval state, expose an A2A agent.
The pattern becomes powerful when combined. A client agent delegates a complex job over A2A. The remote agent uses MCP internally to reach its own tools. The client receives status and artifacts, not the remote agent's private tool chain.
A minimal contract-first implementation
The first implementation step should not be a giant agent mesh. Start with one high-value remote agent and make its contract boring.
An Agent Card should be specific enough for client routing and safe enough for its audience. Public cards can advertise broad capabilities, but sensitive internal endpoints or skills should move behind authenticated cards or private registries.
{
"name": "Incident Triage Agent",
"description": "Classifies production incidents and prepares an escalation brief.",
"url": "https://agents.example.com/a2a/incident-triage",
"version": "1.3.0",
"capabilities": {
"streaming": true,
"pushNotifications": true,
"extendedAgentCard": true
},
"security": [{ "oauth2": ["incident.read", "incident.triage"] }],
"skills": [
{
"id": "triage_incident",
"name": "Triage incident",
"description": "Builds a severity, owner, evidence, and next-action brief from incident context.",
"inputModes": ["text/plain", "application/json"],
"outputModes": ["application/json", "text/markdown"]
}
]
}
The client should treat this as a versioned service contract. Cache it with normal HTTP semantics. Validate the URL, auth schemes, protocol versions, and required capabilities before routing user work to it.
A JSON-RPC message to start work should be similarly constrained. The exact shape depends on the binding and SDK version, but the production principle is stable: pass the minimum task context, use typed parts for machine-readable fields, and keep identity in HTTP authentication headers rather than hiding identity claims inside the A2A payload.
{
"jsonrpc": "2.0",
"id": "req-2026-07-18-001",
"method": "message/send",
"params": {
"message": {
"role": "user",
"messageId": "msg-001",
"parts": [
{
"data": {
"incidentId": "INC-48291",
"service": "checkout-api",
"symptoms": ["elevated 500 rate", "payment timeout spike"]
},
"mediaType": "application/json"
}
]
},
"configuration": {
"acceptedOutputModes": ["application/json", "text/markdown"]
}
}
}
For simple requests, the remote agent may answer directly. For real work, expect a task and design around task lifecycle.
Streaming and push are reliability features, not UI decoration
A2A supports multiple interaction patterns: request and response with polling, streaming over Server-Sent Events, and asynchronous push notifications. Use those as reliability tools.
Streaming is useful when the client can keep a connection open and the user benefits from progress. It should emit meaningful task status and artifact updates, not token-by-token noise copied from the remote model. Good streaming events tell the caller things like "retrieving logs," "waiting for approval," "draft artifact available," or "completed with degraded evidence."
Push notifications are for disconnected or long-running work. They also introduce risk. A server that accepts arbitrary webhook URLs can become an SSRF primitive or a DDoS amplifier. Production implementations need webhook allowlists, ownership verification, egress controls, request signing, replay protection, and clear retry semantics.
A safe pattern is:
- Use streaming for interactive tasks that usually finish in seconds or a few minutes.
- Use push only for workflows where the client may disconnect.
- Require webhook registration and verification before a task can ask for push.
- Keep task retrieval as the source of truth. Treat push as a notification to call
GetTask, not as the only copy of the result.
Security model: keep identity out of the payload
The A2A enterprise guidance is intentionally conventional. Production A2A traffic should run over HTTPS. Authentication should use standard HTTP mechanisms such as OAuth2, OpenID Connect, bearer tokens, API keys, or mTLS, as advertised by the Agent Card. The protocol payload does not need to invent a second identity plane.
That design has an important consequence: your A2A gateway needs to be part of the platform security architecture.
At minimum, put these controls in front of every remote agent:
- Caller authentication: Verify the client application and, when relevant, the end user.
- Skill authorization: Map scopes or policies to specific advertised skills.
- Data minimization: Strip context the remote agent does not need.
- Tenant isolation: Route tenant context explicitly and reject cross-tenant task access.
- Egress policy: Control which downstream tools and webhooks the remote agent can reach.
- Audit logging: Record task creation, status transitions, artifact delivery, approvals, and high-impact actions.
Do not treat an A2A call as a safe chat message just because it is natural language. It is a cross-service operation. The remote agent may trigger tools, retrieve data, or produce artifacts that downstream automation will trust.
Observability: trace the delegation, not just the model call
Agent observability often stops at model spans and tool calls. A2A adds another boundary: delegation between agents. If you cannot trace across that boundary, you will not know whether failures came from the client orchestrator, the gateway, the remote agent, a downstream tool, or a human approval wait.
Instrument A2A like any other distributed service protocol:
- Propagate W3C trace context headers across A2A calls.
- Log
taskId,contextId, client identity, remote agent identity, skill ID, and accepted output modes. - Emit metrics for task creation rate, task duration, terminal states, interrupted states, streaming reconnects, push retries, and artifact size.
- Store enough task history for debugging, but avoid persisting sensitive message parts longer than policy allows.
The key metric is not tokens per second. It is delegated work completed correctly under policy.
Versioning and compatibility will hurt first
A2A is still young enough that production teams should expect compatibility work. The 1.0 release line included breaking changes around task push notification configuration, task IDs, enum formatting, OAuth flow modernization, field names across bindings, and relocation of the extended Agent Card capability. The 1.0.1 release fixed details including the preferred application/a2a+json media type in the HTTP binding and TaskStatus values.
That does not make A2A unusable. It means you need normal API discipline:
- Pin SDK versions for clients and servers.
- Store the protocol version from each Agent Card.
- Validate cards at ingestion time, not at task dispatch time.
- Keep compatibility tests with real example payloads from each remote agent.
- Fail closed when a remote card advertises a capability you do not understand.
- Put extensions behind explicit feature flags.
Avoid routing production work to an agent just because it has a matching skill name. Compatibility is a contract, not a search result.
A rollout plan that will survive contact with production
The lowest-risk way to adopt A2A is inside one organization, behind one gateway, with one or two remote agents.
Phase 1: private delegation
Pick a task that is valuable but bounded, such as incident triage, data quality investigation, sales engineering research, or compliance evidence collection. Configure the client directly with a private Agent Card URL. Require OAuth or mTLS from day one. Return structured artifacts that a human can review.
Success criteria:
- The remote agent produces a useful artifact.
- The client can poll or stream task status.
- The task has trace IDs and audit records.
- Failed, canceled, rejected, and input-required states are handled.
Phase 2: governed discovery
Move Agent Cards into a registry or catalog. Add ownership, version, environment, data classification, allowed callers, and deprecation metadata around the card. Let platform teams approve which skills can be routed automatically.
Success criteria:
- The client can discover agents without hardcoding every endpoint.
- Sensitive cards are selectively disclosed.
- Card changes are reviewed like API changes.
- Deprecations are visible before callers break.
Phase 3: external interoperability
Only after internal patterns work should you connect to partner or vendor agents. Require stronger ingress and egress controls, explicit data-sharing terms, contract tests, and a manual approval path for high-impact actions.
Success criteria:
- External agents cannot receive unnecessary user or tenant context.
- Webhooks are verified and replay-protected.
- Artifacts include provenance and are not blindly executed.
- The system can degrade gracefully when the remote agent is unavailable.
Common mistakes
Mistake 1: exposing every tool as an agent. If the capability is a deterministic function, keep it as a tool. A2A is for delegated work that benefits from task state, autonomy, or opacity.
Mistake 2: publishing sensitive Agent Cards. The public .well-known pattern is useful, but not every skill description or endpoint belongs on the public internet. Use private discovery or authenticated extended cards for sensitive capabilities.
Mistake 3: streaming model noise. Streaming should communicate task progress and artifact updates. If the client only receives partial prose, it still cannot orchestrate the workflow reliably.
Mistake 4: skipping webhook threat modeling. Push notifications create outbound network behavior. Treat webhook URLs as untrusted until verified.
Mistake 5: ignoring artifact contracts. The artifact is what downstream systems will use. Define schemas, media types, validation rules, and provenance. Do not make every artifact a blob of markdown unless humans are the only consumers.
Mistake 6: routing by natural-language skill names. Skills need stable IDs, ownership, versions, and policy. Semantic routing can suggest candidates, but production dispatch should use verified contracts.
The practical takeaway
A2A is useful because it gives agent systems a service boundary. It does not remove the hard parts of production engineering. You still need identity, policy, versioning, observability, data minimization, and failure handling. But it gives those controls a protocol surface to attach to.
The right question is not "Should every agent support A2A?" The better question is: "Where do we need to delegate stateful work to an opaque system without collapsing that system into our own tool loop?"
For those boundaries, A2A is the pattern to evaluate.