A2A Protocol Features in Apicurio Registry
Apicurio Registry implements the A2A (Agent-to-Agent) protocol, enabling AI agent discovery, orchestration, and lifecycle management. This document provides comprehensive documentation of all A2A features.
Overview
The A2A protocol enables AI agents to discover and communicate with each other through standardized endpoints. Apicurio Registry serves as both:
-
An A2A Agent - Exposing its own capabilities (schema validation, search, artifact management)
-
An Agent Registry - Storing and discovering other agents' Agent Cards
┌─────────────────────────────────────────────────────────────────────────────┐
│ Apicurio Registry │
│ │
│ ┌─────────────────────┐ ┌──────────────────────────────────────┐ │
│ │ Registry as Agent │ │ Agent Card Registry │ │
│ │ │ │ │ │
│ │ /.well-known/ │ │ /.well-known/agents │ │
│ │ agent.json │ │ /.well-known/agents/{group}/{id} │ │
│ │ │ │ │ │
│ │ Skills: │ │ - Store agent cards │ │
│ │ - schema-validation│ │ - Search by skill │ │
│ │ - schema-search │ │ - Filter by capability │ │
│ │ - artifact-mgmt │ │ - Version management │ │
│ │ - compatibility │ │ - Compatibility checking │ │
│ │ - agent-discovery │ │ │ │
│ └─────────────────────┘ └──────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
Configuration
A2A features are controlled via configuration properties:
| Property | Default | Description |
|---|---|---|
|
|
Enable/disable A2A protocol support |
|
|
Name of the registry as an A2A agent |
|
varies |
Description of the registry agent |
|
app version |
Agent version (defaults to application version) |
|
base URL |
Base URL for A2A endpoint |
|
|
Provider organization name |
|
Provider organization URL |
|
|
|
Whether streaming is supported |
|
|
Whether push notifications are supported |
Well-Known Endpoints
GET /.well-known/agent.json
Returns the Agent Card for the Apicurio Registry instance itself.
Response: Agent Card JSON document
{
"name": "Apicurio Registry",
"description": "Central registry for AI agents and schemas",
"version": "3.1.0",
"url": "http://localhost:8080",
"provider": {
"organization": "Apicurio",
"url": "https://www.apicur.io"
},
"skills": [
{
"id": "schema-validation",
"name": "Schema Validation",
"description": "Validate schemas against format specifications"
},
{
"id": "schema-search",
"name": "Schema Search",
"description": "Search for schemas and APIs in the registry"
}
],
"capabilities": {
"streaming": false,
"pushNotifications": false
},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"]
}
GET /.well-known/agents
Search for registered Agent Cards with filtering support.
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
|
string |
Filter by agent name (partial match) |
|
string (repeatable) |
Filter by skill ID |
|
string |
Filter by capability (e.g., |
|
string |
Filter by input mode (e.g., |
|
string |
Filter by output mode |
|
integer |
Pagination offset (default: 0) |
|
integer |
Pagination limit (default: 20) |
Example Request:
curl "http://localhost:8080/.well-known/agents?skill=translation&capability=streaming:true"
Response: AgentSearchResults
{
"count": 2,
"agents": [
{
"groupId": "ai-agents",
"artifactId": "translator-agent",
"name": "Translation Agent",
"description": "Translates text between languages",
"version": "1.0.0",
"url": "http://translator:9001",
"skills": [{"id": "translation", "name": "Translation"}],
"capabilities": {"streaming": true}
}
]
}
GET /.well-known/agents/{groupId}/{artifactId}
Retrieve a specific registered Agent Card.
Path Parameters:
- groupId - The group containing the agent card
- artifactId - The artifact ID of the agent card
Query Parameters:
- version (optional) - Specific version (defaults to latest)
Response: Agent Card JSON document
Agent Card Artifact Type
Agent Cards are stored as artifacts with type AGENT_CARD.
Creating an Agent Card
curl -X POST "http://localhost:8080/apis/registry/v3/groups/ai-agents/artifacts" \
-H "Content-Type: application/json" \
-d '{
"artifactId": "my-agent",
"artifactType": "AGENT_CARD",
"firstVersion": {
"version": "1.0.0",
"content": {
"contentType": "application/json",
"content": "{\"name\": \"My Agent\", \"skills\": [{\"id\": \"task\", \"name\": \"Task Execution\"}]}"
}
}
}'
Agent Card JSON Schema
Agent Cards must conform to the A2A specification:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string"},
"description": {"type": "string"},
"version": {"type": "string"},
"url": {"type": "string", "format": "uri"},
"provider": {
"type": "object",
"properties": {
"organization": {"type": "string"},
"url": {"type": "string", "format": "uri"}
}
},
"capabilities": {
"type": "object",
"properties": {
"streaming": {"type": "boolean"},
"pushNotifications": {"type": "boolean"}
}
},
"skills": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {"type": "string"},
"name": {"type": "string"},
"description": {"type": "string"},
"tags": {"type": "array", "items": {"type": "string"}},
"examples": {"type": "array", "items": {"type": "string"}}
}
}
},
"defaultInputModes": {"type": "array", "items": {"type": "string"}},
"defaultOutputModes": {"type": "array", "items": {"type": "string"}},
"authentication": {
"type": "object",
"properties": {
"schemes": {"type": "array", "items": {"type": "string"}}
}
}
}
}
Validation Rules
Agent Cards support three validation levels:
| Level | Description |
|---|---|
|
No validation performed |
|
Validates JSON syntax only |
|
Complete schema validation including:
- Required |
Compatibility Checking
When versioning Agent Cards, compatibility rules are enforced:
Compatible Changes (allowed): - Adding new skills - Adding new capabilities - Adding authentication schemes - Adding input/output modes
Incompatible Changes (may break clients): - Removing skills - Removing or disabling capabilities - Changing the agent URL - Removing authentication schemes - Removing input/output modes
Automatic Label Extraction
When Agent Cards are stored, labels are automatically extracted for search:
| Label Pattern | Source |
|---|---|
|
Each skill ID in the skills array |
|
Enabled capabilities (streaming, pushNotifications) |
|
Each input mode |
|
Each output mode |
|
Agent name |
|
Agent URL |
This enables efficient capability-based discovery using the Registry’s label search.
Registry Built-in Skills
Apicurio Registry exposes itself as an A2A agent with these skills:
| Skill ID | Description |
|---|---|
|
Validate schemas against format specifications (Avro, JSON Schema, Protobuf, OpenAPI, AsyncAPI, GraphQL, WSDL, XSD) |
|
Search for schemas and APIs in the registry by name, labels, or content |
|
Create, update, and manage schema artifacts with full versioning |
|
Check schema compatibility between versions using configurable rules |
|
Discover and manage A2A agent cards stored in the registry |
LLM Lifecycle Management
The A2A integration extends to full LLM lifecycle management with additional artifact types:
MODEL_SCHEMA
Defines input/output schemas for LLM agents:
{
"$schema": "https://apicurio.io/schemas/model-schema/v1",
"modelId": "sentiment-analysis-output",
"provider": "a2a-demo",
"version": "1.0.0",
"output": {
"type": "object",
"required": ["sentiment", "confidence"],
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"confidence": {"type": "number", "minimum": 0, "maximum": 1}
}
}
}
PROMPT_TEMPLATE
Stores versioned prompt templates with variable support:
templateId: sentiment-analysis
name: Sentiment Analysis Prompt
version: "1.0.0"
template: |
Analyze the sentiment of the following message:
MESSAGE: {{customerMessage}}
Respond with JSON containing sentiment and confidence.
variables:
customerMessage:
type: string
required: true
description: The message to analyze
metadata:
outputSchema: urn:apicurio:llm-agents.schemas/sentiment-output
Linking Artifacts
Agent Cards can reference their schemas and prompts using URN references:
{
"name": "Sentiment Agent",
"skills": [
{
"id": "sentiment-analysis",
"name": "Sentiment Analysis",
"outputSchema": "urn:apicurio:llm-agents.schemas/sentiment-agent-output",
"promptTemplate": "urn:apicurio:llm-agents.prompts/sentiment-agent-prompt"
}
]
}
Example: Multi-Agent Workflow
The examples/a2a-real-world-integration demonstrates context chaining:
Customer Message
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Step 1: Sentiment Agent │
│ Input: {{original}} │
│ Output: {"sentiment": "very_negative", "urgency": "critical"} │
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Step 2: Issue Analyzer │
│ Input: {{original}} + {{sentiment}} │
│ Output: {"priority": "P1", "issue_type": "delayed_delivery"} │
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Step 3: Response Generator │
│ Input: {{original}} + {{sentiment}} + {{analysis}} │
│ Output: {"response": "Dear customer, I sincerely apologize..."} │
└──────────────────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────────────────────────────────────────────────────────┐
│ Step 4: Translation Agent │
│ Input: {{response}} │
│ Output: {"translated": "Estimado cliente, le pido disculpas..."} │
└──────────────────────────────────────────────────────────────────────────┘
Running the Example
cd examples/a2a-real-world-integration
docker-compose up -d
mvn clean compile exec:java
Access the Web UI at http://localhost:9000.
Java SDK Usage
Discovering Agents
RegistryClient client = RegistryClientFactory.create(
RegistryClientOptions.create("http://localhost:8080/apis/registry/v3"));
// Search for agents with specific skill
var agents = client.wellKnown().agents()
.get(config -> {
config.queryParameters.skill = List.of("translation");
config.queryParameters.limit = 10;
});
for (var agent : agents.getAgents()) {
System.out.println("Found: " + agent.getName() + " @ " + agent.getUrl());
}
Registering an Agent Card
CreateArtifact artifact = new CreateArtifact();
artifact.setArtifactId("my-agent");
artifact.setArtifactType("AGENT_CARD");
CreateVersion version = new CreateVersion();
version.setVersion("1.0.0");
VersionContent content = new VersionContent();
content.setContentType("application/json");
content.setContent(agentCardJson);
version.setContent(content);
artifact.setFirstVersion(version);
client.groups().byGroupId("ai-agents").artifacts()
.post(artifact, config -> {
config.queryParameters.ifExists = IfArtifactExists.FIND_OR_CREATE_VERSION;
});
REST API Reference
Core A2A Endpoints
| Endpoint | Method | Description |
|---|---|---|
|
GET |
Get registry’s own Agent Card |
|
GET |
Search registered Agent Cards |
|
GET |
Get specific Agent Card by artifact ID |
|
POST |
Create Agent Card artifact (type: AGENT_CARD) |
|
GET |
Get Agent Card artifact metadata |
|
GET |
Get Agent Card content |
