# Agentic Resource Discovery

> An open, federated specification for publishing, discovering, and cryptographically verifying AI capabilities across organizational and network boundaries.

- **Category**: 

- **Canonical URL**: https://designpattern.fyi/ard/

---

## Description
An open, federated specification for publishing, discovering, and cryptographically verifying AI capabilities across organizational and network boundaries.








## Additional Notes

**Origin:** Agentic Resource Discovery (ARD) was announced by Google on June 17, 2026 and developed with partners across the industry including Microsoft, Hugging Face, GitHub, Cisco, Salesforce, NVIDIA, Databricks, and more. Licensed Apache 2.0. Source: [`agenticresourcediscovery.org/spec`](https://agenticresourcediscovery.org/spec/) and [`github.com/ards-project/ard-spec`](https://github.com/ards-project/ard-spec).

**Problem:** Today, an agent that needs a capability must have it **pre-installed** or **hardcoded**. This mirrors the early mobile app paradigm: you had to know a tool existed, manually install it, and keep it updated. As the ecosystem scales to thousands or millions of agents, this approach breaks in three ways:

1. **Discovery across organizations** — There is no standard way for an agent to ask "what capability should I use for X?" across teams, organizations, or cloud providers.
2. **Context window saturation** — Agents currently select tools by stuffing all tool descriptions into their context window. At scale (thousands of tools), this does not fit. You cannot inject 10,000 MCP server descriptions into an LLM prompt.
3. **Trust and identity** — Even if an agent finds a capability, there is no standard mechanism to confirm it is connecting to a legitimate, uncompromised endpoint — not an impersonator or a compromised mirror.

**Solution:** **Agentic Resource Discovery (ARD)** — an open, federated specification for publishing, discovering, and cryptographically verifying AI capabilities — including MCP servers, A2A agents, skills, APIs, and other callable services — across organizational and network boundaries.

Think of it as:
- **DNS for AI agents** — a standard naming and lookup infrastructure
- **`robots.txt` for AI capabilities** — a well-known, crawlable declaration format
- **A search engine for tools** — an indexed, queryable registry system

ARD answers all three questions:
- **Where does the right capability live?** → Catalogs + Registries
- **Which capability should I actually use?** → Semantic search + scoring
- **How do I verify it is safe to connect to?** → Trust manifest + cryptographic attestation

---

## Core Concepts: Catalogs and Registries

ARD architecture rests on two primitives:

### Catalogs

A **catalog** is a static JSON manifest file — `ai-catalog.json` — hosted on an organization's own domain at a well-known path. It advertises the AI capabilities that organization makes available.

Because the catalog is hosted at the organization's own domain (e.g., `https://acme.com/.well-known/ai-catalog.json`), **domain ownership becomes the cryptographic foundation for identity and trust**. If you control `acme.com`, your catalog is authoritative for all capabilities under `urn:ai:acme.com:...`.

### Registries

A **registry** is a searchable, dynamic service that crawls published catalogs, indexes their entries, and exposes a REST search API for agents to query. Registries are the "search engines" of the agentic web.

When an agent submits a discovery request (e.g., *"find me a flight booking agent"*), a registry:

1. Runs semantic search over its indexed entries
2. Returns matching capabilities with relevance scores
3. Includes verifiable trust metadata so the agent can authenticate before connecting
4. Optionally refers the agent to other registries for broader coverage

Registries do **not** proxy the actual tool calls. They are purely a discovery and trust layer. Once the agent has found and verified a capability, it connects directly using the native protocol (MCP, A2A, OpenAPI, etc.).

```
┌─────────────────────────────────────────────────┐
│                   AGENT / ORCHESTRATOR           │
│                                                  │
│  1. Query registry  ──────────────────────────►  │
│  4. Connect directly to tool via native protocol │
└────────────────┬────────────────────────────────┘
                 │
         ┌───────▼────────┐
         │   REGISTRY     │  (indexes & searches catalogs)
         └───────┬────────┘
                 │ crawls
    ┌────────────▼──────────────────┐
    │  domain.com/.well-known/      │
    │  ai-catalog.json  (CATALOG)   │  (hosted by capability provider)
    └───────────────────────────────┘
```

---

## The Six Design Principles

ARD is governed by six explicit design principles:

### Search-First Discovery

Instead of requiring pre-installation of agents (the "app store" model), ARD promotes dynamic discovery at runtime. Registries maintain continuously updated indexes. The moment a capability is published, it becomes discoverable.

### Scalability Beyond Context Windows

Traditional tool selection injects all descriptions into the LLM's context window. ARD moves the selection problem *outside* the LLM into a dedicated search service. Information retrieval techniques scale to millions of capabilities without consuming context tokens.

### Artifact-Agnostic Envelope

ARD does not define or constrain the internal schema of MCP servers, A2A agents, or any other type. It acts as a clean *envelope*. A `type` field (formatted as an IANA Media Type) identifies what an artifact is; the protocol-specific schema lives inside the artifact's own spec. This keeps ARD future-proof.

### Strict Value-or-Reference

Every catalog entry must contain **exactly one** of two mutually exclusive keys for content delivery:

- `url` — a remote URL pointing to the full artifact document
- `data` — the artifact document embedded inline as a JSON object

This prevents ambiguity in parsing and ensures predictable behavior in enterprise environments.

### Universal Baseline for Federation

Registries **MUST** expose a standard HTTP REST interface for search. This guarantees that any system can participate in discovery regardless of its execution stack. Federation between registries becomes simple HTTP calls.

### Separation of Concerns

ARD cleanly separates three responsibilities:

- **Authentication** — delegated to the artifact's native protocol (e.g., OAuth for an API, mTLS for MCP)
- **Identity/Trust verification** — handled by the `trustManifest` layer
- **Physical distribution** — left to infrastructure (OCI, npm, S3, etc.)

---

## The Data Model — `ai-catalog.json`

### Top-Level Structure

The manifest lives at `/.well-known/ai-catalog.json` on the publisher's domain.

```json
{
  "specVersion": "1.0",
  "host": {
    "displayName": "Acme Enterprise AI",
    "identifier": "did:web:acme.com"
  },
  "entries": [
    { /* ... catalog entry ... */ }
  ]
}
```

**Top-level fields:**

| Field | Required | Description |
|---|---|---|
| `specVersion` | Yes | Always `"1.0"` for this version |
| `host` | Yes | Describes the operator of this catalog |
| `entries` | Yes | Array of capability entries |

**`host` object fields:**

| Field | Required | Description |
|---|---|---|
| `displayName` | Yes | Human-readable name of the publisher |
| `identifier` | No | Verifiable identifier (DID or domain) |
| `documentationUrl` | No | Link to documentation |
| `logoUrl` | No | Link to a logo image |
| `trustManifest` | No | Trust metadata for the publisher itself |

### Catalog Entry Object

Each entry in the `entries` array describes one AI capability.

**Required fields:**

| Field | Type | Description |
|---|---|---|
| `identifier` | String | Globally unique URN: `urn:ai:<publisher>:<namespace>:<agent-name>` |
| `displayName` | String | Human-readable name |
| `type` | String | IANA media type of the artifact |

**Exactly one of:**

| Field | Type | Description |
|---|---|---|
| `url` | String | Remote URL of the full artifact document |
| `data` | Object | Inline embedded artifact document |

**Optional fields:**

| Field | Type | Description |
|---|---|---|
| `description` | String | Short description of the capability |
| `tags` | Array | Keywords for filtering |
| `capabilities` | Array | Specific skill/tool names (e.g., `["WeatherTool"]`) |
| `representativeQueries` | Array | 2–5 natural language example queries for semantic search |
| `version` | String | Artifact version string |
| `updatedAt` | String | ISO 8601 timestamp |
| `metadata` | Map | Custom key-value pairs |
| `trustManifest` | Object | Verifiable identity and trust metadata |

### The URN Identifier Format

The `identifier` field follows a mandatory domain-anchored URN format per IETF RFC 8141:

```
urn:ai:<publisher>:<namespace>:<agent-name>
```

**Breaking down each segment:**

```
urn        →  Mandatory RFC 8141 prefix
ai         →  Namespace Identifier (NID) for the AI ecosystem
acme.com   →  <publisher>: a fully qualified domain name (FQDN) — the trust anchor
travel     →  <namespace>: optional hierarchical category (dept, team, product line)
concierge  →  <agent-name>: the specific logical name of this capability
```

**Example:**

```
urn:ai:acme.com:travel:concierge
urn:ai:github.com:alice-dev:pptx-creator
urn:ai:hf.co:alice-dev:weather-agent
```

**Why this format?** Five architectural reasons:

1. **Nomenclature stability** — A URN is a permanent "noun" for the capability, decoupled from its physical location. If Acme migrates to a new API gateway, the URL in `url` changes but `urn:ai:acme.com:travel:concierge` stays stable forever.

2. **Separation of concerns** — Discovery registries index the URN as a stable key. Security meshes use the `trustManifest.identity` (a SPIFFE ID or DID) for runtime authentication. These are separate systems that must not be conflated.

3. **Decentralized trust binding** — Registries programmatically extract the domain from the URN (`acme.com`) and cross-reference it against the cryptographic claim in `trustManifest.identity`. No central naming committee required.

4. **Search ergonomics** — Structured hierarchy enables deterministic parsing. An LLM query for "the Acme travel agent" maps cleanly to publisher `acme.com` + namespace `travel`.

5. **Cross-network uniqueness** — Domain names are globally unique via DNS, so URNs anchored to domains are collision-free when merging catalogs across federated registries.

### Supported Artifact Types

The `type` field uses IANA media type format. Current de-facto community types:

| Type | Description |
|---|---|
| `application/mcp-server+json` | Model Context Protocol server |
| `application/a2a-agent-card+json` | Google A2A agent card |
| `application/ai-catalog+json` | A nested ARD catalog (for bundles or sub-catalogs) |
| `application/ai-registry+json` | An ARD registry endpoint |
| `application/ai-skill` | A callable skill or function |
| `application/ai-skill+md` | A skill defined as a markdown document |
| `application/parquet` | A data artifact (e.g., market dataset) |

> **Note:** `application/a2a-agent-card+json` and `application/mcp-server+json` are de-facto community standards tracking towards formal IANA registration. Implementations should not perform strict type verification by intermediaries until registration is complete.

---

## Identity, Trust, and the `trustManifest`

ARD separates the **discovery identifier** (the URN, used for indexing) from the **cryptographic identity** (used for runtime authentication). The `trustManifest` object bridges them.

### The Trust Manifest Object

```json
"trustManifest": {
  "identity": "spiffe://acme.com/travel/concierge",  // Required
  "identityType": "spiffe",                           // Optional type hint
  "attestations": [ /* ... */ ],                     // Optional compliance proofs
  "provenance": [ /* ... */ ],                       // Optional lineage
  "signature": "eyJhbGci..."                         // Optional JWS signature
}
```

| Field | Required | Description |
|---|---|---|
| `identity` | Yes | Cryptographic workload identifier (SPIFFE ID, DID, or HTTPS FQDN URI). The trust domain in this identity MUST align with the `<publisher>` domain in the URN. |
| `identityType` | No | Type hint: `"did"`, `"spiffe"`, or `"https"` |
| `attestations` | No | Array of verifiable compliance claims |
| `provenance` | No | Array of lineage records |
| `signature` | No | Detached JWS signature over the trust manifest content |

### Attestation Object

Attestations provide cryptographically verifiable proof of compliance claims.

```json
{
  "type": "SOC2-Type2",
  "uri": "https://trust.acme.com/reports/soc2.pdf",
  "digest": "sha256:abc123..."  // Optional hash for integrity
}
```

| Field | Required | Description |
|---|---|---|
| `type` | Yes | Claim type: `"SOC2-Type2"`, `"HIPAA-Audit"`, `"GDPR"`, `"SPIFFE-X509"`, etc. |
| `uri` | Yes | URL of the attestation document |
| `digest` | No | Cryptographic hash for integrity verification |

### Trust Verification Flow

```
1. Agent fetches entry from registry
        │
        ▼
2. Agent extracts <publisher> from URN identifier
   (e.g., "acme.com" from "urn:ai:acme.com:travel:concierge")
        │
        ▼
3. Agent reads trustManifest.identity
   (e.g., "spiffe://acme.com/travel/concierge")
        │
        ▼
4. Agent verifies the trust domain in the identity
   matches the publisher domain in the URN
        │
        ▼
5. Agent fetches and validates attestation documents
   (e.g., checks SOC2 report URI, SPIFFE JWKS endpoint)
        │
        ▼
6. Agent establishes direct connection using native protocol
   (the trustManifest hands off; ARD steps out of the way)
```

> **Important:** The relevance `score` in search results (0–100) reflects only semantic relevance. It MUST NOT be interpreted as a trust, compliance, or safety rating. Trust evaluation is fully decoupled and handled entirely through `trustManifest` verification.

---

## Discovery Mechanisms

ARD defines four ways a capability can be found:

### Method 1: Well-Known URI (Primary)

Host the manifest at the standard path. This is the default and most widely supported method.

```
https://<your-domain>/.well-known/ai-catalog.json
```

### Method 2: Agentmap Directive in `robots.txt`

Add a line to your existing `robots.txt` pointing to a non-standard location:

```
Agentmap: https://example.com/path/to/catalog.json
```

### Method 3: HTML `<link>` Tag

Include a link tag in the `<head>` of your website's HTML:

```html
<link rel="ai-catalog" href="https://example.com/ai-catalog.json">
```

### Method 4: DNS Records

Publish DNS records for discovery when you cannot modify the web server.

**For a static catalog (TXT record):**

```
Name:  _catalog._agents.yourdomain.com
Type:  TXT
Value: "url=https://custom-bucket.s3.amazonaws.com/ai-catalog.json"
```

**For a dynamic registry search endpoint (SRV record):**

```
Name:    _search._agents.yourdomain.com
Type:    SRV
Port:    443
Target:  search.yourdomain.com
```

---

## The ARD REST API

An ARD registry MUST expose a standard HTTP REST interface. The base URL is discovered by finding catalog entries with type `application/ai-registry+json` in the `ai-catalog.json` manifest.

### The Query Model

The `POST /search` and `POST /explore` endpoints both accept a shared `query` object:

```json
{
  "query": {
    "text": "find me a flight booking agent",
    "filter": {
      "type": ["application/a2a-agent-card+json"],
      "tags": ["travel"],
      "trustManifest.attestations.type": ["SOC2-Type2"]
    }
  }
}
```

| Field | Description |
|---|---|
| `text` | Natural language intent. Enables semantic relevance ranking. |
| `filter` | Structured key-value constraints. Keys are dot-separated field paths into the catalog entry schema. |

**Filter logic:** `text` and `filter` compose with AND. Within a single filter key, multiple values compose with OR. Across keys, all constraints compose with AND.

### `POST /search` — Semantic Search (Required)

Returns catalog entries ranked by relevance to a natural language query. `text` is required; `filter` is optional.

**Request:**

```json
{
  "query": {
    "text": "find me a flight booking agent",
    "filter": {
      "type": ["application/a2a-agent-card+json"]
    }
  },
  "federation": "referrals",
  "pageSize": 5
}
```

**Additional parameters beyond `query`:**

| Field | Default | Description |
|---|---|---|
| `federation` | `"auto"` | Federation mode: `"auto"`, `"referrals"`, or `"none"` |
| `pageSize` | `10` | Max results per page (max: 100) |
| `pageToken` | — | Pagination token for subsequent pages |

**Response:**

```json
{
  "results": [
    {
      "identifier": "urn:ai:acme.com:agent:assistant",
      "displayName": "Corporate Assistant (A2A)",
      "type": "application/a2a-agent-card+json",
      "url": "https://api.acme.com/agents/assistant.json",
      "score": 95,
      "source": "https://registry.acme.com/api/v1/"
    }
  ],
  "referrals": [
    {
      "identifier": "urn:ai:nlweb.ai:registry:public",
      "displayName": "Public Agent Finder",
      "type": "application/ai-registry",
      "url": "https://finder.nlweb.ai/search"
    }
  ],
  "pageToken": "eyJwYWdlIjogMn0="
}
```

---

## Federation — Connecting Registries

Federation is how individual registries form a global network. Because the REST API is mandated, registry-to-registry routing is a simple HTTP operation.

The client controls federation via the `federation` parameter on `POST /search`:

| Mode | Behavior |
|---|---|
| `"auto"` | Registry queries upstream registries automatically, merges results, returns unified response. Client sees one result set. |
| `"referrals"` | Registry returns its own results plus catalog entries for other registries the client may query. Client decides which referrals to follow. |
| `"none"` | Registry searches only its own index. No upstream queries. |

---

## Quick Reference

**Publish your first catalog:**

1. Create `ai-catalog.json` with your capability entries
2. Host at `https://yourdomain.com/.well-known/ai-catalog.json`
3. Configure CORS headers: `Access-Control-Allow-Origin: *`
4. Verify with `curl -I https://yourdomain.com/.well-known/ai-catalog.json`
5. (Optional) Add `Agentmap` directive to `robots.txt`
6. (Optional) Register with a public ARD registry

**Query an ARD registry:**

```bash
curl -X POST https://api.registry-provider.com/v1/search \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "text": "find me a flight booking agent"
    },
    "pageSize": 5
  }'
```

**Add trust metadata:**

```json
"trustManifest": {
  "identity": "spiffe://acme.com/travel/concierge",
  "identityType": "spiffe",
  "attestations": [
    {
      "type": "SOC2-Type2",
      "uri": "https://trust.acme.com/reports/soc2.pdf"
    }
  ]
}
```

**References:**

| Resource | URL |
|---|---|
| Specification | https://agenticresourcediscovery.org/spec/ |
| GitHub Repository | https://github.com/ards-project/ard-spec |
| How to Publish | https://agenticresourcediscovery.org/how_to_publish/ |
| Google Cloud Implementation | https://docs.cloud.google.com/agent-registry/overview |
| Registries | GitHub's Agent Finder (https://github.com/agentfinder) and Hugging Face's Discover (https://github.com/huggingface/hf-discover), Directory of Agentic Services (https://dir.agntcy.org)



