Skip to content

Clarifications on mcp-server-card dynamic flag#2269

Closed
maiargu wants to merge 3 commits intomodelcontextprotocol:sep/mcp-server-cardsfrom
maiargu:sep/mcp-server-cards-2
Closed

Clarifications on mcp-server-card dynamic flag#2269
maiargu wants to merge 3 commits intomodelcontextprotocol:sep/mcp-server-cardsfrom
maiargu:sep/mcp-server-cards-2

Conversation

@maiargu
Copy link
Copy Markdown

@maiargu maiargu commented Feb 18, 2026

Clarifications on mcp-server-card dynamic flag

Builds on #2127

The scope of this PR is strictly limited to provide clarifications for point 2. from @tadasant comment
Whether to have dynamic as a value in tools/primitives?

The answer to this question is probably NO.
A dynamic flag is not necessary to be introduced, if a MCP primitive is "dynamic" or not can be already expressed by using the listChanged flag from the MCP protocol itself.

This PR incorporates feedback from @Fannon comment
And solves concerns about "dynamic" raised by:

@maiargu maiargu changed the title Clarifications on mcp-server-card dynamic flag Clarifications on mcp-server-card dynamic flag Feb 18, 2026
- Cached security validations reducing runtime overhead

However, clients MUST still validate that the actual tools provided during initialization match the advertised tools in the server card. Servers MAY omit sensitive tool descriptions from the server card and mark tools as "dynamic" if pre-connection disclosure is undesirable.
However, clients MUST still validate that the actual primitives provided during initialization lifecycle phase match the advertised primitives in the server card.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I am personally deeply uncomfortable with requirement that they match completely, as some users for auth reasons cannot use certain tools and omitting them doesn't feel morally dynamic.

As another example, a server that does dynamic tool updates (list changed) but only potentially provides tools that can be statically declared in the server card as the superset of functionality also feels like it could avoid being "dynamic", because it is static in the security sense. It's not capable of providing new functionality that the client doesn't know about.

So the MUST should perhaps be must validate that the advertised primitives are equal to or a subset of the advertised functionality.

Additionally, a remote server might be redeployed and server card updated in a race between checking it and initialization. Maybe resilience should be suggested by re-checking before flagging the issue or failing.

Further to that, opt-in features or functionality may reasonably conflict with the advertised superset (which for GitHub Includes rolling out some changes gradually via feature flag to observer potential performance issues and error rates etc).

I am really worried about this because I think dynamic is handwaving and not very actionable, and we should seek to reduce the amount of functionality that would be considered dynamic to avoid clients breaking production servers for end users by saying that are potentially dangerous/malicious when they are absolutely not, doing totally normal things.

Finally Resources are almost always dynamic. Very few Resources can be reasonably enumerated statically (could depend on logged in user, configuration, access), and if they are could often be replaced by a standard http link to the same content. I had suggested maybe static Resources could provide a Template Resource style syntax in server card, so it's clear what the available space would be.

@tadasant and @dsp I know I've had my chance a couple of times to give a perspective, but I am concerned that the current proposal with dynamic:

  • needlessly restricts dynamic behaviours that are deterministic with a clear outer boundary
  • can be broken as a contract by the simple act of deploying a server
  • may be naively enforced by a bunch of clients in the name of security in cases where it actually isn't security at all
  • would lead to one of the most popular public servers being rejected or warned about by clients that acknowledge the server card

Please can we be very careful about the expectations we set if we go ahead with this.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Hi @SamMorrowDrums
As from my point of view I did not add the MUST statement or the security paragraph, it was there before in the initial proposal from @dsp.

This sentence:
However, clients MUST still validate that the actual primitives provided during initialization lifecycle phase match the advertised primitives in the server card.

I read and understand it like this:
An MCP client can discover an MCP server by a .well-known endpoint and automatically connect to it, however a card is just a card. It does not provide more that the possibility for an automatic client connection.

The card is not replacing the MCP protocol initialization lifecycle phase, where the client and the server exchange and negotiate capabilities. (like. e.g. tools listChange is true)

Or the cards tools, resources, prompts information don't replace the fact that a client needs to do after the MCP protocol initialization phase a tools/list, resources/list or prompts/list request.
And the response to this request may return something else than what is advertised in the card, so far my understanding.

Probably the sentence creates confusion and needs adjustments.

I am happy to directly apply what will be suggested by the owners here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@maiargu I totally see that, and appreciate you didn't add. The issue for me is more existential. I think there's a moderate to high risk of server cards being used for enforcement in the name of security. Not everywhere but in enough places that it's a real concern.

13. **prompts** (string | array, optional): Prompt definitions
1. If "dynamic": Must be discovered via protocol
2. If array: Static list following the `Prompt` interface
11. **resources** (array, optional): array of static Resource definitions exposed by the server, array items following the [`Resource`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L2947) JSON Schema
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You might want to reference a concrete commit here, since the main branch is a moving target.

Suggested change
11. **resources** (array, optional): array of static Resource definitions exposed by the server, array items following the [`Resource`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L2947) JSON Schema
11. **resources** (array, optional): array of static Resource definitions exposed by the server, array items following the [`Resource`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/ff8bd88d1dc1973a699bbdc85d8e52bb4d869edf/schema/draft/schema.json#L2947) JSON Schema

1. If "dynamic": Must be discovered via protocol
2. If array: Static list following the `Prompt` interface
11. **resources** (array, optional): array of static Resource definitions exposed by the server, array items following the [`Resource`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L2947) JSON Schema
12. **tools** (array, optional): array of static Tool definitions exposed by the server, array items following the [`Tool`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L3993) JSON Schema
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
12. **tools** (array, optional): array of static Tool definitions exposed by the server, array items following the [`Tool`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L3993) JSON Schema
12. **tools** (array, optional): array of static Tool definitions exposed by the server, array items following the [`Tool`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/ff8bd88d1dc1973a699bbdc85d8e52bb4d869edf/schema/draft/schema.json#L3993) JSON Schema

2. If array: Static list following the `Prompt` interface
11. **resources** (array, optional): array of static Resource definitions exposed by the server, array items following the [`Resource`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L2947) JSON Schema
12. **tools** (array, optional): array of static Tool definitions exposed by the server, array items following the [`Tool`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L3993) JSON Schema
13. **prompts** (array, optional): array of static Prompt definitions exposed by the server, array items following the [`Prompt`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L2682) JSON Schema
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
13. **prompts** (array, optional): array of static Prompt definitions exposed by the server, array items following the [`Prompt`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/draft/schema.json#L2682) JSON Schema
13. **prompts** (array, optional): array of static Prompt definitions exposed by the server, array items following the [`Prompt`](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/ff8bd88d1dc1973a699bbdc85d8e52bb4d869edf/schema/draft/schema.json#L2682) JSON Schema

@SamMorrowDrums
Copy link
Copy Markdown
Contributor

I think we should close this for now, as dynamic, and primitives in general have been removed from the current spec.

@kaikreuzer
Copy link
Copy Markdown

Ah, thanks @SamMorrowDrums, I didn't notice that yet - will have to do some more reading!

@maiargu
Copy link
Copy Markdown
Author

maiargu commented Mar 24, 2026

closing this PR in favour of #2336 that was already merged and covered the same objective

@maiargu maiargu closed this Mar 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request SEP

Projects

Status: No status

Development

Successfully merging this pull request may close these issues.

4 participants