spec: make Catalog Entry displayName optional (not required) (ADR 0016)#39
Merged
tadasant merged 5 commits intoJun 26, 2026
Merged
Conversation
tadasant
force-pushed
the
spec/remove-catalog-entry-displayname
branch
from
June 8, 2026 01:26
e23aed1 to
ede6f35
Compare
Move `displayName` from the required members of a Catalog Entry to the OPTIONAL members, and drop it from the Minimal Catalog (Level 1) conformance requirement. Add guidance that `displayName` SHOULD be set only when the referenced artifact does not already carry its own canonical human-readable name (e.g. a raw dataset, model blob, or skill bundle), and SHOULD be omitted when the artifact carries one (A2A Agent Card `name`, MCP Server Card `title`) so the catalog does not duplicate a value that can drift out of sync. When both are present and disagree, the artifact's own name is authoritative. - Examples: card-backed entries (A2A cards, MCP Server Cards, registry server.json, plugin manifests) omit displayName; opaque artifacts (parquet datasets, skill zips) and nested catalogs keep it, since they have no embedded canonical name. HostInfo and Publisher displayName are unaffected -- they name the host/publisher org. - Conceptual-mapping tables (MCP registry, Claude plugins) updated so the human-readable name maps to the artifact, with displayName as the fallback only when the artifact lacks a name. An earlier draft of this change removed `displayName` from the entry level entirely; that was dismissed because opaque artifacts (e.g. the Parquet dataset in examples/ai-catalog.json) have no other home for a human-readable name. Draft for discussion -- see PR description. Co-Authored-By: Claude Opus 4.8 <[email protected]> Signed-off-by: Tadas Antanavicius <[email protected]>
tadasant
force-pushed
the
spec/remove-catalog-entry-displayname
branch
from
June 8, 2026 02:27
ede6f35 to
0798bcc
Compare
tadasant
marked this pull request as ready for review
June 8, 2026 04:13
muscariello
requested review from
a team,
darrelmiller,
dsp-ant,
mindpower and
muscariello
and removed request for
muscariello
June 9, 2026 21:07
Documents the decision already implemented by this PR: displayName moves from a REQUIRED to an OPTIONAL member of a Catalog Entry and is dropped from the Minimal Catalog (Level 1) required-at-minimum set. Pairs each substantive spec PR with an ADR, matching ADR-0014 (Agent-Card#37) / ADR-0015 (Agent-Card#36). Status is Proposed pending the 2026-06-18 working-group call. Signed-off-by: Tadas Antanavicius <[email protected]> Co-Authored-By: Claude Opus 4.8 <[email protected]>
Refines the displayName-optional change with the consumer-vs-producer guidance agreed at the 2026-06-18 AI Catalog TSC working-group call. - Catalog Entry displayName is now an explicit *master override*: when a publisher sets it, it is authoritative for display and a consumer renders it as given, even if it differs from the artifact's own name. - Add a "Resolving an Artifact's Display Name" section with the consumer fallback order the WG agreed on: displayName -> the referenced artifact's own canonical name (A2A `name` / MCP Server Card `title`) -> the trailing segment of the `identifier` URN (the last-segment hack raised on the call). - Steer name resolution to ingestion-time caching rather than render-time dereferencing, reflecting the point that registries already normalize/cache at ingestion. - Update ADR-0016 to match. Co-Authored-By: Claude Opus 4.8 <[email protected]>
…isplayName') The lead-in said 'For an entry without displayName' but step (1) is 'displayName if present' — reword to the general rendering case. Co-Authored-By: Claude Opus 4.8 <[email protected]>
darrelmiller
approved these changes
Jun 25, 2026
Contributor
|
My perspective on this is that with the identifier and description property, a registry can synthesize a friendly display name for their registry. Picking the last segment of the URN identifier would likely be a reasonable substitute |
Member
|
Agree that for browsing/indexing, the |
mindpower
approved these changes
Jun 25, 2026
…ntry-displayname # Conflicts: # specification/ai-catalog.md
tadasant
pushed a commit
that referenced
this pull request
Jun 30, 2026
… ADR-0016) ADR-0016 (#39) made displayName OPTIONAL on Catalog Entry; the prose, the Level-1 conformance definition, and the ADR all agree, but the normative CDDL still listed displayName: text as required. This aligns the CDDL. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
6 tasks
tadasant
pushed a commit
to modelcontextprotocol/experimental-ext-server-card
that referenced
this pull request
Jul 7, 2026
Rather than making the MCP Catalog entry field displayName optional, drop it from the MCP Catalog entirely. Every MCP Catalog entry references a Server Card, and the Server Card's `title` is the source of truth for the server's human-readable name. Documenting displayName on the entry — even as optional — only invites publishers to duplicate a name that already lives in the card and risks it drifting out of sync. An MCP Catalog entry now requires only identifier, mediaType, and url. The doc notes that AI Catalog defines an OPTIONAL displayName (ADR 0016, Agent-Card/ai-catalog#39); because it is optional upstream, an MCP entry that omits it remains a valid drop-in subset of an AI Catalog entry. Removes displayName from the field table and from all catalog examples. Co-Authored-By: Claude Opus 4.8 <[email protected]>
SamMorrowDrums
pushed a commit
to modelcontextprotocol/experimental-ext-server-card
that referenced
this pull request
Jul 13, 2026
## Summary Removes the `displayName` field from **MCP Catalog** entries in `docs/discovery.md`. An MCP Catalog entry now requires only `identifier`, `mediaType`, and `url` — there is no human-readable-name field on the entry at all. Resolves #14. ## Rationale Issue #14 originally proposed making `displayName` **optional**, gated on the upstream AI Catalog spec doing the same. That gate resolved — **Agent-Card/ai-catalog#39** ("make Catalog Entry displayName optional (not required), ADR 0016") **merged** 2026-06-26: Agent-Card/ai-catalog#39. But for the **MCP-scoped** catalog we can go one step further and drop the field entirely, which is cleaner: - Every MCP Catalog entry references a **Server Card**, and the Server Card's `title` is the source of truth for the server's human-readable name. A client fetches that card anyway (the discovery flow retrieves the card at `url` for connection details), so it can read the name straight from the card. - Documenting `displayName` on the entry — even as optional — only invites publishers to duplicate a name that already lives in the card, where it can drift out of sync. This is the general-AI-Catalog concern (some non-MCP/non-A2A artifacts have no baked-in name) not applying to us: an MCP entry *always* points at a card that carries its own `title`. This still **preserves the drop-in-subset guarantee**. AI Catalog makes `displayName` optional (ADR 0016), so an MCP Catalog entry that omits it remains valid as-is inside a full AI Catalog document. The two specs agree; MCP simply declines to use the field and defers to the Server Card's `title`. The doc states this explicitly so the intentional omission is clear rather than looking like an oversight. ## What changed (`docs/discovery.md` only) - **Catalog Entry table**: removed the `displayName` row. Entry now lists only `identifier`, `mediaType`, `url` (all required). - **Prose**: replaced the required/optional language with a paragraph explaining that the entry carries no name field and clients read the name from the referenced Server Card's `title`, plus a paragraph documenting the AI-Catalog compatibility (optional `displayName` upstream → MCP entry is still a drop-in subset). - **Examples**: removed `displayName` from the single-server example and from all three entries in the multiple-servers example. Docs/spec-text only. No TypeScript or JSON Schema changes were needed — the catalog entry shape lives entirely in `discovery.md`; `schema.ts`/`schema.json` describe the Server Card itself and never encoded the catalog entry's `displayName`, so there was no schema coupling to update. ## Verification - [x] `npm run check` passes (schema.json up to date; `tsc --noEmit` clean) — docs-only diff - [x] `npm run validate` passes (all 7 Server Card examples validate as expected) - [x] `npm run format:check` clean for `docs/discovery.md` (ran `prettier --write`; remaining warnings are AO-injected untracked files not present in CI) - [x] Whole-file `displayName` sweep: the field is gone from the table and every example; the only remaining mentions are the deliberate AI-Catalog compatibility note explaining why MCP omits it — no contradictory "required"/"optional-field" language remains - [x] CI green on this PR (build, CodeQL, Analyze — see checks) - [x] Independent fresh-eyes review performed via in-session subagent; feedback addressed --------- Co-authored-by: tadasant <[email protected]> Co-authored-by: Claude Opus 4.8 <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this proposes
Make
displayNameOPTIONAL on the Catalog Entry rather than required — i.e. move it from the required members of a Catalog Entry (ai-catalog.md§Catalog Entry) into the OPTIONAL members, drop it from the Minimal Catalog (Level 1) conformance requirement, and add guidance that it SHOULD be set only when the referenced artifact does not already carry its own canonical human-readable name.The intent: when an entry points at an artifact that names itself (an A2A Agent Card, an MCP Server Card), the artifact is the single source of truth and the entry shouldn't duplicate the name. When an entry points at something opaque that has no embedded name (a raw dataset, a model blob, a skill bundle), the entry is the only place a human-readable name can live — so the field stays available for exactly that case.
This change deliberately does not touch
displayNameon the HostInfo or Publisher objects — those name the catalog host and the publishing org respectively, which is genuinely catalog-authored metadata with no other home.Alternative considered: removing the field entirely
My first instinct was to remove
displayNamefrom the entry level altogether and always defer to the artifact, but I'm not suggesting it because that would mean opaque artifacts have nowhere else to put a name.examples/ai-catalog.jsonhas anapplication/parquetdataset entry; a Parquet file, a model blob, or a skill.zipdoesn't embed a self-describing display name the way a card does. Removing the field outright would leave those artifacts nameless in a catalog. So "optional, with guidance" is the proposal; "remove entirely" is the rejected alternative.Why make it optional — the duplication / drift problem
A Catalog Entry already points at the full artifact via
urlordata. For the card-shaped artifact types this spec calls out by media type, the human-readable name is already present in the artifact itself:nameis a REQUIRED, human-readable field. From the A2A protobuf spec (specification/a2a.proto,message AgentCard):nameis a reverse-DNS machine identifier (^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$), whiletitleis documented as "Optional human-readable title or display name for the MCP server", anddescription(required) is human-readable too.So for the two flagship artifact types, requiring
displayNameon the entry means every catalog publisher copies a value that already exists in the document the client is about to fetch, and then has to keep the two in sync forever. When they drift — and over time they will — a consumer has two conflicting human-readable names for the same thing and no principled way to pick. Making the field optional (and recommending omission for self-naming artifacts) keeps the name fresh and authoritative at its source, while the entry stays a thin pointer.What's in the diff
displayNamemoved from required → OPTIONAL members, with a SHOULD-guidance paragraph (set it only when the artifact has no canonical name; omit it for self-naming cards; the artifact's own name wins on conflict). Removed from the Minimal Catalog (Level 1) required-at-minimum list.server.json, plugin manifests) now omitdisplayName; opaque entries (theapplication/parquetdataset,application/agentskill+zipskill bundles) and nestedapplication/ai-catalog+jsonentries — which have no embedded canonical name — keep it.HostInfo/PublisherdisplayNameuntouched. The field still exists, so the class diagram and the "logical format" vocabulary lists are unchanged.displayNameframed as the fallback for nameless artifacts.Some history (for transparency)
As far as I can reconstruct from the public record,
displayNamewas required from its first appearance rather than as the outcome of an explicit "should this be mandatory?" debate:namein commit0271c14(2026-03-31), already under "It MUST contain the following members."name→displayNamein1e8c70c9per the AI Actor Naming Standard (PR #19), still required, and shipped via PR #27.I went looking for a written rationale for the mandatory status specifically — across the ADRs (0001–0013), issues, and discussions — and couldn't find one. The closest articulations of the field's purpose are PR #19 ("a human-readable name used for discovery in UIs … not required to be unique") and ADR 0013 framing the catalog as "the authoring and discovery format — a human-readable JSON document." I might simply be missing the discussion where requiring it was decided — if there's prior context I've overlooked, please point me to it, since it likely bears directly on the tradeoff.
Counter-argument to landing this
The strongest argument I can construct for keeping it required is browsing UX: a UI that renders a list of N artifacts shouldn't have to fetch N separate cards just to show names, so requiring
displayNameon the entry makes the catalog self-describing for a cheap list view.However, that's a steep trade-off for a permanent duplication/sync cost; one we'd like to avoid making on the MCP side. I'm not sure I'm convinced that UIs of AI Catalogs will be a major use case of AI Catalog (please correct me if you foresee otherwise, would love to understand the use case), and the optional form still lets a publisher populate
displayNameon every entry if they want the self-describing list view. It just doesn't force the card-backed entries to carry a redundant copy.If there's a use case beyond browsing that makes the field load-bearing enough to mandate, would love to understand.