Skip to content

SEP-2127: Remove primitives from server cards#2336

Merged
dsp merged 7 commits intomodelcontextprotocol:sep/mcp-server-cardsfrom
SamMorrowDrums:sep/server-cards-no-primitives
Mar 9, 2026
Merged

SEP-2127: Remove primitives from server cards#2336
dsp merged 7 commits intomodelcontextprotocol:sep/mcp-server-cardsfrom
SamMorrowDrums:sep/server-cards-no-primitives

Conversation

@SamMorrowDrums
Copy link
Copy Markdown
Contributor

Summary

This PR removes primitive definitions (tools, resources, prompts) from the MCP Server Cards SEP, making server cards focused on identity, transport, capability, and authentication discovery.

Why remove primitives?

MCP servers are inherently dynamic. The primitives a server exposes can vary by authenticated user, session, configuration, feature flags, deployment state, and more. A static document cannot reliably represent this surface.

Key concerns with including primitives in a pre-connection document:

  • No substitute for runtime listing. Only tools/list, resources/list, and prompts/list with the logged-in user's identity produce correct results. A static manifest cannot know the user's OAuth scopes, subscription tier, feature-flag cohort, or which deployment version they will reach.
  • Deployment is not atomic. During rolling deploys, the server card and live fleet can disagree. Even nominally static servers have a window where the card is wrong.
  • Cache without invalidation. A server card with primitives is effectively a cache of the runtime surface, but the protocol provides no invalidation signal. Cache coherence problems are notoriously hard, and introducing a cache without an invalidation strategy is a well-known source of distributed-systems bugs.
  • Disadvantages dynamic servers. If server cards normalise primitive listings, clients and gateways will prefer servers that provide a complete static listing, structurally penalising servers that are dynamic for legitimate reasons (auth-scoped filtering, feature flags, paid tiers, configuration-based surfaces).
  • A survey of dynamic server behaviors catalogs at least ten dimensions of dynamism that make static primitive advertisement unreliable.

Until proposals like Server Variants (SEP-2053) provide a mechanism for clients to understand which primitive surface applies to their context, server cards should be conservative.

Discovery should not wait

The primitives debate should not delay server card adoption. Discovery (where to connect, what transports are available, what auth is required) is enormously valuable on its own. It is the information an end user or IDE needs to install a server, and the information a registry needs to index one. None of this depends on knowing the tool list in advance.

What changed (13 insertions, 96 deletions)

  • Removed resources, tools, prompts fields from schema and examples
  • Removed "Dynamic Primitives" section and field descriptions 11-13
  • Replaced "Why Support Both Static and Dynamic Primitives?" with concise "Why Exclude Primitives?" rationale
  • Added "Why Not Wait for Primitives?" rationale section
  • Updated Security section: "Primitive Information" replaces "Tool Description Security"
  • Minor wording in Abstract, Design Philosophy, and Enabled Use Cases

Everything else is preserved: identity, transport, capabilities, auth, server.json alignment, .well-known endpoints, CORS, caching, IETF registration.

SamMorrowDrums and others added 6 commits March 2, 2026 23:50
Server cards should focus on identity, transport, and capability
discovery. Primitive definitions (tools, resources, prompts) are
removed because MCP servers are inherently dynamic — primitives vary
by auth scope, feature flags, configuration, deployment state,
session state, and more.

A static manifest cannot reliably represent this dynamic surface.
The 'dynamic' escape hatch acknowledged the problem but did not
solve it. Until the protocol provides a mechanism for clients to
understand which primitive surface applies to their context (e.g.
server variants), server cards should not include information that
cannot be reliably interpreted.

Primitives remain discoverable through the protocol's standard list
operations after connection establishment.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Clarify that including primitives in server cards risks creating a
structural bias toward static servers, penalising servers that are
dynamic for legitimate reasons. Call for a follow-on SEP to address
prerequisites (variant enumeration, auth-scope signalling, partial
listing contracts) before primitives are added.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add three further arguments for excluding primitives:

- Deployment is not atomic: rolling deploys make server cards
  transiently wrong even for nominally static servers.
- No substitute for runtime listing: only the protocol's list
  operations reflect the actual surface for the authenticated user.
- Cache-invalidation analogy: a server card with primitives is an
  incoherent cache with no invalidation signal, and introducing
  caches without invalidation strategies is a well-known source of
  subtle distributed-systems bugs.
- If primitives are ever reintroduced they must be treated as
  documentation-only, never for caching or signatures.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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>
@SamMorrowDrums SamMorrowDrums requested review from dsp and tadasant and removed request for dsp March 2, 2026 23:11
@dend dend added proposal SEP proposal without a sponsor. SEP labels Mar 4, 2026
Copy link
Copy Markdown
Member

@tadasant tadasant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm on board with deferring this; tricky topic we should collect feedback on from a variety of folks and shouldn't block the discovery work.

- 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>
@SamMorrowDrums
Copy link
Copy Markdown
Contributor Author

@tadasant agreed on changes. I don't know if we want to wait for Monday meeting before merge for quick consensus check? I don't have permission to do so at any rate, so I defer to you and David.

@tadasant
Copy link
Copy Markdown
Member

tadasant commented Mar 6, 2026

@tadasant agreed on changes. I don't know if we want to wait for Monday meeting before merge for quick consensus check? I don't have permission to do so at any rate, so I defer to you and David.

Let's do it Monday; I don't have the permissions either.

@dsp dsp merged commit ea4ffd3 into modelcontextprotocol:sep/mcp-server-cards Mar 9, 2026
2 checks passed
@Fannon
Copy link
Copy Markdown

Fannon commented Mar 31, 2026

Sorry, I wasn't paying attention to all the changes / discussions in the meantime, but if we now remove the primitives, we have no static metadata description of the MCP Service anymore. Of course, the actual list of tools is dynamic and depends on the user / roles etc. - but sometimes you need to understand the server before you have that access, or independent of a particular user / role, e.g. to generate documentation, generate clients.

E.g. compare this to OpenAPI, it also lists all operations, even though a particular user / role would not have access to all of them.

With this change, it would make the MCP Server Card unfit for those purposes. Would then there be any alternative to describe the MCP Server statically?

@SamMorrowDrums
Copy link
Copy Markdown
Contributor Author

@Fannon we are open to discussing this, it is not a closed discussion. It's not quite as simple as the Open API example, because it's not limited to permissions, but content might even change depending on available tools (simple example is server instructions that are only relevant where combinations of tools are available).

The core reason for this decision was to unblock discovery for now, ultimately a weak contract providing "roughly what the server contains" might be fine if it's understood to be a weak contract, and not abused for enforcement.

@Fannon
Copy link
Copy Markdown

Fannon commented Mar 31, 2026

@SamMorrowDrums - yes, I understand that list of tools can be dynamic. Actually at my company, same is true for REST APIs and OpenAPI, too. In a static metadata, you can only describe what you know at design-time. But at run-time the APIs can change due to config, extensions, customizations. And what's really available then depends on user-context and permissions.

In my understanding MCP is not different than any other API protocol out there. But that it can exchange this information at runtime via the protocol standards itself is nice.

Yes, it would be a "weaker contract", basically what you can know at that point in time. Only what you get back at runtime is then the reality. But usually this is a compatible subset/superset of the design-time contract.

@SamMorrowDrums
Copy link
Copy Markdown
Contributor Author

SamMorrowDrums commented Mar 31, 2026

I don't disagree, dynamic in the original proposal just felt like it needed a lot more discussion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

proposal SEP proposal without a sponsor. SEP

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

5 participants