Message Structure Proposal to align MRTR & Tasks#9
Conversation
Updated pros and cons for MRTR & Tasks message structure options.
| 6. <b>Server Response</b> returns `elicitation/create` to request additional input | ||
| ```json | ||
| { | ||
| "id": 3, |
There was a problem hiding this comment.
This isn't quite right as stated - this is:
- a server-to-client request (with its own request ID)
- that occurs as a side-effect of a
tasks/resultclient-to-server request
In Tasks, we're not altering the fundamental request/response flow (I mean we are actually with CreateTaskResult, but that's it) - what we're doing is creating an opportunity for the server to open an SSE stream to side-channel an elicitation request on, independent of the final task result itself. The server is actually allowed to open this side-channel in response to any request (or even send messages on the background stream), but we specifically require tasks/result to block until a terminal state to reserve it for this purpose.
The sequence diagram from the spec shows the client terminating the stream after receiving the elicitation request, but that's not actually required even though it is allowed.
There was a problem hiding this comment.
The sequence diagram from the spec shows the client terminating the stream after receiving the elicitation request, but that's not actually required even though it is allowed.
Does the TS SDK client terminate the result stream after receiving a request? I assume not. If it did, it would by heavily relying on Last-Event-Id based stream resumability to work so it doesn't miss any messages when it comes back, and I'm not sure how widely supported that is even for MCP servers that support tasks.
There was a problem hiding this comment.
@LucaButBoring ack on how it behaves today. One of the goals with the MRTR is to eliminate Server initiated messages, so this is the proposal on how the request flow would change to accommodate that today.
Also in the December meetup we discussed having the SSE be an option for performance but not a required part of functionality since it is Optional in the protocol itself. Additionally the current behavior adds a lot of complexity for what could be a request/response pattern.
There was a problem hiding this comment.
The sequence diagram from the spec shows the client terminating the stream after receiving the elicitation request, but that's not actually required even though it is allowed.
Does the TS SDK client terminate the result stream after receiving a request? I assume not. If it did, it would by heavily relying on
Last-Event-Idbased stream resumability to work so it doesn't miss any messages when it comes back, and I'm not sure how widely supported that is even for MCP servers that support tasks.
The client does not proactively terminate streams, correct - that flow can use regular stream resumability there, too (though with MRTR we might be able to do away with even that for the most-common use cases).
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 4, |
There was a problem hiding this comment.
Should reflect the request ID of the elicitation request
There was a problem hiding this comment.
👍 That probably means that the elicitation/create request should get a new ID rather than reusing the tasks/result request ID.
There was a problem hiding this comment.
Good call outs, I think this is a place where the spec is ambiguous and we should align ourselves here. Right now we have MCP-Session-Id (slated to be removed), MessageId, and TaskId all encapsulating some state.
Is the JsonRPC Envelope Id a piece of state that persists across sessions, or is it something that is tied to request/response flow.
There was a problem hiding this comment.
Is the JsonRPC Envelope Id a piece of state that persists across sessions, or is it something that is tied to request/response flow.
From requests:
The request ID MUST NOT have been previously used by the requestor within the same session.
But notably, this part of the spec doesn't actually define what a session is. I am at least certain that multiple clients can use the same request IDs as each other with a given server.
| 11. <b>Client Request</b> calls `tasks/result` to get the final result of the `Task` from the server. | ||
| Client Message | ||
| ```json | ||
| { | ||
| "id": 6, |
There was a problem hiding this comment.
The client is also allowed to keep a stream from the initial tasks/result request open, in which case the server response will have an id of 3 (as that would be the response to the tasks/result request).
There was a problem hiding this comment.
Gotcha in how it works today, see above I'm trying to model how this would work without requiring the SSE stream since its marked as Optional in the spec.
| ```json | ||
| { | ||
| "id": 3, | ||
| "jsonrpc": "2.0", | ||
| "result":{ | ||
| "content": [ | ||
| { | ||
| "type": "elicitation", | ||
| "mode": "form", | ||
| "message": "Please provide the input string to echo back", | ||
| "requestedSchema": | ||
| { | ||
| "type": "object", | ||
| "properties": | ||
| { | ||
| "input": {"type": "string"} | ||
| }, | ||
| "required": ["input"] | ||
| } | ||
| }], | ||
| "isError": false, | ||
| } | ||
| } | ||
| ``` |
There was a problem hiding this comment.
How would the client send the response back to the server, here?
There was a problem hiding this comment.
I assume as part of the "dependent_responses" as described in #7 for MRTR or continue as part of an independent request for Tasks.
There was a problem hiding this comment.
My understanding is that Elicitation responses get sent to the POST /mcp endpoint today anyway. It would include the task metadata to be routed to the right task on the server handling the request. Because we have the task_id as the unifying session/state identifier for this request we can use that to route, and don't need a persistent connection, MCP-Session-Id or the Json-RPC Id.
This is how I have it in my prototype implementation.
There was a problem hiding this comment.
I'm more wondering how separate elicitation requests are kept unique - today that's via request IDs, and in the MRTR example in #7, that's via named identifiers, but there doesn't seem to be anything equivalent here. A task can have multiple elicitations, so the task ID alone isn't enough to disambiguate them.
| 6. <b>Server Response</b> returns `elicitation/create` to request additional input | ||
| ```json | ||
| { | ||
| "id": 3, |
There was a problem hiding this comment.
The sequence diagram from the spec shows the client terminating the stream after receiving the elicitation request, but that's not actually required even though it is allowed.
Does the TS SDK client terminate the result stream after receiving a request? I assume not. If it did, it would by heavily relying on Last-Event-Id based stream resumability to work so it doesn't miss any messages when it comes back, and I'm not sure how widely supported that is even for MCP servers that support tasks.
| ```json | ||
| { | ||
| "jsonrpc": "2.0", | ||
| "id": 4, |
There was a problem hiding this comment.
👍 That probably means that the elicitation/create request should get a new ID rather than reusing the tasks/result request ID.
| ```json | ||
| { | ||
| "id": 3, | ||
| "jsonrpc": "2.0", | ||
| "result":{ | ||
| "content": [ | ||
| { | ||
| "type": "elicitation", | ||
| "mode": "form", | ||
| "message": "Please provide the input string to echo back", | ||
| "requestedSchema": | ||
| { | ||
| "type": "object", | ||
| "properties": | ||
| { | ||
| "input": {"type": "string"} | ||
| }, | ||
| "required": ["input"] | ||
| } | ||
| }], | ||
| "isError": false, | ||
| } | ||
| } | ||
| ``` |
There was a problem hiding this comment.
I assume as part of the "dependent_responses" as described in #7 for MRTR or continue as part of an independent request for Tasks.
Co-authored-by: Stephen Halter <halter73@gmail.com>
Adding additional overview to capture Discord discussion
| "result": | ||
| { | ||
| "taskId": "echo_dc792e24-01b5-4c0a-abcb-0559848ca3c5", | ||
| "status": "input_require", |
There was a problem hiding this comment.
| "status": "input_require", | |
| "status": "input_required", |
Co-authored-by: shaun smith <1936278+evalstate@users.noreply.github.com>
|
Closing this as the discussion and proposal is incorporated into SEP-XXXX: Multi Round-Trip Requests |
Updated pros and cons for MRTR & Tasks message structure options, This is an addendum to Multi Round-Trip Request (MRTR) Proposal.
This proposal is aligned with MRTR proposal and dives deeper into options on message structure and ensuring the changes align with Tasks.
It is informed by a test implementation of an EchoTool that can work as a standard Tool, Task and also request Elicitations.