🤖 Drafted by Claude Code (an AI coding agent) on behalf of @tadasant. The substance was reviewed by a human before filing.
Summary
Server Card discovery is currently specified as a static document served from a .well-known path (/.well-known/mcp-server-card, per SEP-2127 / schema.ts / docs/discovery.md). This issue argues we should seriously consider not using .well-known at all for the single-server case, and instead let a client discover a server's card by issuing a plain GET against the server's own URL (e.g. with Accept: application/json or the Server Card media type), with the server responding with its card.
This is deliberately scoped as an alternative to the .well-known mechanism, and is independent of the separate question of which .well-known spelling to standardize on if we do keep .well-known (tracked in #11). The two can be decided separately: this one asks "should there be a .well-known file at all," #11 asks "if there is, what is its exact path."
What's specified today
SEP-2127 currently puts the card at a .well-known URI (seps/2127-mcp-server-cards.md#L257-L274, PR #2127):
Servers using HTTP-based transports SHOULD provide their server card at:
/.well-known/mcp-server-card
…and schema.ts documents the same (schema.ts#L13-L14):
* A static metadata document describing a remote MCP server, suitable for
* publishing at a `.well-known/mcp-server-card` URI for pre-connection discovery.
The argument
-
Dynamic servers. A .well-known file presumes a static artifact (or a second route) that the server author maintains separately from the server itself. For servers that generate their descriptor dynamically, serving the card from the server URL directly is simpler — there's exactly one endpoint to implement and keep in sync, and no risk of the .well-known copy drifting from reality.
-
One endpoint, not two. The server URL is already the thing a client must know to connect. Reusing it for discovery (content-negotiated GET) avoids introducing a second well-known location that has to be hosted, routed, and kept consistent — especially painful on platforms where authors don't control /.well-known/* (e.g. some managed site hosts).
-
It's been proposed before and never resolved. This exact idea was raised on the original SEP thread but not adopted — @janwilmake at modelcontextprotocol#1649 (comment), verbatim:
Another idea: Can't we simply reserve the MCP URL's GET method with accept 'application/json' for this? Makes it much easier for dynamic servers.
I created installthismcp and it'd be great to be able to dynamically get the name, icon, description, and other metadata based on the url alone. It would also enable dynamically generated metadata for multiple mcp servers on the same hostname. For more context, see this thread
Worth revisiting now that the extension is in execution mode rather than re-litigating it ad hoc.
Considerations / open questions
- Method collision. MCP's Streamable HTTP transport already uses the server URL for POST (and GET for SSE streams). We'd need to define how a discovery GET (
Accept: application/mcp-server-card+json) is distinguished from a transport GET (Accept: text/event-stream) so the two don't conflict. Content negotiation via Accept is the natural lever, but it needs to be written down precisely.
- stdio / non-HTTP servers. GET-on-URL only makes sense for HTTP servers. Note that SEP-2127 already scopes
.well-known discovery to HTTP-based transports and routes local/stdio servers through server.json + the Registry (seps/2127-mcp-server-cards.md#L257-L274) — so GET-on-URL isn't a regression for stdio, and it reinforces that pre-connection discovery is an HTTP-remote concern.
- Catalog case is unaffected. Domain-level indexing via the MCP Catalog / AI Catalog is a separate layer; this issue is only about how a client fetches one server's card given its URL.
- Relationship to
.well-known. These need not be mutually exclusive — we could allow both, or pick one. But if GET-on-URL covers the dynamic-server case cleanly, it's worth asking whether .well-known earns its complexity for single servers at all.
Proposed resolution
Decide, as an explicit WG question, between (a) .well-known static file, (b) content-negotiated GET on the server URL, or (c) both. If we adopt (b) or (c), specify the Accept header / media type that selects the card response and how it coexists with the Streamable HTTP transport's existing use of GET on the same URL.
Summary
Server Card discovery is currently specified as a static document served from a
.well-knownpath (/.well-known/mcp-server-card, per SEP-2127 /schema.ts/docs/discovery.md). This issue argues we should seriously consider not using.well-knownat all for the single-server case, and instead let a client discover a server's card by issuing a plainGETagainst the server's own URL (e.g. withAccept: application/jsonor the Server Card media type), with the server responding with its card.This is deliberately scoped as an alternative to the
.well-knownmechanism, and is independent of the separate question of which.well-knownspelling to standardize on if we do keep.well-known(tracked in #11). The two can be decided separately: this one asks "should there be a.well-knownfile at all," #11 asks "if there is, what is its exact path."What's specified today
SEP-2127 currently puts the card at a
.well-knownURI (seps/2127-mcp-server-cards.md#L257-L274, PR #2127):…and
schema.tsdocuments the same (schema.ts#L13-L14):The argument
Dynamic servers. A
.well-knownfile presumes a static artifact (or a second route) that the server author maintains separately from the server itself. For servers that generate their descriptor dynamically, serving the card from the server URL directly is simpler — there's exactly one endpoint to implement and keep in sync, and no risk of the.well-knowncopy drifting from reality.One endpoint, not two. The server URL is already the thing a client must know to connect. Reusing it for discovery (content-negotiated GET) avoids introducing a second well-known location that has to be hosted, routed, and kept consistent — especially painful on platforms where authors don't control
/.well-known/*(e.g. some managed site hosts).It's been proposed before and never resolved. This exact idea was raised on the original SEP thread but not adopted — @janwilmake at modelcontextprotocol#1649 (comment), verbatim:
Worth revisiting now that the extension is in execution mode rather than re-litigating it ad hoc.
Considerations / open questions
Accept: application/mcp-server-card+json) is distinguished from a transport GET (Accept: text/event-stream) so the two don't conflict. Content negotiation viaAcceptis the natural lever, but it needs to be written down precisely..well-knowndiscovery to HTTP-based transports and routes local/stdio servers throughserver.json+ the Registry (seps/2127-mcp-server-cards.md#L257-L274) — so GET-on-URL isn't a regression for stdio, and it reinforces that pre-connection discovery is an HTTP-remote concern..well-known. These need not be mutually exclusive — we could allow both, or pick one. But if GET-on-URL covers the dynamic-server case cleanly, it's worth asking whether.well-knownearns its complexity for single servers at all.Proposed resolution
Decide, as an explicit WG question, between (a)
.well-knownstatic file, (b) content-negotiatedGETon the server URL, or (c) both. If we adopt (b) or (c), specify theAcceptheader / media type that selects the card response and how it coexists with the Streamable HTTP transport's existing use of GET on the same URL.