Improvements and fixes (#223)
Some checks failed
CI / Test (macos-latest, Swift 6.1.0) (push) Has been cancelled
CI / Test (ubuntu-latest, Swift 6.1.0) (push) Has been cancelled
CI / MCP Conformance Tests (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / Linux Static SDK Build (6.1.2 - ubuntu-latest) (push) Has been cancelled

* feat: added http transport context to the task local execution

* fix: added refresh_token to the grantTypes for DCR

* chore: updated documentation
This commit is contained in:
yehorsobko 2026-04-29 13:34:21 +02:00 • committed by GitHub
commit a0ae212ebf
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -298,13 +298,41 @@ public actor Server {
// MARK: - Request Context
/// The JSON-RPC request ID of the currently executing method handler.
/// Per-dispatch context the SDK attaches to the currently executing handler.
///
/// Exposed via the ``Server/currentHandlerContext`` task-local so method
/// handlers can observe the originating HTTP request (headers, auth, path,
/// body) without changing the `withMethodHandler` signature.
public struct HandlerContext: Sendable {
/// The JSON-RPC request id of the in-flight request. SDK-internal use
/// (e.g. transports closing an SSE stream mid-call per SEP-1699).
package let id: ID
/// The originating HTTP request, if the active transport conforms to
/// ``HTTPContextProviding``. `nil` for transports that don't carry HTTP
/// context (stdio, in-memory) or for handlers reached off the dispatch
/// path.
public let httpContext: HTTPRequest?
package init(id: ID, httpContext: HTTPRequest?) {
self.id = id
self.httpContext = httpContext
}
}
/// The handler context for the currently executing method handler.
///
/// Set via `@TaskLocal` before dispatching each request, so it propagates
/// automatically into the handler task. Accessible package-wide for
/// transports that need to identify the active request (e.g. closing an
/// SSE stream mid-call for reconnection testing per SEP-1699).
@TaskLocal package static var currentRequestID: ID? = nil
/// automatically into the handler task. `nil` outside of a handler.
///
/// When spawning `Task.detached { … }` from inside a handler, capture the
/// value up front — detached tasks do not inherit task-locals:
///
/// ```swift
/// let ctx = Server.currentHandlerContext
/// Task.detached { await doWork(with: ctx?.httpContext) }
/// ```
@TaskLocal public static var currentHandlerContext: HandlerContext? = nil
// MARK: - Registration
@ -750,10 +778,17 @@ public actor Server {
return response
}
// Ask the transport for the originating HTTP request so handlers can observe
// headers/auth via `Server.currentHandlerContext?.httpContext`. Transports
// that don't carry HTTP context (stdio, in-memory) don't conform.
let httpContext = await (connection as? any HTTPContextProviding)?
.httpRequestContext(for: request.id)
let handlerContext = HandlerContext(id: request.id, httpContext: httpContext)
// Create a task to handle the request with cancellation support.
// Set currentRequestID as a task local so handlers can identify the active request.
// Set currentHandlerContext as a task local so handlers see it.
var handlerTask: Task<Response<AnyMethod>, Error>!
Server.$currentRequestID.withValue(request.id) {
Server.$currentHandlerContext.withValue(handlerContext) {
handlerTask = Task<Response<AnyMethod>, Error> {
do {
// Check if task was cancelled before starting