Close transport-layer specification gaps in the draft#2891
Conversation
Tool and prompt names are only SHOULD-constrained to header-safe
characters, so a name outside the safe set previously made the tool
uncallable over Streamable HTTP: Mcp-Name is required, but no encoding
was defined for it.
- Allow the =?base64?...?= sentinel encoding (already defined for
Mcp-Param-{Name} headers) for the Mcp-Name header value.
- Require servers to decode encoded Mcp-Name and Mcp-Param-{Name}
values before comparing them to the request body during server
validation.
The x-mcp-header extraction rule was undefined for properties nested under array 'items', inside composition or conditional keywords (oneOf/anyOf/allOf/not, if/then/else), or behind $ref: such properties have no single static location in the call arguments. - x-mcp-header annotations are now only valid on properties reachable from the schema root via a chain consisting solely of 'properties' keys. Annotations anywhere else make the tool definition invalid, triggering the existing client rejection rules. - Define extraction as reading the instance value at the annotated property's exact path; if the value is absent, the header is omitted. - Mirror the rule in the Tool.inputSchema schema documentation.
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
notifications/elicitation/complete had no legal delivery channel: the HTTP GET stream is gone, response-stream notifications must relate to the in-flight request, and the subscriptions/listen filter had no field covering elicitation completion — while servers must not send notification types the client has not requested. - Add an opt-in elicitationComplete boolean to SubscriptionFilter; when true, the server may deliver notifications/elicitation/complete on that subscription's stream. - Document on ElicitationCompleteNotification that it is only sent to clients that opted in via elicitationComplete and is delivered on that subscription's stream (with the subscription ID in _meta). - Document the URL-mode elicitation flow: the client subscribes via subscriptions/listen with elicitationComplete: true, waits for the completion notification, then retries the original request. - Regenerate schema.json and the schema reference.
In this revision, the only client-sent notification in the core protocol is notifications/cancelled, and it is used only on the stdio transport: on Streamable HTTP, closing the SSE response stream is itself the cancellation signal and no notifications/cancelled message is expected. - Note this in the Sending Messages section, cross-linking the cancellation pattern; the notification POST rules remain as transport mechanics, with header requirements for notification POSTs left undefined by this revision. - Scope the protocol-version header-body match requirement and the Mcp-Method header requirement to requests. Request-side rules are unchanged.
d612b11 to
22d61dc
Compare
| Servers **MAY** send a `notifications/elicitation/complete` notification when an | ||
| out-of-band interaction started by URL mode elicitation is completed. This allows clients to react programmatically if appropriate. | ||
|
|
||
| The notification is delivered on a |
There was a problem hiding this comment.
I don't think this should go on a subscription/listen stream.
If used this should come back on the result stream from the initial request. See the URL Mode Flow diagram which shows the intended usage. https://modelcontextprotocol.io/specification/draft/client/elicitation#url-mode-flow
I would remove all the changes in this file.
Even with MRTR we do allow progress notifications to go back on Result streams outside of subscription listen.
| safe range for integers represented using IEEE754 double-precision floating point numbers (−2<sup>53</sup>+1 to 2<sup>53</sup>−1) | ||
| - **MAY** be applied to properties at any nesting depth within the `inputSchema`, not | ||
| only top-level properties | ||
| - **MUST** only be applied to properties that are _statically reachable_ from the schema |
There was a problem hiding this comment.
We also define this same requirements in Streamable-http.mdx right?
Keeping these in sync will be a pain, should we just have this one reference the transport specific requirements?
| "jsonrpc": "2.0", | ||
| "method": "notifications/elicitation/complete", | ||
| "params": { | ||
| "_meta": { |
There was a problem hiding this comment.
I don't think this should be sent via subscription change should be reverted
|
I've been mulling over the Elicitation Notification question some more. The high level problem is in URL Mode Elicitation the client doesn't send the input required to the server, the URL does. There are a couple complications with this:
The Elicitation Complete Notification could solve 2, as clients could wait until they received an elicitation notification before retrying the request. However this notification is completely optional, therefore clients can not rely on this as the mechanism to retry requests. so we still have to solve 2 without the notification. Clients can mitigate 2 by waiting for the web form/pop up to be closed before they retry the request, but you still have race conditions under which the server code will need to block if the messages are received out of order. I'm actually now questioning the value of the elicitation/complete notification. Should we keep this? what value does this provide to clients? @maxisbey, @localden, @pja-ant, @felixweinberger, @halter73 |
What this does
Three normative fixes plus one clarification to draft transport/pattern rules where the current text is unimplementable or leaves conforming implementations free to diverge.
Changes
notifications/elicitation/completea delivery channel. The draft removed the GET stream, response-stream notifications must relate to the in-flight request, andSubscriptionFilterhad no field for elicitation completion — so the 'wait for the completion notification, then retry' flow the spec endorses could never receive the notification. Adds anelicitationCompleteopt-in toSubscriptionFilter; elicitation.mdx's URL-mode flow now subscribes viasubscriptions/listen.x-mcp-headerto statically reachable properties. The extraction rule was undefined for properties under arrayitems, composition keywords, or$ref— two conforming clients could disagree on whether a tool is valid. Annotations are now valid only on properties reachable via a chain ofpropertieskeys, with extraction and absent-value behavior defined.Mcp-Name. Tool/prompt names are only SHOULD-constrained, so a non-header-safe name made the tool permanently uncallable over Streamable HTTP with no defined encoding.MCP-Protocol-Versionheader on those POSTs to match a body_metafield that notifications do not carry — an unsatisfiable rule. In this revision the only client-sent notification,notifications/cancelled, is stdio-only (on Streamable HTTP, closing the SSE response stream is the cancellation signal), so the header–body match requirements are now stated for requests, and header requirements for notification POSTs are explicitly left undefined.Mcp-Method's Required For scope is corrected to "All requests".Verification
npm run generate:schemaartifacts committed;npm run prepandnpm run checkpass clean.