Skip to content

docs(discovery): clarify /server-card discovery (bare-GET + resolution rule) + evaluation of a /server-card.json convention#38

Closed
tadasant wants to merge 3 commits into
mainfrom
docs/evaluate-server-card-json-suffix
Closed

docs(discovery): clarify /server-card discovery (bare-GET + resolution rule) + evaluation of a /server-card.json convention#38
tadasant wants to merge 3 commits into
mainfrom
docs/evaluate-server-card-json-suffix

Conversation

@tadasant

@tadasant tadasant commented Jun 27, 2026

Copy link
Copy Markdown
Member

Summary

Evaluates the suggestion to fetch a Server Card via a plain GET at a fixed path suffix — <mcp_url>/server-card.json — to spare simple scrapers from HTTP content-type negotiation, and implements the recommended outcome as concrete, mergeable edits to docs/discovery.md so maintainers can merge directly if they agree.

Two files change:

  • docs/proposals/server-card-json-suffix.md (new) — the objective written evaluation, pros/cons, and recommendation.
  • docs/discovery.md — the two non-breaking normative clarifications the evaluation recommends (see below). The reserved suffix stays /server-card; .json is deliberately not adopted.

Key finding: the motivating premise is already largely satisfied

The suggestion is pitched as "switch away from content negotiation to a path suffix." But docs/discovery.md already reserves a path-suffix convention — GET <streamable-http-url>/server-card — and its "Alternatives considered" section already explicitly rejects serving the card off the bare /mcp endpoint because that "forces content negotiation to disambiguate 'give me the card' from 'open the stream.'" The headline win (plain GET to a predictable URL) is the design the spec landed on in #22 (resolving #12).

That narrows the live decision to two questions, both addressed: the .json spelling, and how hard to lean on Accept.

Recommendation (argued, not rubber-stamped) — and what this PR implements

  • Keep /server-card; do NOT adopt /server-card.json. .json's main benefit (static-host content-type inference) is weakest at the dynamic MCP endpoint the suffix governs, it nudges static hosts toward generic application/json rather than the registered application/mcp-server-card+json, it couples the path to a serialization, and it re-litigates a just-decided experimental convention. The .json option is presented fairly, then argued against. → No-op by design (reserved suffix unchanged).
  • Bare-GET guaranteeimplemented in discovery.md: if a server hosts its card at the reserved /server-card path, a plain GET (no Accept) MUST return it. Scoped to the reserved path; hosting there stays OPTIONAL; auth-gated and catalog-url-only servers are unaffected. This is the cheap, non-breaking change that delivers the scraper-friendliness the suggestion wants.
  • Suffix-resolution ruleimplemented in discovery.md: append /server-card to the RFC 3986 path component after template expansion, collapse a single trailing slash, and do not carry the endpoint's query/fragment onto the card URL (query-routed/multi-tenant servers publish an explicit catalog url). This closes a real ambiguity ("just tack it on the end of an /mcp URL" is not unambiguous — query strings, trailing slashes, templated URLs) that exists for the current /server-card too.
  • CORS reconciliationimplemented in discovery.md: add Accept to the discovery Access-Control-Allow-Headers example so a browser client can actually send the recommended Accept cross-origin; the bare-GET guarantee is the documented fallback.

Reviewers who disagree with the normative edits can drop the discovery.md changes and keep just the evaluation doc.

Verification

  • Scope: docs-only. New proposal under docs/proposals/; the discovery.md edits are confined to the Server Card discovery convention this repo owns. Honors the conservative, spec-tracked posture (AGENTS.md).
  • Grounded in the repo's actual spec text (docs/discovery.md, README, examples/), correcting the premise where inaccurate.
  • Breaking-change review: the bare-GET rule is non-breaking for card consumers; it is a new producer obligation, called out explicitly per AGENTS.md Principle 4. The reserved path spelling is unchanged, so no existing card URL breaks.
  • Local CI green on tracked files: npm run check (schema in sync + tsc) ✓, npm run validate (all 7 examples) ✓, prettier --check on both changed docs ✓.
  • GitHub Actions CI green on this branch (build / Analyze / CodeQL — see checks below).
  • Self-review of the diff completed. Two independent fresh-eyes reviews run via in-process subagent (one on the evaluation, one on the new normative discovery.md edits); all SHOULD-FIX feedback addressed — catalog-url scoping for templated servers, media-type con marked contingent, producer-vs-consumer precision, auth/private-server caveat, collision-with-route note, conditional-before-MUST ordering, and the CORS/Accept reconciliation.
  • Opened as draft; not merged. The merge decision belongs to a human maintainer.

🤖 Generated with Claude Code

Peter (via Claude Code agent) and others added 3 commits June 27, 2026 14:33
Adds a draft proposal under docs/proposals/ evaluating the suggestion to
recommend fetching Server Cards at <mcp_url>/server-card.json via a plain GET.

The writeup corrects the motivating premise (discovery already uses a path
suffix, /server-card, not content negotiation against /mcp), lays out the
honest pros/cons of the .json spelling, and recommends keeping /server-card
while adding a non-breaking bare-GET guarantee and a suffix-resolution rule.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Scope the "catalog url is pre-resolved" claim: note templated/multi-tenant
  remotes have no single concrete card URL either.
- Mark the application/json media-type con as contingent on open question #4.
- Clarify the bare-GET MUST is non-breaking for consumers but a new producer
  obligation (AGENTS.md Principle 4).
- Add an Authenticated/private-servers caveat scoping the bare-GET MUST, and a
  Collision-with-a-real-route consideration.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Apply the two non-breaking normative edits the proposal recommends, so the
change is ready to merge if maintainers agree (the reserved suffix stays
/server-card; .json is deliberately not adopted):

- Bare-GET guarantee: if a server hosts its card at the reserved /server-card
  path, a plain GET (no Accept) MUST return it. Scoped to the reserved path;
  hosting there remains OPTIONAL and auth/catalog-url paths are unaffected.
- Suffix-resolution rule: append to the RFC 3986 path component after template
  expansion, collapse a single trailing slash, and do not carry query/fragment
  onto the card URL (query-routed servers publish an explicit catalog url).
- Reconcile the CORS allow-list with the recommended Accept header.

Fresh-eyes review feedback addressed: lead the bullet with the conditional
before the MUST; note the bare-GET path as the cross-origin CORS fallback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@tadasant tadasant changed the title docs: evaluate a /server-card.json path-suffix discovery convention (draft proposal) docs(discovery): clarify /server-card discovery (bare-GET + resolution rule) + evaluation of a /server-card.json convention Jun 27, 2026
@tadasant tadasant closed this Jun 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant