AI Catalog and ARD discovery
Apicurio Registry can publish a spec-compliant AI Catalog document and expose the ARD (Agentic Resource Discovery) search API, so registered AGENT_CARD and MCP_TOOL artifacts are discoverable by any AI Catalog- or ARD-aware client, not just Apicurio Registry’s own well-known endpoints.
AI Catalog and ARD overview
AI Catalog and ARD are two related, community-driven discovery standards for agentic AI artifacts (A2A agent cards, MCP servers, and others), maintained by a Linux Foundation working group.
- AI Catalog
-
A static, artifact-agnostic JSON envelope, typically served at
/.well-known/ai-catalog.json. It lists entries that identify an artifact by IANA media type and either link to it (url) or embed it (data). - ARD
-
Builds on AI Catalog by adding a domain-anchored identifier scheme (
urn:air:<publisher>:<namespace>:<name>), a mandatoryPOST /searchREST API for dynamic discovery, and optionalGET /agentsandPOST /exploreendpoints. ARD’s normative publish/consume path is/.well-known/ard.json.
Apicurio Registry projects its existing AGENT_CARD and MCP_TOOL artifacts into both formats as a read-only view over existing storage — no schema migration, no new artifact types.
AI Catalog and ARD configuration properties
Both features are disabled by default and independently feature-gated.
| Property | Default | Description |
|---|---|---|
|
|
Enable the |
|
derived from request host |
The |
|
|
Display name for this registry instance, reported as the catalog’s |
|
|
The AI Catalog specification version reported in the catalog document |
|
|
Enable the |
|
|
Default ARD federation mode advertised by this registry. Only |
AI Catalog publishing
When apicurio.ai-catalog.enabled=true, Apicurio Registry serves an AI Catalog document at two equivalent paths.
- GET /.well-known/ai-catalog.json
-
Returns the AI Catalog document. This is the predecessor path, retained for AI-Catalog-only consumers.
- GET /.well-known/ard.json
-
Returns the identical document. This is the path a strictly-conformant ARD crawler resolves per the ARD specification; a consumer that only fetches
ard.jsonis fully conformant, so publish here if you can serve only one path.
{
"specVersion": "1.0",
"host": {
"displayName": "Apicurio Registry",
"identifier": "registry.example.com:8080"
},
"entries": [
{
"identifier": "urn:air:registry.example.com:8080:ai-agents:translator-agent",
"displayName": "Translation Agent",
"type": "application/a2a-agent-card+json",
"url": "http://registry.example.com:8080/.well-known/agents/ai-agents/translator-agent",
"description": "Translates text between languages",
"capabilities": ["translation"],
"version": "1.0.0"
},
{
"identifier": "urn:air:registry.example.com:8080:system:registry",
"displayName": "Apicurio Registry",
"type": "application/ai-registry+json",
"url": "http://registry.example.com:8080/.well-known/ard/search",
"description": "ARD search API for this registry."
}
]
}
Every entry’s identifier follows the urn:air:<publisher>:<namespace>:<name> form. Entries backed by AGENT_CARD artifacts use application/a2a-agent-card+json; entries backed by MCP_TOOL artifacts use application/mcp-server-card+json. When apicurio.ard.enabled=true, the catalog also includes a self-describing entry of type application/ai-registry+json pointing at this registry’s own /.well-known/ard/search endpoint, so a crawler that only ingests the static catalog can still discover the live search API, per the ARD specification.
Only artifacts visible under the caller’s visibility (public/entitled/private, the same model used by /.well-known/agents) are included.
ARD search API
When apicurio.ard.enabled=true, Apicurio Registry exposes the ARD REST search surface, mirrored under both /.well-known/ard/ and /apis/registry/v3/well-known/ard/.
- POST /ard/search
-
The ARD-mandated search endpoint. Accepts a
queryobject with a requiredtextfield and an optional structuredfilter(supported keys:type,tags,capabilities,publisher). Values within a filter key are OR-ed together; different keys are AND-ed.Example request{ "query": { "text": "translation", "filter": { "type": ["application/a2a-agent-card+json"] } }, "pageSize": 10 }Example response{ "results": [ { "identifier": "urn:air:registry.example.com:8080:ai-agents:translator-agent", "displayName": "Translation Agent", "type": "application/a2a-agent-card+json", "url": "http://registry.example.com:8080/.well-known/agents/ai-agents/translator-agent", "score": 100, "source": "http://registry.example.com:8080" } ], "pageToken": null }Because only entries satisfying every requested criterion are returned at all, every result’s scoreis a deterministic100in this release — there is no fuzzy or semantic ranking yet. Onlyfederation: nonesemantics are implemented; otherfederationvalues are accepted for forward compatibility but do not change behavior. - GET /ard/agents
-
Optional, deterministic browsing endpoint. Accepts a
filterquery parameter using the formkey=value[ AND key=value]*(supported keys:type,tags,capabilities,publisher), plusorderBy,pageSize, andpageToken. Returns an AI Catalog document; when more results remain,nextPageTokenis populated so you can request the next page.Example requestcurl -G "http://localhost:8080/.well-known/ard/agents" \ --data-urlencode "filter=type=application/a2a-agent-card+json" \ --data-urlencode "pageSize=10" - POST /ard/explore
-
Optional facet-aggregation endpoint. Accepts the same
queryasPOST /searchplus a requiredresultType.facetsarray naming the fields to aggregate (supported:type,publisher). Returns bucketed counts, not ranked entries.Example request{ "resultType": { "facets": [ { "field": "type" } ] } }
Scope and limitations
This implementation is a read-only projection over existing artifacts, consistent with Apicurio Registry’s role as a metadata store and governance tool, not a runtime platform.
-
No Trust Manifest support (optional in the specification; not yet implemented).
-
No federation — Apicurio Registry always searches only its own index (
federation: none). -
No catalog importer — Apicurio Registry does not crawl external
ai-catalog.json/ard.jsondocuments to register their entries as artifacts. -
Relevance ranking is not yet semantic;
scoreis always100for matching results. Full-text search (tracked separately) is expected to enable real relevance scoring in a future release.
