{"version":3,"file":"index.mjs","names":["task: Task","resourceMetadata: OAuthProtectedResourceMetadata | undefined","authorizationServerUrl: string | URL","metadata: AuthorizationServerMetadata | undefined","resource: URL | undefined","tokens","resourceMetadataUrl: URL | undefined","url: URL","urlsToTry: { url: URL; type: 'oauth' | 'oidc' }[]","authorizationServerUrl: string | undefined","authorizationUrl: URL","json: unknown","tokenRequestParams: URLSearchParams | undefined","registrationUrl: URL","key: unknown","_client: Client","_clientInfo: Implementation","parseResult","defaultLogger: RequestLogger","code: number | undefined","event: ErrorEvent","headers: RequestInit['headers'] & Record<string, string>","error","message: JSONRPCMessage","env: Record<string, string>","DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS: StreamableHTTPReconnectionOptions","headers: RequestInit['headers'] & Record<string, string>","lastEventId: string | undefined","error","_defaultValidator: jsonSchemaValidator | undefined","coreFromJsonSchema"],"sources":["../../core/src/experimental/tasks/helpers.ts","../../core/src/experimental/tasks/stores/inMemory.ts","../src/client/auth.ts","../src/client/authExtensions.ts","../src/experimental/tasks/client.ts","../src/client/client.ts","../src/client/crossAppAccess.ts","../src/client/middleware.ts","../src/client/sse.ts","../src/client/stdio.ts","../src/client/streamableHttp.ts","../src/fromJsonSchema.ts"],"sourcesContent":["/**\n * Experimental task capability assertion helpers.\n * WARNING: These APIs are experimental and may change without notice.\n *\n * @experimental\n */\n\nimport { SdkError, SdkErrorCode } from '../../errors/sdkErrors.js';\n\n/**\n * Type representing the task requests capability structure.\n * This is derived from `ClientTasksCapability.requests` and `ServerTasksCapability.requests`.\n */\ninterface TaskRequestsCapability {\n    tools?: { call?: object };\n    sampling?: { createMessage?: object };\n    elicitation?: { create?: object };\n}\n\n/**\n * Asserts that task creation is supported for `tools/call`.\n * Used to implement the `assertTaskCapability` or `assertTaskHandlerCapability` abstract methods on Protocol.\n *\n * @param requests - The task requests capability object\n * @param method - The method being checked\n * @param entityName - `'Server'` or `'Client'` for error messages\n * @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported\n *\n * @experimental\n */\nexport function assertToolsCallTaskCapability(\n    requests: TaskRequestsCapability | undefined,\n    method: string,\n    entityName: 'Server' | 'Client'\n): void {\n    if (!requests) {\n        throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);\n    }\n\n    switch (method) {\n        case 'tools/call': {\n            if (!requests.tools?.call) {\n                throw new SdkError(\n                    SdkErrorCode.CapabilityNotSupported,\n                    `${entityName} does not support task creation for tools/call (required for ${method})`\n                );\n            }\n            break;\n        }\n\n        default: {\n            // Method doesn't support tasks, which is fine - no error\n            break;\n        }\n    }\n}\n\n/**\n * Asserts that task creation is supported for `sampling/createMessage` or `elicitation/create`.\n * Used to implement the `assertTaskCapability` or `assertTaskHandlerCapability` abstract methods on Protocol.\n *\n * @param requests - The task requests capability object\n * @param method - The method being checked\n * @param entityName - `'Server'` or `'Client'` for error messages\n * @throws {@linkcode SdkError} with {@linkcode SdkErrorCode.CapabilityNotSupported} if the capability is not supported\n *\n * @experimental\n */\nexport function assertClientRequestTaskCapability(\n    requests: TaskRequestsCapability | undefined,\n    method: string,\n    entityName: 'Server' | 'Client'\n): void {\n    if (!requests) {\n        throw new SdkError(SdkErrorCode.CapabilityNotSupported, `${entityName} does not support task creation (required for ${method})`);\n    }\n\n    switch (method) {\n        case 'sampling/createMessage': {\n            if (!requests.sampling?.createMessage) {\n                throw new SdkError(\n                    SdkErrorCode.CapabilityNotSupported,\n                    `${entityName} does not support task creation for sampling/createMessage (required for ${method})`\n                );\n            }\n            break;\n        }\n\n        case 'elicitation/create': {\n            if (!requests.elicitation?.create) {\n                throw new SdkError(\n                    SdkErrorCode.CapabilityNotSupported,\n                    `${entityName} does not support task creation for elicitation/create (required for ${method})`\n                );\n            }\n            break;\n        }\n\n        default: {\n            // Method doesn't support tasks, which is fine - no error\n            break;\n        }\n    }\n}\n","/**\n * In-memory implementations of {@linkcode TaskStore} and {@linkcode TaskMessageQueue}.\n * @experimental\n */\n\nimport type { Request, RequestId, Result, Task } from '../../../types/index.js';\nimport type { CreateTaskOptions, QueuedMessage, TaskMessageQueue, TaskStore } from '../interfaces.js';\nimport { isTerminal } from '../interfaces.js';\n\ninterface StoredTask {\n    task: Task;\n    request: Request;\n    requestId: RequestId;\n    sessionId?: string;\n    result?: Result;\n}\n\n/**\n * In-memory {@linkcode TaskStore} implementation for development and testing.\n * For production, use a database or distributed cache.\n * @experimental\n */\nexport class InMemoryTaskStore implements TaskStore {\n    private tasks = new Map<string, StoredTask>();\n    private cleanupTimers = new Map<string, ReturnType<typeof setTimeout>>();\n\n    /**\n     * Generates a unique task ID using Web Crypto API.\n     */\n    private generateTaskId(): string {\n        return crypto.randomUUID().replaceAll('-', '');\n    }\n\n    /** {@inheritDoc TaskStore.createTask} */\n    async createTask(taskParams: CreateTaskOptions, requestId: RequestId, request: Request, sessionId?: string): Promise<Task> {\n        // Generate a unique task ID\n        const taskId = this.generateTaskId();\n\n        // Ensure uniqueness\n        if (this.tasks.has(taskId)) {\n            throw new Error(`Task with ID ${taskId} already exists`);\n        }\n\n        const actualTtl = taskParams.ttl ?? null;\n\n        // Create task with generated ID and timestamps\n        const createdAt = new Date().toISOString();\n        const task: Task = {\n            taskId,\n            status: 'working',\n            ttl: actualTtl,\n            createdAt,\n            lastUpdatedAt: createdAt,\n            pollInterval: taskParams.pollInterval ?? 1000\n        };\n\n        this.tasks.set(taskId, {\n            task,\n            request,\n            requestId,\n            sessionId\n        });\n\n        // Schedule cleanup if ttl is specified\n        // Cleanup occurs regardless of task status\n        if (actualTtl) {\n            const timer = setTimeout(() => {\n                this.tasks.delete(taskId);\n                this.cleanupTimers.delete(taskId);\n            }, actualTtl);\n\n            this.cleanupTimers.set(taskId, timer);\n        }\n\n        return task;\n    }\n\n    /**\n     * Retrieves a stored task, enforcing session ownership when a sessionId is provided.\n     * Returns undefined if the task does not exist or belongs to a different session.\n     */\n    private getStoredTask(taskId: string, sessionId?: string): StoredTask | undefined {\n        const stored = this.tasks.get(taskId);\n        if (!stored) {\n            return undefined;\n        }\n        // Enforce session isolation: if a sessionId is provided and the task\n        // was created with a sessionId, they must match.\n        if (sessionId !== undefined && stored.sessionId !== undefined && stored.sessionId !== sessionId) {\n            return undefined;\n        }\n        return stored;\n    }\n\n    async getTask(taskId: string, sessionId?: string): Promise<Task | null> {\n        const stored = this.getStoredTask(taskId, sessionId);\n        return stored ? { ...stored.task } : null;\n    }\n\n    /** {@inheritDoc TaskStore.storeTaskResult} */\n    async storeTaskResult(taskId: string, status: 'completed' | 'failed', result: Result, sessionId?: string): Promise<void> {\n        const stored = this.getStoredTask(taskId, sessionId);\n        if (!stored) {\n            throw new Error(`Task with ID ${taskId} not found`);\n        }\n\n        // Don't allow storing results for tasks already in terminal state\n        if (isTerminal(stored.task.status)) {\n            throw new Error(\n                `Cannot store result for task ${taskId} in terminal status '${stored.task.status}'. Task results can only be stored once.`\n            );\n        }\n\n        stored.result = result;\n        stored.task.status = status;\n        stored.task.lastUpdatedAt = new Date().toISOString();\n\n        // Reset cleanup timer to start from now (if ttl is set)\n        if (stored.task.ttl) {\n            const existingTimer = this.cleanupTimers.get(taskId);\n            if (existingTimer) {\n                clearTimeout(existingTimer);\n            }\n\n            const timer = setTimeout(() => {\n                this.tasks.delete(taskId);\n                this.cleanupTimers.delete(taskId);\n            }, stored.task.ttl);\n\n            this.cleanupTimers.set(taskId, timer);\n        }\n    }\n\n    /** {@inheritDoc TaskStore.getTaskResult} */\n    async getTaskResult(taskId: string, sessionId?: string): Promise<Result> {\n        const stored = this.getStoredTask(taskId, sessionId);\n        if (!stored) {\n            throw new Error(`Task with ID ${taskId} not found`);\n        }\n\n        if (!stored.result) {\n            throw new Error(`Task ${taskId} has no result stored`);\n        }\n\n        return stored.result;\n    }\n\n    /** {@inheritDoc TaskStore.updateTaskStatus} */\n    async updateTaskStatus(taskId: string, status: Task['status'], statusMessage?: string, sessionId?: string): Promise<void> {\n        const stored = this.getStoredTask(taskId, sessionId);\n        if (!stored) {\n            throw new Error(`Task with ID ${taskId} not found`);\n        }\n\n        // Don't allow transitions from terminal states\n        if (isTerminal(stored.task.status)) {\n            throw new Error(\n                `Cannot update task ${taskId} from terminal status '${stored.task.status}' to '${status}'. Terminal states (completed, failed, cancelled) cannot transition to other states.`\n            );\n        }\n\n        stored.task.status = status;\n        if (statusMessage) {\n            stored.task.statusMessage = statusMessage;\n        }\n\n        stored.task.lastUpdatedAt = new Date().toISOString();\n\n        // If task is in a terminal state and has ttl, start cleanup timer\n        if (isTerminal(status) && stored.task.ttl) {\n            const existingTimer = this.cleanupTimers.get(taskId);\n            if (existingTimer) {\n                clearTimeout(existingTimer);\n            }\n\n            const timer = setTimeout(() => {\n                this.tasks.delete(taskId);\n                this.cleanupTimers.delete(taskId);\n            }, stored.task.ttl);\n\n            this.cleanupTimers.set(taskId, timer);\n        }\n    }\n\n    /** {@inheritDoc TaskStore.listTasks} */\n    async listTasks(cursor?: string, sessionId?: string): Promise<{ tasks: Task[]; nextCursor?: string }> {\n        const PAGE_SIZE = 10;\n\n        // Filter tasks by session ownership before pagination\n        const filteredTaskIds = [...this.tasks.entries()]\n            .filter(([, stored]) => {\n                if (sessionId === undefined || stored.sessionId === undefined) {\n                    return true;\n                }\n                return stored.sessionId === sessionId;\n            })\n            .map(([taskId]) => taskId);\n\n        let startIndex = 0;\n        if (cursor) {\n            const cursorIndex = filteredTaskIds.indexOf(cursor);\n            if (cursorIndex === -1) {\n                // Invalid cursor - throw error\n                throw new Error(`Invalid cursor: ${cursor}`);\n            } else {\n                startIndex = cursorIndex + 1;\n            }\n        }\n\n        const pageTaskIds = filteredTaskIds.slice(startIndex, startIndex + PAGE_SIZE);\n        const tasks = pageTaskIds.map(taskId => {\n            const stored = this.tasks.get(taskId)!;\n            return { ...stored.task };\n        });\n\n        const nextCursor = startIndex + PAGE_SIZE < filteredTaskIds.length ? pageTaskIds.at(-1) : undefined;\n\n        return { tasks, nextCursor };\n    }\n\n    /**\n     * Cleanup all timers (useful for testing or graceful shutdown)\n     */\n    cleanup(): void {\n        for (const timer of this.cleanupTimers.values()) {\n            clearTimeout(timer);\n        }\n        this.cleanupTimers.clear();\n        this.tasks.clear();\n    }\n\n    /**\n     * Get all tasks (useful for debugging)\n     */\n    getAllTasks(): Task[] {\n        return [...this.tasks.values()].map(stored => ({ ...stored.task }));\n    }\n}\n\n/**\n * In-memory {@linkcode TaskMessageQueue} implementation for development and testing.\n * For production, use Redis or another distributed queue.\n * @experimental\n */\nexport class InMemoryTaskMessageQueue implements TaskMessageQueue {\n    private queues = new Map<string, QueuedMessage[]>();\n\n    /**\n     * Generates a queue key from taskId.\n     * SessionId is intentionally ignored because taskIds are globally unique\n     * and tasks need to be accessible across HTTP requests/sessions.\n     */\n    private getQueueKey(taskId: string, _sessionId?: string): string {\n        return taskId;\n    }\n\n    /**\n     * Gets or creates a queue for the given task and session.\n     */\n    private getQueue(taskId: string, sessionId?: string): QueuedMessage[] {\n        const key = this.getQueueKey(taskId, sessionId);\n        let queue = this.queues.get(key);\n        if (!queue) {\n            queue = [];\n            this.queues.set(key, queue);\n        }\n        return queue;\n    }\n\n    /**\n     * Adds a message to the end of the queue for a specific task.\n     * Atomically checks queue size and throws if maxSize would be exceeded.\n     * @param taskId The task identifier\n     * @param message The message to enqueue\n     * @param sessionId Optional session ID for binding the operation to a specific session\n     * @param maxSize Optional maximum queue size - if specified and queue is full, throws an error\n     * @throws Error if maxSize is specified and would be exceeded\n     */\n    async enqueue(taskId: string, message: QueuedMessage, sessionId?: string, maxSize?: number): Promise<void> {\n        const queue = this.getQueue(taskId, sessionId);\n\n        // Atomically check size and enqueue\n        if (maxSize !== undefined && queue.length >= maxSize) {\n            throw new Error(`Task message queue overflow: queue size (${queue.length}) exceeds maximum (${maxSize})`);\n        }\n\n        queue.push(message);\n    }\n\n    /**\n     * Removes and returns the first message from the queue for a specific task.\n     * @param taskId The task identifier\n     * @param sessionId Optional session ID for binding the query to a specific session\n     * @returns The first message, or `undefined` if the queue is empty\n     */\n    async dequeue(taskId: string, sessionId?: string): Promise<QueuedMessage | undefined> {\n        const queue = this.getQueue(taskId, sessionId);\n        return queue.shift();\n    }\n\n    /**\n     * Removes and returns all messages from the queue for a specific task.\n     * @param taskId The task identifier\n     * @param sessionId Optional session ID for binding the query to a specific session\n     * @returns Array of all messages that were in the queue\n     */\n    async dequeueAll(taskId: string, sessionId?: string): Promise<QueuedMessage[]> {\n        const key = this.getQueueKey(taskId, sessionId);\n        const queue = this.queues.get(key) ?? [];\n        this.queues.delete(key);\n        return queue;\n    }\n}\n","import { CORS_IS_POSSIBLE } from '@modelcontextprotocol/client/_shims';\nimport type {\n    AuthorizationServerMetadata,\n    FetchLike,\n    OAuthClientInformation,\n    OAuthClientInformationFull,\n    OAuthClientInformationMixed,\n    OAuthClientMetadata,\n    OAuthMetadata,\n    OAuthProtectedResourceMetadata,\n    OAuthTokens\n} from '@modelcontextprotocol/core';\nimport {\n    checkResourceAllowed,\n    LATEST_PROTOCOL_VERSION,\n    OAuthClientInformationFullSchema,\n    OAuthError,\n    OAuthErrorCode,\n    OAuthErrorResponseSchema,\n    OAuthMetadataSchema,\n    OAuthProtectedResourceMetadataSchema,\n    OAuthTokensSchema,\n    OpenIdProviderDiscoveryMetadataSchema,\n    resourceUrlFromServerUrl\n} from '@modelcontextprotocol/core';\nimport pkceChallenge from 'pkce-challenge';\n\n/**\n * Function type for adding client authentication to token requests.\n */\nexport type AddClientAuthentication = (\n    headers: Headers,\n    params: URLSearchParams,\n    url: string | URL,\n    metadata?: AuthorizationServerMetadata\n) => void | Promise<void>;\n\n/**\n * Context passed to {@linkcode AuthProvider.onUnauthorized} when the server\n * responds with 401. Provides everything needed to refresh credentials.\n */\nexport interface UnauthorizedContext {\n    /** The 401 response — inspect `WWW-Authenticate` for resource metadata, scope, etc. */\n    response: Response;\n    /** The MCP server URL, for passing to {@linkcode auth} or discovery helpers. */\n    serverUrl: URL;\n    /** Fetch function configured with the transport's `requestInit`, for making auth requests. */\n    fetchFn: FetchLike;\n}\n\n/**\n * Minimal interface for authenticating MCP client transports with bearer tokens.\n *\n * Transports call {@linkcode AuthProvider.token | token()} before every request\n * to obtain the current token, and {@linkcode AuthProvider.onUnauthorized | onUnauthorized()}\n * (if provided) when the server responds with 401, giving the provider a chance\n * to refresh credentials before the transport retries once.\n *\n * For simple cases (API keys, gateway-managed tokens), implement only `token()`:\n * ```typescript\n * const authProvider: AuthProvider = { token: async () => process.env.API_KEY };\n * ```\n *\n * For OAuth flows, pass an {@linkcode OAuthClientProvider} directly — transports\n * accept either shape and adapt OAuth providers automatically via {@linkcode adaptOAuthProvider}.\n */\nexport interface AuthProvider {\n    /**\n     * Returns the current bearer token, or `undefined` if no token is available.\n     * Called before every request.\n     */\n    token(): Promise<string | undefined>;\n\n    /**\n     * Called when the server responds with 401. If provided, the transport will\n     * await this, then retry the request once. If the retry also gets 401, or if\n     * this method is not provided, the transport throws {@linkcode UnauthorizedError}.\n     *\n     * Implementations should refresh tokens, re-authenticate, etc. — whatever is\n     * needed so the next `token()` call returns a valid token.\n     */\n    onUnauthorized?(ctx: UnauthorizedContext): Promise<void>;\n}\n\n/**\n * Type guard distinguishing `OAuthClientProvider` from a minimal `AuthProvider`.\n * Transports use this at construction time to classify the `authProvider` option.\n *\n * Checks for `tokens()` + `clientInformation()` — two required `OAuthClientProvider`\n * methods that a minimal `AuthProvider` `{ token: ... }` would never have.\n */\nexport function isOAuthClientProvider(provider: AuthProvider | OAuthClientProvider | undefined): provider is OAuthClientProvider {\n    if (provider == null) return false;\n    const p = provider as OAuthClientProvider;\n    return typeof p.tokens === 'function' && typeof p.clientInformation === 'function';\n}\n\n/**\n * Standard `onUnauthorized` behavior for OAuth providers: extracts\n * `WWW-Authenticate` parameters from the 401 response and runs {@linkcode auth}.\n * Used by {@linkcode adaptOAuthProvider} to bridge `OAuthClientProvider` to `AuthProvider`.\n */\nexport async function handleOAuthUnauthorized(provider: OAuthClientProvider, ctx: UnauthorizedContext): Promise<void> {\n    const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(ctx.response);\n    const result = await auth(provider, {\n        serverUrl: ctx.serverUrl,\n        resourceMetadataUrl,\n        scope,\n        fetchFn: ctx.fetchFn\n    });\n    if (result !== 'AUTHORIZED') {\n        throw new UnauthorizedError();\n    }\n}\n\n/**\n * Adapts an `OAuthClientProvider` to the minimal `AuthProvider` interface that\n * transports consume. Called once at transport construction — the transport stores\n * the adapted provider for `_commonHeaders()` and 401 handling, while keeping the\n * original `OAuthClientProvider` for OAuth-specific paths (`finishAuth()`, 403 upscoping).\n */\nexport function adaptOAuthProvider(provider: OAuthClientProvider): AuthProvider {\n    return {\n        token: async () => {\n            const tokens = await provider.tokens();\n            return tokens?.access_token;\n        },\n        onUnauthorized: async ctx => handleOAuthUnauthorized(provider, ctx)\n    };\n}\n\n/**\n * Implements an end-to-end OAuth client to be used with one MCP server.\n *\n * This client relies upon a concept of an authorized \"session,\" the exact\n * meaning of which is application-defined. Tokens, authorization codes, and\n * code verifiers should not cross different sessions.\n *\n * Transports accept `OAuthClientProvider` directly via the `authProvider` option —\n * they adapt it to {@linkcode AuthProvider} internally via {@linkcode adaptOAuthProvider}.\n * No changes are needed to existing implementations.\n */\nexport interface OAuthClientProvider {\n    /**\n     * The URL to redirect the user agent to after authorization.\n     * Return `undefined` for non-interactive flows that don't require user interaction\n     * (e.g., `client_credentials`, `jwt-bearer`).\n     */\n    get redirectUrl(): string | URL | undefined;\n\n    /**\n     * External URL the server should use to fetch client metadata document\n     */\n    clientMetadataUrl?: string;\n\n    /**\n     * Metadata about this OAuth client.\n     */\n    get clientMetadata(): OAuthClientMetadata;\n\n    /**\n     * Returns an OAuth2 state parameter.\n     */\n    state?(): string | Promise<string>;\n\n    /**\n     * Loads information about this OAuth client, as registered already with the\n     * server, or returns `undefined` if the client is not registered with the\n     * server.\n     */\n    clientInformation(): OAuthClientInformationMixed | undefined | Promise<OAuthClientInformationMixed | undefined>;\n\n    /**\n     * If implemented, this permits the OAuth client to dynamically register with\n     * the server. Client information saved this way should later be read via\n     * {@linkcode OAuthClientProvider.clientInformation | clientInformation()}.\n     *\n     * This method is not required to be implemented if client information is\n     * statically known (e.g., pre-registered).\n     */\n    saveClientInformation?(clientInformation: OAuthClientInformationMixed): void | Promise<void>;\n\n    /**\n     * Loads any existing OAuth tokens for the current session, or returns\n     * `undefined` if there are no saved tokens.\n     */\n    tokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined>;\n\n    /**\n     * Stores new OAuth tokens for the current session, after a successful\n     * authorization.\n     */\n    saveTokens(tokens: OAuthTokens): void | Promise<void>;\n\n    /**\n     * Invoked to redirect the user agent to the given URL to begin the authorization flow.\n     */\n    redirectToAuthorization(authorizationUrl: URL): void | Promise<void>;\n\n    /**\n     * Saves a PKCE code verifier for the current session, before redirecting to\n     * the authorization flow.\n     */\n    saveCodeVerifier(codeVerifier: string): void | Promise<void>;\n\n    /**\n     * Loads the PKCE code verifier for the current session, necessary to validate\n     * the authorization result.\n     */\n    codeVerifier(): string | Promise<string>;\n\n    /**\n     * Adds custom client authentication to OAuth token requests.\n     *\n     * This optional method allows implementations to customize how client credentials\n     * are included in token exchange and refresh requests. When provided, this method\n     * is called instead of the default authentication logic, giving full control over\n     * the authentication mechanism.\n     *\n     * Common use cases include:\n     * - Supporting authentication methods beyond the standard OAuth 2.0 methods\n     * - Adding custom headers for proprietary authentication schemes\n     * - Implementing client assertion-based authentication (e.g., JWT bearer tokens)\n     *\n     * @param headers - The request headers (can be modified to add authentication)\n     * @param params - The request body parameters (can be modified to add credentials)\n     * @param url - The token endpoint URL being called\n     * @param metadata - Optional OAuth metadata for the server, which may include supported authentication methods\n     */\n    addClientAuthentication?: AddClientAuthentication;\n\n    /**\n     * If defined, overrides the selection and validation of the\n     * RFC 8707 Resource Indicator. If left undefined, default\n     * validation behavior will be used.\n     *\n     * Implementations must verify the returned resource matches the MCP server.\n     */\n    validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;\n\n    /**\n     * If implemented, provides a way for the client to invalidate (e.g. delete) the specified\n     * credentials, in the case where the server has indicated that they are no longer valid.\n     * This avoids requiring the user to intervene manually.\n     */\n    invalidateCredentials?(scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery'): void | Promise<void>;\n\n    /**\n     * Prepares grant-specific parameters for a token request.\n     *\n     * This optional method allows providers to customize the token request based on\n     * the grant type they support. When implemented, it returns the grant type and\n     * any grant-specific parameters needed for the token exchange.\n     *\n     * If not implemented, the default behavior depends on the flow:\n     * - For authorization code flow: uses `code`, `code_verifier`, and `redirect_uri`\n     * - For `client_credentials`: detected via `grant_types` in {@linkcode OAuthClientProvider.clientMetadata | clientMetadata}\n     *\n     * @param scope - Optional scope to request\n     * @returns Grant type and parameters, or `undefined` to use default behavior\n     *\n     * @example\n     * // For client_credentials grant:\n     * prepareTokenRequest(scope) {\n     *   return {\n     *     grantType: 'client_credentials',\n     *     params: scope ? { scope } : {}\n     *   };\n     * }\n     *\n     * @example\n     * // For authorization_code grant (default behavior):\n     * async prepareTokenRequest() {\n     *   return {\n     *     grantType: 'authorization_code',\n     *     params: {\n     *       code: this.authorizationCode,\n     *       code_verifier: await this.codeVerifier(),\n     *       redirect_uri: String(this.redirectUrl)\n     *     }\n     *   };\n     * }\n     */\n    prepareTokenRequest?(scope?: string): URLSearchParams | Promise<URLSearchParams | undefined> | undefined;\n\n    /**\n     * Saves the authorization server URL after RFC 9728 discovery.\n     * This method is called by {@linkcode auth} after successful discovery of the\n     * authorization server via protected resource metadata.\n     *\n     * Providers implementing Cross-App Access or other flows that need access to\n     * the discovered authorization server URL should implement this method.\n     *\n     * @param authorizationServerUrl - The authorization server URL discovered via RFC 9728\n     */\n    saveAuthorizationServerUrl?(authorizationServerUrl: string): void | Promise<void>;\n\n    /**\n     * Returns the previously saved authorization server URL, if available.\n     *\n     * Providers implementing Cross-App Access can use this to access the\n     * authorization server URL discovered during the OAuth flow.\n     *\n     * @returns The authorization server URL, or `undefined` if not available\n     */\n    authorizationServerUrl?(): string | undefined | Promise<string | undefined>;\n\n    /**\n     * Saves the resource URL after RFC 9728 discovery.\n     * This method is called by {@linkcode auth} after successful discovery of the\n     * resource metadata.\n     *\n     * Providers implementing Cross-App Access or other flows that need access to\n     * the discovered resource URL should implement this method.\n     *\n     * @param resourceUrl - The resource URL discovered via RFC 9728\n     */\n    saveResourceUrl?(resourceUrl: string): void | Promise<void>;\n\n    /**\n     * Returns the previously saved resource URL, if available.\n     *\n     * Providers implementing Cross-App Access can use this to access the\n     * resource URL discovered during the OAuth flow.\n     *\n     * @returns The resource URL, or `undefined` if not available\n     */\n    resourceUrl?(): string | undefined | Promise<string | undefined>;\n\n    /**\n     * Saves the OAuth discovery state after RFC 9728 and authorization server metadata\n     * discovery. Providers can persist this state to avoid redundant discovery requests\n     * on subsequent {@linkcode auth} calls.\n     *\n     * This state can also be provided out-of-band (e.g., from a previous session or\n     * external configuration) to bootstrap the OAuth flow without discovery.\n     *\n     * Called by {@linkcode auth} after successful discovery.\n     */\n    saveDiscoveryState?(state: OAuthDiscoveryState): void | Promise<void>;\n\n    /**\n     * Returns previously saved discovery state, or `undefined` if none is cached.\n     *\n     * When available, {@linkcode auth} restores the discovery state (authorization server\n     * URL, resource metadata, etc.) instead of performing RFC 9728 discovery, reducing\n     * latency on subsequent calls.\n     *\n     * Providers should clear cached discovery state on repeated authentication failures\n     * (via {@linkcode invalidateCredentials} with scope `'discovery'` or `'all'`) to allow\n     * re-discovery in case the authorization server has changed.\n     */\n    discoveryState?(): OAuthDiscoveryState | undefined | Promise<OAuthDiscoveryState | undefined>;\n}\n\n/**\n * Discovery state that can be persisted across sessions by an {@linkcode OAuthClientProvider}.\n *\n * Contains the results of RFC 9728 protected resource metadata discovery and\n * authorization server metadata discovery. Persisting this state avoids\n * redundant discovery HTTP requests on subsequent {@linkcode auth} calls.\n */\n// TODO: Consider adding `authorizationServerMetadataUrl` to capture the exact well-known URL\n// at which authorization server metadata was discovered. This would require\n// `discoverAuthorizationServerMetadata()` to return the successful discovery URL.\nexport interface OAuthDiscoveryState extends OAuthServerInfo {\n    /** The URL at which the protected resource metadata was found, if available. */\n    resourceMetadataUrl?: string;\n}\n\nexport type AuthResult = 'AUTHORIZED' | 'REDIRECT';\n\nexport class UnauthorizedError extends Error {\n    constructor(message?: string) {\n        super(message ?? 'Unauthorized');\n    }\n}\n\nexport type ClientAuthMethod = 'client_secret_basic' | 'client_secret_post' | 'none';\n\nfunction isClientAuthMethod(method: string): method is ClientAuthMethod {\n    return ['client_secret_basic', 'client_secret_post', 'none'].includes(method);\n}\n\nconst AUTHORIZATION_CODE_RESPONSE_TYPE = 'code';\nconst AUTHORIZATION_CODE_CHALLENGE_METHOD = 'S256';\n\n/**\n * Determines the best client authentication method to use based on server support and client configuration.\n *\n * Priority order (highest to lowest):\n * 1. `client_secret_basic` (if client secret is available)\n * 2. `client_secret_post` (if client secret is available)\n * 3. `none` (for public clients)\n *\n * @param clientInformation - OAuth client information containing credentials\n * @param supportedMethods - Authentication methods supported by the authorization server\n * @returns The selected authentication method\n */\nexport function selectClientAuthMethod(clientInformation: OAuthClientInformationMixed, supportedMethods: string[]): ClientAuthMethod {\n    const hasClientSecret = clientInformation.client_secret !== undefined;\n\n    // Prefer the method returned by the server during client registration, if valid.\n    // When server metadata is present we also require the method to be listed as supported;\n    // when supportedMethods is empty (metadata omitted the field) the DCR hint stands alone.\n    if (\n        'token_endpoint_auth_method' in clientInformation &&\n        clientInformation.token_endpoint_auth_method &&\n        isClientAuthMethod(clientInformation.token_endpoint_auth_method) &&\n        (supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method))\n    ) {\n        return clientInformation.token_endpoint_auth_method;\n    }\n\n    // If server metadata omits token_endpoint_auth_methods_supported, RFC 8414 §2 says the\n    // default is client_secret_basic. RFC 6749 §2.3.1 also requires servers to support HTTP\n    // Basic authentication for clients with a secret, making it the safest default.\n    if (supportedMethods.length === 0) {\n        return hasClientSecret ? 'client_secret_basic' : 'none';\n    }\n\n    // Try methods in priority order (most secure first)\n    if (hasClientSecret && supportedMethods.includes('client_secret_basic')) {\n        return 'client_secret_basic';\n    }\n\n    if (hasClientSecret && supportedMethods.includes('client_secret_post')) {\n        return 'client_secret_post';\n    }\n\n    if (supportedMethods.includes('none')) {\n        return 'none';\n    }\n\n    // Fallback: use what we have\n    return hasClientSecret ? 'client_secret_post' : 'none';\n}\n\n/**\n * Applies client authentication to the request based on the specified method.\n *\n * Implements OAuth 2.1 client authentication methods:\n * - `client_secret_basic`: HTTP Basic authentication (RFC 6749 Section 2.3.1)\n * - `client_secret_post`: Credentials in request body (RFC 6749 Section 2.3.1)\n * - `none`: Public client authentication (RFC 6749 Section 2.1)\n *\n * @param method - The authentication method to use\n * @param clientInformation - OAuth client information containing credentials\n * @param headers - HTTP headers object to modify\n * @param params - URL search parameters to modify\n * @throws {Error} When required credentials are missing\n */\nexport function applyClientAuthentication(\n    method: ClientAuthMethod,\n    clientInformation: OAuthClientInformation,\n    headers: Headers,\n    params: URLSearchParams\n): void {\n    const { client_id, client_secret } = clientInformation;\n\n    switch (method) {\n        case 'client_secret_basic': {\n            applyBasicAuth(client_id, client_secret, headers);\n            return;\n        }\n        case 'client_secret_post': {\n            applyPostAuth(client_id, client_secret, params);\n            return;\n        }\n        case 'none': {\n            applyPublicAuth(client_id, params);\n            return;\n        }\n        default: {\n            throw new Error(`Unsupported client authentication method: ${method}`);\n        }\n    }\n}\n\n/**\n * Applies HTTP Basic authentication (RFC 6749 Section 2.3.1)\n */\nexport function applyBasicAuth(clientId: string, clientSecret: string | undefined, headers: Headers): void {\n    if (!clientSecret) {\n        throw new Error('client_secret_basic authentication requires a client_secret');\n    }\n\n    const credentials = btoa(`${clientId}:${clientSecret}`);\n    headers.set('Authorization', `Basic ${credentials}`);\n}\n\n/**\n * Applies POST body authentication (RFC 6749 Section 2.3.1)\n */\nexport function applyPostAuth(clientId: string, clientSecret: string | undefined, params: URLSearchParams): void {\n    params.set('client_id', clientId);\n    if (clientSecret) {\n        params.set('client_secret', clientSecret);\n    }\n}\n\n/**\n * Applies public client authentication (RFC 6749 Section 2.1)\n */\nexport function applyPublicAuth(clientId: string, params: URLSearchParams): void {\n    params.set('client_id', clientId);\n}\n\n/**\n * Parses an OAuth error response from a string or Response object.\n *\n * If the input is a standard OAuth2.0 error response, it will be parsed according to the spec\n * and an {@linkcode OAuthError} will be returned with the appropriate error code.\n * If parsing fails, it falls back to a generic {@linkcode OAuthErrorCode.ServerError | ServerError} that includes\n * the response status (if available) and original content.\n *\n * @param input - A Response object or string containing the error response\n * @returns A Promise that resolves to an {@linkcode OAuthError} instance\n */\nexport async function parseErrorResponse(input: Response | string): Promise<OAuthError> {\n    const statusCode = input instanceof Response ? input.status : undefined;\n    const body = input instanceof Response ? await input.text() : input;\n\n    try {\n        const result = OAuthErrorResponseSchema.parse(JSON.parse(body));\n        return OAuthError.fromResponse(result);\n    } catch (error) {\n        // Not a valid OAuth error response, but try to inform the user of the raw data anyway\n        const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ''}Invalid OAuth error response: ${error}. Raw body: ${body}`;\n        return new OAuthError(OAuthErrorCode.ServerError, errorMessage);\n    }\n}\n\n/**\n * Orchestrates the full auth flow with a server.\n *\n * This can be used as a single entry point for all authorization functionality,\n * instead of linking together the other lower-level functions in this module.\n */\nexport async function auth(\n    provider: OAuthClientProvider,\n    options: {\n        serverUrl: string | URL;\n        authorizationCode?: string;\n        scope?: string;\n        resourceMetadataUrl?: URL;\n        fetchFn?: FetchLike;\n    }\n): Promise<AuthResult> {\n    try {\n        return await authInternal(provider, options);\n    } catch (error) {\n        // Handle recoverable error types by invalidating credentials and retrying\n        if (error instanceof OAuthError) {\n            if (error.code === OAuthErrorCode.InvalidClient || error.code === OAuthErrorCode.UnauthorizedClient) {\n                await provider.invalidateCredentials?.('all');\n                return await authInternal(provider, options);\n            } else if (error.code === OAuthErrorCode.InvalidGrant) {\n                await provider.invalidateCredentials?.('tokens');\n                return await authInternal(provider, options);\n            }\n        }\n\n        // Throw otherwise\n        throw error;\n    }\n}\n\n/**\n * Selects scopes per the MCP spec and augment for refresh token support.\n */\nexport function determineScope(options: {\n    requestedScope?: string;\n    resourceMetadata?: OAuthProtectedResourceMetadata;\n    authServerMetadata?: AuthorizationServerMetadata;\n    clientMetadata: OAuthClientMetadata;\n}): string | undefined {\n    const { requestedScope, resourceMetadata, authServerMetadata, clientMetadata } = options;\n\n    // Scope selection priority (MCP spec):\n    //   1. WWW-Authenticate header scope\n    //   2. PRM scopes_supported\n    //   3. clientMetadata.scope (SDK fallback)\n    //   4. Omit scope parameter\n    let effectiveScope = requestedScope || resourceMetadata?.scopes_supported?.join(' ') || clientMetadata.scope;\n\n    // SEP-2207: Append offline_access when the AS advertises it\n    // and the client supports the refresh_token grant.\n    if (\n        effectiveScope &&\n        authServerMetadata?.scopes_supported?.includes('offline_access') &&\n        !effectiveScope.split(' ').includes('offline_access') &&\n        clientMetadata.grant_types?.includes('refresh_token')\n    ) {\n        effectiveScope = `${effectiveScope} offline_access`;\n    }\n\n    return effectiveScope;\n}\n\nasync function authInternal(\n    provider: OAuthClientProvider,\n    {\n        serverUrl,\n        authorizationCode,\n        scope,\n        resourceMetadataUrl,\n        fetchFn\n    }: {\n        serverUrl: string | URL;\n        authorizationCode?: string;\n        scope?: string;\n        resourceMetadataUrl?: URL;\n        fetchFn?: FetchLike;\n    }\n): Promise<AuthResult> {\n    // Check if the provider has cached discovery state to skip discovery\n    const cachedState = await provider.discoveryState?.();\n\n    let resourceMetadata: OAuthProtectedResourceMetadata | undefined;\n    let authorizationServerUrl: string | URL;\n    let metadata: AuthorizationServerMetadata | undefined;\n\n    // If resourceMetadataUrl is not provided, try to load it from cached state\n    // This handles browser redirects where the URL was saved before navigation\n    let effectiveResourceMetadataUrl = resourceMetadataUrl;\n    if (!effectiveResourceMetadataUrl && cachedState?.resourceMetadataUrl) {\n        effectiveResourceMetadataUrl = new URL(cachedState.resourceMetadataUrl);\n    }\n\n    if (cachedState?.authorizationServerUrl) {\n        // Restore discovery state from cache\n        authorizationServerUrl = cachedState.authorizationServerUrl;\n        resourceMetadata = cachedState.resourceMetadata;\n        metadata =\n            cachedState.authorizationServerMetadata ?? (await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn }));\n\n        // If resource metadata wasn't cached, try to fetch it for selectResourceURL\n        if (!resourceMetadata) {\n            try {\n                resourceMetadata = await discoverOAuthProtectedResourceMetadata(\n                    serverUrl,\n                    { resourceMetadataUrl: effectiveResourceMetadataUrl },\n                    fetchFn\n                );\n            } catch (error) {\n                // Network failures (DNS, connection refused) surface as TypeError — propagate\n                // those rather than masking a transient reachability problem.\n                if (error instanceof TypeError) {\n                    throw error;\n                }\n                // RFC 9728 not available — selectResourceURL will handle undefined\n            }\n        }\n\n        // Re-save if we enriched the cached state with missing metadata\n        if (metadata !== cachedState.authorizationServerMetadata || resourceMetadata !== cachedState.resourceMetadata) {\n            await provider.saveDiscoveryState?.({\n                authorizationServerUrl: String(authorizationServerUrl),\n                resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),\n                resourceMetadata,\n                authorizationServerMetadata: metadata\n            });\n        }\n    } else {\n        // Full discovery via RFC 9728\n        const serverInfo = await discoverOAuthServerInfo(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl, fetchFn });\n        authorizationServerUrl = serverInfo.authorizationServerUrl;\n        metadata = serverInfo.authorizationServerMetadata;\n        resourceMetadata = serverInfo.resourceMetadata;\n\n        // Persist discovery state for future use\n        // TODO: resourceMetadataUrl is only populated when explicitly provided via options\n        // or loaded from cached state. The URL derived internally by\n        // discoverOAuthProtectedResourceMetadata() is not captured back here.\n        await provider.saveDiscoveryState?.({\n            authorizationServerUrl: String(authorizationServerUrl),\n            resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),\n            resourceMetadata,\n            authorizationServerMetadata: metadata\n        });\n    }\n\n    // Save authorization server URL for providers that need it (e.g., CrossAppAccessProvider)\n    await provider.saveAuthorizationServerUrl?.(String(authorizationServerUrl));\n\n    const resource: URL | undefined = await selectResourceURL(serverUrl, provider, resourceMetadata);\n\n    // Save resource URL for providers that need it (e.g., CrossAppAccessProvider)\n    if (resource) {\n        await provider.saveResourceUrl?.(String(resource));\n    }\n\n    // Scope selection used consistently for DCR and the authorization request.\n    const resolvedScope = determineScope({\n        requestedScope: scope,\n        resourceMetadata,\n        authServerMetadata: metadata,\n        clientMetadata: provider.clientMetadata\n    });\n\n    // Handle client registration if needed\n    let clientInformation = await Promise.resolve(provider.clientInformation());\n    if (!clientInformation) {\n        if (authorizationCode !== undefined) {\n            throw new Error('Existing OAuth client information is required when exchanging an authorization code');\n        }\n\n        const supportsUrlBasedClientId = metadata?.client_id_metadata_document_supported === true;\n        const clientMetadataUrl = provider.clientMetadataUrl;\n\n        if (clientMetadataUrl && !isHttpsUrl(clientMetadataUrl)) {\n            throw new OAuthError(\n                OAuthErrorCode.InvalidClientMetadata,\n                `clientMetadataUrl must be a valid HTTPS URL with a non-root pathname, got: ${clientMetadataUrl}`\n            );\n        }\n\n        const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;\n\n        if (shouldUseUrlBasedClientId) {\n            // SEP-991: URL-based Client IDs\n            clientInformation = {\n                client_id: clientMetadataUrl\n            };\n            await provider.saveClientInformation?.(clientInformation);\n        } else {\n            // Fallback to dynamic registration\n            if (!provider.saveClientInformation) {\n                throw new Error('OAuth client information must be saveable for dynamic registration');\n            }\n\n            const fullInformation = await registerClient(authorizationServerUrl, {\n                metadata,\n                clientMetadata: provider.clientMetadata,\n                scope: resolvedScope,\n                fetchFn\n            });\n\n            await provider.saveClientInformation(fullInformation);\n            clientInformation = fullInformation;\n        }\n    }\n\n    // Non-interactive flows (e.g., client_credentials, jwt-bearer) don't need a redirect URL\n    const nonInteractiveFlow = !provider.redirectUrl;\n\n    // Exchange authorization code for tokens, or fetch tokens directly for non-interactive flows\n    if (authorizationCode !== undefined || nonInteractiveFlow) {\n        const tokens = await fetchToken(provider, authorizationServerUrl, {\n            metadata,\n            resource,\n            authorizationCode,\n            scope: resolvedScope,\n            fetchFn\n        });\n\n        await provider.saveTokens(tokens);\n        return 'AUTHORIZED';\n    }\n\n    const tokens = await provider.tokens();\n\n    // Handle token refresh or new authorization\n    if (tokens?.refresh_token) {\n        try {\n            // Attempt to refresh the token\n            const newTokens = await refreshAuthorization(authorizationServerUrl, {\n                metadata,\n                clientInformation,\n                refreshToken: tokens.refresh_token,\n                resource,\n                addClientAuthentication: provider.addClientAuthentication,\n                fetchFn\n            });\n\n            await provider.saveTokens(newTokens);\n            return 'AUTHORIZED';\n        } catch (error) {\n            // If this is a ServerError, or an unknown type, log it out and try to continue. Otherwise, escalate so we can fix things and retry.\n            if (!(error instanceof OAuthError) || error.code === OAuthErrorCode.ServerError) {\n                // Could not refresh OAuth tokens\n            } else {\n                // Refresh failed for another reason, re-throw\n                throw error;\n            }\n        }\n    }\n\n    const state = provider.state ? await provider.state() : undefined;\n\n    // Start new authorization flow\n    const { authorizationUrl, codeVerifier } = await startAuthorization(authorizationServerUrl, {\n        metadata,\n        clientInformation,\n        state,\n        redirectUrl: provider.redirectUrl,\n        scope: resolvedScope,\n        resource\n    });\n\n    await provider.saveCodeVerifier(codeVerifier);\n    await provider.redirectToAuthorization(authorizationUrl);\n    return 'REDIRECT';\n}\n\n/**\n * SEP-991: URL-based Client IDs\n * Validate that the `client_id` is a valid URL with `https` scheme\n */\nexport function isHttpsUrl(value?: string): boolean {\n    if (!value) return false;\n    try {\n        const url = new URL(value);\n        return url.protocol === 'https:' && url.pathname !== '/';\n    } catch {\n        return false;\n    }\n}\n\nexport async function selectResourceURL(\n    serverUrl: string | URL,\n    provider: OAuthClientProvider,\n    resourceMetadata?: OAuthProtectedResourceMetadata\n): Promise<URL | undefined> {\n    const defaultResource = resourceUrlFromServerUrl(serverUrl);\n\n    // If provider has custom validation, delegate to it\n    if (provider.validateResourceURL) {\n        return await provider.validateResourceURL(defaultResource, resourceMetadata?.resource);\n    }\n\n    // Only include resource parameter when Protected Resource Metadata is present\n    if (!resourceMetadata) {\n        return undefined;\n    }\n\n    // Validate that the metadata's resource is compatible with our request\n    if (!checkResourceAllowed({ requestedResource: defaultResource, configuredResource: resourceMetadata.resource })) {\n        throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`);\n    }\n    // Prefer the resource from metadata since it's what the server is telling us to request\n    return new URL(resourceMetadata.resource);\n}\n\n/**\n * Extract `resource_metadata`, `scope`, and `error` from `WWW-Authenticate` header.\n */\nexport function extractWWWAuthenticateParams(res: Response): { resourceMetadataUrl?: URL; scope?: string; error?: string } {\n    const authenticateHeader = res.headers.get('WWW-Authenticate');\n    if (!authenticateHeader) {\n        return {};\n    }\n\n    const [type, scheme] = authenticateHeader.split(' ');\n    if (type?.toLowerCase() !== 'bearer' || !scheme) {\n        return {};\n    }\n\n    const resourceMetadataMatch = extractFieldFromWwwAuth(res, 'resource_metadata') || undefined;\n\n    let resourceMetadataUrl: URL | undefined;\n    if (resourceMetadataMatch) {\n        try {\n            resourceMetadataUrl = new URL(resourceMetadataMatch);\n        } catch {\n            // Ignore invalid URL\n        }\n    }\n\n    const scope = extractFieldFromWwwAuth(res, 'scope') || undefined;\n    const error = extractFieldFromWwwAuth(res, 'error') || undefined;\n\n    return {\n        resourceMetadataUrl,\n        scope,\n        error\n    };\n}\n\n/**\n * Extracts a specific field's value from the `WWW-Authenticate` header string.\n *\n * @param response The HTTP response object containing the headers.\n * @param fieldName The name of the field to extract (e.g., `\"realm\"`, `\"nonce\"`).\n * @returns The field value\n */\nfunction extractFieldFromWwwAuth(response: Response, fieldName: string): string | null {\n    const wwwAuthHeader = response.headers.get('WWW-Authenticate');\n    if (!wwwAuthHeader) {\n        return null;\n    }\n\n    const pattern = new RegExp(String.raw`${fieldName}=(?:\"([^\"]+)\"|([^\\s,]+))`);\n    const match = wwwAuthHeader.match(pattern);\n\n    if (match) {\n        // Pattern matches: field_name=\"value\" or field_name=value (unquoted)\n        const result = match[1] || match[2];\n        if (result) {\n            return result;\n        }\n    }\n\n    return null;\n}\n\n/**\n * Extract `resource_metadata` from response header.\n * @deprecated Use {@linkcode extractWWWAuthenticateParams} instead.\n */\nexport function extractResourceMetadataUrl(res: Response): URL | undefined {\n    const authenticateHeader = res.headers.get('WWW-Authenticate');\n    if (!authenticateHeader) {\n        return undefined;\n    }\n\n    const [type, scheme] = authenticateHeader.split(' ');\n    if (type?.toLowerCase() !== 'bearer' || !scheme) {\n        return undefined;\n    }\n    const regex = /resource_metadata=\"([^\"]*)\"/;\n    const match = regex.exec(authenticateHeader);\n\n    if (!match || !match[1]) {\n        return undefined;\n    }\n\n    try {\n        return new URL(match[1]);\n    } catch {\n        return undefined;\n    }\n}\n\n/**\n * Looks up {@link https://datatracker.ietf.org/doc/html/rfc9728 | RFC 9728}\n * OAuth 2.0 Protected Resource Metadata.\n *\n * If the server returns a 404 for the well-known endpoint, this function will\n * return `undefined`. Any other errors will be thrown as exceptions.\n */\nexport async function discoverOAuthProtectedResourceMetadata(\n    serverUrl: string | URL,\n    opts?: { protocolVersion?: string; resourceMetadataUrl?: string | URL },\n    fetchFn: FetchLike = fetch\n): Promise<OAuthProtectedResourceMetadata> {\n    const response = await discoverMetadataWithFallback(serverUrl, 'oauth-protected-resource', fetchFn, {\n        protocolVersion: opts?.protocolVersion,\n        metadataUrl: opts?.resourceMetadataUrl\n    });\n\n    if (!response || response.status === 404) {\n        await response?.text?.().catch(() => {});\n        throw new Error(`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`);\n    }\n\n    if (!response.ok) {\n        await response.text?.().catch(() => {});\n        throw new Error(`HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`);\n    }\n    return OAuthProtectedResourceMetadataSchema.parse(await response.json());\n}\n\n/**\n * Fetch with a retry heuristic for CORS errors caused by custom headers.\n *\n * In browsers, adding a custom header (e.g. `MCP-Protocol-Version`) triggers a CORS preflight.\n * If the server doesn't allow that header, the browser throws a `TypeError` before any response\n * is received. Retrying without custom headers often succeeds because the request becomes\n * \"simple\" (no preflight). If the server sends no CORS headers at all, the retry also fails\n * with `TypeError` and we return `undefined` so callers can fall through to an alternate URL.\n *\n * However, `fetch()` also throws `TypeError` for non-CORS failures (DNS resolution, connection\n * refused, invalid URL). Swallowing those and returning `undefined` masks real errors and can\n * cause callers to silently fall through to a different discovery URL. CORS is a browser-only\n * concept, so in non-browser runtimes (Node.js, Workers) a `TypeError` from `fetch` is never a\n * CORS error — there we propagate the error instead of swallowing it.\n *\n * In browsers, we cannot reliably distinguish CORS `TypeError` from network `TypeError` from the\n * error object alone, so the swallow-and-fallthrough heuristic is preserved there.\n */\nasync function fetchWithCorsRetry(url: URL, headers?: Record<string, string>, fetchFn: FetchLike = fetch): Promise<Response | undefined> {\n    try {\n        return await fetchFn(url, { headers });\n    } catch (error) {\n        if (!(error instanceof TypeError) || !CORS_IS_POSSIBLE) {\n            throw error;\n        }\n        if (headers) {\n            // Could be a CORS preflight rejection caused by our custom header. Retry as a simple\n            // request: if that succeeds, we've sidestepped the preflight.\n            try {\n                return await fetchFn(url, {});\n            } catch (retryError) {\n                if (!(retryError instanceof TypeError)) {\n                    throw retryError;\n                }\n                // Retry also got CORS-blocked (server sends no CORS headers at all).\n                // Return undefined so the caller tries the next discovery URL.\n                return undefined;\n            }\n        }\n        return undefined;\n    }\n}\n\n/**\n * Constructs the well-known path for auth-related metadata discovery\n */\nfunction buildWellKnownPath(\n    wellKnownPrefix: 'oauth-authorization-server' | 'oauth-protected-resource' | 'openid-configuration',\n    pathname: string = '',\n    options: { prependPathname?: boolean } = {}\n): string {\n    // Strip trailing slash from pathname to avoid double slashes\n    if (pathname.endsWith('/')) {\n        pathname = pathname.slice(0, -1);\n    }\n\n    return options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;\n}\n\n/**\n * Tries to discover OAuth metadata at a specific URL\n */\nasync function tryMetadataDiscovery(url: URL, protocolVersion: string, fetchFn: FetchLike = fetch): Promise<Response | undefined> {\n    const headers = {\n        'MCP-Protocol-Version': protocolVersion\n    };\n    return await fetchWithCorsRetry(url, headers, fetchFn);\n}\n\n/**\n * Determines if fallback to root discovery should be attempted\n */\nfunction shouldAttemptFallback(response: Response | undefined, pathname: string): boolean {\n    if (!response) return true; // CORS error — always try fallback\n    if (pathname === '/') return false; // Already at root\n    return (response.status >= 400 && response.status < 500) || response.status === 502;\n}\n\n/**\n * Generic function for discovering OAuth metadata with fallback support\n */\nasync function discoverMetadataWithFallback(\n    serverUrl: string | URL,\n    wellKnownType: 'oauth-authorization-server' | 'oauth-protected-resource',\n    fetchFn: FetchLike,\n    opts?: { protocolVersion?: string; metadataUrl?: string | URL; metadataServerUrl?: string | URL }\n): Promise<Response | undefined> {\n    const issuer = new URL(serverUrl);\n    const protocolVersion = opts?.protocolVersion ?? LATEST_PROTOCOL_VERSION;\n\n    let url: URL;\n    if (opts?.metadataUrl) {\n        url = new URL(opts.metadataUrl);\n    } else {\n        // Try path-aware discovery first\n        const wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);\n        url = new URL(wellKnownPath, opts?.metadataServerUrl ?? issuer);\n        url.search = issuer.search;\n    }\n\n    let response = await tryMetadataDiscovery(url, protocolVersion, fetchFn);\n\n    // If path-aware discovery fails (4xx or 502 Bad Gateway) and we're not already at root, try fallback to root discovery\n    if (!opts?.metadataUrl && shouldAttemptFallback(response, issuer.pathname)) {\n        const rootUrl = new URL(`/.well-known/${wellKnownType}`, issuer);\n        response = await tryMetadataDiscovery(rootUrl, protocolVersion, fetchFn);\n    }\n\n    return response;\n}\n\n/**\n * Looks up RFC 8414 OAuth 2.0 Authorization Server Metadata.\n *\n * If the server returns a 404 for the well-known endpoint, this function will\n * return `undefined`. Any other errors will be thrown as exceptions.\n *\n * @deprecated This function is deprecated in favor of {@linkcode discoverAuthorizationServerMetadata}.\n */\nexport async function discoverOAuthMetadata(\n    issuer: string | URL,\n    {\n        authorizationServerUrl,\n        protocolVersion\n    }: {\n        authorizationServerUrl?: string | URL;\n        protocolVersion?: string;\n    } = {},\n    fetchFn: FetchLike = fetch\n): Promise<OAuthMetadata | undefined> {\n    if (typeof issuer === 'string') {\n        issuer = new URL(issuer);\n    }\n    if (!authorizationServerUrl) {\n        authorizationServerUrl = issuer;\n    }\n    if (typeof authorizationServerUrl === 'string') {\n        authorizationServerUrl = new URL(authorizationServerUrl);\n    }\n    protocolVersion ??= LATEST_PROTOCOL_VERSION;\n\n    const response = await discoverMetadataWithFallback(authorizationServerUrl, 'oauth-authorization-server', fetchFn, {\n        protocolVersion,\n        metadataServerUrl: authorizationServerUrl\n    });\n\n    if (!response || response.status === 404) {\n        await response?.text?.().catch(() => {});\n        return undefined;\n    }\n\n    if (!response.ok) {\n        await response.text?.().catch(() => {});\n        throw new Error(`HTTP ${response.status} trying to load well-known OAuth metadata`);\n    }\n\n    return OAuthMetadataSchema.parse(await response.json());\n}\n\n/**\n * Builds a list of discovery URLs to try for authorization server metadata.\n * URLs are returned in priority order:\n * 1. OAuth metadata at the given URL\n * 2. OIDC metadata endpoints at the given URL\n */\nexport function buildDiscoveryUrls(authorizationServerUrl: string | URL): { url: URL; type: 'oauth' | 'oidc' }[] {\n    const url = typeof authorizationServerUrl === 'string' ? new URL(authorizationServerUrl) : authorizationServerUrl;\n    const hasPath = url.pathname !== '/';\n    const urlsToTry: { url: URL; type: 'oauth' | 'oidc' }[] = [];\n\n    if (!hasPath) {\n        urlsToTry.push(\n            // Root path: https://example.com/.well-known/oauth-authorization-server\n\n            {\n                url: new URL('/.well-known/oauth-authorization-server', url.origin),\n                type: 'oauth'\n            },\n            // OIDC: https://example.com/.well-known/openid-configuration\n\n            {\n                url: new URL(`/.well-known/openid-configuration`, url.origin),\n                type: 'oidc'\n            }\n        );\n\n        return urlsToTry;\n    }\n\n    // Strip trailing slash from pathname to avoid double slashes\n    let pathname = url.pathname;\n    if (pathname.endsWith('/')) {\n        pathname = pathname.slice(0, -1);\n    }\n\n    urlsToTry.push(\n        // 1. OAuth metadata at the given URL\n        // Insert well-known before the path: https://example.com/.well-known/oauth-authorization-server/tenant1\n        {\n            url: new URL(`/.well-known/oauth-authorization-server${pathname}`, url.origin),\n            type: 'oauth'\n        },\n        // 2. OIDC metadata endpoints\n        // RFC 8414 style: Insert /.well-known/openid-configuration before the path\n        {\n            url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin),\n            type: 'oidc'\n        },\n        // OIDC Discovery 1.0 style: Append /.well-known/openid-configuration after the path\n\n        {\n            url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),\n            type: 'oidc'\n        }\n    );\n\n    return urlsToTry;\n}\n\n/**\n * Discovers authorization server metadata with support for\n * {@link https://datatracker.ietf.org/doc/html/rfc8414 | RFC 8414} OAuth 2.0\n * Authorization Server Metadata and\n * {@link https://openid.net/specs/openid-connect-discovery-1_0.html | OpenID Connect Discovery 1.0}\n * specifications.\n *\n * This function implements a fallback strategy for authorization server discovery:\n * 1. Attempts RFC 8414 OAuth metadata discovery first\n * 2. If OAuth discovery fails, falls back to OpenID Connect Discovery\n *\n * @param authorizationServerUrl - The authorization server URL obtained from the MCP Server's\n *                                 protected resource metadata, or the MCP server's URL if the\n *                                 metadata was not found.\n * @param options - Configuration options\n * @param options.fetchFn - Optional fetch function for making HTTP requests, defaults to global fetch\n * @param options.protocolVersion - MCP protocol version to use, defaults to {@linkcode LATEST_PROTOCOL_VERSION}\n * @returns Promise resolving to authorization server metadata, or undefined if discovery fails\n */\nexport async function discoverAuthorizationServerMetadata(\n    authorizationServerUrl: string | URL,\n    {\n        fetchFn = fetch,\n        protocolVersion = LATEST_PROTOCOL_VERSION\n    }: {\n        fetchFn?: FetchLike;\n        protocolVersion?: string;\n    } = {}\n): Promise<AuthorizationServerMetadata | undefined> {\n    const headers = {\n        'MCP-Protocol-Version': protocolVersion,\n        Accept: 'application/json'\n    };\n\n    // Get the list of URLs to try\n    const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);\n\n    // Try each URL in order\n    for (const { url: endpointUrl, type } of urlsToTry) {\n        const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);\n\n        if (!response) {\n            /**\n             * CORS error occurred - don't throw as the endpoint may not allow CORS,\n             * continue trying other possible endpoints\n             */\n            continue;\n        }\n\n        if (!response.ok) {\n            await response.text?.().catch(() => {});\n            if ((response.status >= 400 && response.status < 500) || response.status === 502) {\n                continue; // Try next URL for 4xx or 502 (Bad Gateway)\n            }\n            throw new Error(\n                `HTTP ${response.status} trying to load ${type === 'oauth' ? 'OAuth' : 'OpenID provider'} metadata from ${endpointUrl}`\n            );\n        }\n\n        // Parse and validate based on type\n        return type === 'oauth'\n            ? OAuthMetadataSchema.parse(await response.json())\n            : OpenIdProviderDiscoveryMetadataSchema.parse(await response.json());\n    }\n\n    return undefined;\n}\n\n/**\n * Result of {@linkcode discoverOAuthServerInfo}.\n */\nexport interface OAuthServerInfo {\n    /**\n     * The authorization server URL, either discovered via RFC 9728\n     * or derived from the MCP server URL as a fallback.\n     */\n    authorizationServerUrl: string;\n\n    /**\n     * The authorization server metadata (endpoints, capabilities),\n     * or `undefined` if metadata discovery failed.\n     */\n    authorizationServerMetadata?: AuthorizationServerMetadata;\n\n    /**\n     * The OAuth 2.0 Protected Resource Metadata from RFC 9728,\n     * or `undefined` if the server does not support it.\n     */\n    resourceMetadata?: OAuthProtectedResourceMetadata;\n}\n\n/**\n * Discovers the authorization server for an MCP server following\n * {@link https://datatracker.ietf.org/doc/html/rfc9728 | RFC 9728} (OAuth 2.0 Protected\n * Resource Metadata), with fallback to treating the server URL as the\n * authorization server.\n *\n * This function combines two discovery steps into one call:\n * 1. Probes `/.well-known/oauth-protected-resource` on the MCP server to find the\n *    authorization server URL (RFC 9728).\n * 2. Fetches authorization server metadata from that URL (RFC 8414 / OpenID Connect Discovery).\n *\n * Use this when you need the authorization server metadata for operations outside the\n * {@linkcode auth} orchestrator, such as token refresh or token revocation.\n *\n * @param serverUrl - The MCP resource server URL\n * @param opts - Optional configuration\n * @param opts.resourceMetadataUrl - Override URL for the protected resource metadata endpoint\n * @param opts.fetchFn - Custom fetch function for HTTP requests\n * @returns Authorization server URL, metadata, and resource metadata (if available)\n */\nexport async function discoverOAuthServerInfo(\n    serverUrl: string | URL,\n    opts?: {\n        resourceMetadataUrl?: URL;\n        fetchFn?: FetchLike;\n    }\n): Promise<OAuthServerInfo> {\n    let resourceMetadata: OAuthProtectedResourceMetadata | undefined;\n    let authorizationServerUrl: string | undefined;\n\n    try {\n        resourceMetadata = await discoverOAuthProtectedResourceMetadata(\n            serverUrl,\n            { resourceMetadataUrl: opts?.resourceMetadataUrl },\n            opts?.fetchFn\n        );\n        if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {\n            authorizationServerUrl = resourceMetadata.authorization_servers[0];\n        }\n    } catch (error) {\n        // Network failures (DNS, connection refused) surface as TypeError from fetch. Those are\n        // transient reachability problems, not \"server doesn't support PRM\" — propagate so the\n        // caller sees the real error instead of silently falling back to a different auth server.\n        if (error instanceof TypeError) {\n            throw error;\n        }\n        // RFC 9728 not supported -- fall back to treating the server URL as the authorization server\n    }\n\n    // If we don't get a valid authorization server from protected resource metadata,\n    // fall back to the legacy MCP spec behavior: MCP server base URL acts as the authorization server\n    if (!authorizationServerUrl) {\n        authorizationServerUrl = String(new URL('/', serverUrl));\n    }\n\n    const authorizationServerMetadata = await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn: opts?.fetchFn });\n\n    return {\n        authorizationServerUrl,\n        authorizationServerMetadata,\n        resourceMetadata\n    };\n}\n\n/**\n * Begins the authorization flow with the given server, by generating a PKCE challenge and constructing the authorization URL.\n */\nexport async function startAuthorization(\n    authorizationServerUrl: string | URL,\n    {\n        metadata,\n        clientInformation,\n        redirectUrl,\n        scope,\n        state,\n        resource\n    }: {\n        metadata?: AuthorizationServerMetadata;\n        clientInformation: OAuthClientInformationMixed;\n        redirectUrl: string | URL;\n        scope?: string;\n        state?: string;\n        resource?: URL;\n    }\n): Promise<{ authorizationUrl: URL; codeVerifier: string }> {\n    let authorizationUrl: URL;\n    if (metadata) {\n        authorizationUrl = new URL(metadata.authorization_endpoint);\n\n        if (!metadata.response_types_supported.includes(AUTHORIZATION_CODE_RESPONSE_TYPE)) {\n            throw new Error(`Incompatible auth server: does not support response type ${AUTHORIZATION_CODE_RESPONSE_TYPE}`);\n        }\n\n        if (\n            metadata.code_challenge_methods_supported &&\n            !metadata.code_challenge_methods_supported.includes(AUTHORIZATION_CODE_CHALLENGE_METHOD)\n        ) {\n            throw new Error(`Incompatible auth server: does not support code challenge method ${AUTHORIZATION_CODE_CHALLENGE_METHOD}`);\n        }\n    } else {\n        authorizationUrl = new URL('/authorize', authorizationServerUrl);\n    }\n\n    // Generate PKCE challenge\n    const challenge = await pkceChallenge();\n    const codeVerifier = challenge.code_verifier;\n    const codeChallenge = challenge.code_challenge;\n\n    authorizationUrl.searchParams.set('response_type', AUTHORIZATION_CODE_RESPONSE_TYPE);\n    authorizationUrl.searchParams.set('client_id', clientInformation.client_id);\n    authorizationUrl.searchParams.set('code_challenge', codeChallenge);\n    authorizationUrl.searchParams.set('code_challenge_method', AUTHORIZATION_CODE_CHALLENGE_METHOD);\n    authorizationUrl.searchParams.set('redirect_uri', String(redirectUrl));\n\n    if (state) {\n        authorizationUrl.searchParams.set('state', state);\n    }\n\n    if (scope) {\n        authorizationUrl.searchParams.set('scope', scope);\n    }\n\n    if (scope?.split(' ').includes('offline_access')) {\n        // if the request includes the OIDC-only \"offline_access\" scope,\n        // we need to set the prompt to \"consent\" to ensure the user is prompted to grant offline access\n        // https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess\n        authorizationUrl.searchParams.append('prompt', 'consent');\n    }\n\n    if (resource) {\n        authorizationUrl.searchParams.set('resource', resource.href);\n    }\n\n    return { authorizationUrl, codeVerifier };\n}\n\n/**\n * Prepares token request parameters for an authorization code exchange.\n *\n * This is the default implementation used by {@linkcode fetchToken} when the provider\n * doesn't implement {@linkcode OAuthClientProvider.prepareTokenRequest | prepareTokenRequest}.\n *\n * @param authorizationCode - The authorization code received from the authorization endpoint\n * @param codeVerifier - The PKCE code verifier\n * @param redirectUri - The redirect URI used in the authorization request\n * @returns URLSearchParams for the `authorization_code` grant\n */\nexport function prepareAuthorizationCodeRequest(\n    authorizationCode: string,\n    codeVerifier: string,\n    redirectUri: string | URL\n): URLSearchParams {\n    return new URLSearchParams({\n        grant_type: 'authorization_code',\n        code: authorizationCode,\n        code_verifier: codeVerifier,\n        redirect_uri: String(redirectUri)\n    });\n}\n\n/**\n * Internal helper to execute a token request with the given parameters.\n * Used by {@linkcode exchangeAuthorization}, {@linkcode refreshAuthorization}, and {@linkcode fetchToken}.\n */\nexport async function executeTokenRequest(\n    authorizationServerUrl: string | URL,\n    {\n        metadata,\n        tokenRequestParams,\n        clientInformation,\n        addClientAuthentication,\n        resource,\n        fetchFn\n    }: {\n        metadata?: AuthorizationServerMetadata;\n        tokenRequestParams: URLSearchParams;\n        clientInformation?: OAuthClientInformationMixed;\n        addClientAuthentication?: OAuthClientProvider['addClientAuthentication'];\n        resource?: URL;\n        fetchFn?: FetchLike;\n    }\n): Promise<OAuthTokens> {\n    const tokenUrl = metadata?.token_endpoint ? new URL(metadata.token_endpoint) : new URL('/token', authorizationServerUrl);\n\n    const headers = new Headers({\n        'Content-Type': 'application/x-www-form-urlencoded',\n        Accept: 'application/json'\n    });\n\n    if (resource) {\n        tokenRequestParams.set('resource', resource.href);\n    }\n\n    if (addClientAuthentication) {\n        await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);\n    } else if (clientInformation) {\n        const supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [];\n        const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);\n        applyClientAuthentication(authMethod, clientInformation as OAuthClientInformation, headers, tokenRequestParams);\n    }\n\n    const response = await (fetchFn ?? fetch)(tokenUrl, {\n        method: 'POST',\n        headers,\n        body: tokenRequestParams\n    });\n\n    if (!response.ok) {\n        throw await parseErrorResponse(response);\n    }\n\n    const json: unknown = await response.json();\n\n    try {\n        return OAuthTokensSchema.parse(json);\n    } catch (parseError) {\n        // Some OAuth servers (e.g., GitHub) return error responses with HTTP 200 status.\n        // Check for error field only if token parsing failed.\n        if (typeof json === 'object' && json !== null && 'error' in json) {\n            throw await parseErrorResponse(JSON.stringify(json));\n        }\n        throw parseError;\n    }\n}\n\n/**\n * Exchanges an authorization code for an access token with the given server.\n *\n * Supports multiple client authentication methods as specified in OAuth 2.1:\n * - Automatically selects the best authentication method based on server support\n * - Falls back to appropriate defaults when server metadata is unavailable\n *\n * @param authorizationServerUrl - The authorization server's base URL\n * @param options - Configuration object containing client info, auth code, etc.\n * @returns Promise resolving to OAuth tokens\n * @throws {Error} When token exchange fails or authentication is invalid\n */\nexport async function exchangeAuthorization(\n    authorizationServerUrl: string | URL,\n    {\n        metadata,\n        clientInformation,\n        authorizationCode,\n        codeVerifier,\n        redirectUri,\n        resource,\n        addClientAuthentication,\n        fetchFn\n    }: {\n        metadata?: AuthorizationServerMetadata;\n        clientInformation: OAuthClientInformationMixed;\n        authorizationCode: string;\n        codeVerifier: string;\n        redirectUri: string | URL;\n        resource?: URL;\n        addClientAuthentication?: OAuthClientProvider['addClientAuthentication'];\n        fetchFn?: FetchLike;\n    }\n): Promise<OAuthTokens> {\n    const tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, redirectUri);\n\n    return executeTokenRequest(authorizationServerUrl, {\n        metadata,\n        tokenRequestParams,\n        clientInformation,\n        addClientAuthentication,\n        resource,\n        fetchFn\n    });\n}\n\n/**\n * Exchange a refresh token for an updated access token.\n *\n * Supports multiple client authentication methods as specified in OAuth 2.1:\n * - Automatically selects the best authentication method based on server support\n * - Preserves the original refresh token if a new one is not returned\n *\n * @param authorizationServerUrl - The authorization server's base URL\n * @param options - Configuration object containing client info, refresh token, etc.\n * @returns Promise resolving to OAuth tokens (preserves original `refresh_token` if not replaced)\n * @throws {Error} When token refresh fails or authentication is invalid\n */\nexport async function refreshAuthorization(\n    authorizationServerUrl: string | URL,\n    {\n        metadata,\n        clientInformation,\n        refreshToken,\n        resource,\n        addClientAuthentication,\n        fetchFn\n    }: {\n        metadata?: AuthorizationServerMetadata;\n        clientInformation: OAuthClientInformationMixed;\n        refreshToken: string;\n        resource?: URL;\n        addClientAuthentication?: OAuthClientProvider['addClientAuthentication'];\n        fetchFn?: FetchLike;\n    }\n): Promise<OAuthTokens> {\n    const tokenRequestParams = new URLSearchParams({\n        grant_type: 'refresh_token',\n        refresh_token: refreshToken\n    });\n\n    const tokens = await executeTokenRequest(authorizationServerUrl, {\n        metadata,\n        tokenRequestParams,\n        clientInformation,\n        addClientAuthentication,\n        resource,\n        fetchFn\n    });\n\n    // Preserve original refresh token if server didn't return a new one\n    return { refresh_token: refreshToken, ...tokens };\n}\n\n/**\n * Unified token fetching that works with any grant type via {@linkcode OAuthClientProvider.prepareTokenRequest | prepareTokenRequest()}.\n *\n * This function provides a single entry point for obtaining tokens regardless of the\n * OAuth grant type. The provider's `prepareTokenRequest()` method determines which grant\n * to use and supplies the grant-specific parameters.\n *\n * @param provider - OAuth client provider that implements `prepareTokenRequest()`\n * @param authorizationServerUrl - The authorization server's base URL\n * @param options - Configuration for the token request\n * @returns Promise resolving to OAuth tokens\n * @throws {Error} When provider doesn't implement `prepareTokenRequest` or token fetch fails\n *\n * @example\n * ```ts source=\"./auth.examples.ts#fetchToken_clientCredentials\"\n * // Provider for client_credentials:\n * class MyProvider extends MyProviderBase implements OAuthClientProvider {\n *     prepareTokenRequest(scope?: string) {\n *         const params = new URLSearchParams({ grant_type: 'client_credentials' });\n *         if (scope) params.set('scope', scope);\n *         return params;\n *     }\n * }\n *\n * const tokens = await fetchToken(new MyProvider(), authServerUrl, { metadata });\n * ```\n */\nexport async function fetchToken(\n    provider: OAuthClientProvider,\n    authorizationServerUrl: string | URL,\n    {\n        metadata,\n        resource,\n        authorizationCode,\n        scope,\n        fetchFn\n    }: {\n        metadata?: AuthorizationServerMetadata;\n        resource?: URL;\n        /** Authorization code for the default `authorization_code` grant flow */\n        authorizationCode?: string;\n        /** Optional scope parameter from auth() options */\n        scope?: string;\n        fetchFn?: FetchLike;\n    } = {}\n): Promise<OAuthTokens> {\n    // Prefer scope from options, fallback to provider.clientMetadata.scope\n    const effectiveScope = scope ?? provider.clientMetadata.scope;\n\n    // Use provider's prepareTokenRequest if available, otherwise fall back to authorization_code\n    let tokenRequestParams: URLSearchParams | undefined;\n    if (provider.prepareTokenRequest) {\n        tokenRequestParams = await provider.prepareTokenRequest(effectiveScope);\n    }\n\n    // Default to authorization_code grant if no custom prepareTokenRequest\n    if (!tokenRequestParams) {\n        if (!authorizationCode) {\n            throw new Error('Either provider.prepareTokenRequest() or authorizationCode is required');\n        }\n        if (!provider.redirectUrl) {\n            throw new Error('redirectUrl is required for authorization_code flow');\n        }\n        const codeVerifier = await provider.codeVerifier();\n        tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);\n    }\n\n    const clientInformation = await provider.clientInformation();\n\n    return executeTokenRequest(authorizationServerUrl, {\n        metadata,\n        tokenRequestParams,\n        clientInformation: clientInformation ?? undefined,\n        addClientAuthentication: provider.addClientAuthentication,\n        resource,\n        fetchFn\n    });\n}\n\n/**\n * Performs OAuth 2.0 Dynamic Client Registration according to\n * {@link https://datatracker.ietf.org/doc/html/rfc7591 | RFC 7591}.\n *\n * If `scope` is provided, it overrides `clientMetadata.scope` in the registration\n * request body. This allows callers to apply the Scope Selection Strategy (SEP-835)\n * consistently across both DCR and the subsequent authorization request.\n */\nexport async function registerClient(\n    authorizationServerUrl: string | URL,\n    {\n        metadata,\n        clientMetadata,\n        scope,\n        fetchFn\n    }: {\n        metadata?: AuthorizationServerMetadata;\n        clientMetadata: OAuthClientMetadata;\n        scope?: string;\n        fetchFn?: FetchLike;\n    }\n): Promise<OAuthClientInformationFull> {\n    let registrationUrl: URL;\n\n    if (metadata) {\n        if (!metadata.registration_endpoint) {\n            throw new Error('Incompatible auth server: does not support dynamic client registration');\n        }\n\n        registrationUrl = new URL(metadata.registration_endpoint);\n    } else {\n        registrationUrl = new URL('/register', authorizationServerUrl);\n    }\n\n    const response = await (fetchFn ?? fetch)(registrationUrl, {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/json'\n        },\n        body: JSON.stringify({\n            ...clientMetadata,\n            ...(scope === undefined ? {} : { scope })\n        })\n    });\n\n    if (!response.ok) {\n        throw await parseErrorResponse(response);\n    }\n\n    return OAuthClientInformationFullSchema.parse(await response.json());\n}\n","/**\n * OAuth provider extensions for specialized authentication flows.\n *\n * This module provides ready-to-use {@linkcode OAuthClientProvider} implementations\n * for common machine-to-machine authentication scenarios.\n */\n\nimport type { FetchLike, OAuthClientInformation, OAuthClientMetadata, OAuthTokens } from '@modelcontextprotocol/core';\nimport type { CryptoKey, JWK } from 'jose';\n\nimport type { AddClientAuthentication, OAuthClientProvider } from './auth.js';\n\n/**\n * Helper to produce a `private_key_jwt` client authentication function.\n *\n * @example\n * ```ts source=\"./authExtensions.examples.ts#createPrivateKeyJwtAuth_basicUsage\"\n * const addClientAuth = createPrivateKeyJwtAuth({\n *     issuer: 'my-client',\n *     subject: 'my-client',\n *     privateKey: pemEncodedPrivateKey,\n *     alg: 'RS256'\n * });\n * // pass addClientAuth as provider.addClientAuthentication implementation\n * ```\n */\nexport function createPrivateKeyJwtAuth(options: {\n    issuer: string;\n    subject: string;\n    privateKey: string | Uint8Array | Record<string, unknown>;\n    alg: string;\n    audience?: string | URL;\n    lifetimeSeconds?: number;\n    claims?: Record<string, unknown>;\n}): AddClientAuthentication {\n    return async (_headers, params, url, metadata) => {\n        // Lazy import to avoid heavy dependency unless used\n        if (globalThis.crypto === undefined) {\n            throw new TypeError(\n                'crypto is not available, please ensure you have Web Crypto API support for older Node.js versions (see https://github.com/modelcontextprotocol/typescript-sdk#nodejs-web-crypto-globalthiscrypto-compatibility)'\n            );\n        }\n\n        const jose = await import('jose');\n\n        const audience = String(options.audience ?? metadata?.issuer ?? url);\n        const lifetimeSeconds = options.lifetimeSeconds ?? 300;\n\n        const now = Math.floor(Date.now() / 1000);\n        const jti = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n        const baseClaims = {\n            iss: options.issuer,\n            sub: options.subject,\n            aud: audience,\n            exp: now + lifetimeSeconds,\n            iat: now,\n            jti\n        };\n        const claims = options.claims ? { ...baseClaims, ...options.claims } : baseClaims;\n\n        // Import key for the requested algorithm\n        const alg = options.alg;\n        let key: unknown;\n        if (typeof options.privateKey === 'string') {\n            if (alg.startsWith('RS') || alg.startsWith('ES') || alg.startsWith('PS')) {\n                key = await jose.importPKCS8(options.privateKey, alg);\n            } else if (alg.startsWith('HS')) {\n                key = new TextEncoder().encode(options.privateKey);\n            } else {\n                throw new Error(`Unsupported algorithm ${alg}`);\n            }\n        } else if (options.privateKey instanceof Uint8Array) {\n            // Assume PKCS#8 DER in Uint8Array for asymmetric algorithms\n            key = alg.startsWith('HS') ? options.privateKey : await jose.importPKCS8(new TextDecoder().decode(options.privateKey), alg);\n        } else {\n            // Treat as JWK\n            key = await jose.importJWK(options.privateKey as JWK, alg);\n        }\n\n        // Sign JWT\n        const assertion = await new jose.SignJWT(claims)\n            .setProtectedHeader({ alg, typ: 'JWT' })\n            .setIssuer(options.issuer)\n            .setSubject(options.subject)\n            .setAudience(audience)\n            .setIssuedAt(now)\n            .setExpirationTime(now + lifetimeSeconds)\n            .setJti(jti)\n            .sign(key as unknown as Uint8Array | CryptoKey);\n\n        params.set('client_assertion', assertion);\n        params.set('client_assertion_type', 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer');\n    };\n}\n\n/**\n * Options for creating a {@linkcode ClientCredentialsProvider}.\n */\nexport interface ClientCredentialsProviderOptions {\n    /**\n     * The `client_id` for this OAuth client.\n     */\n    clientId: string;\n\n    /**\n     * The `client_secret` for `client_secret_basic` authentication.\n     */\n    clientSecret: string;\n\n    /**\n     * Optional client name for metadata.\n     */\n    clientName?: string;\n\n    /**\n     * Space-separated scopes values requested by the client.\n     */\n    scope?: string;\n}\n\n/**\n * OAuth provider for `client_credentials` grant with `client_secret_basic` authentication.\n *\n * This provider is designed for machine-to-machine authentication where\n * the client authenticates using a `client_id` and `client_secret`.\n *\n * @example\n * ```ts source=\"./authExtensions.examples.ts#ClientCredentialsProvider_basicUsage\"\n * const provider = new ClientCredentialsProvider({\n *     clientId: 'my-client',\n *     clientSecret: 'my-secret'\n * });\n *\n * const transport = new StreamableHTTPClientTransport(serverUrl, {\n *     authProvider: provider\n * });\n * ```\n */\nexport class ClientCredentialsProvider implements OAuthClientProvider {\n    private _tokens?: OAuthTokens;\n    private _clientInfo: OAuthClientInformation;\n    private _clientMetadata: OAuthClientMetadata;\n\n    constructor(options: ClientCredentialsProviderOptions) {\n        this._clientInfo = {\n            client_id: options.clientId,\n            client_secret: options.clientSecret\n        };\n        this._clientMetadata = {\n            client_name: options.clientName ?? 'client-credentials-client',\n            redirect_uris: [],\n            grant_types: ['client_credentials'],\n            token_endpoint_auth_method: 'client_secret_basic',\n            scope: options.scope\n        };\n    }\n\n    get redirectUrl(): undefined {\n        return undefined;\n    }\n\n    get clientMetadata(): OAuthClientMetadata {\n        return this._clientMetadata;\n    }\n\n    clientInformation(): OAuthClientInformation {\n        return this._clientInfo;\n    }\n\n    saveClientInformation(info: OAuthClientInformation): void {\n        this._clientInfo = info;\n    }\n\n    tokens(): OAuthTokens | undefined {\n        return this._tokens;\n    }\n\n    saveTokens(tokens: OAuthTokens): void {\n        this._tokens = tokens;\n    }\n\n    redirectToAuthorization(): void {\n        throw new Error('redirectToAuthorization is not used for client_credentials flow');\n    }\n\n    saveCodeVerifier(): void {\n        // Not used for client_credentials\n    }\n\n    codeVerifier(): string {\n        throw new Error('codeVerifier is not used for client_credentials flow');\n    }\n\n    prepareTokenRequest(scope?: string): URLSearchParams {\n        const params = new URLSearchParams({ grant_type: 'client_credentials' });\n        if (scope) params.set('scope', scope);\n        return params;\n    }\n}\n\n/**\n * Options for creating a {@linkcode PrivateKeyJwtProvider}.\n */\nexport interface PrivateKeyJwtProviderOptions {\n    /**\n     * The `client_id` for this OAuth client.\n     */\n    clientId: string;\n\n    /**\n     * The private key for signing JWT assertions.\n     * Can be a PEM string, Uint8Array, or JWK object.\n     */\n    privateKey: string | Uint8Array | Record<string, unknown>;\n\n    /**\n     * The algorithm to use for signing (e.g., 'RS256', 'ES256').\n     */\n    algorithm: string;\n\n    /**\n     * Optional client name for metadata.\n     */\n    clientName?: string;\n\n    /**\n     * Optional JWT lifetime in seconds (default: 300).\n     */\n    jwtLifetimeSeconds?: number;\n\n    /**\n     * Space-separated scopes values requested by the client.\n     */\n    scope?: string;\n}\n\n/**\n * OAuth provider for `client_credentials` grant with `private_key_jwt` authentication.\n *\n * This provider is designed for machine-to-machine authentication where\n * the client authenticates using a signed JWT assertion\n * ({@link https://datatracker.ietf.org/doc/html/rfc7523#section-2.2 | RFC 7523 Section 2.2}).\n *\n * @example\n * ```ts source=\"./authExtensions.examples.ts#PrivateKeyJwtProvider_basicUsage\"\n * const provider = new PrivateKeyJwtProvider({\n *     clientId: 'my-client',\n *     privateKey: pemEncodedPrivateKey,\n *     algorithm: 'RS256'\n * });\n *\n * const transport = new StreamableHTTPClientTransport(serverUrl, {\n *     authProvider: provider\n * });\n * ```\n */\nexport class PrivateKeyJwtProvider implements OAuthClientProvider {\n    private _tokens?: OAuthTokens;\n    private _clientInfo: OAuthClientInformation;\n    private _clientMetadata: OAuthClientMetadata;\n    addClientAuthentication: AddClientAuthentication;\n\n    constructor(options: PrivateKeyJwtProviderOptions) {\n        this._clientInfo = {\n            client_id: options.clientId\n        };\n        this._clientMetadata = {\n            client_name: options.clientName ?? 'private-key-jwt-client',\n            redirect_uris: [],\n            grant_types: ['client_credentials'],\n            token_endpoint_auth_method: 'private_key_jwt',\n            scope: options.scope\n        };\n        this.addClientAuthentication = createPrivateKeyJwtAuth({\n            issuer: options.clientId,\n            subject: options.clientId,\n            privateKey: options.privateKey,\n            alg: options.algorithm,\n            lifetimeSeconds: options.jwtLifetimeSeconds\n        });\n    }\n\n    get redirectUrl(): undefined {\n        return undefined;\n    }\n\n    get clientMetadata(): OAuthClientMetadata {\n        return this._clientMetadata;\n    }\n\n    clientInformation(): OAuthClientInformation {\n        return this._clientInfo;\n    }\n\n    saveClientInformation(info: OAuthClientInformation): void {\n        this._clientInfo = info;\n    }\n\n    tokens(): OAuthTokens | undefined {\n        return this._tokens;\n    }\n\n    saveTokens(tokens: OAuthTokens): void {\n        this._tokens = tokens;\n    }\n\n    redirectToAuthorization(): void {\n        throw new Error('redirectToAuthorization is not used for client_credentials flow');\n    }\n\n    saveCodeVerifier(): void {\n        // Not used for client_credentials\n    }\n\n    codeVerifier(): string {\n        throw new Error('codeVerifier is not used for client_credentials flow');\n    }\n\n    prepareTokenRequest(scope?: string): URLSearchParams {\n        const params = new URLSearchParams({ grant_type: 'client_credentials' });\n        if (scope) params.set('scope', scope);\n        return params;\n    }\n}\n\n/**\n * Options for creating a {@linkcode StaticPrivateKeyJwtProvider}.\n */\nexport interface StaticPrivateKeyJwtProviderOptions {\n    /**\n     * The `client_id` for this OAuth client.\n     */\n    clientId: string;\n\n    /**\n     * A pre-built JWT client assertion to use for authentication.\n     *\n     * This token should already contain the appropriate claims\n     * (`iss`, `sub`, `aud`, `exp`, etc.) and be signed by the client's key.\n     */\n    jwtBearerAssertion: string;\n\n    /**\n     * Optional client name for metadata.\n     */\n    clientName?: string;\n\n    /**\n     * Space-separated scopes values requested by the client.\n     */\n    scope?: string;\n}\n\n/**\n * OAuth provider for `client_credentials` grant with a static `private_key_jwt` assertion.\n *\n * This provider mirrors {@linkcode PrivateKeyJwtProvider} but instead of constructing and\n * signing a JWT on each request, it accepts a pre-built JWT assertion string and\n * uses it directly for authentication.\n */\nexport class StaticPrivateKeyJwtProvider implements OAuthClientProvider {\n    private _tokens?: OAuthTokens;\n    private _clientInfo: OAuthClientInformation;\n    private _clientMetadata: OAuthClientMetadata;\n    addClientAuthentication: AddClientAuthentication;\n\n    constructor(options: StaticPrivateKeyJwtProviderOptions) {\n        this._clientInfo = {\n            client_id: options.clientId\n        };\n        this._clientMetadata = {\n            client_name: options.clientName ?? 'static-private-key-jwt-client',\n            redirect_uris: [],\n            grant_types: ['client_credentials'],\n            token_endpoint_auth_method: 'private_key_jwt',\n            scope: options.scope\n        };\n\n        const assertion = options.jwtBearerAssertion;\n        this.addClientAuthentication = async (_headers, params) => {\n            params.set('client_assertion', assertion);\n            params.set('client_assertion_type', 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer');\n        };\n    }\n\n    get redirectUrl(): undefined {\n        return undefined;\n    }\n\n    get clientMetadata(): OAuthClientMetadata {\n        return this._clientMetadata;\n    }\n\n    clientInformation(): OAuthClientInformation {\n        return this._clientInfo;\n    }\n\n    saveClientInformation(info: OAuthClientInformation): void {\n        this._clientInfo = info;\n    }\n\n    tokens(): OAuthTokens | undefined {\n        return this._tokens;\n    }\n\n    saveTokens(tokens: OAuthTokens): void {\n        this._tokens = tokens;\n    }\n\n    redirectToAuthorization(): void {\n        throw new Error('redirectToAuthorization is not used for client_credentials flow');\n    }\n\n    saveCodeVerifier(): void {\n        // Not used for client_credentials\n    }\n\n    codeVerifier(): string {\n        throw new Error('codeVerifier is not used for client_credentials flow');\n    }\n\n    prepareTokenRequest(scope?: string): URLSearchParams {\n        const params = new URLSearchParams({ grant_type: 'client_credentials' });\n        if (scope) params.set('scope', scope);\n        return params;\n    }\n}\n\n/**\n * Context provided to the assertion callback in {@linkcode CrossAppAccessProvider}.\n * Contains orchestrator-discovered information needed for JWT Authorization Grant requests.\n */\nexport interface CrossAppAccessContext {\n    /**\n     * The authorization server URL of the target MCP server.\n     * Discovered via RFC 9728 protected resource metadata.\n     */\n    authorizationServerUrl: string;\n\n    /**\n     * The resource URL of the target MCP server.\n     * Discovered via RFC 9728 protected resource metadata.\n     */\n    resourceUrl: string;\n\n    /**\n     * Optional scope being requested for the MCP server.\n     */\n    scope?: string;\n\n    /**\n     * Fetch function to use for HTTP requests (e.g., for IdP token exchange).\n     */\n    fetchFn: FetchLike;\n}\n\n/**\n * Callback function type that provides a JWT Authorization Grant (ID-JAG).\n *\n * The callback receives context about the target MCP server (authorization server URL,\n * resource URL, scope) and should return a JWT Authorization Grant that will be used\n * to obtain an access token from the MCP server.\n */\nexport type AssertionCallback = (context: CrossAppAccessContext) => string | Promise<string>;\n\n/**\n * Options for creating a {@linkcode CrossAppAccessProvider}.\n */\nexport interface CrossAppAccessProviderOptions {\n    /**\n     * Callback function that provides a JWT Authorization Grant (ID-JAG).\n     *\n     * The callback receives the MCP server's authorization server URL, resource URL,\n     * and requested scope, and should return a JWT Authorization Grant obtained from\n     * the enterprise IdP via RFC 8693 token exchange.\n     *\n     * You can use the utility functions from the `crossAppAccess` module\n     * for standard flows, or implement custom logic.\n     *\n     * @example\n     * ```ts\n     * assertion: async (ctx) => {\n     *     const result = await discoverAndRequestJwtAuthGrant({\n     *         idpUrl: 'https://idp.example.com',\n     *         audience: ctx.authorizationServerUrl,\n     *         resource: ctx.resourceUrl,\n     *         idToken: await getIdToken(),\n     *         clientId: 'my-idp-client',\n     *         clientSecret: 'my-idp-secret',\n     *         scope: ctx.scope,\n     *         fetchFn: ctx.fetchFn\n     *     });\n     *     return result.jwtAuthGrant;\n     * }\n     * ```\n     */\n    assertion: AssertionCallback;\n\n    /**\n     * The `client_id` registered with the MCP server's authorization server.\n     */\n    clientId: string;\n\n    /**\n     * The `client_secret` for authenticating with the MCP server's authorization server.\n     */\n    clientSecret: string;\n\n    /**\n     * Optional client name for metadata.\n     */\n    clientName?: string;\n\n    /**\n     * Custom fetch implementation. Defaults to global fetch.\n     */\n    fetchFn?: FetchLike;\n}\n\n/**\n * OAuth provider for Cross-App Access (Enterprise Managed Authorization) using JWT Authorization Grant.\n *\n * This provider implements the Enterprise Managed Authorization flow (SEP-990) where:\n * 1. User authenticates with an enterprise IdP and the client obtains an ID Token\n * 2. Client exchanges the ID Token for a JWT Authorization Grant (ID-JAG) via RFC 8693 token exchange\n * 3. Client uses the JAG to obtain an access token from the MCP server via RFC 7523 JWT bearer grant\n *\n * The provider handles steps 2-3 automatically, with the JAG acquisition delegated to\n * a callback function that you provide. This allows flexibility in how you obtain and\n * cache ID Tokens from the IdP.\n *\n * @see https://github.com/modelcontextprotocol/ext-auth/blob/main/specification/draft/enterprise-managed-authorization.mdx\n *\n * @example\n * ```ts\n * const provider = new CrossAppAccessProvider({\n *     assertion: async (ctx) => {\n *         const result = await discoverAndRequestJwtAuthGrant({\n *             idpUrl: 'https://idp.example.com',\n *             audience: ctx.authorizationServerUrl,\n *             resource: ctx.resourceUrl,\n *             idToken: await getIdToken(), // Your function to get ID token\n *             clientId: 'my-idp-client',\n *             clientSecret: 'my-idp-secret',\n *             scope: ctx.scope,\n *             fetchFn: ctx.fetchFn\n *         });\n *         return result.jwtAuthGrant;\n *     },\n *     clientId: 'my-mcp-client',\n *     clientSecret: 'my-mcp-secret'\n * });\n *\n * const transport = new StreamableHTTPClientTransport(serverUrl, {\n *     authProvider: provider\n * });\n * ```\n */\nexport class CrossAppAccessProvider implements OAuthClientProvider {\n    private _tokens?: OAuthTokens;\n    private _clientInfo: OAuthClientInformation;\n    private _clientMetadata: OAuthClientMetadata;\n    private _assertionCallback: AssertionCallback;\n    private _fetchFn: FetchLike;\n    private _authorizationServerUrl?: string;\n    private _resourceUrl?: string;\n    private _scope?: string;\n\n    constructor(options: CrossAppAccessProviderOptions) {\n        this._clientInfo = {\n            client_id: options.clientId,\n            client_secret: options.clientSecret\n        };\n        this._clientMetadata = {\n            client_name: options.clientName ?? 'cross-app-access-client',\n            redirect_uris: [],\n            grant_types: ['urn:ietf:params:oauth:grant-type:jwt-bearer'],\n            token_endpoint_auth_method: 'client_secret_basic'\n        };\n        this._assertionCallback = options.assertion;\n        this._fetchFn = options.fetchFn ?? fetch;\n    }\n\n    get redirectUrl(): undefined {\n        return undefined;\n    }\n\n    get clientMetadata(): OAuthClientMetadata {\n        return this._clientMetadata;\n    }\n\n    clientInformation(): OAuthClientInformation {\n        return this._clientInfo;\n    }\n\n    saveClientInformation(info: OAuthClientInformation): void {\n        this._clientInfo = info;\n    }\n\n    tokens(): OAuthTokens | undefined {\n        return this._tokens;\n    }\n\n    saveTokens(tokens: OAuthTokens): void {\n        this._tokens = tokens;\n    }\n\n    redirectToAuthorization(): void {\n        throw new Error('redirectToAuthorization is not used for jwt-bearer flow');\n    }\n\n    saveCodeVerifier(): void {\n        // Not used for jwt-bearer\n    }\n\n    codeVerifier(): string {\n        throw new Error('codeVerifier is not used for jwt-bearer flow');\n    }\n\n    /**\n     * Saves the authorization server URL discovered during OAuth flow.\n     * This is called by the auth() function after RFC 9728 discovery.\n     */\n    saveAuthorizationServerUrl?(authorizationServerUrl: string): void {\n        this._authorizationServerUrl = authorizationServerUrl;\n    }\n\n    /**\n     * Returns the cached authorization server URL if available.\n     */\n    authorizationServerUrl?(): string | undefined {\n        return this._authorizationServerUrl;\n    }\n\n    /**\n     * Saves the resource URL discovered during OAuth flow.\n     * This is called by the auth() function after RFC 9728 discovery.\n     */\n    saveResourceUrl?(resourceUrl: string): void {\n        this._resourceUrl = resourceUrl;\n    }\n\n    /**\n     * Returns the cached resource URL if available.\n     */\n    resourceUrl?(): string | undefined {\n        return this._resourceUrl;\n    }\n\n    async prepareTokenRequest(scope?: string): Promise<URLSearchParams> {\n        // Get the authorization server URL and resource URL from cached state\n        const authServerUrl = this._authorizationServerUrl;\n        const resourceUrl = this._resourceUrl;\n\n        if (!authServerUrl) {\n            throw new Error('Authorization server URL not available. Ensure auth() has been called first.');\n        }\n\n        if (!resourceUrl) {\n            throw new Error(\n                'Resource URL not available — server may not implement RFC 9728 ' +\n                    'Protected Resource Metadata (required for Cross-App Access), or ' +\n                    'auth() has not been called'\n            );\n        }\n\n        // Store scope for assertion callback\n        this._scope = scope;\n\n        // Call the assertion callback to get the JWT Authorization Grant\n        const jwtAuthGrant = await this._assertionCallback({\n            authorizationServerUrl: authServerUrl,\n            resourceUrl: resourceUrl,\n            scope: this._scope,\n            fetchFn: this._fetchFn\n        });\n\n        // Return params for JWT bearer grant per RFC 7523\n        const params = new URLSearchParams({\n            grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n            assertion: jwtAuthGrant\n        });\n\n        if (scope) {\n            params.set('scope', scope);\n        }\n\n        return params;\n    }\n}\n","/**\n * Experimental client task features for MCP SDK.\n * WARNING: These APIs are experimental and may change without notice.\n *\n * @experimental\n */\n\nimport type {\n    AnyObjectSchema,\n    CallToolRequest,\n    CallToolResult,\n    CancelTaskResult,\n    CreateTaskResult,\n    GetTaskPayloadResult,\n    GetTaskResult,\n    ListTasksResult,\n    Request,\n    RequestMethod,\n    RequestOptions,\n    ResponseMessage,\n    ResultTypeMap\n} from '@modelcontextprotocol/core';\nimport {\n    CallToolResultSchema,\n    getResultSchema,\n    GetTaskPayloadResultSchema,\n    ProtocolError,\n    ProtocolErrorCode\n} from '@modelcontextprotocol/core';\n\nimport type { Client } from '../../client/client.js';\n\n/**\n * Internal interface for accessing {@linkcode Client}'s private methods.\n * @internal\n */\ninterface ClientInternal {\n    isToolTask(toolName: string): boolean;\n    getToolOutputValidator(toolName: string): ((data: unknown) => { valid: boolean; errorMessage?: string }) | undefined;\n}\n\n/**\n * Experimental task features for MCP clients.\n *\n * Access via `client.experimental.tasks`:\n * ```typescript\n * const stream = client.experimental.tasks.callToolStream({ name: 'tool', arguments: {} });\n * const task = await client.experimental.tasks.getTask(taskId);\n * ```\n *\n * @experimental\n */\nexport class ExperimentalClientTasks {\n    constructor(private readonly _client: Client) {}\n\n    private get _module() {\n        return this._client.taskManager;\n    }\n\n    /**\n     * Calls a tool and returns an AsyncGenerator that yields response messages.\n     * The generator is guaranteed to end with either a `'result'` or `'error'` message.\n     *\n     * This method provides streaming access to tool execution, allowing you to\n     * observe intermediate task status updates for long-running tool calls.\n     * Automatically validates structured output if the tool has an `outputSchema`.\n     *\n     * @example\n     * ```ts source=\"./client.examples.ts#ExperimentalClientTasks_callToolStream\"\n     * const stream = client.experimental.tasks.callToolStream({ name: 'myTool', arguments: {} });\n     * for await (const message of stream) {\n     *     switch (message.type) {\n     *         case 'taskCreated': {\n     *             console.log('Tool execution started:', message.task.taskId);\n     *             break;\n     *         }\n     *         case 'taskStatus': {\n     *             console.log('Tool status:', message.task.status);\n     *             break;\n     *         }\n     *         case 'result': {\n     *             console.log('Tool result:', message.result);\n     *             break;\n     *         }\n     *         case 'error': {\n     *             console.error('Tool error:', message.error);\n     *             break;\n     *         }\n     *     }\n     * }\n     * ```\n     *\n     * @param params - Tool call parameters (name and arguments)\n     * @param options - Optional request options (timeout, signal, task creation params, etc.)\n     * @returns AsyncGenerator that yields {@linkcode ResponseMessage} objects\n     *\n     * @experimental\n     */\n    async *callToolStream(\n        params: CallToolRequest['params'],\n        options?: RequestOptions\n    ): AsyncGenerator<ResponseMessage<CallToolResult | CreateTaskResult>, void, void> {\n        // Access Client's internal methods\n        const clientInternal = this._client as unknown as ClientInternal;\n\n        // Add task creation parameters if server supports it and not explicitly provided\n        const optionsWithTask = {\n            ...options,\n            // We check if the tool is known to be a task during auto-configuration, but assume\n            // the caller knows what they're doing if they pass this explicitly\n            task: options?.task ?? (clientInternal.isToolTask(params.name) ? {} : undefined)\n        };\n\n        const stream = this._module.requestStream({ method: 'tools/call', params }, CallToolResultSchema, optionsWithTask);\n\n        // Get the validator for this tool (if it has an output schema)\n        const validator = clientInternal.getToolOutputValidator(params.name);\n\n        // Iterate through the stream and validate the final result if needed\n        for await (const message of stream) {\n            // If this is a result message and the tool has an output schema, validate it\n            // Only validate CallToolResult (has 'content'), not CreateTaskResult (has 'task')\n            if (message.type === 'result' && validator && 'content' in message.result) {\n                const result = message.result as CallToolResult;\n\n                // If tool has outputSchema, it MUST return structuredContent (unless it's an error)\n                if (!result.structuredContent && !result.isError) {\n                    yield {\n                        type: 'error',\n                        error: new ProtocolError(\n                            ProtocolErrorCode.InvalidRequest,\n                            `Tool ${params.name} has an output schema but did not return structured content`\n                        )\n                    };\n                    return;\n                }\n\n                // Only validate structured content if present (not when there's an error)\n                if (result.structuredContent) {\n                    try {\n                        // Validate the structured content against the schema\n                        const validationResult = validator(result.structuredContent);\n\n                        if (!validationResult.valid) {\n                            yield {\n                                type: 'error',\n                                error: new ProtocolError(\n                                    ProtocolErrorCode.InvalidParams,\n                                    `Structured content does not match the tool's output schema: ${validationResult.errorMessage}`\n                                )\n                            };\n                            return;\n                        }\n                    } catch (error) {\n                        if (error instanceof ProtocolError) {\n                            yield { type: 'error', error };\n                            return;\n                        }\n                        yield {\n                            type: 'error',\n                            error: new ProtocolError(\n                                ProtocolErrorCode.InvalidParams,\n                                `Failed to validate structured content: ${error instanceof Error ? error.message : String(error)}`\n                            )\n                        };\n                        return;\n                    }\n                }\n            }\n\n            // Yield the message (either validated result or any other message type)\n            yield message;\n        }\n    }\n\n    /**\n     * Gets the current status of a task.\n     *\n     * @param taskId - The task identifier\n     * @param options - Optional request options\n     * @returns The task status\n     *\n     * @experimental\n     */\n    async getTask(taskId: string, options?: RequestOptions): Promise<GetTaskResult> {\n        return this._module.getTask({ taskId }, options);\n    }\n\n    /**\n     * Retrieves the result of a completed task.\n     *\n     * @param taskId - The task identifier\n     * @param options - Optional request options\n     * @returns The task result. The payload structure matches the result type of the\n     *   original request (e.g., a `tools/call` task returns a `CallToolResult`).\n     *\n     * @experimental\n     */\n    async getTaskResult(taskId: string, options?: RequestOptions): Promise<GetTaskPayloadResult> {\n        return this._module.getTaskResult({ taskId }, GetTaskPayloadResultSchema, options);\n    }\n\n    /**\n     * Lists tasks with optional pagination.\n     *\n     * @param cursor - Optional pagination cursor\n     * @param options - Optional request options\n     * @returns List of tasks with optional next cursor\n     *\n     * @experimental\n     */\n    async listTasks(cursor?: string, options?: RequestOptions): Promise<ListTasksResult> {\n        return this._module.listTasks(cursor ? { cursor } : undefined, options);\n    }\n\n    /**\n     * Cancels a running task.\n     *\n     * @param taskId - The task identifier\n     * @param options - Optional request options\n     *\n     * @experimental\n     */\n    async cancelTask(taskId: string, options?: RequestOptions): Promise<CancelTaskResult> {\n        return this._module.cancelTask({ taskId }, options);\n    }\n\n    /**\n     * Sends a request and returns an AsyncGenerator that yields response messages.\n     * The generator is guaranteed to end with either a `'result'` or `'error'` message.\n     *\n     * This method provides streaming access to request processing, allowing you to\n     * observe intermediate task status updates for task-augmented requests.\n     *\n     * @example\n     * ```ts source=\"./client.examples.ts#ExperimentalClientTasks_requestStream\"\n     * const stream = client.experimental.tasks.requestStream({ method: 'tools/call', params: { name: 'my-tool', arguments: {} } }, options);\n     * for await (const message of stream) {\n     *     switch (message.type) {\n     *         case 'taskCreated': {\n     *             console.log('Task created:', message.task.taskId);\n     *             break;\n     *         }\n     *         case 'taskStatus': {\n     *             console.log('Task status:', message.task.status);\n     *             break;\n     *         }\n     *         case 'result': {\n     *             console.log('Final result:', message.result);\n     *             break;\n     *         }\n     *         case 'error': {\n     *             console.error('Error:', message.error);\n     *             break;\n     *         }\n     *     }\n     * }\n     * ```\n     *\n     * @param request - The request to send\n     * @param options - Optional request options (timeout, signal, task creation params, etc.)\n     * @returns AsyncGenerator that yields {@linkcode ResponseMessage} objects\n     *\n     * @experimental\n     */\n    requestStream<M extends RequestMethod>(\n        request: { method: M; params?: Record<string, unknown> },\n        options?: RequestOptions\n    ): AsyncGenerator<ResponseMessage<ResultTypeMap[M]>, void, void> {\n        const resultSchema = getResultSchema(request.method) as unknown as AnyObjectSchema;\n        return this._module.requestStream(request as Request, resultSchema, options) as AsyncGenerator<\n            ResponseMessage<ResultTypeMap[M]>,\n            void,\n            void\n        >;\n    }\n}\n","import { DefaultJsonSchemaValidator } from '@modelcontextprotocol/client/_shims';\nimport type {\n    BaseContext,\n    CallToolRequest,\n    ClientCapabilities,\n    ClientContext,\n    ClientNotification,\n    ClientRequest,\n    ClientResult,\n    CompleteRequest,\n    GetPromptRequest,\n    Implementation,\n    JsonSchemaType,\n    JsonSchemaValidator,\n    jsonSchemaValidator,\n    ListChangedHandlers,\n    ListChangedOptions,\n    ListPromptsRequest,\n    ListResourcesRequest,\n    ListResourceTemplatesRequest,\n    ListToolsRequest,\n    LoggingLevel,\n    MessageExtraInfo,\n    NotificationMethod,\n    ProtocolOptions,\n    ReadResourceRequest,\n    RequestMethod,\n    RequestOptions,\n    RequestTypeMap,\n    ResultTypeMap,\n    ServerCapabilities,\n    SubscribeRequest,\n    TaskManagerOptions,\n    Tool,\n    Transport,\n    UnsubscribeRequest\n} from '@modelcontextprotocol/core';\nimport {\n    assertClientRequestTaskCapability,\n    assertToolsCallTaskCapability,\n    CallToolResultSchema,\n    CompleteResultSchema,\n    CreateMessageRequestSchema,\n    CreateMessageResultSchema,\n    CreateMessageResultWithToolsSchema,\n    CreateTaskResultSchema,\n    ElicitRequestSchema,\n    ElicitResultSchema,\n    EmptyResultSchema,\n    extractTaskManagerOptions,\n    GetPromptResultSchema,\n    InitializeResultSchema,\n    LATEST_PROTOCOL_VERSION,\n    ListChangedOptionsBaseSchema,\n    ListPromptsResultSchema,\n    ListResourcesResultSchema,\n    ListResourceTemplatesResultSchema,\n    ListToolsResultSchema,\n    mergeCapabilities,\n    parseSchema,\n    Protocol,\n    ProtocolError,\n    ProtocolErrorCode,\n    ReadResourceResultSchema,\n    SdkError,\n    SdkErrorCode\n} from '@modelcontextprotocol/core';\n\nimport { ExperimentalClientTasks } from '../experimental/tasks/client.js';\n\n/**\n * Elicitation default application helper. Applies defaults to the `data` based on the `schema`.\n *\n * @param schema - The schema to apply defaults to.\n * @param data - The data to apply defaults to.\n */\nfunction applyElicitationDefaults(schema: JsonSchemaType | undefined, data: unknown): void {\n    if (!schema || data === null || typeof data !== 'object') return;\n\n    // Handle object properties\n    if (schema.type === 'object' && schema.properties && typeof schema.properties === 'object') {\n        const obj = data as Record<string, unknown>;\n        const props = schema.properties as Record<string, JsonSchemaType & { default?: unknown }>;\n        for (const key of Object.keys(props)) {\n            const propSchema = props[key]!;\n            // If missing or explicitly undefined, apply default if present\n            if (obj[key] === undefined && Object.prototype.hasOwnProperty.call(propSchema, 'default')) {\n                obj[key] = propSchema.default;\n            }\n            // Recurse into existing nested objects/arrays\n            if (obj[key] !== undefined) {\n                applyElicitationDefaults(propSchema, obj[key]);\n            }\n        }\n    }\n\n    if (Array.isArray(schema.anyOf)) {\n        for (const sub of schema.anyOf) {\n            // Skip boolean schemas (true/false are valid JSON Schemas but have no defaults)\n            if (typeof sub !== 'boolean') {\n                applyElicitationDefaults(sub, data);\n            }\n        }\n    }\n\n    // Combine schemas\n    if (Array.isArray(schema.oneOf)) {\n        for (const sub of schema.oneOf) {\n            // Skip boolean schemas (true/false are valid JSON Schemas but have no defaults)\n            if (typeof sub !== 'boolean') {\n                applyElicitationDefaults(sub, data);\n            }\n        }\n    }\n}\n\n/**\n * Determines which elicitation modes are supported based on declared client capabilities.\n *\n * According to the spec:\n * - An empty elicitation capability object defaults to form mode support (backwards compatibility)\n * - URL mode is only supported if explicitly declared\n *\n * @param capabilities - The client's elicitation capabilities\n * @returns An object indicating which modes are supported\n */\nexport function getSupportedElicitationModes(capabilities: ClientCapabilities['elicitation']): {\n    supportsFormMode: boolean;\n    supportsUrlMode: boolean;\n} {\n    if (!capabilities) {\n        return { supportsFormMode: false, supportsUrlMode: false };\n    }\n\n    const hasFormCapability = capabilities.form !== undefined;\n    const hasUrlCapability = capabilities.url !== undefined;\n\n    // If neither form nor url are explicitly declared, form mode is supported (backwards compatibility)\n    const supportsFormMode = hasFormCapability || (!hasFormCapability && !hasUrlCapability);\n    const supportsUrlMode = hasUrlCapability;\n\n    return { supportsFormMode, supportsUrlMode };\n}\n\n/**\n * Extended tasks capability that includes runtime configuration (store, messageQueue).\n * The runtime-only fields are stripped before advertising capabilities to servers.\n */\nexport type ClientTasksCapabilityWithRuntime = NonNullable<ClientCapabilities['tasks']> & TaskManagerOptions;\n\nexport type ClientOptions = ProtocolOptions & {\n    /**\n     * Capabilities to advertise as being supported by this client.\n     */\n    capabilities?: Omit<ClientCapabilities, 'tasks'> & {\n        tasks?: ClientTasksCapabilityWithRuntime;\n    };\n\n    /**\n     * JSON Schema validator for tool output validation.\n     *\n     * The validator is used to validate structured content returned by tools\n     * against their declared output schemas.\n     *\n     * @default {@linkcode DefaultJsonSchemaValidator} ({@linkcode index.AjvJsonSchemaValidator | AjvJsonSchemaValidator} on Node.js, {@linkcode index.CfWorkerJsonSchemaValidator | CfWorkerJsonSchemaValidator} on Cloudflare Workers)\n     */\n    jsonSchemaValidator?: jsonSchemaValidator;\n\n    /**\n     * Configure handlers for list changed notifications (tools, prompts, resources).\n     *\n     * @example\n     * ```ts source=\"./client.examples.ts#ClientOptions_listChanged\"\n     * const client = new Client(\n     *     { name: 'my-client', version: '1.0.0' },\n     *     {\n     *         listChanged: {\n     *             tools: {\n     *                 onChanged: (error, tools) => {\n     *                     if (error) {\n     *                         console.error('Failed to refresh tools:', error);\n     *                         return;\n     *                     }\n     *                     console.log('Tools updated:', tools);\n     *                 }\n     *             },\n     *             prompts: {\n     *                 onChanged: (error, prompts) => console.log('Prompts updated:', prompts)\n     *             }\n     *         }\n     *     }\n     * );\n     * ```\n     */\n    listChanged?: ListChangedHandlers;\n};\n\n/**\n * An MCP client on top of a pluggable transport.\n *\n * The client will automatically begin the initialization flow with the server when {@linkcode connect} is called.\n *\n */\nexport class Client extends Protocol<ClientContext> {\n    private _serverCapabilities?: ServerCapabilities;\n    private _serverVersion?: Implementation;\n    private _negotiatedProtocolVersion?: string;\n    private _capabilities: ClientCapabilities;\n    private _instructions?: string;\n    private _jsonSchemaValidator: jsonSchemaValidator;\n    private _cachedToolOutputValidators: Map<string, JsonSchemaValidator<unknown>> = new Map();\n    private _cachedKnownTaskTools: Set<string> = new Set();\n    private _cachedRequiredTaskTools: Set<string> = new Set();\n    private _experimental?: { tasks: ExperimentalClientTasks };\n    private _listChangedDebounceTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();\n    private _pendingListChangedConfig?: ListChangedHandlers;\n    private _enforceStrictCapabilities: boolean;\n\n    /**\n     * Initializes this client with the given name and version information.\n     */\n    constructor(\n        private _clientInfo: Implementation,\n        options?: ClientOptions\n    ) {\n        super({\n            ...options,\n            tasks: extractTaskManagerOptions(options?.capabilities?.tasks)\n        });\n        this._capabilities = options?.capabilities ? { ...options.capabilities } : {};\n        this._jsonSchemaValidator = options?.jsonSchemaValidator ?? new DefaultJsonSchemaValidator();\n        this._enforceStrictCapabilities = options?.enforceStrictCapabilities ?? false;\n\n        // Strip runtime-only fields from advertised capabilities\n        if (options?.capabilities?.tasks) {\n            // eslint-disable-next-line @typescript-eslint/no-unused-vars\n            const { taskStore, taskMessageQueue, defaultTaskPollInterval, maxTaskQueueSize, ...wireCapabilities } =\n                options.capabilities.tasks;\n            this._capabilities.tasks = wireCapabilities;\n        }\n\n        // Store list changed config for setup after connection (when we know server capabilities)\n        if (options?.listChanged) {\n            this._pendingListChangedConfig = options.listChanged;\n        }\n    }\n\n    protected override buildContext(ctx: BaseContext, _transportInfo?: MessageExtraInfo): ClientContext {\n        return ctx;\n    }\n\n    /**\n     * Set up handlers for list changed notifications based on config and server capabilities.\n     * This should only be called after initialization when server capabilities are known.\n     * Handlers are silently skipped if the server doesn't advertise the corresponding listChanged capability.\n     * @internal\n     */\n    private _setupListChangedHandlers(config: ListChangedHandlers): void {\n        if (config.tools && this._serverCapabilities?.tools?.listChanged) {\n            this._setupListChangedHandler('tools', 'notifications/tools/list_changed', config.tools, async () => {\n                const result = await this.listTools();\n                return result.tools;\n            });\n        }\n\n        if (config.prompts && this._serverCapabilities?.prompts?.listChanged) {\n            this._setupListChangedHandler('prompts', 'notifications/prompts/list_changed', config.prompts, async () => {\n                const result = await this.listPrompts();\n                return result.prompts;\n            });\n        }\n\n        if (config.resources && this._serverCapabilities?.resources?.listChanged) {\n            this._setupListChangedHandler('resources', 'notifications/resources/list_changed', config.resources, async () => {\n                const result = await this.listResources();\n                return result.resources;\n            });\n        }\n    }\n\n    /**\n     * Access experimental features.\n     *\n     * WARNING: These APIs are experimental and may change without notice.\n     *\n     * @experimental\n     */\n    get experimental(): { tasks: ExperimentalClientTasks } {\n        if (!this._experimental) {\n            this._experimental = {\n                tasks: new ExperimentalClientTasks(this)\n            };\n        }\n        return this._experimental;\n    }\n\n    /**\n     * Registers new capabilities. This can only be called before connecting to a transport.\n     *\n     * The new capabilities will be merged with any existing capabilities previously given (e.g., at initialization).\n     */\n    public registerCapabilities(capabilities: ClientCapabilities): void {\n        if (this.transport) {\n            throw new Error('Cannot register capabilities after connecting to transport');\n        }\n\n        this._capabilities = mergeCapabilities(this._capabilities, capabilities);\n    }\n\n    /**\n     * Registers a handler for server-initiated requests (sampling, elicitation, roots).\n     * The client must declare the corresponding capability for the handler to be accepted.\n     * Replaces any previously registered handler for the same method.\n     *\n     * For `sampling/createMessage` and `elicitation/create`, the handler is automatically\n     * wrapped with schema validation for both the incoming request and the returned result.\n     *\n     * @example Handling a sampling request\n     * ```ts source=\"./client.examples.ts#Client_setRequestHandler_sampling\"\n     * client.setRequestHandler('sampling/createMessage', async request => {\n     *     const lastMessage = request.params.messages.at(-1);\n     *     console.log('Sampling request:', lastMessage);\n     *\n     *     // In production, send messages to your LLM here\n     *     return {\n     *         model: 'my-model',\n     *         role: 'assistant' as const,\n     *         content: {\n     *             type: 'text' as const,\n     *             text: 'Response from the model'\n     *         }\n     *     };\n     * });\n     * ```\n     */\n    public override setRequestHandler<M extends RequestMethod>(\n        method: M,\n        handler: (request: RequestTypeMap[M], ctx: ClientContext) => ResultTypeMap[M] | Promise<ResultTypeMap[M]>\n    ): void {\n        if (method === 'elicitation/create') {\n            const wrappedHandler = async (request: RequestTypeMap[M], ctx: ClientContext): Promise<ClientResult> => {\n                const validatedRequest = parseSchema(ElicitRequestSchema, request);\n                if (!validatedRequest.success) {\n                    // Type guard: if success is false, error is guaranteed to exist\n                    const errorMessage =\n                        validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);\n                    throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid elicitation request: ${errorMessage}`);\n                }\n\n                const { params } = validatedRequest.data;\n                params.mode = params.mode ?? 'form';\n                const { supportsFormMode, supportsUrlMode } = getSupportedElicitationModes(this._capabilities.elicitation);\n\n                if (params.mode === 'form' && !supportsFormMode) {\n                    throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Client does not support form-mode elicitation requests');\n                }\n\n                if (params.mode === 'url' && !supportsUrlMode) {\n                    throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Client does not support URL-mode elicitation requests');\n                }\n\n                const result = await Promise.resolve(handler(request, ctx));\n\n                // When task creation is requested, validate and return CreateTaskResult\n                if (params.task) {\n                    const taskValidationResult = parseSchema(CreateTaskResultSchema, result);\n                    if (!taskValidationResult.success) {\n                        const errorMessage =\n                            taskValidationResult.error instanceof Error\n                                ? taskValidationResult.error.message\n                                : String(taskValidationResult.error);\n                        throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);\n                    }\n                    return taskValidationResult.data;\n                }\n\n                // For non-task requests, validate against ElicitResultSchema\n                const validationResult = parseSchema(ElicitResultSchema, result);\n                if (!validationResult.success) {\n                    // Type guard: if success is false, error is guaranteed to exist\n                    const errorMessage =\n                        validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);\n                    throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid elicitation result: ${errorMessage}`);\n                }\n\n                const validatedResult = validationResult.data;\n                const requestedSchema = params.mode === 'form' ? (params.requestedSchema as JsonSchemaType) : undefined;\n\n                if (\n                    params.mode === 'form' &&\n                    validatedResult.action === 'accept' &&\n                    validatedResult.content &&\n                    requestedSchema &&\n                    this._capabilities.elicitation?.form?.applyDefaults\n                ) {\n                    try {\n                        applyElicitationDefaults(requestedSchema, validatedResult.content);\n                    } catch {\n                        // gracefully ignore errors in default application\n                    }\n                }\n\n                return validatedResult;\n            };\n\n            // Install the wrapped handler\n            return super.setRequestHandler(method, wrappedHandler);\n        }\n\n        if (method === 'sampling/createMessage') {\n            const wrappedHandler = async (request: RequestTypeMap[M], ctx: ClientContext): Promise<ClientResult> => {\n                const validatedRequest = parseSchema(CreateMessageRequestSchema, request);\n                if (!validatedRequest.success) {\n                    const errorMessage =\n                        validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);\n                    throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid sampling request: ${errorMessage}`);\n                }\n\n                const { params } = validatedRequest.data;\n\n                const result = await Promise.resolve(handler(request, ctx));\n\n                // When task creation is requested, validate and return CreateTaskResult\n                if (params.task) {\n                    const taskValidationResult = parseSchema(CreateTaskResultSchema, result);\n                    if (!taskValidationResult.success) {\n                        const errorMessage =\n                            taskValidationResult.error instanceof Error\n                                ? taskValidationResult.error.message\n                                : String(taskValidationResult.error);\n                        throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);\n                    }\n                    return taskValidationResult.data;\n                }\n\n                // For non-task requests, validate against appropriate schema based on tools presence\n                const hasTools = params.tools || params.toolChoice;\n                const resultSchema = hasTools ? CreateMessageResultWithToolsSchema : CreateMessageResultSchema;\n                const validationResult = parseSchema(resultSchema, result);\n                if (!validationResult.success) {\n                    const errorMessage =\n                        validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);\n                    throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Invalid sampling result: ${errorMessage}`);\n                }\n\n                return validationResult.data;\n            };\n\n            // Install the wrapped handler\n            return super.setRequestHandler(method, wrappedHandler);\n        }\n\n        // Other handlers use default behavior\n        return super.setRequestHandler(method, handler);\n    }\n\n    protected assertCapability(capability: keyof ServerCapabilities, method: string): void {\n        if (!this._serverCapabilities?.[capability]) {\n            throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support ${capability} (required for ${method})`);\n        }\n    }\n\n    /**\n     * Connects to a server via the given transport and performs the MCP initialization handshake.\n     *\n     * @example Basic usage (stdio)\n     * ```ts source=\"./client.examples.ts#Client_connect_stdio\"\n     * const client = new Client({ name: 'my-client', version: '1.0.0' });\n     * const transport = new StdioClientTransport({ command: 'my-mcp-server' });\n     * await client.connect(transport);\n     * ```\n     *\n     * @example Streamable HTTP with SSE fallback\n     * ```ts source=\"./client.examples.ts#Client_connect_sseFallback\"\n     * const baseUrl = new URL(url);\n     *\n     * try {\n     *     // Try modern Streamable HTTP transport first\n     *     const client = new Client({ name: 'my-client', version: '1.0.0' });\n     *     const transport = new StreamableHTTPClientTransport(baseUrl);\n     *     await client.connect(transport);\n     *     return { client, transport };\n     * } catch {\n     *     // Fall back to legacy SSE transport\n     *     const client = new Client({ name: 'my-client', version: '1.0.0' });\n     *     const transport = new SSEClientTransport(baseUrl);\n     *     await client.connect(transport);\n     *     return { client, transport };\n     * }\n     * ```\n     */\n    override async connect(transport: Transport, options?: RequestOptions): Promise<void> {\n        await super.connect(transport);\n        // When transport sessionId is already set this means we are trying to reconnect.\n        // Restore the protocol version negotiated during the original initialize handshake\n        // so HTTP transports include the required mcp-protocol-version header, but skip re-init.\n        if (transport.sessionId !== undefined) {\n            if (this._negotiatedProtocolVersion !== undefined && transport.setProtocolVersion) {\n                transport.setProtocolVersion(this._negotiatedProtocolVersion);\n            }\n            return;\n        }\n        try {\n            const result = await this._requestWithSchema(\n                {\n                    method: 'initialize',\n                    params: {\n                        protocolVersion: this._supportedProtocolVersions[0] ?? LATEST_PROTOCOL_VERSION,\n                        capabilities: this._capabilities,\n                        clientInfo: this._clientInfo\n                    }\n                },\n                InitializeResultSchema,\n                options\n            );\n\n            if (result === undefined) {\n                throw new Error(`Server sent invalid initialize result: ${result}`);\n            }\n\n            if (!this._supportedProtocolVersions.includes(result.protocolVersion)) {\n                throw new Error(`Server's protocol version is not supported: ${result.protocolVersion}`);\n            }\n\n            this._serverCapabilities = result.capabilities;\n            this._serverVersion = result.serverInfo;\n            this._negotiatedProtocolVersion = result.protocolVersion;\n            // HTTP transports must set the protocol version in each header after initialization.\n            if (transport.setProtocolVersion) {\n                transport.setProtocolVersion(result.protocolVersion);\n            }\n\n            this._instructions = result.instructions;\n\n            await this.notification({\n                method: 'notifications/initialized'\n            });\n\n            // Set up list changed handlers now that we know server capabilities\n            if (this._pendingListChangedConfig) {\n                this._setupListChangedHandlers(this._pendingListChangedConfig);\n                this._pendingListChangedConfig = undefined;\n            }\n        } catch (error) {\n            // Disconnect if initialization fails.\n            void this.close();\n            throw error;\n        }\n    }\n\n    /**\n     * After initialization has completed, this will be populated with the server's reported capabilities.\n     */\n    getServerCapabilities(): ServerCapabilities | undefined {\n        return this._serverCapabilities;\n    }\n\n    /**\n     * After initialization has completed, this will be populated with information about the server's name and version.\n     */\n    getServerVersion(): Implementation | undefined {\n        return this._serverVersion;\n    }\n\n    /**\n     * After initialization has completed, this will be populated with the protocol version negotiated\n     * during the initialize handshake. When manually reconstructing a transport for reconnection, pass this\n     * value to the new transport so it continues sending the required `mcp-protocol-version` header.\n     */\n    getNegotiatedProtocolVersion(): string | undefined {\n        return this._negotiatedProtocolVersion;\n    }\n\n    /**\n     * After initialization has completed, this may be populated with information about the server's instructions.\n     */\n    getInstructions(): string | undefined {\n        return this._instructions;\n    }\n\n    protected assertCapabilityForMethod(method: RequestMethod): void {\n        switch (method as ClientRequest['method']) {\n            case 'logging/setLevel': {\n                if (!this._serverCapabilities?.logging) {\n                    throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support logging (required for ${method})`);\n                }\n                break;\n            }\n\n            case 'prompts/get':\n            case 'prompts/list': {\n                if (!this._serverCapabilities?.prompts) {\n                    throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support prompts (required for ${method})`);\n                }\n                break;\n            }\n\n            case 'resources/list':\n            case 'resources/templates/list':\n            case 'resources/read':\n            case 'resources/subscribe':\n            case 'resources/unsubscribe': {\n                if (!this._serverCapabilities?.resources) {\n                    throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support resources (required for ${method})`);\n                }\n\n                if (method === 'resources/subscribe' && !this._serverCapabilities.resources.subscribe) {\n                    throw new SdkError(\n                        SdkErrorCode.CapabilityNotSupported,\n                        `Server does not support resource subscriptions (required for ${method})`\n                    );\n                }\n\n                break;\n            }\n\n            case 'tools/call':\n            case 'tools/list': {\n                if (!this._serverCapabilities?.tools) {\n                    throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support tools (required for ${method})`);\n                }\n                break;\n            }\n\n            case 'completion/complete': {\n                if (!this._serverCapabilities?.completions) {\n                    throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support completions (required for ${method})`);\n                }\n                break;\n            }\n\n            case 'initialize': {\n                // No specific capability required for initialize\n                break;\n            }\n\n            case 'ping': {\n                // No specific capability required for ping\n                break;\n            }\n        }\n    }\n\n    protected assertNotificationCapability(method: NotificationMethod): void {\n        switch (method as ClientNotification['method']) {\n            case 'notifications/roots/list_changed': {\n                if (!this._capabilities.roots?.listChanged) {\n                    throw new SdkError(\n                        SdkErrorCode.CapabilityNotSupported,\n                        `Client does not support roots list changed notifications (required for ${method})`\n                    );\n                }\n                break;\n            }\n\n            case 'notifications/initialized': {\n                // No specific capability required for initialized\n                break;\n            }\n\n            case 'notifications/cancelled': {\n                // Cancellation notifications are always allowed\n                break;\n            }\n\n            case 'notifications/progress': {\n                // Progress notifications are always allowed\n                break;\n            }\n        }\n    }\n\n    protected assertRequestHandlerCapability(method: string): void {\n        switch (method) {\n            case 'sampling/createMessage': {\n                if (!this._capabilities.sampling) {\n                    throw new SdkError(\n                        SdkErrorCode.CapabilityNotSupported,\n                        `Client does not support sampling capability (required for ${method})`\n                    );\n                }\n                break;\n            }\n\n            case 'elicitation/create': {\n                if (!this._capabilities.elicitation) {\n                    throw new SdkError(\n                        SdkErrorCode.CapabilityNotSupported,\n                        `Client does not support elicitation capability (required for ${method})`\n                    );\n                }\n                break;\n            }\n\n            case 'roots/list': {\n                if (!this._capabilities.roots) {\n                    throw new SdkError(\n                        SdkErrorCode.CapabilityNotSupported,\n                        `Client does not support roots capability (required for ${method})`\n                    );\n                }\n                break;\n            }\n\n            case 'ping': {\n                // No specific capability required for ping\n                break;\n            }\n        }\n    }\n\n    protected assertTaskCapability(method: string): void {\n        assertToolsCallTaskCapability(this._serverCapabilities?.tasks?.requests, method, 'Server');\n    }\n\n    protected assertTaskHandlerCapability(method: string): void {\n        assertClientRequestTaskCapability(this._capabilities?.tasks?.requests, method, 'Client');\n    }\n\n    async ping(options?: RequestOptions) {\n        return this._requestWithSchema({ method: 'ping' }, EmptyResultSchema, options);\n    }\n\n    /** Requests argument autocompletion suggestions from the server for a prompt or resource. */\n    async complete(params: CompleteRequest['params'], options?: RequestOptions) {\n        return this._requestWithSchema({ method: 'completion/complete', params }, CompleteResultSchema, options);\n    }\n\n    /** Sets the minimum severity level for log messages sent by the server. */\n    async setLoggingLevel(level: LoggingLevel, options?: RequestOptions) {\n        return this._requestWithSchema({ method: 'logging/setLevel', params: { level } }, EmptyResultSchema, options);\n    }\n\n    /** Retrieves a prompt by name from the server, passing the given arguments for template substitution. */\n    async getPrompt(params: GetPromptRequest['params'], options?: RequestOptions) {\n        return this._requestWithSchema({ method: 'prompts/get', params }, GetPromptResultSchema, options);\n    }\n\n    /**\n     * Lists available prompts. Results may be paginated — loop on `nextCursor` to collect all pages.\n     *\n     * Returns an empty list if the server does not advertise prompts capability\n     * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n     *\n     * @example\n     * ```ts source=\"./client.examples.ts#Client_listPrompts_pagination\"\n     * const allPrompts: Prompt[] = [];\n     * let cursor: string | undefined;\n     * do {\n     *     const { prompts, nextCursor } = await client.listPrompts({ cursor });\n     *     allPrompts.push(...prompts);\n     *     cursor = nextCursor;\n     * } while (cursor);\n     * console.log(\n     *     'Available prompts:',\n     *     allPrompts.map(p => p.name)\n     * );\n     * ```\n     */\n    async listPrompts(params?: ListPromptsRequest['params'], options?: RequestOptions) {\n        if (!this._serverCapabilities?.prompts && !this._enforceStrictCapabilities) {\n            // Respect capability negotiation: server does not support prompts\n            console.debug('Client.listPrompts() called but server does not advertise prompts capability - returning empty list');\n            return { prompts: [] };\n        }\n        return this._requestWithSchema({ method: 'prompts/list', params }, ListPromptsResultSchema, options);\n    }\n\n    /**\n     * Lists available resources. Results may be paginated — loop on `nextCursor` to collect all pages.\n     *\n     * Returns an empty list if the server does not advertise resources capability\n     * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n     *\n     * @example\n     * ```ts source=\"./client.examples.ts#Client_listResources_pagination\"\n     * const allResources: Resource[] = [];\n     * let cursor: string | undefined;\n     * do {\n     *     const { resources, nextCursor } = await client.listResources({ cursor });\n     *     allResources.push(...resources);\n     *     cursor = nextCursor;\n     * } while (cursor);\n     * console.log(\n     *     'Available resources:',\n     *     allResources.map(r => r.name)\n     * );\n     * ```\n     */\n    async listResources(params?: ListResourcesRequest['params'], options?: RequestOptions) {\n        if (!this._serverCapabilities?.resources && !this._enforceStrictCapabilities) {\n            // Respect capability negotiation: server does not support resources\n            console.debug('Client.listResources() called but server does not advertise resources capability - returning empty list');\n            return { resources: [] };\n        }\n        return this._requestWithSchema({ method: 'resources/list', params }, ListResourcesResultSchema, options);\n    }\n\n    /**\n     * Lists available resource URI templates for dynamic resources. Results may be paginated — see {@linkcode listResources | listResources()} for the cursor pattern.\n     *\n     * Returns an empty list if the server does not advertise resources capability\n     * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n     */\n    async listResourceTemplates(params?: ListResourceTemplatesRequest['params'], options?: RequestOptions) {\n        if (!this._serverCapabilities?.resources && !this._enforceStrictCapabilities) {\n            // Respect capability negotiation: server does not support resources\n            console.debug(\n                'Client.listResourceTemplates() called but server does not advertise resources capability - returning empty list'\n            );\n            return { resourceTemplates: [] };\n        }\n        return this._requestWithSchema({ method: 'resources/templates/list', params }, ListResourceTemplatesResultSchema, options);\n    }\n\n    /** Reads the contents of a resource by URI. */\n    async readResource(params: ReadResourceRequest['params'], options?: RequestOptions) {\n        return this._requestWithSchema({ method: 'resources/read', params }, ReadResourceResultSchema, options);\n    }\n\n    /** Subscribes to change notifications for a resource. The server must support resource subscriptions. */\n    async subscribeResource(params: SubscribeRequest['params'], options?: RequestOptions) {\n        return this._requestWithSchema({ method: 'resources/subscribe', params }, EmptyResultSchema, options);\n    }\n\n    /** Unsubscribes from change notifications for a resource. */\n    async unsubscribeResource(params: UnsubscribeRequest['params'], options?: RequestOptions) {\n        return this._requestWithSchema({ method: 'resources/unsubscribe', params }, EmptyResultSchema, options);\n    }\n\n    /**\n     * Calls a tool on the connected server and returns the result. Automatically validates structured output\n     * if the tool has an `outputSchema`.\n     *\n     * Tool results have two error surfaces: `result.isError` for tool-level failures (the tool ran but reported\n     * a problem), and thrown {@linkcode ProtocolError} for protocol-level failures or {@linkcode SdkError} for\n     * SDK-level issues (timeouts, missing capabilities).\n     *\n     * For task-based execution with streaming behavior, use {@linkcode ExperimentalClientTasks.callToolStream | client.experimental.tasks.callToolStream()} instead.\n     *\n     * @example Basic usage\n     * ```ts source=\"./client.examples.ts#Client_callTool_basic\"\n     * const result = await client.callTool({\n     *     name: 'calculate-bmi',\n     *     arguments: { weightKg: 70, heightM: 1.75 }\n     * });\n     *\n     * // Tool-level errors are returned in the result, not thrown\n     * if (result.isError) {\n     *     console.error('Tool error:', result.content);\n     *     return;\n     * }\n     *\n     * console.log(result.content);\n     * ```\n     *\n     * @example Structured output\n     * ```ts source=\"./client.examples.ts#Client_callTool_structuredOutput\"\n     * const result = await client.callTool({\n     *     name: 'calculate-bmi',\n     *     arguments: { weightKg: 70, heightM: 1.75 }\n     * });\n     *\n     * // Machine-readable output for the client application\n     * if (result.structuredContent) {\n     *     console.log(result.structuredContent); // e.g. { bmi: 22.86 }\n     * }\n     * ```\n     */\n    async callTool(params: CallToolRequest['params'], options?: RequestOptions) {\n        // Guard: required-task tools need experimental API\n        if (this.isToolTaskRequired(params.name)) {\n            throw new ProtocolError(\n                ProtocolErrorCode.InvalidRequest,\n                `Tool \"${params.name}\" requires task-based execution. Use client.experimental.tasks.callToolStream() instead.`\n            );\n        }\n\n        const result = await this._requestWithSchema({ method: 'tools/call', params }, CallToolResultSchema, options);\n\n        // Check if the tool has an outputSchema\n        const validator = this.getToolOutputValidator(params.name);\n        if (validator) {\n            // If tool has outputSchema, it MUST return structuredContent (unless it's an error)\n            if (!result.structuredContent && !result.isError) {\n                throw new ProtocolError(\n                    ProtocolErrorCode.InvalidRequest,\n                    `Tool ${params.name} has an output schema but did not return structured content`\n                );\n            }\n\n            // Only validate structured content if present (not when there's an error)\n            if (result.structuredContent) {\n                try {\n                    // Validate the structured content against the schema\n                    const validationResult = validator(result.structuredContent);\n\n                    if (!validationResult.valid) {\n                        throw new ProtocolError(\n                            ProtocolErrorCode.InvalidParams,\n                            `Structured content does not match the tool's output schema: ${validationResult.errorMessage}`\n                        );\n                    }\n                } catch (error) {\n                    if (error instanceof ProtocolError) {\n                        throw error;\n                    }\n                    throw new ProtocolError(\n                        ProtocolErrorCode.InvalidParams,\n                        `Failed to validate structured content: ${error instanceof Error ? error.message : String(error)}`\n                    );\n                }\n            }\n        }\n\n        return result;\n    }\n\n    private isToolTask(toolName: string): boolean {\n        if (!this._serverCapabilities?.tasks?.requests?.tools?.call) {\n            return false;\n        }\n\n        return this._cachedKnownTaskTools.has(toolName);\n    }\n\n    /**\n     * Check if a tool requires task-based execution.\n     * Unlike {@linkcode isToolTask} which includes `'optional'` tools, this only checks for `'required'`.\n     */\n    private isToolTaskRequired(toolName: string): boolean {\n        return this._cachedRequiredTaskTools.has(toolName);\n    }\n\n    /**\n     * Cache validators for tool output schemas.\n     * Called after {@linkcode listTools | listTools()} to pre-compile validators for better performance.\n     */\n    private cacheToolMetadata(tools: Tool[]): void {\n        this._cachedToolOutputValidators.clear();\n        this._cachedKnownTaskTools.clear();\n        this._cachedRequiredTaskTools.clear();\n\n        for (const tool of tools) {\n            // If the tool has an outputSchema, create and cache the validator\n            if (tool.outputSchema) {\n                const toolValidator = this._jsonSchemaValidator.getValidator(tool.outputSchema as JsonSchemaType);\n                this._cachedToolOutputValidators.set(tool.name, toolValidator);\n            }\n\n            // If the tool supports task-based execution, cache that information\n            const taskSupport = tool.execution?.taskSupport;\n            if (taskSupport === 'required' || taskSupport === 'optional') {\n                this._cachedKnownTaskTools.add(tool.name);\n            }\n            if (taskSupport === 'required') {\n                this._cachedRequiredTaskTools.add(tool.name);\n            }\n        }\n    }\n\n    /**\n     * Get cached validator for a tool\n     */\n    private getToolOutputValidator(toolName: string): JsonSchemaValidator<unknown> | undefined {\n        return this._cachedToolOutputValidators.get(toolName);\n    }\n\n    /**\n     * Lists available tools. Results may be paginated — loop on `nextCursor` to collect all pages.\n     *\n     * Returns an empty list if the server does not advertise tools capability\n     * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n     *\n     * @example\n     * ```ts source=\"./client.examples.ts#Client_listTools_pagination\"\n     * const allTools: Tool[] = [];\n     * let cursor: string | undefined;\n     * do {\n     *     const { tools, nextCursor } = await client.listTools({ cursor });\n     *     allTools.push(...tools);\n     *     cursor = nextCursor;\n     * } while (cursor);\n     * console.log(\n     *     'Available tools:',\n     *     allTools.map(t => t.name)\n     * );\n     * ```\n     */\n    async listTools(params?: ListToolsRequest['params'], options?: RequestOptions) {\n        if (!this._serverCapabilities?.tools && !this._enforceStrictCapabilities) {\n            // Respect capability negotiation: server does not support tools\n            console.debug('Client.listTools() called but server does not advertise tools capability - returning empty list');\n            return { tools: [] };\n        }\n        const result = await this._requestWithSchema({ method: 'tools/list', params }, ListToolsResultSchema, options);\n\n        // Cache the tools and their output schemas for future validation\n        this.cacheToolMetadata(result.tools);\n\n        return result;\n    }\n\n    /**\n     * Set up a single list changed handler.\n     * @internal\n     */\n    private _setupListChangedHandler<T>(\n        listType: string,\n        notificationMethod: NotificationMethod,\n        options: ListChangedOptions<T>,\n        fetcher: () => Promise<T[]>\n    ): void {\n        // Validate options using Zod schema (validates autoRefresh and debounceMs)\n        const parseResult = parseSchema(ListChangedOptionsBaseSchema, options);\n        if (!parseResult.success) {\n            throw new Error(`Invalid ${listType} listChanged options: ${parseResult.error.message}`);\n        }\n\n        // Validate callback\n        if (typeof options.onChanged !== 'function') {\n            throw new TypeError(`Invalid ${listType} listChanged options: onChanged must be a function`);\n        }\n\n        const { autoRefresh, debounceMs } = parseResult.data;\n        const { onChanged } = options;\n\n        const refresh = async () => {\n            if (!autoRefresh) {\n                onChanged(null, null);\n                return;\n            }\n\n            try {\n                const items = await fetcher();\n                onChanged(null, items);\n            } catch (error) {\n                const newError = error instanceof Error ? error : new Error(String(error));\n                onChanged(newError, null);\n            }\n        };\n\n        const handler = () => {\n            if (debounceMs) {\n                // Clear any pending debounce timer for this list type\n                const existingTimer = this._listChangedDebounceTimers.get(listType);\n                if (existingTimer) {\n                    clearTimeout(existingTimer);\n                }\n\n                // Set up debounced refresh\n                const timer = setTimeout(refresh, debounceMs);\n                this._listChangedDebounceTimers.set(listType, timer);\n            } else {\n                // No debounce, refresh immediately\n                refresh();\n            }\n        };\n\n        // Register notification handler\n        this.setNotificationHandler(notificationMethod, handler);\n    }\n\n    /** Notifies the server that the client's root list has changed. Requires the `roots.listChanged` capability. */\n    async sendRootsListChanged() {\n        return this.notification({ method: 'notifications/roots/list_changed' });\n    }\n}\n","/**\n * Cross-App Access (Enterprise Managed Authorization) Layer 2 utilities.\n *\n * Provides standalone functions for RFC 8693 Token Exchange and RFC 7523 JWT Authorization Grant\n * flows as specified in the Enterprise Managed Authorization specification (SEP-990).\n *\n * @see https://github.com/modelcontextprotocol/ext-auth/blob/main/specification/draft/enterprise-managed-authorization.mdx\n * @module\n */\n\nimport type { FetchLike } from '@modelcontextprotocol/core';\nimport { IdJagTokenExchangeResponseSchema, OAuthErrorResponseSchema, OAuthTokensSchema } from '@modelcontextprotocol/core';\n\nimport type { ClientAuthMethod } from './auth.js';\nimport { applyClientAuthentication, discoverAuthorizationServerMetadata } from './auth.js';\n\n/**\n * Options for requesting a JWT Authorization Grant via RFC 8693 Token Exchange.\n */\nexport interface RequestJwtAuthGrantOptions {\n    /**\n     * The IdP's token endpoint URL where the token exchange request will be sent.\n     */\n    tokenEndpoint: string | URL;\n\n    /**\n     * The authorization server URL of the target MCP server (used as `audience` in the token exchange request).\n     */\n    audience: string | URL;\n\n    /**\n     * The resource identifier of the target MCP server (RFC 9728).\n     */\n    resource: string | URL;\n\n    /**\n     * The identity assertion (ID Token) from the enterprise IdP.\n     * This should be the OpenID Connect ID Token obtained during user authentication.\n     */\n    idToken: string;\n\n    /**\n     * The client ID registered with the IdP for token exchange.\n     */\n    clientId: string;\n\n    /**\n     * The client secret for authenticating with the IdP.\n     *\n     * Optional: the IdP may register the MCP client as a public client. RFC 8693 does\n     * not mandate confidential clients for token exchange. Omitting this parameter\n     * omits `client_secret` from the request body.\n     */\n    clientSecret?: string;\n\n    /**\n     * Optional space-separated list of scopes to request for the target MCP server.\n     */\n    scope?: string;\n\n    /**\n     * Custom fetch implementation. Defaults to global fetch.\n     */\n    fetchFn?: FetchLike;\n}\n\n/**\n * Options for discovering the IdP's token endpoint and requesting a JWT Authorization Grant.\n * Extends {@linkcode RequestJwtAuthGrantOptions} with IdP discovery.\n */\nexport interface DiscoverAndRequestJwtAuthGrantOptions extends Omit<RequestJwtAuthGrantOptions, 'tokenEndpoint'> {\n    /**\n     * The IdP's issuer URL for OAuth metadata discovery.\n     * Will be used to discover the token endpoint via `.well-known/oauth-authorization-server`.\n     */\n    idpUrl: string | URL;\n}\n\n/**\n * Result from a successful JWT Authorization Grant token exchange.\n */\nexport interface JwtAuthGrantResult {\n    /**\n     * The JWT Authorization Grant (ID-JAG) that can be used to request an access token from the MCP server.\n     */\n    jwtAuthGrant: string;\n\n    /**\n     * Optional expiration time in seconds for the JWT Authorization Grant.\n     */\n    expiresIn?: number;\n\n    /**\n     * Optional scope granted by the IdP (may differ from requested scope).\n     */\n    scope?: string;\n}\n\n/**\n * Requests a JWT Authorization Grant (ID-JAG) from an enterprise IdP using RFC 8693 Token Exchange.\n *\n * This function performs step 2 of the Enterprise Managed Authorization flow:\n * exchanges an ID Token for a JWT Authorization Grant that can be used with the target MCP server.\n *\n * @param options - Configuration for the token exchange request\n * @returns The JWT Authorization Grant and related metadata\n * @throws {Error} If the token exchange fails or returns an error response\n *\n * @example\n * ```ts\n * const result = await requestJwtAuthorizationGrant({\n *     tokenEndpoint: 'https://idp.example.com/token',\n *     audience: 'https://auth.chat.example/',\n *     resource: 'https://mcp.chat.example/',\n *     idToken: 'eyJhbGciOiJS...',\n *     clientId: 'my-idp-client',\n *     clientSecret: 'my-idp-secret',\n *     scope: 'chat.read chat.history'\n * });\n *\n * // Use result.jwtAuthGrant with the MCP server's authorization server\n * ```\n */\nexport async function requestJwtAuthorizationGrant(options: RequestJwtAuthGrantOptions): Promise<JwtAuthGrantResult> {\n    const { tokenEndpoint, audience, resource, idToken, clientId, clientSecret, scope, fetchFn = fetch } = options;\n\n    // Prepare token exchange request per RFC 8693\n    const params = new URLSearchParams({\n        grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n        requested_token_type: 'urn:ietf:params:oauth:token-type:id-jag',\n        audience: String(audience),\n        resource: String(resource),\n        subject_token: idToken,\n        subject_token_type: 'urn:ietf:params:oauth:token-type:id_token',\n        client_id: clientId\n    });\n\n    // Only include client_secret when provided — sending an empty/undefined secret\n    // triggers `invalid_client` on strict IdPs that registered this as a public client.\n    if (clientSecret) {\n        params.set('client_secret', clientSecret);\n    }\n\n    if (scope) {\n        params.set('scope', scope);\n    }\n\n    const response = await fetchFn(String(tokenEndpoint), {\n        method: 'POST',\n        headers: {\n            'Content-Type': 'application/x-www-form-urlencoded'\n        },\n        body: params.toString()\n    });\n\n    if (!response.ok) {\n        const errorBody = await response.json().catch(() => ({}));\n\n        // Try to parse as OAuth error response\n        const parseResult = OAuthErrorResponseSchema.safeParse(errorBody);\n        if (parseResult.success) {\n            const { error, error_description } = parseResult.data;\n            throw new Error(`Token exchange failed: ${error}${error_description ? ` - ${error_description}` : ''}`);\n        }\n\n        throw new Error(`Token exchange failed with status ${response.status}: ${JSON.stringify(errorBody)}`);\n    }\n\n    const parseResult = IdJagTokenExchangeResponseSchema.safeParse(await response.json());\n    if (!parseResult.success) {\n        throw new Error(`Invalid token exchange response: ${parseResult.error.message}`);\n    }\n\n    return {\n        jwtAuthGrant: parseResult.data.access_token,\n        expiresIn: parseResult.data.expires_in,\n        scope: parseResult.data.scope\n    };\n}\n\n/**\n * Discovers the IdP's token endpoint and requests a JWT Authorization Grant.\n *\n * This is a convenience wrapper around {@linkcode requestJwtAuthorizationGrant} that\n * first performs OAuth metadata discovery to find the token endpoint.\n *\n * @param options - Configuration including IdP URL for discovery\n * @returns The JWT Authorization Grant and related metadata\n * @throws {Error} If discovery fails or the token exchange fails\n *\n * @example\n * ```ts\n * const result = await discoverAndRequestJwtAuthGrant({\n *     idpUrl: 'https://idp.example.com',\n *     audience: 'https://auth.chat.example/',\n *     resource: 'https://mcp.chat.example/',\n *     idToken: await getIdToken(),\n *     clientId: 'my-idp-client',\n *     clientSecret: 'my-idp-secret'\n * });\n * ```\n */\nexport async function discoverAndRequestJwtAuthGrant(options: DiscoverAndRequestJwtAuthGrantOptions): Promise<JwtAuthGrantResult> {\n    const { idpUrl, fetchFn = fetch, ...restOptions } = options;\n\n    // Discover IdP's authorization server metadata\n    const metadata = await discoverAuthorizationServerMetadata(String(idpUrl), { fetchFn });\n\n    if (!metadata?.token_endpoint) {\n        throw new Error(`Failed to discover token endpoint for IdP: ${idpUrl}`);\n    }\n\n    // Perform token exchange\n    return requestJwtAuthorizationGrant({\n        ...restOptions,\n        tokenEndpoint: metadata.token_endpoint,\n        fetchFn\n    });\n}\n\n/**\n * Exchanges a JWT Authorization Grant for an access token at the MCP server's authorization server.\n *\n * This function performs step 3 of the Enterprise Managed Authorization flow:\n * uses the JWT Authorization Grant to obtain an access token from the MCP server.\n *\n * @param options - Configuration for the JWT grant exchange\n * @returns OAuth tokens (access token, token type, etc.)\n * @throws {Error} If the exchange fails or returns an error response\n *\n * Defaults to `client_secret_basic` (HTTP Basic Authorization header), matching\n * `CrossAppAccessProvider`'s declared `token_endpoint_auth_method` and the\n * SEP-990 conformance test requirements. Use `authMethod: 'client_secret_post'` only\n * when the authorization server explicitly requires it.\n *\n * @example\n * ```ts\n * const tokens = await exchangeJwtAuthGrant({\n *     tokenEndpoint: 'https://auth.chat.example/token',\n *     jwtAuthGrant: 'eyJhbGci...',\n *     clientId: 'my-mcp-client',\n *     clientSecret: 'my-mcp-secret'\n * });\n *\n * // Use tokens.access_token to access the MCP server\n * ```\n */\nexport async function exchangeJwtAuthGrant(options: {\n    tokenEndpoint: string | URL;\n    jwtAuthGrant: string;\n    clientId: string;\n    clientSecret?: string;\n    /**\n     * Client authentication method. Defaults to `'client_secret_basic'` to align with\n     * `CrossAppAccessProvider` and SEP-990 conformance requirements.\n     * Callers with no `clientSecret` should pass `'none'` for public-client auth.\n     */\n    authMethod?: ClientAuthMethod;\n    fetchFn?: FetchLike;\n}): Promise<{ access_token: string; token_type: string; expires_in?: number; scope?: string }> {\n    const { tokenEndpoint, jwtAuthGrant, clientId, clientSecret, authMethod = 'client_secret_basic', fetchFn = fetch } = options;\n\n    // Prepare JWT bearer grant request per RFC 7523\n    const params = new URLSearchParams({\n        grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n        assertion: jwtAuthGrant\n    });\n\n    const headers = new Headers({\n        'Content-Type': 'application/x-www-form-urlencoded'\n    });\n\n    applyClientAuthentication(authMethod, { client_id: clientId, client_secret: clientSecret }, headers, params);\n\n    const response = await fetchFn(String(tokenEndpoint), {\n        method: 'POST',\n        headers,\n        body: params.toString()\n    });\n\n    if (!response.ok) {\n        const errorBody = await response.json().catch(() => ({}));\n\n        // Try to parse as OAuth error response\n        const parseResult = OAuthErrorResponseSchema.safeParse(errorBody);\n        if (parseResult.success) {\n            const { error, error_description } = parseResult.data;\n            throw new Error(`JWT grant exchange failed: ${error}${error_description ? ` - ${error_description}` : ''}`);\n        }\n\n        throw new Error(`JWT grant exchange failed with status ${response.status}: ${JSON.stringify(errorBody)}`);\n    }\n\n    const responseBody = await response.json();\n\n    // Validate response using core schema\n    const parseResult = OAuthTokensSchema.safeParse(responseBody);\n    if (!parseResult.success) {\n        throw new Error(`Invalid token response: ${parseResult.error.message}`);\n    }\n\n    return parseResult.data;\n}\n","import type { FetchLike } from '@modelcontextprotocol/core';\n\nimport type { OAuthClientProvider } from './auth.js';\nimport { auth, extractWWWAuthenticateParams, UnauthorizedError } from './auth.js';\n\n/**\n * Middleware function that wraps and enhances fetch functionality.\n * Takes a fetch handler and returns an enhanced fetch handler.\n */\nexport type Middleware = (next: FetchLike) => FetchLike;\n\n/**\n * Creates a fetch wrapper that handles OAuth authentication automatically.\n *\n * This wrapper will:\n * - Add `Authorization` headers with access tokens\n * - Handle 401 responses by attempting re-authentication\n * - Retry the original request after successful auth\n * - Handle OAuth errors appropriately ({@linkcode index.OAuthErrorCode.InvalidClient | OAuthErrorCode.InvalidClient}, etc.)\n *\n * The `baseUrl` parameter is optional and defaults to using the domain from the request URL.\n * However, you should explicitly provide `baseUrl` when:\n * - Making requests to multiple subdomains (e.g., api.example.com, cdn.example.com)\n * - Using API paths that differ from OAuth discovery paths (e.g., requesting /api/v1/data but OAuth is at /)\n * - The OAuth server is on a different domain than your API requests\n * - You want to ensure consistent OAuth behavior regardless of request URLs\n *\n * For MCP transports, set `baseUrl` to the same URL you pass to the transport constructor.\n *\n * Note: This wrapper is designed for general-purpose fetch operations.\n * MCP transports (SSE and StreamableHTTP) already have built-in OAuth handling\n * and should not need this wrapper.\n *\n * @param provider - OAuth client provider for authentication\n * @param baseUrl - Base URL for OAuth server discovery (defaults to request URL domain)\n * @returns A fetch middleware function\n */\nexport const withOAuth =\n    (provider: OAuthClientProvider, baseUrl?: string | URL): Middleware =>\n    next => {\n        return async (input, init) => {\n            const makeRequest = async (): Promise<Response> => {\n                const headers = new Headers(init?.headers);\n\n                // Add authorization header if tokens are available\n                const tokens = await provider.tokens();\n                if (tokens) {\n                    headers.set('Authorization', `Bearer ${tokens.access_token}`);\n                }\n\n                return await next(input, { ...init, headers });\n            };\n\n            let response = await makeRequest();\n\n            // Handle 401 responses by attempting re-authentication\n            if (response.status === 401) {\n                try {\n                    const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n\n                    // Use provided baseUrl or extract from request URL\n                    const serverUrl = baseUrl || (typeof input === 'string' ? new URL(input).origin : input.origin);\n\n                    const result = await auth(provider, {\n                        serverUrl,\n                        resourceMetadataUrl,\n                        scope,\n                        fetchFn: next\n                    });\n\n                    if (result === 'REDIRECT') {\n                        throw new UnauthorizedError('Authentication requires user authorization - redirect initiated');\n                    }\n\n                    if (result !== 'AUTHORIZED') {\n                        throw new UnauthorizedError(`Authentication failed with result: ${result}`);\n                    }\n\n                    // Retry the request with fresh tokens\n                    response = await makeRequest();\n                } catch (error) {\n                    if (error instanceof UnauthorizedError) {\n                        throw error;\n                    }\n                    throw new UnauthorizedError(`Failed to re-authenticate: ${error instanceof Error ? error.message : String(error)}`);\n                }\n            }\n\n            // If we still have a 401 after re-auth attempt, throw an error\n            if (response.status === 401) {\n                const url = typeof input === 'string' ? input : input.toString();\n                throw new UnauthorizedError(`Authentication failed for ${url}`);\n            }\n\n            return response;\n        };\n    };\n\n/**\n * Logger function type for HTTP requests\n */\nexport type RequestLogger = (input: {\n    method: string;\n    url: string | URL;\n    status: number;\n    statusText: string;\n    duration: number;\n    requestHeaders?: Headers;\n    responseHeaders?: Headers;\n    error?: Error;\n}) => void;\n\n/**\n * Configuration options for the logging middleware\n */\nexport type LoggingOptions = {\n    /**\n     * Custom logger function, defaults to console logging\n     */\n    logger?: RequestLogger;\n\n    /**\n     * Whether to include request headers in logs\n     * @default false\n     */\n    includeRequestHeaders?: boolean;\n\n    /**\n     * Whether to include response headers in logs\n     * @default false\n     */\n    includeResponseHeaders?: boolean;\n\n    /**\n     * Status level filter - only log requests with status >= this value\n     * Set to `0` to log all requests, `400` to log only errors\n     * @default 0\n     */\n    statusLevel?: number;\n};\n\n/**\n * Creates a fetch middleware that logs HTTP requests and responses.\n *\n * When called without arguments `withLogging()`, it uses the default logger that:\n * - Logs successful requests (2xx) to `console.log`\n * - Logs error responses (4xx/5xx) and network errors to `console.error`\n * - Logs all requests regardless of status (`statusLevel: 0`)\n * - Does not include request or response headers in logs\n * - Measures and displays request duration in milliseconds\n *\n * Important: the default logger uses both `console.log` and `console.error` so it should not be used with\n * `stdio` transports and applications.\n *\n * @param options - Logging configuration options\n * @returns A fetch middleware function\n */\nexport const withLogging = (options: LoggingOptions = {}): Middleware => {\n    const { logger, includeRequestHeaders = false, includeResponseHeaders = false, statusLevel = 0 } = options;\n\n    const defaultLogger: RequestLogger = input => {\n        const { method, url, status, statusText, duration, requestHeaders, responseHeaders, error } = input;\n\n        let message = error\n            ? `HTTP ${method} ${url} failed: ${error.message} (${duration}ms)`\n            : `HTTP ${method} ${url} ${status} ${statusText} (${duration}ms)`;\n\n        // Add headers to message if requested\n        if (includeRequestHeaders && requestHeaders) {\n            const reqHeaders = [...requestHeaders.entries()].map(([key, value]) => `${key}: ${value}`).join(', ');\n            message += `\\n  Request Headers: {${reqHeaders}}`;\n        }\n\n        if (includeResponseHeaders && responseHeaders) {\n            const resHeaders = [...responseHeaders.entries()].map(([key, value]) => `${key}: ${value}`).join(', ');\n            message += `\\n  Response Headers: {${resHeaders}}`;\n        }\n\n        if (error || status >= 400) {\n            // eslint-disable-next-line no-console\n            console.error(message);\n        } else {\n            // eslint-disable-next-line no-console\n            console.log(message);\n        }\n    };\n\n    const logFn = logger || defaultLogger;\n\n    return next => async (input, init) => {\n        const startTime = performance.now();\n        const method = init?.method || 'GET';\n        const url = typeof input === 'string' ? input : input.toString();\n        const requestHeaders = includeRequestHeaders ? new Headers(init?.headers) : undefined;\n\n        try {\n            const response = await next(input, init);\n            const duration = performance.now() - startTime;\n\n            // Only log if status meets the log level threshold\n            if (response.status >= statusLevel) {\n                logFn({\n                    method,\n                    url,\n                    status: response.status,\n                    statusText: response.statusText,\n                    duration,\n                    requestHeaders,\n                    responseHeaders: includeResponseHeaders ? response.headers : undefined\n                });\n            }\n\n            return response;\n        } catch (error) {\n            const duration = performance.now() - startTime;\n\n            // Always log errors regardless of log level\n            logFn({\n                method,\n                url,\n                status: 0,\n                statusText: 'Network Error',\n                duration,\n                requestHeaders,\n                error: error as Error\n            });\n\n            throw error;\n        }\n    };\n};\n\n/**\n * Composes multiple fetch middleware functions into a single middleware pipeline.\n * Middleware are applied in the order they appear, creating a chain of handlers.\n *\n * @example\n * ```ts source=\"./middleware.examples.ts#applyMiddlewares_basicUsage\"\n * // Create a middleware pipeline that handles both OAuth and logging\n * const enhancedFetch = applyMiddlewares(withOAuth(oauthProvider, 'https://api.example.com'), withLogging({ statusLevel: 400 }))(fetch);\n *\n * // Use the enhanced fetch - it will handle auth and log errors\n * const response = await enhancedFetch('https://api.example.com/data');\n * ```\n *\n * @param middleware - Array of fetch middleware to compose into a pipeline\n * @returns A single composed middleware function\n */\nexport const applyMiddlewares = (...middleware: Middleware[]): Middleware => {\n    return next => {\n        let handler = next;\n        for (const mw of middleware) {\n            handler = mw(handler);\n        }\n        return handler;\n    };\n};\n\n/**\n * Helper function to create custom fetch middleware with cleaner syntax.\n * Provides the next handler and request details as separate parameters for easier access.\n *\n * @example\n * ```ts source=\"./middleware.examples.ts#createMiddleware_examples\"\n * // Create custom authentication middleware\n * const customAuthMiddleware = createMiddleware(async (next, input, init) => {\n *     const headers = new Headers(init?.headers);\n *     headers.set('X-Custom-Auth', 'my-token');\n *\n *     const response = await next(input, { ...init, headers });\n *\n *     if (response.status === 401) {\n *         console.log('Authentication failed');\n *     }\n *\n *     return response;\n * });\n *\n * // Create conditional middleware\n * const conditionalMiddleware = createMiddleware(async (next, input, init) => {\n *     const url = typeof input === 'string' ? input : input.toString();\n *\n *     // Only add headers for API routes\n *     if (url.includes('/api/')) {\n *         const headers = new Headers(init?.headers);\n *         headers.set('X-API-Version', 'v2');\n *         return next(input, { ...init, headers });\n *     }\n *\n *     // Pass through for non-API routes\n *     return next(input, init);\n * });\n *\n * // Create caching middleware\n * const cacheMiddleware = createMiddleware(async (next, input, init) => {\n *     const cacheKey = typeof input === 'string' ? input : input.toString();\n *\n *     // Check cache first\n *     const cached = await getFromCache(cacheKey);\n *     if (cached) {\n *         return new Response(cached, { status: 200 });\n *     }\n *\n *     // Make request and cache result\n *     const response = await next(input, init);\n *     if (response.ok) {\n *         await saveToCache(cacheKey, await response.clone().text());\n *     }\n *\n *     return response;\n * });\n * ```\n *\n * @param handler - Function that receives the next handler and request parameters\n * @returns A fetch middleware function\n */\nexport const createMiddleware = (handler: (next: FetchLike, input: string | URL, init?: RequestInit) => Promise<Response>): Middleware => {\n    return next => (input, init) => handler(next, input as string | URL, init);\n};\n","import type { FetchLike, JSONRPCMessage, Transport } from '@modelcontextprotocol/core';\nimport { createFetchWithInit, JSONRPCMessageSchema, normalizeHeaders, SdkError, SdkErrorCode } from '@modelcontextprotocol/core';\nimport type { ErrorEvent, EventSourceInit } from 'eventsource';\nimport { EventSource } from 'eventsource';\n\nimport type { AuthProvider, OAuthClientProvider } from './auth.js';\nimport { adaptOAuthProvider, auth, extractWWWAuthenticateParams, isOAuthClientProvider, UnauthorizedError } from './auth.js';\n\nexport class SseError extends Error {\n    constructor(\n        public readonly code: number | undefined,\n        message: string | undefined,\n        public readonly event: ErrorEvent\n    ) {\n        super(`SSE error: ${message}`);\n    }\n}\n\n/**\n * Configuration options for the {@linkcode SSEClientTransport}.\n */\nexport type SSEClientTransportOptions = {\n    /**\n     * An OAuth client provider to use for authentication.\n     *\n     * {@linkcode AuthProvider.token | token()} is called before every request to obtain the\n     * bearer token. When the server responds with 401, {@linkcode AuthProvider.onUnauthorized | onUnauthorized()}\n     * is called (if provided) to refresh credentials, then the request is retried once. If\n     * the retry also gets 401, or `onUnauthorized` is not provided, {@linkcode UnauthorizedError}\n     * is thrown.\n     *\n     * For simple bearer tokens: `{ token: async () => myApiKey }`.\n     *\n     * For OAuth flows, pass an {@linkcode index.OAuthClientProvider | OAuthClientProvider} implementation.\n     * Interactive flows: after {@linkcode UnauthorizedError}, redirect the user, then call\n     * {@linkcode SSEClientTransport.finishAuth | finishAuth} with the authorization code before reconnecting.\n     */\n    authProvider?: AuthProvider | OAuthClientProvider;\n\n    /**\n     * Customizes the initial SSE request to the server (the request that begins the stream).\n     *\n     * NOTE: Setting this property will prevent an `Authorization` header from\n     * being automatically attached to the SSE request, if an {@linkcode SSEClientTransportOptions.authProvider | authProvider} is\n     * also given. This can be worked around by setting the `Authorization` header\n     * manually.\n     */\n    eventSourceInit?: EventSourceInit;\n\n    /**\n     * Customizes recurring `POST` requests to the server.\n     */\n    requestInit?: RequestInit;\n\n    /**\n     * Custom fetch implementation used for all network requests.\n     */\n    fetch?: FetchLike;\n};\n\n/**\n * Client transport for SSE: this will connect to a server using Server-Sent Events for receiving\n * messages and make separate `POST` requests for sending messages.\n * @deprecated SSEClientTransport is deprecated. Prefer to use {@linkcode index.StreamableHTTPClientTransport | StreamableHTTPClientTransport} where possible instead. Note that because some servers are still using SSE, clients may need to support both transports during the migration period.\n */\nexport class SSEClientTransport implements Transport {\n    private _eventSource?: EventSource;\n    private _endpoint?: URL;\n    private _abortController?: AbortController;\n    private _url: URL;\n    private _resourceMetadataUrl?: URL;\n    private _scope?: string;\n    private _eventSourceInit?: EventSourceInit;\n    private _requestInit?: RequestInit;\n    private _authProvider?: AuthProvider;\n    private _oauthProvider?: OAuthClientProvider;\n    private _fetch?: FetchLike;\n    private _fetchWithInit: FetchLike;\n    private _protocolVersion?: string;\n\n    onclose?: () => void;\n    onerror?: (error: Error) => void;\n    onmessage?: (message: JSONRPCMessage) => void;\n\n    constructor(url: URL, opts?: SSEClientTransportOptions) {\n        this._url = url;\n        this._resourceMetadataUrl = undefined;\n        this._scope = undefined;\n        this._eventSourceInit = opts?.eventSourceInit;\n        this._requestInit = opts?.requestInit;\n        if (isOAuthClientProvider(opts?.authProvider)) {\n            this._oauthProvider = opts.authProvider;\n            this._authProvider = adaptOAuthProvider(opts.authProvider);\n        } else {\n            this._authProvider = opts?.authProvider;\n        }\n        this._fetch = opts?.fetch;\n        this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);\n    }\n\n    private _last401Response?: Response;\n\n    private async _commonHeaders(): Promise<Headers> {\n        const headers: RequestInit['headers'] & Record<string, string> = {};\n        const token = await this._authProvider?.token();\n        if (token) {\n            headers['Authorization'] = `Bearer ${token}`;\n        }\n        if (this._protocolVersion) {\n            headers['mcp-protocol-version'] = this._protocolVersion;\n        }\n\n        const extraHeaders = normalizeHeaders(this._requestInit?.headers);\n\n        return new Headers({\n            ...headers,\n            ...extraHeaders\n        });\n    }\n\n    private _startOrAuth(): Promise<void> {\n        const fetchImpl = (this?._eventSourceInit?.fetch ?? this._fetch ?? fetch) as typeof fetch;\n        return new Promise((resolve, reject) => {\n            this._eventSource = new EventSource(this._url.href, {\n                ...this._eventSourceInit,\n                fetch: async (url, init) => {\n                    const headers = await this._commonHeaders();\n                    headers.set('Accept', 'text/event-stream');\n                    const response = await fetchImpl(url, {\n                        ...init,\n                        headers\n                    });\n\n                    if (response.status === 401) {\n                        this._last401Response = response;\n                        if (response.headers.has('www-authenticate')) {\n                            const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n                            this._resourceMetadataUrl = resourceMetadataUrl;\n                            this._scope = scope;\n                        }\n                    }\n\n                    return response;\n                }\n            });\n            this._abortController = new AbortController();\n\n            this._eventSource.onerror = event => {\n                if (event.code === 401 && this._authProvider) {\n                    if (this._authProvider.onUnauthorized && this._last401Response) {\n                        const response = this._last401Response;\n                        this._last401Response = undefined;\n                        this._eventSource?.close();\n                        this._authProvider.onUnauthorized({ response, serverUrl: this._url, fetchFn: this._fetchWithInit }).then(\n                            // onUnauthorized succeeded → retry fresh. Its onerror handles its own onerror?.() + reject.\n                            () => this._startOrAuth().then(resolve, reject),\n                            // onUnauthorized failed → not yet reported.\n                            error => {\n                                this.onerror?.(error);\n                                reject(error);\n                            }\n                        );\n                        return;\n                    }\n                    const error = new UnauthorizedError();\n                    reject(error);\n                    this.onerror?.(error);\n                    return;\n                }\n\n                const error = new SseError(event.code, event.message, event);\n                reject(error);\n                this.onerror?.(error);\n            };\n\n            this._eventSource.onopen = () => {\n                // The connection is open, but we need to wait for the endpoint to be received.\n            };\n\n            this._eventSource.addEventListener('endpoint', (event: Event) => {\n                const messageEvent = event as MessageEvent;\n\n                try {\n                    this._endpoint = new URL(messageEvent.data, this._url);\n                    if (this._endpoint.origin !== this._url.origin) {\n                        throw new Error(`Endpoint origin does not match connection origin: ${this._endpoint.origin}`);\n                    }\n                } catch (error) {\n                    reject(error);\n                    this.onerror?.(error as Error);\n\n                    void this.close();\n                    return;\n                }\n\n                resolve();\n            });\n\n            this._eventSource.onmessage = (event: Event) => {\n                const messageEvent = event as MessageEvent;\n                let message: JSONRPCMessage;\n                try {\n                    message = JSONRPCMessageSchema.parse(JSON.parse(messageEvent.data));\n                } catch (error) {\n                    this.onerror?.(error as Error);\n                    return;\n                }\n\n                this.onmessage?.(message);\n            };\n        });\n    }\n\n    async start() {\n        if (this._eventSource) {\n            throw new Error('SSEClientTransport already started! If using Client class, note that connect() calls start() automatically.');\n        }\n\n        return await this._startOrAuth();\n    }\n\n    /**\n     * Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.\n     */\n    async finishAuth(authorizationCode: string): Promise<void> {\n        if (!this._oauthProvider) {\n            throw new UnauthorizedError('finishAuth requires an OAuthClientProvider');\n        }\n\n        const result = await auth(this._oauthProvider, {\n            serverUrl: this._url,\n            authorizationCode,\n            resourceMetadataUrl: this._resourceMetadataUrl,\n            scope: this._scope,\n            fetchFn: this._fetchWithInit\n        });\n        if (result !== 'AUTHORIZED') {\n            throw new UnauthorizedError('Failed to authorize');\n        }\n    }\n\n    async close(): Promise<void> {\n        this._abortController?.abort();\n        this._eventSource?.close();\n        this.onclose?.();\n    }\n\n    async send(message: JSONRPCMessage): Promise<void> {\n        return this._send(message, false);\n    }\n\n    private async _send(message: JSONRPCMessage, isAuthRetry: boolean): Promise<void> {\n        if (!this._endpoint) {\n            throw new SdkError(SdkErrorCode.NotConnected, 'Not connected');\n        }\n\n        try {\n            const headers = await this._commonHeaders();\n            headers.set('content-type', 'application/json');\n            const init = {\n                ...this._requestInit,\n                method: 'POST',\n                headers,\n                body: JSON.stringify(message),\n                signal: this._abortController?.signal\n            };\n\n            const response = await (this._fetch ?? fetch)(this._endpoint, init);\n            if (!response.ok) {\n                if (response.status === 401 && this._authProvider) {\n                    if (response.headers.has('www-authenticate')) {\n                        const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n                        this._resourceMetadataUrl = resourceMetadataUrl;\n                        this._scope = scope;\n                    }\n\n                    if (this._authProvider.onUnauthorized && !isAuthRetry) {\n                        await this._authProvider.onUnauthorized({\n                            response,\n                            serverUrl: this._url,\n                            fetchFn: this._fetchWithInit\n                        });\n                        await response.text?.().catch(() => {});\n                        // Purposely _not_ awaited, so we don't call onerror twice\n                        return this._send(message, true);\n                    }\n                    await response.text?.().catch(() => {});\n                    if (isAuthRetry) {\n                        throw new SdkError(SdkErrorCode.ClientHttpAuthentication, 'Server returned 401 after re-authentication', {\n                            status: 401\n                        });\n                    }\n                    throw new UnauthorizedError();\n                }\n\n                const text = await response.text?.().catch(() => null);\n                throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);\n            }\n\n            // Release connection - POST responses don't have content we need\n            await response.text?.().catch(() => {});\n        } catch (error) {\n            this.onerror?.(error as Error);\n            throw error;\n        }\n    }\n\n    setProtocolVersion(version: string): void {\n        this._protocolVersion = version;\n    }\n}\n","import type { ChildProcess, IOType } from 'node:child_process';\nimport process from 'node:process';\nimport type { Stream } from 'node:stream';\nimport { PassThrough } from 'node:stream';\n\nimport type { JSONRPCMessage, Transport } from '@modelcontextprotocol/core';\nimport { ReadBuffer, SdkError, SdkErrorCode, serializeMessage } from '@modelcontextprotocol/core';\nimport spawn from 'cross-spawn';\n\nexport type StdioServerParameters = {\n    /**\n     * The executable to run to start the server.\n     */\n    command: string;\n\n    /**\n     * Command line arguments to pass to the executable.\n     */\n    args?: string[];\n\n    /**\n     * The environment to use when spawning the process.\n     *\n     * If not specified, the result of {@linkcode getDefaultEnvironment} will be used.\n     */\n    env?: Record<string, string>;\n\n    /**\n     * How to handle stderr of the child process. This matches the semantics of Node's `child_process.spawn`.\n     *\n     * The default is `\"inherit\"`, meaning messages to stderr will be printed to the parent process's stderr.\n     */\n    stderr?: IOType | Stream | number;\n\n    /**\n     * The working directory to use when spawning the process.\n     *\n     * If not specified, the current working directory will be inherited.\n     */\n    cwd?: string;\n};\n\n/**\n * Environment variables to inherit by default, if an environment is not explicitly given.\n */\nexport const DEFAULT_INHERITED_ENV_VARS =\n    process.platform === 'win32'\n        ? [\n              'APPDATA',\n              'HOMEDRIVE',\n              'HOMEPATH',\n              'LOCALAPPDATA',\n              'PATH',\n              'PROCESSOR_ARCHITECTURE',\n              'SYSTEMDRIVE',\n              'SYSTEMROOT',\n              'TEMP',\n              'USERNAME',\n              'USERPROFILE',\n              'PROGRAMFILES'\n          ]\n        : /* list inspired by the default env inheritance of sudo */\n          ['HOME', 'LOGNAME', 'PATH', 'SHELL', 'TERM', 'USER'];\n\n/**\n * Returns a default environment object including only environment variables deemed safe to inherit.\n */\nexport function getDefaultEnvironment(): Record<string, string> {\n    const env: Record<string, string> = {};\n\n    for (const key of DEFAULT_INHERITED_ENV_VARS) {\n        const value = process.env[key];\n        if (value === undefined) {\n            continue;\n        }\n\n        if (value.startsWith('()')) {\n            // Skip functions, which are a security risk.\n            continue;\n        }\n\n        env[key] = value;\n    }\n\n    return env;\n}\n\n/**\n * Client transport for stdio: this will connect to a server by spawning a process and communicating with it over stdin/stdout.\n *\n * This transport is only available in Node.js environments.\n */\nexport class StdioClientTransport implements Transport {\n    private _process?: ChildProcess;\n    private _readBuffer: ReadBuffer = new ReadBuffer();\n    private _serverParams: StdioServerParameters;\n    private _stderrStream: PassThrough | null = null;\n\n    onclose?: () => void;\n    onerror?: (error: Error) => void;\n    onmessage?: (message: JSONRPCMessage) => void;\n\n    constructor(server: StdioServerParameters) {\n        this._serverParams = server;\n        if (server.stderr === 'pipe' || server.stderr === 'overlapped') {\n            this._stderrStream = new PassThrough();\n        }\n    }\n\n    /**\n     * Starts the server process and prepares to communicate with it.\n     */\n    async start(): Promise<void> {\n        if (this._process) {\n            throw new Error(\n                'StdioClientTransport already started! If using Client class, note that connect() calls start() automatically.'\n            );\n        }\n\n        return new Promise((resolve, reject) => {\n            this._process = spawn(this._serverParams.command, this._serverParams.args ?? [], {\n                // merge default env with server env because mcp server needs some env vars\n                env: {\n                    ...getDefaultEnvironment(),\n                    ...this._serverParams.env\n                },\n                stdio: ['pipe', 'pipe', this._serverParams.stderr ?? 'inherit'],\n                shell: false,\n                windowsHide: process.platform === 'win32',\n                cwd: this._serverParams.cwd\n            });\n\n            this._process.on('error', error => {\n                reject(error);\n                this.onerror?.(error);\n            });\n\n            this._process.on('spawn', () => {\n                resolve();\n            });\n\n            this._process.on('close', _code => {\n                this._process = undefined;\n                this.onclose?.();\n            });\n\n            this._process.stdin?.on('error', error => {\n                this.onerror?.(error);\n            });\n\n            this._process.stdout?.on('data', chunk => {\n                this._readBuffer.append(chunk);\n                this.processReadBuffer();\n            });\n\n            this._process.stdout?.on('error', error => {\n                this.onerror?.(error);\n            });\n\n            if (this._stderrStream && this._process.stderr) {\n                this._process.stderr.pipe(this._stderrStream);\n            }\n        });\n    }\n\n    /**\n     * The `stderr` stream of the child process, if {@linkcode StdioServerParameters.stderr} was set to `\"pipe\"` or `\"overlapped\"`.\n     *\n     * If `stderr` piping was requested, a `PassThrough` stream is returned _immediately_, allowing callers to\n     * attach listeners before the `start` method is invoked. This prevents loss of any early\n     * error output emitted by the child process.\n     */\n    get stderr(): Stream | null {\n        if (this._stderrStream) {\n            return this._stderrStream;\n        }\n\n        return this._process?.stderr ?? null;\n    }\n\n    /**\n     * The child process pid spawned by this transport.\n     *\n     * This is only available after the transport has been started.\n     */\n    get pid(): number | null {\n        return this._process?.pid ?? null;\n    }\n\n    private processReadBuffer() {\n        while (true) {\n            try {\n                const message = this._readBuffer.readMessage();\n                if (message === null) {\n                    break;\n                }\n\n                this.onmessage?.(message);\n            } catch (error) {\n                this.onerror?.(error as Error);\n            }\n        }\n    }\n\n    async close(): Promise<void> {\n        if (this._process) {\n            const processToClose = this._process;\n            this._process = undefined;\n\n            const closePromise = new Promise<void>(resolve => {\n                processToClose.once('close', () => {\n                    resolve();\n                });\n            });\n\n            try {\n                processToClose.stdin?.end();\n            } catch {\n                // ignore\n            }\n\n            await Promise.race([closePromise, new Promise(resolve => setTimeout(resolve, 2000).unref())]);\n\n            if (processToClose.exitCode === null) {\n                try {\n                    processToClose.kill('SIGTERM');\n                } catch {\n                    // ignore\n                }\n\n                await Promise.race([closePromise, new Promise(resolve => setTimeout(resolve, 2000).unref())]);\n            }\n\n            if (processToClose.exitCode === null) {\n                try {\n                    processToClose.kill('SIGKILL');\n                } catch {\n                    // ignore\n                }\n            }\n        }\n\n        this._readBuffer.clear();\n    }\n\n    send(message: JSONRPCMessage): Promise<void> {\n        return new Promise(resolve => {\n            if (!this._process?.stdin) {\n                throw new SdkError(SdkErrorCode.NotConnected, 'Not connected');\n            }\n\n            const json = serializeMessage(message);\n            if (this._process.stdin.write(json)) {\n                resolve();\n            } else {\n                this._process.stdin.once('drain', resolve);\n            }\n        });\n    }\n}\n","import type { ReadableWritablePair } from 'node:stream/web';\n\nimport type { FetchLike, JSONRPCMessage, Transport } from '@modelcontextprotocol/core';\nimport {\n    createFetchWithInit,\n    isInitializedNotification,\n    isJSONRPCErrorResponse,\n    isJSONRPCRequest,\n    isJSONRPCResultResponse,\n    JSONRPCMessageSchema,\n    normalizeHeaders,\n    SdkError,\n    SdkErrorCode\n} from '@modelcontextprotocol/core';\nimport { EventSourceParserStream } from 'eventsource-parser/stream';\n\nimport type { AuthProvider, OAuthClientProvider } from './auth.js';\nimport { adaptOAuthProvider, auth, extractWWWAuthenticateParams, isOAuthClientProvider, UnauthorizedError } from './auth.js';\n\n// Default reconnection options for StreamableHTTP connections\nconst DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS: StreamableHTTPReconnectionOptions = {\n    initialReconnectionDelay: 1000,\n    maxReconnectionDelay: 30_000,\n    reconnectionDelayGrowFactor: 1.5,\n    maxRetries: 2\n};\n\n/**\n * Options for starting or authenticating an SSE connection\n */\nexport interface StartSSEOptions {\n    /**\n     * The resumption token used to continue long-running requests that were interrupted.\n     *\n     * This allows clients to reconnect and continue from where they left off.\n     */\n    resumptionToken?: string;\n\n    /**\n     * A callback that is invoked when the resumption token changes.\n     *\n     * This allows clients to persist the latest token for potential reconnection.\n     */\n    onresumptiontoken?: (token: string) => void;\n\n    /**\n     * Override Message ID to associate with the replay message\n     * so that the response can be associated with the new resumed request.\n     */\n    replayMessageId?: string | number;\n}\n\n/**\n * Configuration options for reconnection behavior of the {@linkcode StreamableHTTPClientTransport}.\n */\nexport interface StreamableHTTPReconnectionOptions {\n    /**\n     * Maximum backoff time between reconnection attempts in milliseconds.\n     * Default is 30000 (30 seconds).\n     */\n    maxReconnectionDelay: number;\n\n    /**\n     * Initial backoff time between reconnection attempts in milliseconds.\n     * Default is 1000 (1 second).\n     */\n    initialReconnectionDelay: number;\n\n    /**\n     * The factor by which the reconnection delay increases after each attempt.\n     * Default is 1.5.\n     */\n    reconnectionDelayGrowFactor: number;\n\n    /**\n     * Maximum number of reconnection attempts before giving up.\n     * Default is 2.\n     */\n    maxRetries: number;\n}\n\n/**\n * Custom scheduler for SSE stream reconnection attempts.\n *\n * Called instead of `setTimeout` when the transport needs to schedule a reconnection.\n * Useful in environments where `setTimeout` is unsuitable (serverless functions that\n * terminate before the timer fires, mobile apps that need platform background scheduling,\n * desktop apps handling sleep/wake).\n *\n * @param reconnect - Call this to perform the reconnection attempt.\n * @param delay - Suggested delay in milliseconds (from backoff calculation).\n * @param attemptCount - Zero-indexed retry attempt number.\n * @returns An optional cancel function. If returned, it will be called on\n * {@linkcode StreamableHTTPClientTransport.close | transport.close()} to abort the\n * pending reconnection.\n *\n * @example\n * ```ts source=\"./streamableHttp.examples.ts#ReconnectionScheduler_basicUsage\"\n * const scheduler: ReconnectionScheduler = (reconnect, delay) => {\n *     const id = platformBackgroundTask.schedule(reconnect, delay);\n *     return () => platformBackgroundTask.cancel(id);\n * };\n * ```\n */\nexport type ReconnectionScheduler = (reconnect: () => void, delay: number, attemptCount: number) => (() => void) | void;\n\n/**\n * Configuration options for the {@linkcode StreamableHTTPClientTransport}.\n */\nexport type StreamableHTTPClientTransportOptions = {\n    /**\n     * An OAuth client provider to use for authentication.\n     *\n     * {@linkcode AuthProvider.token | token()} is called before every request to obtain the\n     * bearer token. When the server responds with 401, {@linkcode AuthProvider.onUnauthorized | onUnauthorized()}\n     * is called (if provided) to refresh credentials, then the request is retried once. If\n     * the retry also gets 401, or `onUnauthorized` is not provided, {@linkcode UnauthorizedError}\n     * is thrown.\n     *\n     * For simple bearer tokens: `{ token: async () => myApiKey }`.\n     *\n     * For OAuth flows, pass an {@linkcode index.OAuthClientProvider | OAuthClientProvider} implementation\n     * directly — the transport adapts it to `AuthProvider` internally. Interactive flows: after\n     * {@linkcode UnauthorizedError}, redirect the user, then call\n     * {@linkcode StreamableHTTPClientTransport.finishAuth | finishAuth} with the authorization code before\n     * reconnecting.\n     */\n    authProvider?: AuthProvider | OAuthClientProvider;\n\n    /**\n     * Customizes HTTP requests to the server.\n     */\n    requestInit?: RequestInit;\n\n    /**\n     * Custom fetch implementation used for all network requests.\n     */\n    fetch?: FetchLike;\n\n    /**\n     * Options to configure the reconnection behavior.\n     */\n    reconnectionOptions?: StreamableHTTPReconnectionOptions;\n\n    /**\n     * Custom scheduler for reconnection attempts. If not provided, `setTimeout` is used.\n     * See {@linkcode ReconnectionScheduler}.\n     */\n    reconnectionScheduler?: ReconnectionScheduler;\n\n    /**\n     * Session ID for the connection. This is used to identify the session on the server.\n     * When not provided and connecting to a server that supports session IDs, the server will generate a new session ID.\n     */\n    sessionId?: string;\n\n    /**\n     * The MCP protocol version to include in the `mcp-protocol-version` header on all requests.\n     * When reconnecting with a preserved `sessionId`, set this to the version negotiated during the original\n     * handshake so the reconnected transport continues sending the required header.\n     */\n    protocolVersion?: string;\n};\n\n/**\n * Client transport for Streamable HTTP: this implements the MCP Streamable HTTP transport specification.\n * It will connect to a server using HTTP `POST` for sending messages and HTTP `GET` with Server-Sent Events\n * for receiving messages.\n */\nexport class StreamableHTTPClientTransport implements Transport {\n    private _abortController?: AbortController;\n    private _url: URL;\n    private _resourceMetadataUrl?: URL;\n    private _scope?: string;\n    private _requestInit?: RequestInit;\n    private _authProvider?: AuthProvider;\n    private _oauthProvider?: OAuthClientProvider;\n    private _fetch?: FetchLike;\n    private _fetchWithInit: FetchLike;\n    private _sessionId?: string;\n    private _reconnectionOptions: StreamableHTTPReconnectionOptions;\n    private _protocolVersion?: string;\n    private _lastUpscopingHeader?: string; // Track last upscoping header to prevent infinite upscoping.\n    private _serverRetryMs?: number; // Server-provided retry delay from SSE retry field\n    private readonly _reconnectionScheduler?: ReconnectionScheduler;\n    private _cancelReconnection?: () => void;\n\n    onclose?: () => void;\n    onerror?: (error: Error) => void;\n    onmessage?: (message: JSONRPCMessage) => void;\n\n    constructor(url: URL, opts?: StreamableHTTPClientTransportOptions) {\n        this._url = url;\n        this._resourceMetadataUrl = undefined;\n        this._scope = undefined;\n        this._requestInit = opts?.requestInit;\n        if (isOAuthClientProvider(opts?.authProvider)) {\n            this._oauthProvider = opts.authProvider;\n            this._authProvider = adaptOAuthProvider(opts.authProvider);\n        } else {\n            this._authProvider = opts?.authProvider;\n        }\n        this._fetch = opts?.fetch;\n        this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);\n        this._sessionId = opts?.sessionId;\n        this._protocolVersion = opts?.protocolVersion;\n        this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;\n        this._reconnectionScheduler = opts?.reconnectionScheduler;\n    }\n\n    private async _commonHeaders(): Promise<Headers> {\n        const headers: RequestInit['headers'] & Record<string, string> = {};\n        const token = await this._authProvider?.token();\n        if (token) {\n            headers['Authorization'] = `Bearer ${token}`;\n        }\n\n        if (this._sessionId) {\n            headers['mcp-session-id'] = this._sessionId;\n        }\n        if (this._protocolVersion) {\n            headers['mcp-protocol-version'] = this._protocolVersion;\n        }\n\n        const extraHeaders = normalizeHeaders(this._requestInit?.headers);\n\n        return new Headers({\n            ...headers,\n            ...extraHeaders\n        });\n    }\n\n    private async _startOrAuthSse(options: StartSSEOptions, isAuthRetry = false): Promise<void> {\n        const { resumptionToken } = options;\n\n        try {\n            // Try to open an initial SSE stream with GET to listen for server messages\n            // This is optional according to the spec - server may not support it\n            const headers = await this._commonHeaders();\n            headers.set('Accept', 'text/event-stream');\n\n            // Include Last-Event-ID header for resumable streams if provided\n            if (resumptionToken) {\n                headers.set('last-event-id', resumptionToken);\n            }\n\n            const response = await (this._fetch ?? fetch)(this._url, {\n                ...this._requestInit,\n                method: 'GET',\n                headers,\n                signal: this._abortController?.signal\n            });\n\n            if (!response.ok) {\n                if (response.status === 401 && this._authProvider) {\n                    if (response.headers.has('www-authenticate')) {\n                        const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n                        this._resourceMetadataUrl = resourceMetadataUrl;\n                        this._scope = scope;\n                    }\n\n                    if (this._authProvider.onUnauthorized && !isAuthRetry) {\n                        await this._authProvider.onUnauthorized({\n                            response,\n                            serverUrl: this._url,\n                            fetchFn: this._fetchWithInit\n                        });\n                        await response.text?.().catch(() => {});\n                        // Purposely _not_ awaited, so we don't call onerror twice\n                        return this._startOrAuthSse(options, true);\n                    }\n                    await response.text?.().catch(() => {});\n                    if (isAuthRetry) {\n                        throw new SdkError(SdkErrorCode.ClientHttpAuthentication, 'Server returned 401 after re-authentication', {\n                            status: 401\n                        });\n                    }\n                    throw new UnauthorizedError();\n                }\n\n                await response.text?.().catch(() => {});\n\n                // 405 indicates that the server does not offer an SSE stream at GET endpoint\n                // This is an expected case that should not trigger an error\n                if (response.status === 405) {\n                    return;\n                }\n\n                throw new SdkError(SdkErrorCode.ClientHttpFailedToOpenStream, `Failed to open SSE stream: ${response.statusText}`, {\n                    status: response.status,\n                    statusText: response.statusText\n                });\n            }\n\n            this._handleSseStream(response.body, options, true);\n        } catch (error) {\n            this.onerror?.(error as Error);\n            throw error;\n        }\n    }\n\n    /**\n     * Calculates the next reconnection delay using a backoff algorithm\n     *\n     * @param attempt Current reconnection attempt count for the specific stream\n     * @returns Time to wait in milliseconds before next reconnection attempt\n     */\n    private _getNextReconnectionDelay(attempt: number): number {\n        // Use server-provided retry value if available\n        if (this._serverRetryMs !== undefined) {\n            return this._serverRetryMs;\n        }\n\n        // Fall back to exponential backoff\n        const initialDelay = this._reconnectionOptions.initialReconnectionDelay;\n        const growFactor = this._reconnectionOptions.reconnectionDelayGrowFactor;\n        const maxDelay = this._reconnectionOptions.maxReconnectionDelay;\n\n        // Cap at maximum delay\n        return Math.min(initialDelay * Math.pow(growFactor, attempt), maxDelay);\n    }\n\n    /**\n     * Schedule a reconnection attempt using server-provided retry interval or backoff\n     *\n     * @param lastEventId The ID of the last received event for resumability\n     * @param attemptCount Current reconnection attempt count for this specific stream\n     */\n    private _scheduleReconnection(options: StartSSEOptions, attemptCount = 0): void {\n        // Use provided options or default options\n        const maxRetries = this._reconnectionOptions.maxRetries;\n\n        // Check if we've exceeded maximum retry attempts\n        if (attemptCount >= maxRetries) {\n            this.onerror?.(new Error(`Maximum reconnection attempts (${maxRetries}) exceeded.`));\n            return;\n        }\n\n        // Calculate next delay based on current attempt count\n        const delay = this._getNextReconnectionDelay(attemptCount);\n\n        const reconnect = (): void => {\n            this._cancelReconnection = undefined;\n            if (this._abortController?.signal.aborted) return;\n            this._startOrAuthSse(options).catch(error => {\n                this.onerror?.(new Error(`Failed to reconnect SSE stream: ${error instanceof Error ? error.message : String(error)}`));\n                try {\n                    this._scheduleReconnection(options, attemptCount + 1);\n                } catch (scheduleError) {\n                    this.onerror?.(scheduleError instanceof Error ? scheduleError : new Error(String(scheduleError)));\n                }\n            });\n        };\n\n        if (this._reconnectionScheduler) {\n            const cancel = this._reconnectionScheduler(reconnect, delay, attemptCount);\n            this._cancelReconnection = typeof cancel === 'function' ? cancel : undefined;\n        } else {\n            const handle = setTimeout(reconnect, delay);\n            this._cancelReconnection = () => clearTimeout(handle);\n        }\n    }\n\n    private _handleSseStream(stream: ReadableStream<Uint8Array> | null, options: StartSSEOptions, isReconnectable: boolean): void {\n        if (!stream) {\n            return;\n        }\n        const { onresumptiontoken, replayMessageId } = options;\n\n        let lastEventId: string | undefined;\n        // Track whether we've received a priming event (event with ID)\n        // Per spec, server SHOULD send a priming event with ID before closing\n        let hasPrimingEvent = false;\n        // Track whether we've received a response - if so, no need to reconnect\n        // Reconnection is for when server disconnects BEFORE sending response\n        let receivedResponse = false;\n        const processStream = async () => {\n            // this is the closest we can get to trying to catch network errors\n            // if something happens reader will throw\n            try {\n                // Create a pipeline: binary stream -> text decoder -> SSE parser\n                const reader = stream\n                    .pipeThrough(new TextDecoderStream() as ReadableWritablePair<string, Uint8Array>)\n                    .pipeThrough(\n                        new EventSourceParserStream({\n                            onRetry: (retryMs: number) => {\n                                // Capture server-provided retry value for reconnection timing\n                                this._serverRetryMs = retryMs;\n                            }\n                        })\n                    )\n                    .getReader();\n\n                while (true) {\n                    const { value: event, done } = await reader.read();\n                    if (done) {\n                        break;\n                    }\n\n                    // Update last event ID if provided\n                    if (event.id) {\n                        lastEventId = event.id;\n                        // Mark that we've received a priming event - stream is now resumable\n                        hasPrimingEvent = true;\n                        onresumptiontoken?.(event.id);\n                    }\n\n                    // Skip events with no data (priming events, keep-alives)\n                    if (!event.data) {\n                        continue;\n                    }\n\n                    if (!event.event || event.event === 'message') {\n                        try {\n                            const message = JSONRPCMessageSchema.parse(JSON.parse(event.data));\n                            // Handle both success AND error responses for completion detection and ID remapping\n                            if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {\n                                // Mark that we received a response - no need to reconnect for this request\n                                receivedResponse = true;\n                                if (replayMessageId !== undefined) {\n                                    message.id = replayMessageId;\n                                }\n                            }\n                            this.onmessage?.(message);\n                        } catch (error) {\n                            this.onerror?.(error as Error);\n                        }\n                    }\n                }\n\n                // Handle graceful server-side disconnect\n                // Server may close connection after sending event ID and retry field\n                // Reconnect if: already reconnectable (GET stream) OR received a priming event (POST stream with event ID)\n                // BUT don't reconnect if we already received a response - the request is complete\n                const canResume = isReconnectable || hasPrimingEvent;\n                const needsReconnect = canResume && !receivedResponse;\n                if (needsReconnect && this._abortController && !this._abortController.signal.aborted) {\n                    this._scheduleReconnection(\n                        {\n                            resumptionToken: lastEventId,\n                            onresumptiontoken,\n                            replayMessageId\n                        },\n                        0\n                    );\n                }\n            } catch (error) {\n                // Handle stream errors - likely a network disconnect\n                this.onerror?.(new Error(`SSE stream disconnected: ${error}`));\n\n                // Attempt to reconnect if the stream disconnects unexpectedly and we aren't closing\n                // Reconnect if: already reconnectable (GET stream) OR received a priming event (POST stream with event ID)\n                // BUT don't reconnect if we already received a response - the request is complete\n                const canResume = isReconnectable || hasPrimingEvent;\n                const needsReconnect = canResume && !receivedResponse;\n                if (needsReconnect && this._abortController && !this._abortController.signal.aborted) {\n                    // Use the exponential backoff reconnection strategy\n                    try {\n                        this._scheduleReconnection(\n                            {\n                                resumptionToken: lastEventId,\n                                onresumptiontoken,\n                                replayMessageId\n                            },\n                            0\n                        );\n                    } catch (error) {\n                        this.onerror?.(new Error(`Failed to reconnect: ${error instanceof Error ? error.message : String(error)}`));\n                    }\n                }\n            }\n        };\n        processStream();\n    }\n\n    async start() {\n        if (this._abortController) {\n            throw new Error(\n                'StreamableHTTPClientTransport already started! If using Client class, note that connect() calls start() automatically.'\n            );\n        }\n\n        this._abortController = new AbortController();\n    }\n\n    /**\n     * Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.\n     */\n    async finishAuth(authorizationCode: string): Promise<void> {\n        if (!this._oauthProvider) {\n            throw new UnauthorizedError('finishAuth requires an OAuthClientProvider');\n        }\n\n        const result = await auth(this._oauthProvider, {\n            serverUrl: this._url,\n            authorizationCode,\n            resourceMetadataUrl: this._resourceMetadataUrl,\n            scope: this._scope,\n            fetchFn: this._fetchWithInit\n        });\n        if (result !== 'AUTHORIZED') {\n            throw new UnauthorizedError('Failed to authorize');\n        }\n    }\n\n    async close(): Promise<void> {\n        try {\n            this._cancelReconnection?.();\n        } finally {\n            this._cancelReconnection = undefined;\n            this._abortController?.abort();\n            this.onclose?.();\n        }\n    }\n\n    async send(\n        message: JSONRPCMessage | JSONRPCMessage[],\n        options?: { resumptionToken?: string; onresumptiontoken?: (token: string) => void }\n    ): Promise<void> {\n        return this._send(message, options, false);\n    }\n\n    private async _send(\n        message: JSONRPCMessage | JSONRPCMessage[],\n        options: { resumptionToken?: string; onresumptiontoken?: (token: string) => void } | undefined,\n        isAuthRetry: boolean\n    ): Promise<void> {\n        try {\n            const { resumptionToken, onresumptiontoken } = options || {};\n\n            if (resumptionToken) {\n                // If we have a last event ID, we need to reconnect the SSE stream\n                this._startOrAuthSse({ resumptionToken, replayMessageId: isJSONRPCRequest(message) ? message.id : undefined }).catch(\n                    error => this.onerror?.(error)\n                );\n                return;\n            }\n\n            const headers = await this._commonHeaders();\n            headers.set('content-type', 'application/json');\n            headers.set('accept', 'application/json, text/event-stream');\n\n            const init = {\n                ...this._requestInit,\n                method: 'POST',\n                headers,\n                body: JSON.stringify(message),\n                signal: this._abortController?.signal\n            };\n\n            const response = await (this._fetch ?? fetch)(this._url, init);\n\n            // Handle session ID received during initialization\n            const sessionId = response.headers.get('mcp-session-id');\n            if (sessionId) {\n                this._sessionId = sessionId;\n            }\n\n            if (!response.ok) {\n                if (response.status === 401 && this._authProvider) {\n                    // Store WWW-Authenticate params for interactive finishAuth() path\n                    if (response.headers.has('www-authenticate')) {\n                        const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n                        this._resourceMetadataUrl = resourceMetadataUrl;\n                        this._scope = scope;\n                    }\n\n                    if (this._authProvider.onUnauthorized && !isAuthRetry) {\n                        await this._authProvider.onUnauthorized({\n                            response,\n                            serverUrl: this._url,\n                            fetchFn: this._fetchWithInit\n                        });\n                        await response.text?.().catch(() => {});\n                        // Purposely _not_ awaited, so we don't call onerror twice\n                        return this._send(message, options, true);\n                    }\n                    await response.text?.().catch(() => {});\n                    if (isAuthRetry) {\n                        throw new SdkError(SdkErrorCode.ClientHttpAuthentication, 'Server returned 401 after re-authentication', {\n                            status: 401\n                        });\n                    }\n                    throw new UnauthorizedError();\n                }\n\n                const text = await response.text?.().catch(() => null);\n\n                if (response.status === 403 && this._oauthProvider) {\n                    const { resourceMetadataUrl, scope, error } = extractWWWAuthenticateParams(response);\n\n                    if (error === 'insufficient_scope') {\n                        const wwwAuthHeader = response.headers.get('WWW-Authenticate');\n\n                        // Check if we've already tried upscoping with this header to prevent infinite loops.\n                        if (this._lastUpscopingHeader === wwwAuthHeader) {\n                            throw new SdkError(SdkErrorCode.ClientHttpForbidden, 'Server returned 403 after trying upscoping', {\n                                status: 403,\n                                text\n                            });\n                        }\n\n                        if (scope) {\n                            this._scope = scope;\n                        }\n\n                        if (resourceMetadataUrl) {\n                            this._resourceMetadataUrl = resourceMetadataUrl;\n                        }\n\n                        // Mark that upscoping was tried.\n                        this._lastUpscopingHeader = wwwAuthHeader ?? undefined;\n                        const result = await auth(this._oauthProvider, {\n                            serverUrl: this._url,\n                            resourceMetadataUrl: this._resourceMetadataUrl,\n                            scope: this._scope,\n                            fetchFn: this._fetchWithInit\n                        });\n\n                        if (result !== 'AUTHORIZED') {\n                            throw new UnauthorizedError();\n                        }\n\n                        return this._send(message, options, isAuthRetry);\n                    }\n                }\n\n                throw new SdkError(SdkErrorCode.ClientHttpNotImplemented, `Error POSTing to endpoint: ${text}`, {\n                    status: response.status,\n                    text\n                });\n            }\n\n            this._lastUpscopingHeader = undefined;\n\n            // If the response is 202 Accepted, there's no body to process\n            if (response.status === 202) {\n                await response.text?.().catch(() => {});\n                // if the accepted notification is initialized, we start the SSE stream\n                // if it's supported by the server\n                if (isInitializedNotification(message)) {\n                    // Start without a lastEventId since this is a fresh connection\n                    this._startOrAuthSse({ resumptionToken: undefined }).catch(error => this.onerror?.(error));\n                }\n                return;\n            }\n\n            // Get original message(s) for detecting request IDs\n            const messages = Array.isArray(message) ? message : [message];\n\n            const hasRequests = messages.some(msg => 'method' in msg && 'id' in msg && msg.id !== undefined);\n\n            // Check the response type\n            const contentType = response.headers.get('content-type');\n\n            if (hasRequests) {\n                if (contentType?.includes('text/event-stream')) {\n                    // Handle SSE stream responses for requests\n                    // We use the same handler as standalone streams, which now supports\n                    // reconnection with the last event ID\n                    this._handleSseStream(response.body, { onresumptiontoken }, false);\n                } else if (contentType?.includes('application/json')) {\n                    // For non-streaming servers, we might get direct JSON responses\n                    const data = await response.json();\n                    const responseMessages = Array.isArray(data)\n                        ? data.map(msg => JSONRPCMessageSchema.parse(msg))\n                        : [JSONRPCMessageSchema.parse(data)];\n\n                    for (const msg of responseMessages) {\n                        this.onmessage?.(msg);\n                    }\n                } else {\n                    await response.text?.().catch(() => {});\n                    throw new SdkError(SdkErrorCode.ClientHttpUnexpectedContent, `Unexpected content type: ${contentType}`, {\n                        contentType\n                    });\n                }\n            } else {\n                // No requests in message but got 200 OK - still need to release connection\n                await response.text?.().catch(() => {});\n            }\n        } catch (error) {\n            this.onerror?.(error as Error);\n            throw error;\n        }\n    }\n\n    get sessionId(): string | undefined {\n        return this._sessionId;\n    }\n\n    /**\n     * Terminates the current session by sending a `DELETE` request to the server.\n     *\n     * Clients that no longer need a particular session\n     * (e.g., because the user is leaving the client application) SHOULD send an\n     * HTTP `DELETE` to the MCP endpoint with the `Mcp-Session-Id` header to explicitly\n     * terminate the session.\n     *\n     * The server MAY respond with HTTP `405 Method Not Allowed`, indicating that\n     * the server does not allow clients to terminate sessions.\n     */\n    async terminateSession(): Promise<void> {\n        if (!this._sessionId) {\n            return; // No session to terminate\n        }\n\n        try {\n            const headers = await this._commonHeaders();\n\n            const init = {\n                ...this._requestInit,\n                method: 'DELETE',\n                headers,\n                signal: this._abortController?.signal\n            };\n\n            const response = await (this._fetch ?? fetch)(this._url, init);\n            await response.text?.().catch(() => {});\n\n            // We specifically handle 405 as a valid response according to the spec,\n            // meaning the server does not support explicit session termination\n            if (!response.ok && response.status !== 405) {\n                throw new SdkError(SdkErrorCode.ClientHttpFailedToTerminateSession, `Failed to terminate session: ${response.statusText}`, {\n                    status: response.status,\n                    statusText: response.statusText\n                });\n            }\n\n            this._sessionId = undefined;\n        } catch (error) {\n            this.onerror?.(error as Error);\n            throw error;\n        }\n    }\n\n    setProtocolVersion(version: string): void {\n        this._protocolVersion = version;\n    }\n    get protocolVersion(): string | undefined {\n        return this._protocolVersion;\n    }\n\n    /**\n     * Resume an SSE stream from a previous event ID.\n     * Opens a `GET` SSE connection with `Last-Event-ID` header to replay missed events.\n     *\n     * @param lastEventId The event ID to resume from\n     * @param options Optional callback to receive new resumption tokens\n     */\n    async resumeStream(lastEventId: string, options?: { onresumptiontoken?: (token: string) => void }): Promise<void> {\n        await this._startOrAuthSse({\n            resumptionToken: lastEventId,\n            onresumptiontoken: options?.onresumptiontoken\n        });\n    }\n}\n","import { DefaultJsonSchemaValidator } from '@modelcontextprotocol/client/_shims';\nimport type { JsonSchemaType, jsonSchemaValidator, StandardSchemaWithJSON } from '@modelcontextprotocol/core';\nimport { fromJsonSchema as coreFromJsonSchema } from '@modelcontextprotocol/core';\n\nlet _defaultValidator: jsonSchemaValidator | undefined;\n\nexport function fromJsonSchema<T = unknown>(schema: JsonSchemaType, validator?: jsonSchemaValidator): StandardSchemaWithJSON<T, T> {\n    return coreFromJsonSchema<T>(schema, validator ?? (_defaultValidator ??= new DefaultJsonSchemaValidator()));\n}\n"],"mappings":"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"}