AI Catalog and ARD discovery

With AI Catalog and Agentic Resource Discovery (ARD), you can discover registered AGENT_CARD and MCP_TOOL artifacts by using compatible clients. Apicurio Registry publishes an AI Catalog document and provides an ARD search API in addition to its existing discovery endpoints.

AI Catalog and ARD overview

AI Catalog and Agentic Resource Discovery (ARD) are related standards for discovering agentic AI artifacts, including Agent2Agent (A2A) agent cards and Model Context Protocol (MCP) servers. A Linux Foundation working group maintains these community standards.

AI Catalog

A static JSON envelope that supports multiple artifact types, typically served at /.well-known/ai-catalog.json. Each entry identifies an artifact by its Internet Assigned Numbers Authority (IANA) media type and either links to it (url) or embeds it (data).

ARD

A discovery standard that extends AI Catalog with a domain-based identifier scheme (urn:air:<publisher>:<namespace>:<name>) and a required POST /search REST API for dynamic discovery. It also defines optional GET /agents and POST /explore endpoints. The standard path for publishing and retrieving an ARD catalog is /.well-known/ard.json.

Apicurio Registry provides a read-only view of existing AGENT_CARD and MCP_TOOL artifacts in both formats. This view requires no schema migration or additional artifact types.

AI Catalog and ARD configuration properties

AI Catalog publishing and ARD search are disabled by default. You can enable each feature independently with its configuration property.

Table 1. AI Catalog and ARD configuration properties
Property Default Description

apicurio.ai-catalog.enabled

false

Whether to enable the /.well-known/ai-catalog.json and /.well-known/ard.json endpoints

apicurio.ai-catalog.publisher-domain

Derived from request host

The <publisher> segment in urn:air: identifiers. If you do not configure this property, Apicurio Registry uses the X-Forwarded-Host header if present, otherwise the request host and port.

apicurio.ai-catalog.host-name

Apicurio Registry

Display name for this registry instance, reported as the catalog’s host.displayName

apicurio.ai-catalog.spec-version

1.0

The AI Catalog specification version reported in the catalog document

apicurio.ard.enabled

false

Whether to enable the POST /ard/search, GET /ard/agents, and POST /ard/explore endpoints

apicurio.ard.federation.default

none

Reserved for the ARD federation mode. Apicurio Registry implements only none (no federation) and does not include the value in any response. It accepts other values for compatibility with later versions, but these values do not change the behavior.

AI Catalog document endpoints

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 earlier path remains available for clients that support only AI Catalog.

GET /.well-known/ard.json

Returns the same AI Catalog document. An ARD crawler retrieves the document from this path as required by the ARD specification. A client conforms to the specification even if it retrieves only ard.json. If you can serve only one path, use this path.

Example response
{
  "specVersion": "1.0",
  "host": {
    "displayName": "Apicurio Registry",
    "identifier": "registry.example.com:8080"
  },
  "entries": [
    {
      "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."
    },
    {
      "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",
      "updatedAt": "2026-09-01T10:15:30Z",
      "tags": ["apicurio.agent.visibility=public", "department=localization"],
      "representativeQueries": [
        "Translate this paragraph into Spanish",
        "Which language is this text written in?"
      ]
    },
    {
      "identifier": "urn:air:registry.example.com:8080:ai-tools:catalog-lookup",
      "displayName": "catalog_lookup",
      "type": "application/mcp-server-card+json",
      "url": "http://registry.example.com:8080/.well-known/mcp-tools/ai-tools/catalog-lookup",
      "description": "Look up entries in the product catalog",
      "capabilities": [],
      "version": "1.0.0",
      "updatedAt": "2026-08-28T08:00:00Z"
    }
  ]
}
Artifact entries

Each entry has an identifier in the urn:air:<publisher>:<namespace>:<name> form. Entries for AGENT_CARD artifacts use application/a2a-agent-card+json. Entries for MCP_TOOL artifacts use application/mcp-server-card+json.

Registry entry

When apicurio.ard.enabled=true, the first entry in the catalog has the type application/ai-registry+json and identifies the registry. This entry points to the /.well-known/ard/search endpoint. A crawler that retrieves only the static catalog can discover the search API from this entry, as defined by the ARD specification.

Table 2. AI Catalog entry fields
Field Source

identifier

urn:air:<publisher>:<groupId>:<artifactId>. The publisher segment is the value of apicurio.ai-catalog.publisher-domain. When the property is not set, Apicurio Registry uses the X-Forwarded-Host header if present, otherwise the request host and port. Artifacts in the default group use default as the group segment.

displayName

The name field of the Agent Card, or the title and then name field of the MCP tool definition. Falls back to the artifact name.

type

application/a2a-agent-card+json for AGENT_CARD artifacts and application/mcp-server-card+json for MCP_TOOL artifacts.

url

The /.well-known/agents/ or /.well-known/mcp-tools/ endpoint that serves the artifact content.

description

The artifact description.

capabilities

The skill IDs from the Agent Card skills array. Empty for MCP tool entries.

version

The version field of the artifact content, when present.

updatedAt

The artifact modification time as an ISO-8601 instant.

tags

The artifact labels as key=value strings. Omitted when the artifact has no labels.

