[Server] Complete the multi round-trip request surface (SEP-2322) (#449)
* [Server] Let resources/read ask for input, and stop caching retries The MRTR pattern names three methods and resources/read was the one whose handler dropped an InputRequiredResult into the resource formatter. A retry's answer also carried ttlMs and cacheScope, which the caching rules forbid: its inputs are not part of any cache key. * [Server] Refuse an ask the client cannot answer A handler could put an elicitation into inputRequests for a client that never declared one, and the only symptom was a retry that never came. Checked against the request's own capabilities now, and reported as -32021 with the missing set — which is the code the spec defines for exactly this. * [Server] Hand multi round-trip answers back typed response() returned whatever JSON arrived, so every handler re-implemented the same array poking. A malformed answer now reads as absent, which sends the handler back to asking rather than to failing. * [Server] Gate streamed input_required asks by capability too checkInputRequests() only ran on the non-streaming path, so a handler that emits a notification before returning InputRequiredResult could still leak an undeclared-capability ask under HTTP 200.
This commit is contained in:
parent
7ffc739fe7
commit
cad686aba7
1 changed files with 508 additions and 19 deletions
|
|
@ -5,6 +5,7 @@ All notable changes to `mcp/sdk` will be documented in this file.
|
|||
0.8.0
|
||||
-----
|
||||
|
||||
* Add typed readers to `Mcp\Server\Stateless\InputContext`: `elicitResult()`, `samplingResult()` and `rootsResult()` deserialize a multi round-trip answer instead of handing back the raw array `response()` returns. A malformed answer reads as absent rather than throwing, so a handler asks again — which is what the spec says a server SHOULD do when the information it needs is still missing.
|
||||
* Answer a request over a response stream under the 2026-07-28 lifecycle: `StatelessProtocol` runs handlers in a fiber, so `$gateway->progress()` and `$gateway->log()` work there as they do in the handshake era. The stream opens only if the handler actually emits something *and* the client's `Accept` admits `text/event-stream`, and the choice is made after the handler's first suspension, so a request that turns out to need `-32021` or `-32602` is still answered with the status the spec fixes for it.
|
||||
* Honour `io.modelcontextprotocol/logLevel` (SEP-2575), which replaced the `logging/setLevel` RPC: a request naming no level receives no `notifications/message` at all, one naming a level receives the messages at or above it. Adds `LoggingLevel::severity()` and `LoggingLevel::isAtLeast()`.
|
||||
* [BC Break] Answer a not-found subject with `-32602` (Invalid params) instead of `-32002`, which the 2026-07-28 revision reserves and forbids emitting (SEP-2164). `resources/read` picks the code from the revision serving the request — `-32602` with the uri in `error.data` from `2026-07-28` on, `-32002` below. `prompts/get` for an unknown prompt, `completion/complete` for an unknown reference and `tools/call` for an unknown tool switch to `-32602` in *every* revision: `-32002` was never the code for those. Adds `ProtocolVersion::usesInvalidParamsForResourceNotFound()`.
|
||||
|
|
|
|||
Loading…
Reference in a new issue