sink receives one serialised JSON-RPC frame per call (the transport adds the newline terminator). progressToken is the originating request's _meta.progressToken, or Json.undefined when it carried none. negotiated is the protocol version agreed for this connection; it gates version-specific wire fields on the notifications this context emits (e.g. the message field on notifications/progress, which only exists from 2025-03-26 onward). This overload wires no server->client request channel (sendRequest throws, clientSupports is false).
As above, plus a server->client request channel: `serverRequest(method, params)` writes the request and blocks the current task until the client's reply (the DuplexChannel correlates it on its read loop), returning the result or throwing on error. clientCaps are the capabilities the client declared at initialize, so clientSupports can gate sample/elicit. serverStateless mirrors server.mode == ServerMode.stateless: when true, server-initiated requests are refused (a stateless server has no per-peer connection to carry the round-trip), exactly as on the HTTP transport.
Whether the client has sent a notifications/cancelled for this request (basic/utilities/cancellation). A long-running handler SHOULD poll this and, when true, stop work and free resources promptly; the server suppresses the late response for a cancelled request regardless. Always false on transports that cannot deliver an out-of-band cancellation while a request is in flight (e.g. the in-process / stdio NullContext).
Emit a notifications/progress. No-op if the originating request carried no _meta.progressToken.
Emit a notifications/message (logging) at the given level. data may be any JSON value (commonly a string or object); logger is optional.
Send sampling/createMessage and block until the client responds, returning the raw result Json. The transport primitive behind sample; gating lives in sample, so a channel-less context just throws here.
Send elicitation/create and block until the client responds, returning the raw result Json. The transport primitive behind elicit/elicitUrl.
Send roots/list and block until the client responds, returning the raw result Json. The transport primitive behind listRoots.
Whether the connected client advertised cap.
True when this request is on a stateless (MRTR) protocol — the draft revision, where there is no server->client channel. On such requests a tool handler must NOT call elicit/sample (they throw); instead it returns ToolResponse.inputRequired(...) and reads the client's answers from inputResponses on the retried request. False on 2025-era requests.
The input responses the client attached when resubmitting an MRTR request, keyed by the InputRequest.id the server issued on the prior round. Empty on the first call and on non-stateless requests.
The opaque MRTR (SEP-2322) requestState the client echoed back from the server's prior InputRequiredResult (params.requestState). Empty on the first call and when the server sent no state. The server owns this value (the client treats it as opaque), so handlers MUST validate it as untrusted input.
The validated OAuth 2.1 access-token info for this request, when the transport enforces authorization (Streamable HTTP with a configured ResourceServerConfig). TokenInfo.valid is false on transports without auth (stdio, in-process) or when no token was required; handlers that need the authenticated subject or token scopes read it here.
Request an LLM completion from the client (sampling/createMessage). Throws on a stateless (MRTR) request — use ToolResponse.inputRequired instead — or if the client does not support sampling.
Typed convenience over sample(Json): build a CreateMessageRequest, send it, and parse the client's reply into a CreateMessageResult. Same preconditions and exceptions as the JSON overload.
Request structured user input from the client (elicitation/create). requestedSchema must be a JSON Schema object. Throws on a stateless (MRTR) request — use ToolResponse.inputRequired instead — or if the client does not support elicitation.
Typed convenience over elicit(string, Json): derive the form requestedSchema from the flat struct T via jsonSchemaOf!T, send the elicitation, and return the typed ElicitResult. On an accept, decode the collected values with result.contentAs!T. T must be a flat struct of scalar fields (string / number / integer / boolean / enum, optionally Nullable) — the elicitation schema restriction (SEP-1034/1330) forbids nested objects and arrays, enforced here at compile time.
Request URL-mode elicitation from the client (elicitation/create with mode: "url", introduced in 2025-11-25). Directs the user to complete an out-of-band interaction (e.g. an OAuth consent or a web form) at url; elicitationId correlates the request with the outcome the client reports back. Per spec a URL-mode request MUST specify mode: "url", a message, url, and elicitationId. Throws when the client did not declare the elicitation.url submode.
List the client's filesystem roots (roots/list). Per client/roots §Implementation Guidelines, checks the client's roots capability before usage and throws McpException if the client does not support it; parses the client's reply into a typed ListRootsResult. Throws on a stateless (MRTR) request — like sample/elicit, a server->client round-trip has no channel on the stateless protocol; use ToolResponse.inputRequired instead.
Typed convenience over inputResponses: decode the MRTR answer the client attached for id into T via T.fromJson (e.g. ElicitResult, CreateMessageResult, ListRootsResult — matching the InputRequest kind the server issued). Returns T.fromJson(Json.emptyObject) when no answer is present for id.
Decode the opaque MRTR requestState as JSON into T. The server owns the requestState value (the encoding contract is the server-side ToolResponse.inputRequired(reqs, state), which carries serializeToJson(state).toString()), so this is the typed inverse: parse the echoed string and deserialise it into T. Returns T.init when the client echoed no state (requestState empty). The value is untrusted input the client round-tripped, so a malformed payload throws.
Typed convenience over log(string, Json, string): emit a notifications/message at the given LogLevel with a plain string payload. Forwards to the JSON overload with the level's wire string and Json(message).
Typed convenience over log(string, Json, string): emit a notifications/message at the given LogLevel with an arbitrary JSON payload (commonly a structured object). Forwards to the string/Json overload with the level's wire string, so the level cannot be misspelled.
Integer-step convenience over `reportProgress(double, Nullable!double, string): a step counter passes done/total` directly without cast(double) and constructing a Nullable!double total.
Whether the client attached an MRTR answer for id on this (resubmitted) request (id present in inputResponses).
Whether this is an MRTR resubmission carrying client answers (inputResponses non-empty). False on the first round and on non-stateless requests.
A RequestContext for the stdio transport. The stdio transport is a single newline-delimited byte stream, and the MCP stdio spec permits the server to write any valid MCP message to stdout at any time — so server->client notifications (notifications/message logging and notifications/progress) are serialised and pushed to the transport's write sink as the handler emits them, out-of-band of the request's eventual reply.
The stdio transport runs each request handler in its own cooperative vibe task while the channel's read loop keeps demultiplexing inbound lines, so an out-of-band notifications/cancelled is dispatched (flipping the matching in-flight CancellationToken) *concurrently* with a running handler — the handler's ctx.isCancelled() simply observes the flipped token.