representativeQueries

Up to five sample queries taken from the examples arrays of the Agent Card skills. Omitted when no skill declares examples, and never set for MCP tool entries.

Artifact visibility

Apicurio Registry filters Agent Card entries by the apicurio.agent.visibility label with the same rules as /.well-known/agents. MCP tool entries have no visibility label, so Apicurio Registry always includes them. When neither OpenID Connect (OIDC) nor basic authentication is configured, Apicurio Registry applies no visibility filtering.

Authorization

Both endpoints require read-level authorization when authentication is enabled. Anonymous clients can read them only if apicurio.auth.anonymous-read-access.enabled is true. The same documents are also available at /apis/registry/v3/well-known/ai-catalog.json and /apis/registry/v3/well-known/ard.json.

ARD search API

When apicurio.ard.enabled=true, Apicurio Registry provides ARD REST search endpoints under both /.well-known/ard/ and /apis/registry/v3/well-known/ard/.

All three endpoints require read-level authorization when authentication is enabled. They apply the same visibility rules as the catalog documents.

POST /ard/search

The required ARD search endpoint accepts a query object with a required text field and an optional structured filter. The supported filter keys are type, tags, capabilities, and publisher. Apicurio Registry matches the text value against artifact names and artifact IDs as a partial match. A value without matches anywhere, and you can use as a prefix or suffix wildcard. Values within a filter key use the OR operator; different keys use the AND operator. A tags value of the form key=value matches an artifact label exactly. A value without = matches any artifact that has a label with that key. A capabilities value matches a skill ID of an Agent Card entry. A type value must match, or be a substring of, one of the two media types that Apicurio Registry emits. pageSize defaults to 10, and Apicurio Registry clamps larger values to 100. To fetch the next page, pass the pageToken value from the previous response. The last page has no pageToken.

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",
      "description": "Translates text between languages",
      "capabilities": ["translation"],
      "version": "1.0.0",
      "updatedAt": "2026-09-01T10:15:30Z",
      "tags": ["apicurio.agent.visibility=public", "department=localization"],
      "score": 100,
      "source": "http://registry.example.com:8080"
    }
  ]
}
The search returns only entries that match every requested criterion, and each result has a score of 100. The implementation does not support fuzzy or semantic ranking. It supports only federation: none semantics and accepts other federation values for compatibility with later versions without changing the behavior.
GET /ard/agents

The optional, deterministic browsing endpoint accepts a filter query parameter in the form key=value[ AND key=value]*. It supports the same filter keys and matching rules as POST /ard/search. The endpoint also accepts orderBy, pageSize, and pageToken parameters. Apicurio Registry accepts orderBy for compatibility with ARD clients, but the parameter has no effect. Apicurio Registry returns Agent Card entries before MCP tool entries and orders each group newest first. pageSize defaults to 20, and Apicurio Registry clamps larger values to 500. The endpoint returns an AI Catalog document. When more results remain, the response includes a nextPageToken value that you can use to request the next page.

Example request
curl -G "http://localhost:8080/.well-known/ard/agents" \
  --data-urlencode "filter=type=application/a2a-agent-card+json" \
  --data-urlencode "pageSize=10"
POST /ard/explore

The optional facet aggregation endpoint accepts an optional query in the same form as POST /ard/search. It requires a resultType.facets array that names the fields to aggregate. The supported fields are type and publisher. Each facet request can also set limit (the maximum number of buckets to return) and minCount (the minimum count for a bucket). Apicurio Registry sums the counts of buckets beyond limit into otherCount. The endpoint returns counts grouped by field value instead of ranked entries.

Example request
{
  "resultType": {
    "facets": [
      { "field": "type" }
    ]
  }
}
Example response
{
  "resultType": "facets",
  "facets": {
    "type": {
      "buckets": [
        { "value": "application/a2a-agent-card+json", "count": 4 },
        { "value": "application/mcp-server-card+json", "count": 2 }
      ],
      "otherCount": 0
    }
  }
}
Table 3. Error responses
Status Cause

400

One of the following conditions applies:

  • For POST /ard/search, the query.text field is missing or empty.

  • A filter key is not one of type, tags, capabilities, or publisher.

  • A type value does not match a media type that Apicurio Registry emits.

  • A GET /ard/agents filter clause is not in key=value form.

  • The pageToken value did not come from a previous response.

  • For POST /ard/explore, resultType.facets is missing or names a field other than type or publisher.

Apicurio Registry clamps out-of-range pageSize values instead of rejecting them.

401

Authentication is enabled, the request is anonymous, and apicurio.auth.anonymous-read-access.enabled is false.

404

apicurio.ard.enabled is false. The catalog documents return 404 when apicurio.ai-catalog.enabled is false.

Scope and limitations

AI Catalog and ARD provide a read-only view of existing artifacts in Apicurio Registry, which stores and governs metadata. They do not provide a runtime platform for those artifacts.

The implementation has the following limitations:

  • It does not support Trust Manifest, which is optional in the specification.

  • It searches only the local Apicurio Registry index (federation: none).

  • It does not import entries from external ai-catalog.json or ard.json documents as artifacts.

  • It returns a score of 100 for matching results without semantic relevance ranking.