-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add 2026-01-21 weekly meeting notes #6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| # 2026-01-21 Transports WG (Weekly) | ||
|
|
||
| ## TL;DR | ||
| The group reached a consensus to move forward with deprecating unsolicited | ||
| server-to-client requests (sampling and elicitations) on the "get stream" to | ||
| simplify protocol design and address security concerns. This decision was | ||
| supported by data showing negligible usage in existing repositories. Mark Roth | ||
| presented a "Multi-Roundtrip Request" proposal designed to replace the current | ||
| SSE-based elicitation flow with a stateless, request-response model where | ||
| clients echo back state. The group discussed the technical implications of this | ||
| change. Finally, the group identified a need to reconcile this new proposal with | ||
| the existing "Tasks" mechanism and will invite the Tasks author (Luca) to the | ||
| next meeting. | ||
|
|
||
| ## Detailed Summary | ||
|
|
||
| ### Deprecation of Unsolicited Requests | ||
| * **Proposal to Remove:** Shaun Smith proposed assuming that unsolicited | ||
| sampling and elicitations (server-to-client requests) are removed from the | ||
| session track. He argued that eliminating these unsolicited communications | ||
| resolves complex state transfer issues regarding cookies and session IDs. | ||
| * **Usage Data:** Peter Alexander shared analysis results from scanning several | ||
| thousand MCP repositories, finding only one instance of unsolicited sampling | ||
| usage (which belonged to Shaun Smith). | ||
| * **Decision:** The group agreed to draft a Specification Enhancement Proposal | ||
| (SEP) to formally deprecate unsolicited requests on the /GET stream. | ||
| * **Scope:** The SEP will specifically disallow servers from sending sampling or | ||
| elicitation requests without an associated client request ID. | ||
|
|
||
| ### Technical Decisions: Multi-Roundtrip Requests | ||
| * **Problem Statement:** Mark Roth outlined the inefficiency of the current | ||
| elicitation flow, where a server opens an SSE stream for elicitation, forcing | ||
| the client to make a completely independent request that must be manually | ||
| linked back to the original context by the server. | ||
| * **Proposed Stateless Flow:** Mark presented a new pattern where the server | ||
| immediately terminates the initial request with a response indicating "more | ||
| information needed." The client then sends a completely new request containing | ||
| the original information plus the elicitation response. | ||
|
Comment on lines
+35
to
+38
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Did anyone discussed about how this would be implemented? This doesn't seem easy to implement gracefully. As a developer, I want to write my code once, with a certain logical flow, and if there's an elicitation, I expect to resume on that line. But with this flow, how is the code supposed to happen? Halt the execution at the point, and continue on that point on a different process doesn't seem a good idea. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be a pretty fundamental change to the tool authoring model for all developers, and would almost certainly be a big breaking change (I also brought this up last month when it was discussed in SFO). With that said, I think it might be possible to shim existing code onto it by essentially "replaying" tool calls on each re-attempt. Say you have something like this in a tool: If any step yields to the client, the entire sequence needs to be repeated from the beginning on the next tool call, because we assume (in general) that servers retain no state. The client makes request 1, and we get to step 3 ( ...and then the server rejects with (some equivalent of) an elicitation request. Then, the client makes request 2 (with an elicitation response squashed into the request this time), and we execute steps 1-3 again, except that at step 3, the server already has the elicitation response and continues to step 5: This isn't perfect, though, and it'd be safer with a state store of some kind to be able to somehow snapshot the request state after request 1. In my example above (which is not representative of what Mark has in mind), I'm assuming that everything before sending the elicitation is idempotent, however. In reality, it may not be. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Though actually, I think that my own idea here would conflict directly with how Tasks work, which could complicate things. In general, almost nothing you would want to wrap in a Task is naturally-idempotent like this, unless you choose to front-load elicitation/sampling and have all non-idempotent logic occur after receiving the responses (and typically sampling is used at the end of an operation).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Your speculation is what I've thought, which doesn't seem a good idea. And as you said in your own message at the end, the user may have a different execution by their own logic, so replying the steps will not be safe. |
||
| * **State Management (Hidden Fields vs. Cookies):** | ||
| * The group debated how to handle state persistence between the terminated | ||
| request and the retry. | ||
| * Gabriel Zimmerman and Simon Russell argued against using HTTP cookies, | ||
| suggesting a "hidden field" mechanism (opaque blob) is more appropriate | ||
| for per-tool-call state that should not persist globally. | ||
| * Mark Roth agreed, noting that cookies fail when multiple tool calls run in | ||
| parallel within the same session. | ||
| * **SDK Impact:** Peter Alexander and Simon Russell acknowledged that while | ||
| switching to this model will be painful for SDK maintainers to implement | ||
| initially, the resulting architecture is significantly easier to maintain and | ||
| conceptually simpler. | ||
|
|
||
| ### Interaction with Tasks | ||
| * **Overlap Analysis:** The group identified that the "Tasks" mechanism | ||
| currently duplicates some functionality discussed in the multi-roundtrip | ||
| proposal, specifically regarding polling and state retention. | ||
| * **Unified Vision:** Caitie McCaffrey noted that Tasks and Tool Calls are | ||
| similar but necessary; she described Tasks as a "promise over a network" and | ||
| suggested that the handling of elicitation responses in both systems needs to | ||
| align. | ||
|
Comment on lines
+53
to
+59
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The tricky piece here (I think) is that it becomes ambiguous how the "more information needed" rejection works when something is fragmented across multiple discrete polling requests. It makes sense that (for example) if an elicitation is required when creating a task, it would be handled exactly like a normal tool call and the creation step is what would "pause," but if an elicitation is required after that it would need to be delivered some other way. It should technically be fine to do the rejection on a polling request, but then that becomes stateful in an awkward orthogonal way to how multi-roundtrip is intended to work. In particular, you can't just replay or snapshot an entire Task's state (consider that it's often offloaded to another service altogether), so this puts you in a tangled state situation where it's unclear where the elicitation/sampling result actually needs to go. I'll need to work through some examples to figure this out, I think. |
||
| * **Next Steps:** The group agreed to invite Luca (author of Tasks) to the next | ||
| meeting to deeply dive into the relationship between the new stateless | ||
| proposal and the existing Tasks implementation. | ||
|
|
||
| ## Action Items | ||
| - [ ] **Shaun Smith** to write a Specification Enhancement Proposal (SEP) to | ||
| deprecate unsolicited server-to-client requests (sponsored by Peter | ||
| Alexander). | ||
| - [ ] **Mark Roth** to post the Multi-Roundtrip Request proposal to GitHub as a | ||
| Pull Request for community feedback. | ||
| - [ ] **Caitie McCaffrey** to write a strawman proposal detailing the overlap | ||
| between "Tasks" and the current multi-roundtrip proposal. | ||
| - [ ] **Kurtis Van Gent** to invite Luca to the next meeting to discuss the | ||
| relationship with tasks. | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to think through this more, but this execution path could also be an answer to both the ask for supporting immediate result acceptance in Tasks (modelcontextprotocol/modelcontextprotocol#1905) and being able to "surprise" a client with a Task - implementing this flow would potentially require some sort of dynamic response handling in a way that Tasks don't currently require, in that the client needs to not be waiting for a specific result type. Not certain yet though, just throwing the idea out there right now.