You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Add MRTR-native backcompat: resolve IncompleteResultException via legacy JSON-RPC
When a tool throws IncompleteResultException and the client doesn't
support MRTR, the server now resolves each InputRequest by sending the
corresponding standard JSON-RPC call (elicitation, sampling, roots) to
the client and retries the handler with the responses. This allows
authors to write a single MRTR-native tool implementation that works
with any client.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: docs/concepts/mrtr/mrtr.md
+39-1Lines changed: 39 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -329,7 +329,45 @@ When a server has MRTR enabled but the connected client does not:
329
329
330
330
- The high-level API (`ElicitAsync`, `SampleAsync`) automatically falls back to sending standard JSON-RPC requests — no code changes needed.
331
331
- The low-level API reports `IsMrtrSupported == false`, allowing the tool to provide a custom fallback message.
332
-
- Throwing `IncompleteResultException` when MRTR is not supported results in a JSON-RPC error being returned to the client.
332
+
333
+
### Backward compatibility for MRTR-native tools
334
+
335
+
Tools written with the low-level MRTR pattern (`IncompleteResultException`) work automatically with clients that don't support MRTR. When a tool throws `IncompleteResultException` and the client hasn't negotiated MRTR, the SDK resolves each `InputRequest` by sending the corresponding standard JSON-RPC call (elicitation, sampling, or roots) to the client, then retries the handler with the resolved responses.
336
+
337
+
This means you can write a single tool implementation using the MRTR-native pattern and it will work with any client:
338
+
339
+
```csharp
340
+
[McpServerTool, Description("Get weather with user's preferred units")]
341
+
publicstaticstringGetWeather(
342
+
RequestContext<CallToolRequestParams>context,
343
+
stringlocation)
344
+
{
345
+
// On retry, inputResponses and requestState are populated
346
+
if (context.Params!.InputResponses?.TryGetValue("units", outvarresponse) ==true)
-**With an MRTR client**: The `IncompleteResult` is sent over the wire. The client resolves the elicitation and retries with `inputResponses`.
367
+
-**Without MRTR**: The SDK sends a standard `elicitation/create` JSON-RPC request to the client, collects the response, and retries the handler internally. The client never sees the `IncompleteResult`.
368
+
369
+
> [!NOTE]
370
+
> The backcompat retry loop resolves up to 10 rounds. Tools that need more rounds should use the high-level API (`ElicitAsync`) instead.
0 commit comments