Multi Round-Trip Requests (MRTR) (#1458)
This commit is contained in:
parent
8202bcc932
commit
f6dbe4372f
1 changed files with 5832 additions and 103 deletions
|
|
@ -120,3 +120,55 @@ McpClientOptions options = new()
|
|||
### Capability negotiation
|
||||
|
||||
Sampling requires the client to advertise the `sampling` capability. This is handled automatically — when a <xref:ModelContextProtocol.Client.McpClientHandlers.SamplingHandler> is set, the client includes the sampling capability during initialization. The server can check whether the client supports sampling before calling <xref:ModelContextProtocol.Server.McpServer.SampleAsync*>; if sampling is not supported, the method throws <xref:System.InvalidOperationException>.
|
||||
|
||||
### Multi Round-Trip Requests (MRTR)
|
||||
|
||||
[MRTR](xref:mrtr) is the SEP-2322 mechanism for server-driven input requests, finalized in protocol revision `DRAFT-2026-v1`. Under the draft protocol, the server-to-client `sampling/createMessage` request method is removed; the recommended way to ask the client to sample from a server handler is to throw <xref:ModelContextProtocol.Protocol.InputRequiredException> and let the SDK emit an <xref:ModelContextProtocol.Protocol.InputRequiredResult> on the wire.
|
||||
|
||||
> [!IMPORTANT]
|
||||
> `SampleAsync` and `AsSamplingChatClient` throw `InvalidOperationException("Sampling is not supported in stateless mode.")` whenever the server is running stateless — which includes every Streamable HTTP server under `DRAFT-2026-v1` once that revision is forced to stateless-only in a future PR. Stdio servers and current-protocol stateful Streamable HTTP servers continue to work via the legacy server-to-client `sampling/createMessage` request flow. For code that needs to run on stateless servers — including all `DRAFT-2026-v1` Streamable HTTP servers going forward — throw `InputRequiredException` from your handler instead. It works under both protocols and both session modes.
|
||||
|
||||
For example:
|
||||
|
||||
```csharp
|
||||
[McpServerTool, Description("Tool that samples via MRTR")]
|
||||
public static string SampleWithMrtr(
|
||||
McpServer server,
|
||||
RequestContext<CallToolRequestParams> context)
|
||||
{
|
||||
// On retry, process the client's sampling response
|
||||
if (context.Params!.InputResponses?.TryGetValue("llm_call", out var response) is true)
|
||||
{
|
||||
var text = response.Deserialize(InputResponse.CreateMessageResultJsonTypeInfo)?.Content
|
||||
.OfType<TextContentBlock>().FirstOrDefault()?.Text;
|
||||
return $"LLM said: {text}";
|
||||
}
|
||||
|
||||
if (!server.IsMrtrSupported)
|
||||
{
|
||||
return "This tool requires MRTR support (DRAFT-2026-v1, or a stateful current-protocol session).";
|
||||
}
|
||||
|
||||
// First call — request LLM completion from the client
|
||||
throw new InputRequiredException(
|
||||
inputRequests: new Dictionary<string, InputRequest>
|
||||
{
|
||||
["llm_call"] = InputRequest.ForSampling(new CreateMessageRequestParams
|
||||
{
|
||||
Messages =
|
||||
[
|
||||
new SamplingMessage
|
||||
{
|
||||
Role = Role.User,
|
||||
Content = [new TextContentBlock { Text = "Summarize the data" }]
|
||||
}
|
||||
],
|
||||
MaxTokens = 256
|
||||
})
|
||||
},
|
||||
requestState: "awaiting-sample");
|
||||
}
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> See [Multi Round-Trip Requests (MRTR)](xref:mrtr) for the full protocol details, including load shedding, multiple round trips, and the compatibility matrix.
|
||||
|
|
|
|||
Loading…
Reference in a new issue