AgentCard Capability Contract For Safe Agent Discovery
In the realm of agent-to-agent (A2A) communication, ensuring seamless and secure interactions is paramount. This article delves into defining a normative AgentCard capability declaration contract, a crucial step towards safe agent discovery and robust multi-agent orchestration. We'll explore the challenges, propose solutions, and outline the benefits of standardized capability declarations.
The Problem: Addressing Interoperability Risks
The current A2A specification faces ambiguities regarding AgentCard capabilities, leading to critical interoperability risks. While AgentCards declare capabilities like pause_resume, streaming_message, and push_notifications, the specification lacks clarity on several fronts. Specifically, it doesn't define which capabilities must be declared versus implicitly assumed, establish backward-compatibility rules for new capabilities, detail how multi-agent orchestration validates capability compatibility, or set safe discovery boundaries.
These ambiguities can lead to several problems:
- Silent capability drift: Agents introduce new capabilities without proper declaration, leading to broken orchestration chains.
- Unsafe discovery: Orchestrators discover agents without validating necessary capability support, resulting in task failures.
- Backwards incompatibility: New agents with updated features silently break clients expecting older behaviors.
Evidence of these issues is apparent in recent discussions and issues, highlighting the urgent need for a clear and comprehensive solution. Issues such as unanswered confusion regarding mandatory supportedInterfaces declarations, requests for adding source fields in messages for multi-agent scenarios, and the addition of pause/resume as a capability flag without a clear discovery mechanism all point to the existing gaps in the specification. The deferral of Message/Artifact unification further underscores the necessity for a robust capability versioning strategy. The absence of a reference implementation or test demonstrating capability negotiation exacerbates these concerns.
Proposed Solution: A Multi-Tiered Approach
To mitigate these risks and foster interoperability, we propose a solution centered around capability tiers, version negotiation, discovery safeguards, and a commitment to capability stability.
1. Define Capability Tiers
We introduce three distinct capability tiers to categorize agent capabilities:
-
Tier 1: Implicit
These are the foundational capabilities that all compliant agents must support without explicit declaration. This ensures a base level of functionality across all agents. This includes actions like
SendMessage(single message, no history),GetTask,ListTasks, and basic error handling. Think of these as the fundamental building blocks every agent should possess, ensuring a common ground for interaction. -
Tier 2: Declared
These are optional capabilities that must be explicitly declared in the
AgentCardif supported by the agent. This allows agents to advertise their advanced functionalities, such as:pause_resume: Indicates support for pause/resume operations.streaming_message: Indicates the ability to stream Message objects with thepartial: trueflag.push_notifications: Indicates support for push notification registration.context_reuse: Indicates whether agents can share context IDs across separate calls.multi_tenant: Indicates operation in multi-tenant mode.message_history_injection: Indicates acceptance of injected message history inSendMessage.- Custom capabilities via Extensions: An extensible schema for vendor-specific capabilities, enabling innovation while maintaining compatibility.
-
Tier 3: Deprecated
These are capabilities that are supported but discouraged. For instance, direct artifact streaming, which has been superseded by Message streaming. The use of deprecated feature should be avoided.
2. Version Negotiation Fields
To manage compatibility as the A2A ecosystem evolves, we propose adding optional version range fields to the AgentCard:
message AgentCard {
...
// Minimum A2A protocol version this agent supports
string min_protocol_version = 7; // e.g., "0.3.0"
// Maximum A2A protocol version this agent supports
string max_protocol_version = 8; // e.g., "1.2"
}
We also add these fields to AgentInterface for protocol-binding-specific version negotiation:
message AgentInterface {
...
// Protocol version(s) supported by this interface
repeated string protocol_versions = 4; // e.g., ["1.0", "1.1"]
}
3. Discovery Safeguards
When discovering an agent, client-side validation becomes crucial. The following pattern should be followed:
def safe_discover(agent_card: AgentCard, my_protocol_version: str) -> bool:
# Check version range compatibility
if not version_in_range(my_protocol_version,
agent_card.min_protocol_version,
agent_card.max_protocol_version):
log.warning(f"Agent protocol version {agent_card.min_protocol_version}-{agent_card.max_protocol_version} incompatible with mine {my_protocol_version}")
return False
# Check required capabilities for intended use case
if my_task_requires_streaming and not agent_card.capabilities.get("streaming_message"):
log.warning("Agent does not declare streaming_message capability; streaming will fail")
return False
return True
4. Multi-Agent Orchestration
In scenarios where Agent A delegates to Agent B, which in turn delegates to Agent C (A → B → C), transitive capability validation is essential.
- Step 1: A discovers B and validates B's capabilities against task requirements.
- Step 2: If B delegates to C, B must validate C's capabilities.
- Step 3: If B's capability is
context_reuse: false, A cannot rely on shared context.
Without validation, a failure mode could occur where A requires streaming_message, discovers B without a capability check, sends a streaming message to B, and B fails because it doesn't support streaming, leading to a silent failure mid-orchestration. With validation, A checks if B.capabilities.streaming_message == false and refuses to delegate to B, resulting in deterministic and predictable behavior.
5. Capability Stability Guarantee
To ensure long-term compatibility, once a capability is declared in the specification, it is subject to stability guarantees. It cannot be removed (only deprecated), can only be extended (new fields added, not removed), and has a deprecation period of two major versions before removal (if ever). For example, if pause_resume is introduced in v1.0, it cannot be removed in v1.x, marked deprecated in v2.0, and removed in v3.0. This prevents orchestration chains from breaking on minor version updates.
Acceptance Criteria
To solidify this solution, we propose the following acceptance criteria:
- Add a new "Capability Declaration & Discovery" section to
docs/specification.mdwith subsections covering capability tiers, declaration requirements, version negotiation, the safe discovery pattern, and multi-agent orchestration rules. - Update
a2a.protoAgentCardandAgentInterfacewith the necessary fields and comment blocks. - Create a conformance test case
tests/conformance/capability-discovery.jsonthat demonstrates capability validation and version mismatch detection. - Document in
CONTRIBUTING.md/ SDK development guide how to declare and validate agent capabilities, along with a checklist for new capability additions. - Update existing issues to include acceptance criteria related to capability declaration.
Why This Matters: The Benefits of Standardization
Without this standardization, we risk silent capability drift, broken multi-agent chains, and new features breaking old clients. SDKs would implement discovery differently, leading to a dangerous "free discovery" environment. With this, we gain explicit declarations, versioning to prevent drift, capability validation before delegation, and a normative pattern that ensures consistency. The result is a bounded discovery process with validated compatibility.
| Without This | With This |
|---|---|
| ❌ Silent capability drift | ✅ Explicit declarations; versioning prevents drift |
| ❌ Multi-agent chains break mid-task | ✅ Capability validation before delegation |
| ❌ New features break old clients | ✅ Version negotiation + deprecation path |
| ❌ SDKs implement discovery differently | ✅ Normative pattern ensures consistency |
| ❌ "Free discovery is dangerous" | ✅ Bounded discovery: validated compatibility |
Related Issues & Linked Work
This proposal is closely linked to several existing issues and ongoing work streams, including:
- Streaming: #1261 (Message streaming) — introduces the new capability
streaming_message. - Unification: #1313 (Message/Artifact) — Phase A/B roadmap references versioning.
- Agent Features: #1276 (pause_resume), #1286 (source field) — examples of declared capabilities.
- Multi-tenant: #1271 (tenant field), #1273 (multi-tenancy) — capability declaration for tenancy.
- Orchestration: #1317 (context reuse) — needs capability negotiation.
Additional Context
This proposal directly addresses the concern that "free discovery is dangerous" by implementing explicit capability declaration, version negotiation, and safe discovery patterns. These safety gates are essential for a stable and interoperable A2A ecosystem.