Skip to content

SEP-2127: MCP Server Cards - HTTP Server Discovery via .well-known#2127

Open
dsp-ant wants to merge 24 commits intomainfrom
sep/mcp-server-cards
Open

SEP-2127: MCP Server Cards - HTTP Server Discovery via .well-known#2127
dsp-ant wants to merge 24 commits intomainfrom
sep/mcp-server-cards

Conversation

@dsp-ant
Copy link
Copy Markdown
Member

@dsp-ant dsp-ant commented Jan 21, 2026

This SEP proposes adding a standardized discovery mechanism for HTTP-based MCP servers using a .well-known/mcp.json endpoint.

Moved from: #1649

Summary

This enables clients to automatically discover:

  • Server capabilities
  • Available transports
  • Authentication requirements
  • Protocol versions
  • Descriptions of primitives

...all before establishing a connection.

Key Features

  • MCP Server Cards: Structured metadata documents exposed through standardized mechanisms
  • .well-known/mcp/server-card.json: HTTP endpoint for pre-connection discovery
  • mcp://server-card.json: MCP resource for post-connection discovery
  • Support for both static and dynamic primitive declarations

See the full specification in seps/2127-mcp-server-cards.md.

Comment thread seps/2127-mcp-server-cards.md Outdated
Comment thread seps/2127-mcp-server-cards.md Outdated
Comment thread seps/2127-mcp-server-cards.md Outdated
@tadasant
Copy link
Copy Markdown
Member

tadasant commented Jan 22, 2026

Just adding a note of context for any readers here that as of the current commit, this is the text of the original SEP proposal, but a lot of folks have contributed feedback to the specifics of reworking the shape in this Google Doc.

Pasting here for readability:

{
  "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
  "name": "io.modelcontextprotocol.anonymous/brave-search",
  "description": "MCP server for Brave Search API integration",
  "title": "Brave Search",
  "websiteUrl": "https://anonymous.modelcontextprotocol.io/examples",
  "repository": {
    "url": "https://github.com/modelcontextprotocol/servers",
    "source": "github",
    "subfolder": "src/everything"
  },
  "version": "1.0.2",
  "supportedProtocolVersions": [ "2025-03-12", "2025-06-15" ],
  "icons": [ ... ],
  "remotes": [ ... ],
  "packages": [ ... ],
  "capabilities":  { ... },
  "requires": { ... },
  "resources": [ ... ],
  "tools": [ ... ],
  "prompts": [ ... ],
  "_meta": { ... }
}

Most significant sticking points so far:

The rest is largely just details we can bikeshed.

I think it's important to design this so we introduce no breaking changes to server.json, as any breaking changes would cause major problems for a lot of production registry-related infrastructure and systems in the ecosystem. So my high level thinking would be to:

  • Adopt server.json as-is exactly as a Server Card, perhaps with additive changes like tools
  • Figure out the right integration point with Agent Card (probably put Server Card in their flexible services field)
  • Then everything else is just a matter of placement in .well-known, initialization sequence, etc. No controversy around deduplication or breaking changes in modeling.

I also liked @yoannarz's points here that there is a use case for non-owners of MCP servers to use Server Cards. So if we're going to require Server Cards to be comprehensive descriptors of all the capabilities of a server that only a server owner can advertise, we still have a gap like "how do I as a restaurant owner advertise that Yelp's MCP server is the way to make bookings on my website; I don't actually control the details of its tools and capabilities but I know where it lives and want to put that on my website's .well-known"

So maybe there is a path where we make Server Card a strict subset of server.json to elegantly fulfill all the above (e.g. perhaps Server Cards = purely Discovery concerns; then server.json is Discovery+Capabilities); will think more on that and circle back.

@mukteshkrmishra
Copy link
Copy Markdown

Shall we also add an optional extended card for ancillary information (such as additional metadata)?

