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
Gate resolver egress on the request channel's sendability
The legacy capability gate keyed on whether the handshake's declaration
was visible, which let a session initialized with a bare
notifications/initialized (no declared capabilities, live back-channel)
receive ungated requests. Gate on the request-scoped channel's
can_send_request instead, the channel these sends actually ride, so any
sendable session is checked and a channel-less one keeps failing with
its no-back-channel error. Adds ServerSession.can_send_request and a
bare-initialized regression test, and corrects docs wording: tool_choice
counts toward sampling.tools, the sampling.tools declaration needs the
explicit client field, and the v1 claims are scoped to what v1 checked.
Copy file name to clipboardExpand all lines: docs/handlers/dependencies.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -142,7 +142,7 @@ Elicitation is one of the three questions a resolver can ask, and the multi-roun
142
142
--8<--"docs_src/dependencies/tutorial004.py"
143
143
```
144
144
145
-
* The framework routes these exactly like `Elicit`: inside the multi-round-trip `tools/call` on **2026-07-28**, over the standalone server->client request on **2025-11-25**. On either transport it refuses with a `-32021` protocol error when the client never declared the matching capability (`sampling`, `roots`, `elicitation`; `sampling.tools` when the request carries tools).
145
+
* The framework routes these exactly like `Elicit`: inside the multi-round-trip `tools/call` on **2026-07-28**, over the standalone server->client request on **2025-11-25**. An undeclared capability refuses the call with a `-32021` protocol error (`sampling`, `roots`, form `elicitation`; `sampling.tools` when the request carries `tools` or `tool_choice`).
146
146
* Everything the info box above says about questions applies unchanged: a `Sample` request is matched to its recorded result by its exact rendering, so build it deterministically from the tool's arguments and earlier answers; the client then pays for the LLM call once per tool call, not once per round. The recorded result rides `request_state` for the rest of the call, so a very large completion makes every remaining round-trip heavier.
147
147
* The standalone sampling and roots *features* are deprecated at 2026-07-28 (SEP-2577). New servers that need the client's model ask through this carrier; servers that don't should integrate with an LLM provider directly. `include_context` values other than `"none"` are themselves deprecated; avoid them.
Copy file name to clipboardExpand all lines: docs/handlers/sampling-and-roots.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -16,7 +16,7 @@ A resolver returns `Sample(...)` and the tool receives the completion, through t
16
16
```
17
17
18
18
*`Sample(messages, max_tokens=...)` mirrors the `sampling/createMessage` parameters. The injected value is the client's `CreateMessageResult`; pass `tools=[...]` and it becomes a `CreateMessageResultWithTools` instead.
19
-
* The client must have declared the `sampling` capability (`sampling.tools` if you pass tools). If it didn't, the call fails with a `-32021` protocol error before anything is sent.
19
+
* The client must have declared the `sampling` capability (`sampling.tools` if you pass `tools` or `tool_choice`). If it didn't, the call fails with a `-32021` protocol error instead of sending a request the client cannot handle. A pre-2026 session with no back-channel fails with its usual no-back-channel error, since there is nothing to send on.
20
20
* At `2026-07-28` the request is delivered inside the multi-round-trip flow (**[Multi-round-trip requests](multi-round-trip.md)**); on `2025-11-25` it is a standalone request to the client. The code is the same either way, but mind the multi-round-trip rule: the request must render identically across retry rounds, so build it only from the tool's arguments and other stable data.
21
21
* Leave `include_context` alone: values other than `"none"` are themselves deprecated (SEP-2596) and need a capability almost no client declares.
22
22
@@ -29,7 +29,7 @@ Roots are the folders the client says the server may operate on. They are inform
29
29
```
30
30
31
31
* The injected `ListRootsResult` carries a list of `Root`s: a `file://` URI and an optional display name.
32
-
* The gate is the same as for sampling: without a declared `roots` capability the call fails with `-32021`before a request is sent.
32
+
* The gate is the same as for sampling: without a declared `roots` capability the call fails with `-32021`instead of sending the request.
33
33
34
34
On the other side of the wire, the client answers both requests with the callbacks it already has: `sampling_callback` and `list_roots_callback`, covered in **[Client callbacks](../client/callbacks.md)**.
35
35
@@ -40,7 +40,7 @@ On the other side of the wire, the client answers both requests with the callbac
40
40
## Recap
41
41
42
42
* Return `Sample(...)` or `ListRoots()` from a resolver; the tool receives the `CreateMessageResult` or `ListRootsResult` like any other dependency.
43
-
* The client must declare the matching capability, or the call fails with `-32021`before a request is sent.
43
+
* The client must declare the matching capability, or the call fails with `-32021`instead of a request being sent.
44
44
* Both features are deprecated at `2026-07-28`: fully functional for now, wrong for new designs. Prefer provider APIs over sampling and explicit parameters over roots.
45
45
46
46
Reporting how far along a slow tool is: **[Progress](progress.md)**.
0 commit comments