Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions adr/0016-displayname-optional.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# ADR-0016: displayName Is Optional on a Catalog Entry

## Status
Proposed
Accepted

## Date
2026-06-18 (Proposed)
2026-06-18

## Context
A Catalog Entry is a thin pointer: it carries an `identifier`, a `mediaType`, and exactly one of `url` or `data` locating the full artifact. `displayName` (a human-readable name for the artifact) is a REQUIRED member of every Catalog Entry, and is listed among the required-at-minimum members of a Minimal Catalog (Level 1).
Expand Down Expand Up @@ -42,4 +42,4 @@ This decision concerns only the Catalog Entry. `displayName` on `HostInfo` and `
An MCP Server Card's `title` is itself OPTIONAL. The guidance above is keyed on whether the artifact *carries a canonical name*, not on its media type: if a referenced Server Card omits `title`, the entry SHOULD keep `displayName` so the artifact is not left with only a reverse-DNS identifier and a prose description.

## Meeting Reference
Slated for discussion at the 2026-06-18 AI Catalog bi-weekly working-group call; this ADR records the proposal ahead of that discussion. Update the Status and Date (and note who raised concerns and the agreed outcome, as in ADR-0011) once the working group ratifies it.
Ratified at the 2026-06-18 AI Catalog bi-weekly working-group call: `displayName` was made OPTIONAL on the Catalog Entry as proposed. Removing the field entirely was considered and rejected so that opaque, self-nameless artifacts retain a place for a human-readable name.
71 changes: 71 additions & 0 deletions adr/0018-entry-field-authoritative-source-parity.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# ADR-0018: `description` and `version` Follow `displayName`'s Authoritative-Source Rule

## Status
Proposed

## Date
2026-07-02 (Proposed)

## Context
[ADR-0016](0016-displayname-optional.md) made the Catalog Entry `displayName` OPTIONAL and gave it a precise "authoritative-source" rule: a publisher SHOULD set `displayName` only when the referenced artifact does not already carry its own canonical human-readable name; when the artifact does carry one (an A2A Agent Card `name`, an MCP Server Card `title`), that artifact is the authoritative source and `displayName` SHOULD be omitted to avoid a value that drifts out of sync; and when `displayName` *is* present it takes precedence for display. A companion [Resolving an Artifact's Display Name](../specification/ai-catalog.md#resolving-an-artifacts-display-name) section defines the consumer resolution order.

`displayName` is not the only Catalog Entry member that can restate a value the referenced artifact already carries. Two others do, and today they are documented as plain optional fields with no equivalent guidance:

- **`description`** — a short prose description of the artifact. An **A2A Agent Card carries a REQUIRED `description`**, and an **MCP Server Card carries a `description`** (optional in [SEP-2127](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2127), where only `name` and `version` are required). When the referenced artifact does carry a description, an entry that copies it restates a value that lives, canonically, in the document the consumer is about to fetch.
- **`version`** — the artifact's version. An **A2A Agent Card carries a REQUIRED `version`**, an **MCP Server Card carries a `version`**, and an MCP Registry `server.json` carries a `version`.

This is incoherent at the field-definition level: the `displayName` field description tells a publisher to omit it when the Server Card already carries a `title`, while the `description` and `version` field descriptions — which have the *same* duplication-and-drift problem against the *same* Server Card — give no such steer. (The MCP mapping appendix already applies the omit-to-avoid-drift rule to `description` and `version` as part of the Server Card mapping, which makes the gap in the field descriptions themselves the remaining inconsistency.) A publisher reading the field list has no reason to treat them differently, so entries end up carrying a copied `description`/`version` that silently drifts from the artifact.

Not every Catalog Entry member has this problem, and the rule should be applied only where it holds (see [Scope](#scope-fields-in-and-out) below).

## Decision
Extend the `displayName` authoritative-source rule (ADR-0016) to the other Catalog Entry members that duplicate a value the referenced artifact carries canonically: **`description`** and **`version`**.

**`description`.** A publisher SHOULD set entry `description` only when the referenced artifact does not already carry its own canonical description. When the artifact does carry one (an A2A Agent Card `description`, an MCP Server Card `description`), that artifact is the authoritative source and entry `description` SHOULD be omitted to avoid duplicating a value that can drift out of sync. When entry `description` *is* present it takes precedence for display: a consumer SHOULD render it as given even when it differs from the artifact's description — this is how a publisher deliberately provides a listing-specific blurb. A new "Resolving an Artifact's Description" section records the consumer resolution order, mirroring "Resolving an Artifact's Display Name".

**`version`.** A publisher SHOULD set entry `version` only when the referenced artifact does not carry its own version, **or** when the entry participates in a multi-version listing. `version` differs from `displayName`/`description` in that it is not merely cosmetic: the combination of `identifier` + `version` is the uniqueness key for [Multi-Version Entries](../specification/ai-catalog.md#multi-version-entries), and consumers sort on it to select the latest. Two consequences follow:

1. When a single entry references an artifact that carries its own version, entry `version` merely restates that value and SHOULD be omitted to avoid drift — the consumer can read the version from the artifact.
2. When a catalog lists multiple versions of the same `identifier`, each such entry needs a distinct `version` to be uniquely addressable (it is what makes `identifier` + `version` the uniqueness key; see [Multi-Version Entries](../specification/ai-catalog.md#multi-version-entries)), so `version` is required there — it is doing structural disambiguation, not display.

Unlike `displayName`/`description`, a present entry `version` is **not** an authorial override of the artifact's value: it is used for sorting and version selection, so it SHOULD equal the version the referenced artifact reports. An entry `version` that contradicts the artifact's own version is a publishing error (it breaks latest-selection), not a deliberate override. Consumers MAY surface such a mismatch but SHOULD treat the entry `version`, when present, as authoritative for catalog-level sorting and selection. A new "Resolving an Artifact's Version" section records the consumer resolution order, adapted for these sorting/selection semantics.

This decision concerns only Catalog Entry members. It does not change `displayName` on `HostInfo` / `Publisher`, nor any Trust Manifest field.

## Scope: fields in and out
In scope (duplicate an artifact's canonical value):

- `displayName` — already covered by ADR-0016 (A2A Agent Card `name`, MCP Server Card `title`).
- `description` — A2A Agent Card `description`, MCP Server Card `description`.
- `version` — A2A Agent Card `version`, MCP Server Card `version`, MCP Registry `server.json` `version`.

Deliberately out of scope (no canonical artifact counterpart, or catalog-owned by design):

- `tags` — a discovery aid the catalog author curates for cross-artifact filtering. Card formats do not expose a canonical top-level tag list (A2A tags live per-skill), so there is nothing authoritative to defer to.
- `updatedAt` — records when the *entry* changed; it describes the catalog record, not a value the artifact carries.
- `publisher`, `trustManifest` — the catalog's deliberate value-add (publisher identity and trust), explicitly the information the referenced artifact formats *lack*; the catalog is the authoritative home, so there is nothing to omit. (A2A's `provider` overlaps loosely with `publisher`, but publisher identity is the catalog's trust anchor by design and is intentionally owned here.)
- `metadata` — the open extension point, already governed by the specification's Metadata Extensibility rules, which themselves say to avoid keys that duplicate defined fields.
- `identifier`, `type`, `url` / `data` — required structural fields, not duplicated human-readable values.

## Rationale
- **Consistency.** The same duplication-and-drift argument that made `displayName` optional applies verbatim to `description` and `version`; treating them differently is an inconsistency publishers will trip over.
- **Single authoritative source.** Keeping the value at its source (the referenced card) keeps it fresh and avoids the "two conflicting values, no principled tiebreak" failure mode.
- **Thin entry.** Reinforces the entry-as-thin-pointer posture ([ADR-0013](0013-authoring-vs-distribution-formats.md)): an entry adds the discovery/trust metadata the artifact lacks, rather than mirroring what it already has.
- **Field-appropriate nuance.** `description` is prose and behaves exactly like `displayName` (a present value is a deliberate override). `version` carries structural meaning (uniqueness + sorting), so the rule is adapted: omit the redundant single-entry case, keep it required for multi-version listings, and treat a present value as sort-authoritative rather than a free-form override.

## Consequences
- The spec's `description` and `version` field descriptions gain the SHOULD-omit-when-authoritative / present-takes-precedence language, and "Resolving an Artifact's Description" and "Resolving an Artifact's Version" sections are added next to the display-name one. The `version` resolution section adapts the pattern to `version`'s structural role: the entry value is authoritative for sorting and selection (not a display override), a single entry that omits `version` resolves it from the referenced artifact, and an entry that carries no version at all falls back to `updatedAt`. The MCP mapping-appendix rows for `description` and `version` already carry the equivalent guidance (from the Server Card mapping); the Claude Plugins mapping-appendix `description` row is aligned to match, and the Claude Plugins example entries drop the now-redundant `description` accordingly (the nested-catalog entry keeps it, since a catalog artifact carries no canonical description of its own).
- No schema change: `description` and `version` are already OPTIONAL in the CDDL, so this ADR is guidance only and is not a breaking change.
- Existing catalogs that populate `description` / `version` on every entry remain conformant; the guidance is a SHOULD, and any publisher that wants a self-describing list view may still populate them.
- Consumers gain a defined resolution order for `description` and `version`, matching the one they already implement for `displayName`.

## Alternatives Considered
- **Leave `description` / `version` as plain optional fields.** Rejected: it is the status quo that motivated this ADR — the guidance gap is exactly the inconsistency being closed.
- **Apply the identical "present takes precedence as a deliberate override" wording to `version`.** Rejected: a `version` that contradicts the artifact would break Multi-Version selection; version needs the sort-authoritative-but-SHOULD-match framing instead.
- **Generalize into one rule over an open set of "duplicating fields."** Rejected for now as over-abstraction; the concrete set is small (`displayName`, `description`, `version`) and each has enough field-specific nuance to warrant explicit treatment. A future field that duplicates an artifact value should follow this same pattern.

## Open Question
As with ADR-0016's note that a Server Card `title` is itself optional: the guidance keys on whether the artifact *actually carries* the value, not on its media type. If a referenced artifact omits its own `description` (or `version`), the entry SHOULD keep the field so the value is not lost.

## Meeting Reference
Records a proposal ahead of an AI Catalog bi-weekly working-group discussion; drafted as a follow-up to [ADR-0016](0016-displayname-optional.md). Update the Status and Date (and note who raised concerns and the agreed outcome, as in ADR-0011) once the working group ratifies it.
94 changes: 89 additions & 5 deletions specification/ai-catalog.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,19 @@ The following members are OPTIONAL:
for the full consumer resolution order.

`description`
: A string containing a short description of the artifact.
: A string containing a short description of the artifact. Like
`displayName`, `description` is OPTIONAL and follows the same
authoritative-source rule: when the referenced artifact carries its
own canonical description — for example the `description` field of an
A2A Agent Card or an MCP Server Card — that artifact is the
authoritative source and entry `description` SHOULD be omitted to
avoid duplicating a value that can drift out of sync. When entry
`description` *is* present, however, it takes precedence: a consumer
SHOULD render it as given even when it differs from a description
carried by the referenced artifact, which is how a publisher provides
a listing-specific blurb. See
[Resolving an Artifact's Description](#resolving-an-artifact-s-description)
for the full consumer resolution order.

`tags`
: An array of strings serving as keywords for filtering and discovery.
Expand All @@ -270,6 +282,23 @@ The following members are OPTIONAL:
required. See [Multi-Version Entries](#multi-version-entries) for
how versions interact with `identifier`.

Like `displayName` and `description`, `version` can restate a value
the referenced artifact already carries (an A2A Agent Card
`version`, an MCP Server Card `version`), and when a single entry
references such an artifact the entry `version` SHOULD be omitted to
avoid drift — the consumer can read it from the artifact. Unlike
`displayName` and `description`, however, `version` is not merely
cosmetic: it is part of the entry's uniqueness key, so it is
REQUIRED when a catalog lists multiple versions of the same
`identifier` (see [Multi-Version Entries](#multi-version-entries)).
A present `version` is used for catalog-level sorting and selection
rather than as a free-form display override, so it SHOULD equal the
version the referenced artifact reports; an entry `version` that
contradicts the artifact's own version is a publishing error, not a
deliberate override. See
[Resolving an Artifact's Version](#resolving-an-artifact-s-version)
for the full consumer resolution order.

`updatedAt`
: A string containing an ISO 8601 [[RFC3339]] timestamp indicating
when this entry was last modified.
Expand Down Expand Up @@ -318,6 +347,64 @@ the `identifier` segment in step 3. A publisher MAY still set
`displayName` on such an entry to provide a better name than the bare
identifier segment.

### Resolving an Artifact's Description

Because `description` is OPTIONAL, a consumer that wants to show a
description cannot assume the entry carries one. It SHOULD resolve one in
the following order:

1. **`description` on the entry**, if present. A publisher-supplied
`description` always wins, even when it differs from a description
carried by the referenced artifact.
2. **The referenced artifact's own canonical description**, if the
consumer has already fetched or cached the artifact — for example the
`description` field of an A2A Agent Card or an MCP Server Card.
3. **No description**, if neither is available. Unlike a name, a
description has no identifier-derived fallback; a consumer SHOULD
simply render the entry without one.

As with name resolution, a consumer SHOULD NOT dereference an artifact at
render time solely to obtain a description. A registry, directory, or
other service built on top of a catalog SHOULD resolve the description
once at ingestion and cache the result, rather than fetching artifacts on
the rendering path.

### Resolving an Artifact's Version

Because `version` is OPTIONAL on a single entry — and present only when
the entry disambiguates others that share its `identifier` (see
[Multi-Version Entries](#multi-version-entries)) or deliberately restates
the artifact's version — a consumer cannot assume every entry carries
one. To obtain a version, a consumer SHOULD resolve one in the following
order:

1. **`version` on the entry**, if present. Unlike `displayName` and
`description`, a present `version` is not a free-form display
override: it is authoritative for catalog-level sorting and version
selection. Within a multi-version listing it is REQUIRED and, combined
with `identifier`, uniquely addresses the entry.
2. **The referenced artifact's own version**, if the consumer has already
fetched or cached the artifact — for example the `version` field of an
A2A Agent Card, an MCP Server Card, or an MCP Registry `server.json`.
A single entry that omits `version` because the artifact already
carries it is resolved here.
3. **No version**, if neither is available — the entry represents an
unversioned artifact. A consumer that needs to order such entries
SHOULD fall back to `updatedAt`, consistent with
[Multi-Version Entries](#multi-version-entries).

When both the entry and the referenced artifact carry a `version` and
they disagree, the entry `version` is authoritative for catalog-level
sorting and selection; the mismatch is a publishing error (it breaks
latest-selection) that a consumer MAY surface but SHOULD NOT resolve by
silently preferring the artifact's value.

As with name and description resolution, a consumer SHOULD NOT dereference
an artifact at render time solely to obtain a version. A registry,
directory, or other service built on top of a catalog SHOULD resolve the
version once at ingestion and cache the result, rather than fetching
artifacts on the rendering path.

## Multi-Version Entries

A catalog MAY contain multiple entries with the same `identifier` and
Expand Down Expand Up @@ -1973,7 +2060,7 @@ plugins/
| Marketplace `owner` | Catalog `host` (with `identifier` derived from owner) |
| `plugins[]` array | Catalog `entries[]` array |
| Plugin `name` | Entry `identifier` (derived as URN); the plugin manifest carries its own name, so entry `displayName` is omitted |
| Plugin `description` | Entry `description` |
| Plugin `description` | Stays in the plugin manifest (which carries its own `description`); entry `description` is omitted to avoid duplicating a value that can drift |
| Plugin `category` | Entry `tags[]` (first tag) |
| Plugin `tags` | Entry `tags[]` (merged with category) |
| Plugin `author` | Entry `publisher` |
Expand Down Expand Up @@ -2022,7 +2109,6 @@ maps to an AI Catalog where each plugin is an entry:
"identifier": "urn:claude-plugin:anthropic:agent-sdk-dev",
"type": "application/vnd.anthropic.claude-plugin+json",
"url": "https://github.com/anthropics/claude-plugins-official/tree/main/plugins/agent-sdk-dev",
"description": "Development kit for working with the Claude Agent SDK",
"tags": ["development"],
"publisher": {
"identifier": "did:web:anthropic.com",
Expand All @@ -2036,7 +2122,6 @@ maps to an AI Catalog where each plugin is an entry:
"identifier": "urn:claude-plugin:adspirer:ads-agent",
"type": "application/vnd.anthropic.claude-plugin+json",
"url": "https://github.com/amekala/adspirer-mcp-plugin.git",
"description": "Cross-platform ad management for Google Ads, Meta Ads, TikTok Ads, and LinkedIn Ads.",
"tags": ["productivity", "ads"],
"metadata": {
"homepage": "https://www.adspirer.com"
Expand All @@ -2056,7 +2141,6 @@ maps to an AI Catalog where each plugin is an entry:
"identifier": "urn:claude-plugin:aikido:security",
"type": "application/vnd.anthropic.claude-plugin+json",
"url": "https://github.com/AikidoSec/aikido-claude-plugin.git",
"description": "Aikido Security scanning — SAST, secrets, and IaC vulnerability detection.",
"tags": ["security"],
"publisher": {
"identifier": "did:web:aikido.dev",
Expand Down
Loading