@localden localden changed the title SEP: MCP Server Cards - HTTP Server Discovery via .well-known SEP-2127: MCP Server Cards - HTTP Server Discovery via .well-known Jan 24, 2026
@Fannon
Copy link
Copy Markdown

Fannon commented Jan 24, 2026

@tadasant It would be great if we can avoid getting two different formats. Instead we could extend the MCP Registry server.json to also cover the requirements that came up here. Then an MCP Server Card would basically be conventions of what has to be provided (required) for describing remote MCP Servers.

The discovery mechanism (.well-known) could be moved to the AI Card initiative, then MCP and A2A (potentially also other AI protocols) could share the discovery mechanism and providers / registries can use one instead of multiple.

For this, I just drafted a SEP in AI Cards: Agent-Card/ai-card#14

My colleagues Vyshnavi and Raluca prepared a JSON Schema of how the MCP Server Card could look like if we combine it as hinted at above. This may help to see if we can get this together.

In discussions with @dsp-ant the question came also up if we need two formats or not. As stated, we should not have two different formats to describe an MCP Server for the same protocol. But the registry itself may have additional information, so for consumers of the registry it is plausible to have a superset model of what the registry provides (like calculated properties, more context). I would keep this separate from the format for self-description and publishing to keep that as simple as possible.

@maiargu
Copy link
Copy Markdown

maiargu commented Jan 26, 2026

@dsp-ant Hi David
as discussed, here is a PR with the JSON schema to better discuss on the code directly maiargu/registry#1

fyi @tadasant

@tadasant
Copy link
Copy Markdown
Member

@dsp-ant to help drive this forward, I've opened a PR against your branch here.

If you are aligned with the direction it's going, could we get it merged and then continue community discussion on the remaining open questions (more detail below)?

I'm happy to formally sign on as sponsor for this or as an author if helpful.

I've taken into account all the feedback from:

Big thank you to @ggoodman, @PederHP, @sdatspun2, @connor4312, @SamMorrowDrums, @Fannon, @maiargu, @electrocucaracha, @ibuildthecloud, @yoannarz, @pcarleton and everyone else commenting and contributing so far; the feedback is all helping progress this forward.

I have avoided iterating on some of the more controversial topics, like dynamic as a value option for primitives, so we can hopefully land this quickly and have separate longer-running discussions on those sticky points.

Pasting the rest of the text from my PR for readability here:

Some highlights worth pulling out

Relationship to AI Card

The AI Card standard is paving a path to providing a protocol-agnostic .well-known path and file format for discovering services. They are planning to serve a list of AI Cards at .well-known/ai-catalog.json.

MCP Server Cards will provide a richer, MCP-specific definition that can be used by MCP clients to actually connect and start performing MCP operations. We will store these values at .well-known/mcp/server-cards.json.

Example:

  • "Restaurant A" works with platform "Restaurant Reservations SaaS" to provide MCP-powered bookings for their restaurant
  • Restaurant A also works with platform "Jobs SaaS" to provide MCP-powered job listings to prospective job seekers
  • Restaurant A would advertise the two relevant AI Cards at restaurant-a.com/.well-known/ai-catalog.json
  • Restaurant Reservations SaaS would have many Server Cards at restaurant-reservations-saas.com/.well-known/mcp/server-cards.json, including entries for each of Restaurant A, Restaurant B, etc.
  • Jobs Saas would have many Server Cards at jobs-saas.com/.well-known/mcp/server-cards.json, including entries for each of Restaurant A, Coffee Shop B, etc.

We can develop and iterate on MCP Server Cards largely independently from the broader effort to integrate with AI Cards, as long as we maintain some integration point so it is possible to understand when an entry in an AI Card references an MCP Server Card that is hosted and maintained elsewhere.

Instructions as a field in the Server Card

@PederHP had a good point here.

I think it's reasonable to consider, but we don't have it in server.json right now and it doesn't seem particularly critical to have blocking discussions on; I think we should leave it out for now. I've removed it in this PR.

supportedProtocolVersion

