Server Cards: recommend /server-card over .well-known (resolves #12)#22
Merged
Conversation
Move the single-server Server Card off a `.well-known` path. Reserve `GET <streamable-http-url>/server-card` as the recommended location while allowing any unreserved URI, since the Catalog already carries each card's `url` and clients never need to guess the location. - docs/discovery.md: new "Server Card Location" convention + permanent "Alternatives considered" subsection (bare endpoint / SSE-GET overload, `.well-known`, `/mcp/`-`/MCP/` nesting); rewrite single- and multi-server example URLs to the new style. - Use `Accept: application/mcp-server-card+json` on the GET request (the representation-negotiation header for a GET); `Content-Type` is the server's response header. - Normalize the media type to `application/mcp-server-card+json` everywhere, removing the prior `application/mcp-server+json` inconsistency. - schema.ts / schema.json / README.md: drop single-card `.well-known` phrasing for the new convention (Catalog + OAuth `.well-known` untouched). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Address review nit: distinguish the rejected domain-root /mcp/ metadata namespace from a streamable-HTTP URL that happens to end in /mcp, whose /server-card suffix is exactly the recommended convention. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Capitalized /MCP/ was never a real candidate; remove it and keep the rejected alternative focused on domain-root /mcp/ nesting. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… only The application/mcp-server+json -> application/mcp-server-card+json rename is handled in a separate PR. Revert the media-type strings here so this PR changes only the Server Card placement convention and does not trample that work. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The reserved-location blockquote and Accept example now name the media type explicitly. Since this is new text the separate rename PR will not touch, use the post-rename application/mcp-server-card+json directly. Pre-existing application/mcp-server+json strings remain untouched for the rename PR to handle. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
dsp-ant
previously approved these changes
Jun 8, 2026
SamMorrowDrums
previously approved these changes
Jun 8, 2026
SamMorrowDrums
left a comment
Collaborator
There was a problem hiding this comment.
Approved with one minor comment.
Allow for any domain
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.
Resolves #12.
What & why
Moves the single-server Server Card off a
.well-knownpath. We reserveGET <streamable-http-url>/server-cardas the recommended location while allowing any unreserved URI — the Catalog (/.well-known/mcp/catalog.json) is the discovery entrypoint and already carries each card'surl, so clients never need to guess where a card lives.Adopts wording close to the resolution discussed in #12 (credit: Darrel Miller's point that
.well-knownis for site-wide metadata, not application-level metadata like an individual server's card; proposed wording from @SamMorrowDrums and @tadasant):Content negotiation
A client fetching a Server Card requests its preferred representation with the
Acceptheader (Accept: application/mcp-server-card+json) — the request-side content-negotiation header for a GET. The server echoes the type it actually served back in the response'sContent-Type.Rationale for
/server-card(also captured permanently indocs/discovery.md→ "Alternatives considered").well-known: site-wide vs. application-level metadata; the Catalog already provides theurl, so.well-knownadds no value for the card.GET <url>with no suffix): a GET there already opens the SSE stream in Streamable HTTP. Hosting the card there overloads the connection-establishing endpoint and forces content negotiation to disambiguate. Spec-allowed, explicitly not recommended — this is the primary motivation for a distinct suffix./mcp/nesting:/mcpdenotes the transport endpoint itself in MCP's canonical-URI examples; there's no precedent for/mcp/as a metadata sub-namespace, and it collides conceptually with "the JSON-RPC endpoint."https://host/mcpnaturally yieldshttps://host/mcp/server-card— path-namespacing for free.Scope guardrail
This applies only to the single-server Server Card.
.well-knownis unchanged and remains correct for the Catalog (/.well-known/mcp/catalog.json) and OAuth metadata (/.well-known/oauth-protected-resource, etc.) — those are genuinely site-wide. The doc calls this out explicitly so it doesn't read as "abandon.well-knowneverywhere."Files changed
docs/discovery.md— new "Server Card Location" section with the reserved convention +Accept-header guidance; permanent "Alternatives considered" subsection; rewritten single- and multi-server example URLs (https://example.com/mcp/server-card;https://acme.com/code-review/server-card,/docs-search/server-card,/ci-cd/server-card).schema.ts— updated the two.well-knowndoc comments (ServerCardandServer) to the new convention.schema.json— regenerated fromschema.ts(npm run generate).README.md— updated the "What is a Server Card?" line to the new convention, normalizing the pre-existing README-vs-schema.well-knownmismatch.Verification
npm run checkpasses (schema.json in sync with schema.ts +tsc --noEmitclean)npm run generaterun and regeneratedschema.jsoncommitted in the same changenpm run validatepasses — all 7 examples validate against the regenerated schemanpm run formatrun (prettier clean).well-knownreferences remain inREADME.md,schema.ts,schema.json, ordocs/discovery.md(verified via grep); remaining.well-knownreferences are Catalog/OAuth/the "Alternatives considered" explainer onlygit diff origin/mainshows zero changes to existingapplication/mcp-server+jsonstrings (rename owned by a separate PR); only the new placement prose names the post-renameapplication/mcp-server-card+json🤖 Generated with Claude Code