I've moved this field inside the remotes field, per discussion with @ggoodman here.

I think it would be reasonable to consider removing this from the SEP to simplify, as we don't currently have it in server.json so we'd be trying to collect feedback on use cases as we try to land this higher level piece of work in Server Card.

authentication

I've also moved this field inside the remotes field. My firsthand experience is that it is very common for different remotes entries to have different valid auth methods, so I think it would be a big shift for the ecosystem to consider authentication a top level Server Card concern.


Some topics I think we should continue discussing (but out of scope for landing this PR) into the SEP --

Removing $schema from server.json and not including it in Server Card

I've removed the explicit $schema field in this PR. We were planning to do this for the MCP Registry in the next iteration of server.json (rationale here, cc @rdimitrov). Basically, hardcoding the $schema field there introduces an unnecessary breaking change across versions, when we don't have intention to make breaking changes to these shapes.

A better solution here would probably be to use something like @vyshnavigadamsetti's suggestion of mcpCard: "1.0" that wouldn't needlessly create breaks with every (non-breaking) change.

Removing dynamic as an option in tools/primitive values

There is pretty significant community opposition to including dynamic as a possible value. @connor4312, @SamMorrowDrums, @Fannon, @sdatspun2 have all expressed their reasoning against it (link, link).

Removing the spec language around serving Server Cards as a resource

I left it as-written in the SEP for now, but there is motivation to have this removed

Placement of .well-known path

I didn't flesh this out further in this PR, but we should probably incorporate the thinking from @pcarleton and @simonrussell (link, link) explicitly into our language.

@ognis1205
Copy link
Copy Markdown

Thanks for driving this forward!

Just a quick question for clarity, there was a PR previously opened for community feedback iteration.
Would you prefer that further feedback and iteration happen directly on this PR, or should we continue using separate iteration PRs as before?

Happy to align with whatever works best for you and the group.

@tadasant
Copy link
Copy Markdown
Member

tadasant commented Jan 30, 2026

Thanks for driving this forward!

Just a quick question for clarity, there was a PR previously opened for community feedback iteration. Would you prefer that further feedback and iteration happen directly on this PR, or should we continue using separate iteration PRs as before?

Happy to align with whatever works best for you and the group.

My suggestion (feel free to direct us otherwise @dsp) would be that going forward, now that we have solid high level alignment, folks should open PRs for discrete sub-topics. For example, one PR proposing dynamic value changes, another PR expanding on the relationship between server.json and Server Cards, another PR perhaps workshopping instructions, and so on.

Then David can choose what he wants to pull it on a topic by topic basis and/or make changes to the SEP directly himself.

Open threads worth iterating on:

  1. Registry server.json vs. Server Card expansion (we aligned on strict subset here but didn't add that conclusion directly to the SEP wording yet), document differences / reasoning [Edit: https://github.com/Clarify relationship between server.json and MCP Server Cards #2186]
  2. Whether to have dynamic as a value in tools/primitives
  3. Server instructions
  4. Should primitives and capabilities live at the per-remote/package or top level per-server-card?
  5. Is allowing for any headers in remotes too permissive? Probably same question for templating in the URL.
  6. Drop .json suffix from the Resource distribution / do we still want Resource distribution?
  7. Clarity around the structure of name (it's fairly clear in server.json spec but important enough I think it should be more prominent in this SEP with guidance on conventions) [Edit: WIP]
  8. Clarity around .well-known placement, especially with respect to suffixing for multiplicity [Edit: WIP]

I think each of these could be separate PRs. I'll definitely work on (1) very soon, and can draft more if other folks don't jump on them first.

Edit: and maybe some of the smaller changes that are pretty constrained to modifying just one section of the SEP could be made directly as comments and discussed as threads, PR might be overkill for all of them.

@ognis1205
Copy link
Copy Markdown

Thanks for the suggestion, @tadasant .

This makes sense to me. Breaking things down into discrete PRs per sub-topic feels like the right next step now that there's high-level alignment.

I'd also be interested to see a bit more community feedback on this approach, and then I'd be happy to help review or contribute where it's most useful.

Looking forward to the follow-up PRs!

@tadasant
Copy link
Copy Markdown
Member

tadasant commented Feb 1, 2026

I opened #2186 as a follow up to @dsp's comment

I very much agree with @localden and @maiargu. The Server card should care about exposing HTTP and only that. We should aim for minimal information not maximal information. In fact, den has me believe we don't want any local package installation mechanisms at all. We might be okay to "refer" to a the registry so that clients trusting the registry can refer to that, but not more.

In the meantime I'll start working on a PR for:

Edit: that PR^ is somewhat intertwined with AI Card discussions, so will likely see where those land before putting something up here.

@ognis1205
Copy link
Copy Markdown

I tried to clarify the reverse-DNS namespacing for name field and _meta keys in the registry docs.

Some ambiguity around reverse-DNS namespacing surfaced during discussions about the name field and .well-known path suffixes, so this PR aims to make the intended conventions explicit without changing behavior:

modelcontextprotocol/registry#926

Please let me know if this matches the intended interpretation.

@qui-sam
Copy link
Copy Markdown

qui-sam commented Feb 17, 2026

Thanks for the thoughtful work on this proposal! (let me know if this feedback/comment is better suited for a different PR)

Wanted to raise a scenario we're seeing frequently in practice. We’re working with many small services businesses (gyms, home services, restaurants, spas..etc) to stand up MCP servers or MCP Apps for their business. A large number of these businesses run their websites on hosted platforms like Wix, or Squarespace, and similar builders. They own their custom domains, but many don't have the ability to place arbitrary files at .well-known paths, that's controlled by their hosting platform.

Some more advanced hosting setups for WordPress sites could likely serve files from .well-known paths. But fully managed platforms like Squarespace and Wix don't expose filesystem level control to their users. And I don't believe this is something a plugin or app on those platforms could solve either with .well-known path routing being below what third-party apps would have access to in most website hosting platforms.

These businesses are building capabilities like bookings, availability, quotes..etc and will want to adopt server cards to enable better discoverability of their tools, but likely won’t be able to without support from their website hosting platform (which could prioritize platform specific features versus the range of saas products that the small business might be using to enable their tools).

I might be misunderstanding how the .well-known mechanism would work in practice for these platforms or businesses, if so would appreciate any guidance!

Just wanted to raise this scenario and consideration to small services businesses building MCP capabilities and looking to evolve with new standards for discoverability.

@HenriChabert
Copy link
Copy Markdown

Excited to see this specification moving forward!

On our end, we have a strong need to support localized titles and descriptions for MCP servers. The goal is to dynamically display server metadata (e.g., title/description) in the user’s preferred language, which would significantly improve UX by making the interface more accessible and user-friendly.

Would it make sense to extend the current schema to accommodate localized fields? For example, we could modify the description field (and similarly for title) to support either:

  • A plain string
  • A dictionary of localized strings, where keys are RFC 5646 language tags (e.g., en-US, fr-FR) and values are the localized strings.
"description": {
  "oneOf": [
    { "type": "string" },
    {
      "type": "object",
      "additionalProperties": { "type": "string" },
      "description": "Keys must be valid RFC 5646 language tags (e.g., 'en-US', 'fr-FR')."
    }
  ]
}

To ensure consistency, we should also apply this localization pattern to tool metadata (title and description). This would allow MCP hosts to display tool information in the user’s language, aligning with the broader goal of a localized UX.

Happy to discuss about it and see if others feel the need of localization.

SamMorrowDrums and others added 8 commits March 26, 2026 19:23
Server cards without primitives already enable the core use cases:
autoconfiguration, domain-level discovery, reduced-latency metadata,
and registry integration. Primitives can follow in a future revision
once the ecosystem has the right mechanisms. Shipping discovery now
and correctly is more important than shipping a larger surface that
risks being wrong.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The detailed arguments belong in the PR discussion, not the spec
itself. The SEP now states the position concisely and defers the
full reasoning to the PR body.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Remove 'full server surface' phrasing from design philosophy
- Soften MUST to SHOULD for primitive discovery after connection

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Make description required to match server.json schema
- Make capabilities optional to avoid breaking existing server.json files
- Remove MCP Resource endpoint (mcp://server-card.json) — discovery
  should happen pre-connection via .well-known, not post-connection
- Remove registry endpoint section — registry already serves server.json
- Clarify that local/stdio servers use server.json + Registry path

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Switch from .well-known/mcp/server-card to .well-known/mcp-server-card to
register a single, precise IANA suffix rather than claiming the broader
mcp/ namespace. Also spec the {server-name} sub-path for hosts that serve
multiple MCP servers from one origin.
These additive fields on top of server.json are conceptually sound, but
by including them we are adding too much in one swoop. We have not yet
vetted the use cases or gotten sufficient feedback on their shapes.

Rather than push them through prematurely, cut scope now and add them
back in follow-on work once there is clear demand and design consensus.

supportedProtocolVersions is retained — it was identified as a
potentially important field at the MCP Dev Summit maintainer day and
its design was discussed in early iterations of this SEP (see
#1649 (comment)
and #1649 (comment)).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
tadasant and others added 2 commits April 6, 2026 09:06
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vyshnavigadamsetti
Copy link
Copy Markdown

vyshnavigadamsetti commented Apr 9, 2026

Hey @dsp-ant , @tadasant , wanted to share a perspective on including tools in the Server Card.
we have built an open-source MCP Server Card renderer (repo) and one thing we keep running into is that without tool definitions in the card, the card doesn't really tell you what a server does.
The spec currently defers primitives because servers are dynamic, but there's a whole class of consumers that will never connect to a live MCP server like registries, developer portals, agent orchestrators planning tool routing.
For them servercard could be like an API catalog that shows URLs but not operations.
This is similar to the role OpenAPI plays for REST APIs static documentation of what a remote server supports and what endpoints are available. OpenAPI works well even and we think the same approach can work here for MCP tools.
I think the fix is straightforward that we add optional tools, resources, prompts arrays using the existing MCP types. Dynamic servers just don't set them. Clients still use tools/list at runtime as the source of truth. The static list is for discovery, not execution.
Our renderer already visualizes static tool definitions from the card JSON and it works really well in practice. Happy to demo if that's helpful.

@ggoodman
Copy link
Copy Markdown
Contributor

ggoodman commented Apr 9, 2026

Some other thoughts about tool metadata being included in (or reachable deterministically from) the server cards.

Premise: Enabling MCP Gateways is in the interest of the community; it offers the sorts of controls, policies and auditability that IT admins require in enterprise world. Making MCP deployable at scale in the enterprise is in the community's interest.

With the premise / hypothesis in mind, at OKTA we're working on such a gateway. An 'IT Admin' persona is the kind of person that will create Virtual MCP Servers, configure Target MCP Servers and configure the policy that exposes stuff from the latter on the former. The other personas involved are the users of agents.

There are two main flows relevant to interacting with this gateway:

  1. Management flows -- Creation of Virtual MCP Servers, on-boarding of Target MCP Servers and definition of policy for Tools that are exposed from the latter on the former.
  2. Runtime flows -- An MCP Client connects to a Virtual MCP Server and does MCP stuff.

Here are some protocol-imposed challenges as they relate to management-time flows where server cards offer a very compelling improvement.

Management flows

  1. The IT Admin is not the intended user of the Target MCP Server. The convention / historical requirement that tools/list is an authenticated request like the others means that the IT Admin needs to figure out 'fake' MCP Client and identity just to list tools in an authoritative and idiomatic way.

    RECOMMENDATION: Offer a standardized, unauthenticated way to get an exhaustive list of tools. This could be a property of a server card or a resource linked to by a server card.

  2. Because tools lists are behind auth, tools/list can conceivable return different tools for the IT Admin than it would for authenticated users at runtime. Further, the set of tools can be different between different authenticated users. There is no standardized way to discover that this may be true.

    RECOMMENDATION: As (1) but the key point is that there is a way to opt into getting an exhaustive list of tools via a public, unauthenticated endpoint that is discoverable via a spec-defined mechanism. The representation would need a spec-defined way of indicating if tools vary by user / client / etc. The HTTP-equivalent would be the Vary header.

  3. The set of tools that are advertised may depend upon the protocol version advertised by an MCP Client.

    RECOMMENDATION: As (1) but either: 1) each tool should advertise which protocol versions it requires (or the earliest one); or 2) the list of tools should be discoverable on a per-endpoint basis and thus inherit the protocol versions of that endpoint.

  4. The set of tools that are usable may depend on the Client capabilities. There is no way for a Client to understand what client capabilities different tools require.

    RECOMMENDATION: As (1) but the tools listing should indicate the required client capabilties on a per-tool basis. The client can still get an exhaustive list of tools deterministically but now it can filter out those requiring capabilities it knowingly doesn't support. This prevents the ambiguity of server authors wondering if they should advertise tools based on negotiated client capabilities (or those soon to be advertised via http header).

  5. The validity period for the advertised set of tools is unclear from the client's perspective from a protocol-level.

    RECOMMENDATION: Since we're not in JSON-RPC-land here, we should clarify that HTTP semantics hold and that the client should respect Cache-Control headers per RFC9111.

@ggoodman
Copy link
Copy Markdown
Contributor

ggoodman commented Apr 9, 2026

We're considering adding ttls on certain listed results in the transports WG in #2549. If server cards end up listing (or linking to a list of) full tool definitions, there's a risk of confusion between any cache signals on the http-only card (or tool list) cache control headers and whatever ttl values the server provides in tools/list.

…ields

Remove authentication, capabilities, and requires to limit Server Card scope
@SamMorrowDrums
Copy link
Copy Markdown
Contributor

@vyshnavigadamsetti and @ggoodman thanks for input, we will definitely discuss it.

And @ggoodman regarding the superset of functionality, I had previously even proposed such a thing: #2091

I think the fundamental problem is that there is no concept in the protocol of configuration -> change in tool surface
User permissions -> change in tool surface
Etc.

My linked gist in the PR removing tools specifically calls out many of these different forms of dynamism but we really could do with a form of expressing correlation between config and tool surface that the protocol is aware of before this can really be done in a serious way.

And that still doesn't account for deployment or feature flags and other legitimate production patterns that cause functionality drift.

I also think people do need to be honest with themselves that if a server simply logs all input and output to a public place, is that not malicious enough that constraining tool schemas is also not really a solution to trust/provenance, but that's a whole other conversation 😅

For example, GitHub (which is one of the most popular servers in existence, serving millions of daily tool calls) will shortly ship MCP APPs to production (from our insiders preview). That will be rolled out as a feature flag in chunks of n users, and at our scale that's a reasonable thing to do.

Somehow these plans should converge on a place where servers, gateways, registries and clients can all understand what is going on, I very much agree with that, but there is work to do to achieve that, otherwise we just have half broken things which doesn't really serve anyone.

olgasafonova added a commit to olgasafonova/mcp-servercard-go that referenced this pull request Apr 13, 2026
…cope reduction

Server cards should focus on identity and transport discovery. Capabilities
and auth belong in the initialize handshake, not in static discovery documents.
Aligns with modelcontextprotocol/modelcontextprotocol#2127 (merged 2026-04-13).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dsp-ant dsp-ant added the roadmap/transport Roadmap: Transport Evolution & Scalability (incl. Server Cards) label Apr 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

draft SEP proposal with a sponsor. roadmap/transport Roadmap: Transport Evolution & Scalability (incl. Server Cards) SEP

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.