@prefecthq/fastmcp-ts 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/cli/index.cjs +208 -36
- package/dist/cli/index.cjs.map +1 -1
- package/dist/client.d.ts +152 -107
- package/dist/client.js +73 -21
- package/dist/client.js.map +1 -1
- package/package.json +1 -1
package/dist/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client/handlers.ts","../src/client/auth.ts","../src/client/browser-stores.ts","../src/client/browser-oauth.ts","../src/client/transports.ts","../src/client/client.ts","../src/client/multi-server.ts","../src/client/utils.ts","../src/client/sampling/types.ts","../src/client/sampling/generic.ts","../src/client/sampling/anthropic.ts","../src/client/sampling/openai.ts","../src/client/sampling/google.ts"],"sourcesContent":["import type { LoggingLevel, CreateMessageRequestParams, ElicitRequestParams, ElicitResult, Tool, Resource, Prompt } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from './results.js'\n\nexport type LogMessage = {\n level: LoggingLevel\n logger?: string\n data: unknown\n}\n\nexport type LogHandler = (message: LogMessage) => void | Promise<void>\n\nexport type ProgressHandler = (\n progress: number,\n total?: number,\n message?: string,\n) => void | Promise<void>\n\nexport type SamplingHandler = (\n params: CreateMessageRequestParams,\n) => AnySamplingResult | Promise<AnySamplingResult>\n\nexport type ElicitationHandler = (\n params: ElicitRequestParams,\n) => ElicitResult | Promise<ElicitResult>\n\nexport type ResourceUpdateHandler = (uri: string) => void | Promise<void>\n\n/**\n * Config for receiving server-initiated list-change notifications.\n * Set debounceMs: 0 in tests for instant delivery.\n */\nexport type ListChangedHandler<T> = {\n onChanged: (error: Error | null, items: T[] | null) => void | Promise<void>\n /** Whether to auto-fetch the updated list before calling onChanged. Default: true. */\n autoRefresh?: boolean\n /** Debounce window in ms. Default: 300. Set to 0 to disable. */\n debounceMs?: number\n}\n\nexport interface ClientHandlers {\n log?: LogHandler\n progress?: ProgressHandler\n sampling?: SamplingHandler\n elicitation?: ElicitationHandler\n onToolsListChanged?: ListChangedHandler<Tool>\n onResourcesListChanged?: ListChangedHandler<Resource>\n onPromptsListChanged?: ListChangedHandler<Prompt>\n}\n\nexport function defaultLogHandler(message: LogMessage): void {\n const prefix = message.logger ? `[${message.logger}]` : '[server]'\n const data =\n typeof message.data === 'string' ? message.data : JSON.stringify(message.data)\n const text = `${prefix} ${data}`\n const level = message.level\n if (level === 'debug') {\n console.debug(text)\n } else if (level === 'warning') {\n console.warn(text)\n } else if (\n level === 'error' ||\n level === 'critical' ||\n level === 'alert' ||\n level === 'emergency'\n ) {\n console.error(text)\n } else {\n console.info(text)\n }\n}\n\nexport function defaultProgressHandler(\n progress: number,\n total?: number,\n message?: string,\n): void {\n const pct = total != null ? ` (${Math.round((progress / total) * 100)}%)` : ''\n const msg = message ? ` — ${message}` : ''\n console.debug(\n `progress: ${progress}${total != null ? `/${total}` : ''}${pct}${msg}`,\n )\n}\n","import {\n validateClientMetadataUrl,\n createPrivateKeyJwtAuth,\n requestJwtAuthorizationGrant,\n exchangeJwtAuthGrant,\n type OAuthClientProvider,\n type OAuthClientInformationContext,\n type OAuthDiscoveryState,\n type OAuthClientMetadata,\n type StoredOAuthClientInformation,\n type StoredOAuthTokens,\n type AddClientAuthentication,\n type ClientAuthMethod,\n} from \"@modelcontextprotocol/client\";\n\n// ---------------------------------------------------------------------------\n// OAuthToken — internal type used by ClientCredentials for expiry tracking.\n// Not the SDK's OAuthTokens: we track expires_at in milliseconds.\n// ---------------------------------------------------------------------------\n\nexport type OAuthToken = {\n access_token: string\n token_type?: string\n refresh_token?: string\n /** Unix timestamp in milliseconds (normalized internally). */\n expires_at?: number\n /** Seconds until expiry — used to compute expires_at on receipt. */\n expires_in?: number\n scope?: string\n}\n\n// ---------------------------------------------------------------------------\n// AsyncHeaderAuth — the shape of a token-acquiring auth provider\n// ---------------------------------------------------------------------------\n\n/**\n * An auth provider that acquires a token asynchronously and injects it as a\n * request header per request. {@link ClientCredentials}, {@link JwtBearerAuth},\n * and {@link EnterpriseManagedAuth} all implement it. The transport recognizes\n * these by their `kind` discriminant and injects `getHeaders()` on every\n * request via a custom fetch wrapper (unlike static `BearerAuth`, whose header\n * never changes, or interactive `OAuth`, which the SDK transport drives itself).\n */\nexport interface AsyncHeaderAuth {\n readonly kind: string\n getHeaders(): Promise<Record<string, string>>\n}\n\n// ---------------------------------------------------------------------------\n// KeyValueStore — single persistence interface for all auth state\n// ---------------------------------------------------------------------------\n\nexport type KeyValueStore = {\n get(key: string): Promise<string | null>\n set(key: string, value: string): Promise<void>\n delete(key: string): Promise<void>\n}\n\n// ---------------------------------------------------------------------------\n// InMemoryStore\n// ---------------------------------------------------------------------------\n\nexport class InMemoryStore implements KeyValueStore {\n private readonly _map = new Map<string, string>()\n\n async get(key: string): Promise<string | null> {\n return this._map.get(key) ?? null\n }\n\n async set(key: string, value: string): Promise<void> {\n this._map.set(key, value)\n }\n\n async delete(key: string): Promise<void> {\n this._map.delete(key)\n }\n}\n\n// ---------------------------------------------------------------------------\n// FileTokenStorage\n// ---------------------------------------------------------------------------\n\nexport class FileTokenStorage implements KeyValueStore {\n private readonly _explicitPath?: string\n private _resolvedPath?: string\n\n constructor(path?: string) {\n this._explicitPath = path\n }\n\n private async _path(): Promise<string> {\n if (this._resolvedPath) return this._resolvedPath\n if (this._explicitPath) return (this._resolvedPath = this._explicitPath)\n const { homedir } = await import('os')\n const { join } = await import('path')\n return (this._resolvedPath = join(homedir(), '.fastmcp', 'tokens.json'))\n }\n\n private async _readAll(): Promise<Record<string, string>> {\n const fs = await import('fs/promises')\n try {\n const raw = await fs.readFile(await this._path(), 'utf8')\n const parsed: unknown = JSON.parse(raw)\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n return parsed as Record<string, string>\n }\n return {}\n } catch {\n return {}\n }\n }\n\n private async _writeAll(data: Record<string, string>): Promise<void> {\n const fs = await import('fs/promises')\n const { dirname } = await import('path')\n const path = await this._path()\n await fs.mkdir(dirname(path), { recursive: true })\n const tmp = `${path}.tmp`\n await fs.writeFile(tmp, JSON.stringify(data, null, 2), 'utf8')\n await fs.rename(tmp, path)\n }\n\n async get(key: string): Promise<string | null> {\n const data = await this._readAll()\n return data[key] ?? null\n }\n\n async set(key: string, value: string): Promise<void> {\n const data = await this._readAll()\n data[key] = value\n await this._writeAll(data)\n }\n\n async delete(key: string): Promise<void> {\n const data = await this._readAll()\n if (!(key in data)) return\n delete data[key]\n await this._writeAll(data)\n }\n}\n\n// ---------------------------------------------------------------------------\n// OAuth — implements OAuthClientProvider (authorization code + PKCE flow)\n// ---------------------------------------------------------------------------\n\nexport interface OAuthOptions {\n /** Pre-registered client ID. When set, Dynamic Client Registration is skipped. */\n clientId?: string\n /** Pre-registered client secret. */\n clientSecret?: string\n /** Requested OAuth scopes (space-separated string or array). */\n scopes?: string | string[]\n /** Client name used in Dynamic Client Registration. Default: \"FastMCP Client\". */\n clientName?: string\n /** Persistent key-value store for tokens, client info, and discovery state. Default: in-memory. */\n store?: KeyValueStore\n /**\n * Port for the local OAuth callback server. Default: 8765.\n * The port must be consistent across calls because it is registered as the\n * redirect_uri during Dynamic Client Registration.\n */\n callbackPort?: number\n /**\n * Override how the authorization URL is opened. When not provided the\n * system browser is launched. Inject a no-op or mock here for testing.\n */\n onRedirect?: (url: URL) => void | Promise<void>\n /**\n * Client ID Metadata Document URL (SEP-991 / CIMD) — an HTTPS URL, with a\n * non-root path, that serves this client's metadata document. When the\n * authorization server advertises `client_id_metadata_document_supported`,\n * the SDK's `auth()` orchestrator uses this URL directly as the `client_id`\n * and skips Dynamic Client Registration entirely. Falls back to normal DCR\n * (or `clientId`, if set) when the server doesn't support CIMD. Validated\n * eagerly in the constructor.\n */\n clientMetadataUrl?: string\n}\n\nexport class OAuth implements OAuthClientProvider {\n private _serverUrl = ''\n private readonly _clientId?: string\n private readonly _clientSecret?: string\n private readonly _scopes?: string\n private readonly _clientName: string\n private readonly _store: KeyValueStore\n private readonly _callbackPort: number\n private readonly _onRedirect?: (url: URL) => void | Promise<void>\n readonly clientMetadataUrl?: string\n\n private _codeVerifier: string | undefined\n protected _callbackPromise: Promise<URLSearchParams> | null = null\n protected _callbackResolve: ((params: URLSearchParams) => void) | null = null\n protected _callbackReject: ((err: Error) => void) | null = null\n private _callbackServer: { close(): void } | null = null\n private _actualCallbackPort: number | null = null\n\n constructor(options: OAuthOptions = {}) {\n this._clientId = options.clientId\n this._clientSecret = options.clientSecret\n this._scopes = Array.isArray(options.scopes)\n ? options.scopes.join(' ')\n : options.scopes\n this._clientName = options.clientName ?? 'FastMCP Client'\n this._store = options.store ?? new InMemoryStore()\n this._callbackPort = options.callbackPort ?? 8765\n this._onRedirect = options.onRedirect\n // SEP-991: validated eagerly so a malformed clientMetadataUrl fails fast\n // at construction rather than deep inside the auth() flow.\n validateClientMetadataUrl(options.clientMetadataUrl)\n this.clientMetadataUrl = options.clientMetadataUrl\n }\n\n /**\n * Binds the MCP server URL so that all storage keys are namespaced by it.\n * Called by Client before connecting.\n */\n _bind(serverUrl: string): void {\n this._serverUrl = serverUrl\n }\n\n // ---- OAuthClientProvider interface ----\n\n get redirectUrl(): string | URL {\n const port = this._actualCallbackPort ?? this._callbackPort\n return `http://localhost:${port}/callback`\n }\n\n get clientMetadata(): OAuthClientMetadata {\n const port = this._actualCallbackPort ?? this._callbackPort\n return {\n redirect_uris: [`http://localhost:${port}/callback`],\n token_endpoint_auth_method: this._clientSecret ? 'client_secret_post' : 'none',\n // grant_types is intentionally omitted: the SDK's resolveClientMetadata()\n // defaults interactive providers (those with a redirectUrl, like this one)\n // to ['authorization_code', 'refresh_token'] (SEP-2207) — authorization\n // servers that gate refresh-token issuance on the registered grant types\n // need 'refresh_token' present to ever issue one during DCR. Setting this\n // explicitly here would suppress that default (an explicit field is never\n // overwritten) and could silently prevent refresh tokens from being\n // issued, even though this class fully supports using one once present.\n response_types: ['code'],\n client_name: this._clientName,\n ...(this._scopes ? { scope: this._scopes } : {}),\n }\n }\n\n async clientInformation(\n ctx?: OAuthClientInformationContext,\n ): Promise<StoredOAuthClientInformation | undefined> {\n if (this._clientId) {\n return {\n client_id: this._clientId,\n ...(this._clientSecret ? { client_secret: this._clientSecret } : {}),\n }\n }\n const issuer = ctx?.issuer ?? (await this._lastIssuer())\n const raw = await this._store.get(this._key('client_info', issuer))\n if (!raw) return undefined\n return JSON.parse(raw) as StoredOAuthClientInformation\n }\n\n async saveClientInformation(\n info: StoredOAuthClientInformation,\n ctx?: OAuthClientInformationContext,\n ): Promise<void> {\n if (this._clientId) return // pre-registered — never overwrite with DCR response\n if (ctx?.issuer) await this._rememberIssuer(ctx.issuer)\n await this._store.set(this._key('client_info', ctx?.issuer), JSON.stringify(info))\n }\n\n async tokens(ctx?: OAuthClientInformationContext): Promise<StoredOAuthTokens | undefined> {\n // Per SEP-2352: the per-request bearer-token read (adaptOAuthProvider's\n // token() bridge) calls this with no ctx at all, so it must resolve the\n // most-recently-saved token set rather than returning undefined.\n const issuer = ctx?.issuer ?? (await this._lastIssuer())\n const raw = await this._store.get(this._key('tokens', issuer))\n if (!raw) return undefined\n return JSON.parse(raw) as StoredOAuthTokens\n }\n\n async saveTokens(tokens: StoredOAuthTokens, ctx?: OAuthClientInformationContext): Promise<void> {\n if (ctx?.issuer) await this._rememberIssuer(ctx.issuer)\n await this._store.set(this._key('tokens', ctx?.issuer), JSON.stringify(tokens))\n }\n\n async redirectToAuthorization(authorizationUrl: URL): Promise<void> {\n this._armCallbackPromise()\n await this._startCallbackServer()\n if (this._onRedirect) {\n await this._onRedirect(authorizationUrl)\n } else {\n await openBrowser(authorizationUrl.toString())\n }\n }\n\n /**\n * Creates the pending-callback promise that {@link waitForCallback} awaits.\n * Subclasses (e.g. BrowserOAuth) call this before opening their own redirect.\n */\n protected _armCallbackPromise(): void {\n this._callbackPromise = new Promise<URLSearchParams>((resolve, reject) => {\n this._callbackResolve = resolve\n this._callbackReject = reject\n })\n // Suppress unhandled-rejection warnings — the promise is observed via Promise.race.\n this._callbackPromise.catch(() => {})\n }\n\n /** Resolves the pending callback with the full authorization callback params. */\n protected _resolveCallback(params: URLSearchParams): void {\n this._callbackResolve?.(params)\n }\n\n /** Rejects the pending callback with an error. */\n protected _rejectCallback(err: Error): void {\n this._callbackReject?.(err)\n }\n\n /**\n * Races the pending callback promise against a timeout and clears the\n * promise state. Subclasses reuse this and add their own teardown.\n */\n protected async _awaitCallback(timeoutMs: number): Promise<URLSearchParams> {\n if (!this._callbackPromise) {\n throw new Error('No pending OAuth callback — call redirectToAuthorization() first')\n }\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error('OAuth callback timed out waiting for authorization')),\n timeoutMs,\n ),\n )\n try {\n return await Promise.race([this._callbackPromise, timeout])\n } finally {\n this._callbackPromise = null\n this._callbackResolve = null\n this._callbackReject = null\n }\n }\n\n saveCodeVerifier(codeVerifier: string): void {\n this._codeVerifier = codeVerifier\n }\n\n codeVerifier(): string {\n if (this._codeVerifier === undefined) {\n throw new Error('No PKCE code verifier has been saved')\n }\n return this._codeVerifier\n }\n\n async invalidateCredentials(\n scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery',\n ): Promise<void> {\n const issuer = await this._lastIssuer()\n if (scope === 'all' || scope === 'tokens') {\n await this._store.delete(this._key('tokens', issuer))\n await this._store.delete(this._key('tokens')) // pre-issuer-keying entries, if any\n }\n if (scope === 'all' || scope === 'client') {\n await this._store.delete(this._key('client_info', issuer))\n await this._store.delete(this._key('client_info'))\n }\n if (scope === 'all' || scope === 'verifier') {\n this._codeVerifier = undefined\n }\n if (scope === 'all' || scope === 'discovery') {\n await this._store.delete(this._key('discovery'))\n }\n }\n\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this._store.set(this._key('discovery'), JSON.stringify(state))\n }\n\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n const raw = await this._store.get(this._key('discovery'))\n if (!raw) return undefined\n return JSON.parse(raw) as OAuthDiscoveryState\n }\n\n // ---- Internal helpers ----\n\n /**\n * Returns the actual port the callback server bound to.\n * Only populated after redirectToAuthorization() has been called.\n */\n get callbackServerPort(): number | null {\n return this._actualCallbackPort\n }\n\n /**\n * Waits for the OAuth authorization code to arrive via the callback server,\n * then stops the server and resolves with the full callback `URLSearchParams`\n * (including `code` and, when present, the RFC 9207 `iss` parameter).\n *\n * Must be called after the UnauthorizedError thrown by connect() is caught.\n * Pass the result directly to the transport's `finishAuth(callbackParams)`.\n */\n async waitForCallback(timeoutMs = 5 * 60 * 1000): Promise<URLSearchParams> {\n try {\n return await this._awaitCallback(timeoutMs)\n } finally {\n this._stopCallbackServer()\n }\n }\n\n private _key(type: string, issuer?: string): string {\n return issuer ? `${issuer}/${type}` : `${this._serverUrl}/${type}`\n }\n\n /** Storage key for the \"last issuer seen for this server\" pointer (SEP-2352). */\n private _issuerPointerKey(): string {\n return `${this._serverUrl}/issuer`\n }\n\n /**\n * Remembers the resolved authorization-server issuer for this MCP server,\n * so later no-ctx reads (e.g. the transport's per-request bearer-token read)\n * know which issuer-keyed credential set to return.\n */\n private async _rememberIssuer(issuer: string): Promise<void> {\n await this._store.set(this._issuerPointerKey(), issuer)\n }\n\n private async _lastIssuer(): Promise<string | undefined> {\n return (await this._store.get(this._issuerPointerKey())) ?? undefined\n }\n\n private async _startCallbackServer(): Promise<void> {\n if (this._callbackServer) return\n const http = await import('http')\n await new Promise<void>((resolve, reject) => {\n const server = http.createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost`)\n const error = url.searchParams.get('error')\n if (error && this._callbackReject) {\n const description = url.searchParams.get('error_description') ?? error\n this._callbackReject(new Error(`OAuth authorization denied: ${description}`))\n res.writeHead(200, { 'content-type': 'text/html' })\n res.end(\n '<html><body><h1>Authorization denied</h1><p>You may close this tab.</p></body></html>',\n )\n return\n }\n const code = url.searchParams.get('code')\n if (code && this._callbackResolve) {\n this._callbackResolve(url.searchParams)\n res.writeHead(200, { 'content-type': 'text/html' })\n res.end(\n '<html><body><h1>Authorization complete</h1><p>You may close this tab.</p></body></html>',\n )\n } else {\n res.writeHead(400)\n res.end('Missing code parameter')\n }\n })\n server.on('error', reject)\n server.listen(this._callbackPort, () => {\n const addr = server.address()\n if (addr && typeof addr !== 'string') {\n this._actualCallbackPort = addr.port\n }\n this._callbackServer = server\n resolve()\n })\n })\n }\n\n private _stopCallbackServer(): void {\n this._callbackServer?.close()\n this._callbackServer = null\n this._actualCallbackPort = null\n }\n}\n\n// ---------------------------------------------------------------------------\n// BearerAuth\n// ---------------------------------------------------------------------------\n\nexport class BearerAuth {\n private readonly _token: string\n\n constructor(token: string) {\n // Strip any existing Bearer prefix to avoid double-prepending\n this._token = token.startsWith('Bearer ') ? token.slice(7) : token\n }\n\n getHeaders(): Record<string, string> {\n return { Authorization: `Bearer ${this._token}` }\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientCredentials — OAuth 2.0 client credentials grant (machine-to-machine)\n// ---------------------------------------------------------------------------\n\n/** Token-endpoint authentication method for a shared client secret. */\nexport type ClientSecretAuthMethod = 'client_secret_post' | 'client_secret_basic'\n\n/** Fields common to every {@link ClientCredentials} configuration. */\ninterface ClientCredentialsBaseOptions {\n tokenEndpoint: string\n clientId: string\n scope?: string\n /**\n * Persistent token store. Default: in-memory. The cache key is derived from\n * `tokenEndpoint` alone, with no client identity in it — use one store per\n * credential identity. Do not share a persistent `store` across two\n * `ClientCredentials` instances that have different `clientId`/`clientSecret`/\n * `privateKey` but the same `tokenEndpoint`; they will read and overwrite\n * each other's cached tokens.\n */\n store?: KeyValueStore\n /** How many seconds before expiry to proactively re-fetch. Default: 60. */\n refreshBufferSeconds?: number\n}\n\n/**\n * Shared-secret configuration for {@link ClientCredentials}.\n *\n * `authMethod` selects how the secret reaches the token endpoint:\n * - `client_secret_post` (default) — `client_id` and `client_secret` in the\n * POST body. Unchanged from earlier releases.\n * - `client_secret_basic` — an RFC 6749 §2.3.1 HTTP Basic `Authorization`\n * header. Nothing secret goes in the body.\n */\nexport interface ClientSecretCredentialsOptions extends ClientCredentialsBaseOptions {\n clientSecret: string\n /** Token-endpoint authentication method. Default: `client_secret_post`. */\n authMethod?: ClientSecretAuthMethod\n privateKey?: never\n algorithm?: never\n}\n\n/**\n * `private_key_jwt` configuration for {@link ClientCredentials} (RFC 7523 /\n * SEP-1046): the client proves its identity with a signed JWT `client_assertion`\n * instead of a shared secret. The assertion is signed by the SDK's own\n * `private_key_jwt` machinery — no secret is ever sent to the token endpoint.\n */\nexport interface PrivateKeyJwtCredentialsOptions extends ClientCredentialsBaseOptions {\n /** Signing key: a PEM (PKCS#8) string, its bytes, or a JWK object. */\n privateKey: string | Uint8Array | Record<string, unknown>\n /** JWS signing algorithm, e.g. `ES256` or `RS256`. */\n algorithm: string\n /**\n * The assertion's `aud` claim. Required — there is no safe default, because\n * this provider does no discovery and cannot learn the authorization server's\n * identity on its own. RFC 7523 §3 recommends the authorization server's\n * `issuer` identifier; some servers instead verify against the token endpoint\n * URL. Set whichever your server checks (issuer is the more common choice).\n */\n audience: string\n /** Assertion lifetime in seconds. Default: 300. */\n jwtLifetimeSeconds?: number\n /** Extra claims merged over the standard `iss`/`sub`/`aud`/`exp`/`iat`/`jti`. */\n claims?: Record<string, unknown>\n clientSecret?: never\n authMethod?: never\n}\n\n/**\n * Configuration for {@link ClientCredentials}. A discriminated union: supply\n * either a `clientSecret` (with an optional `authMethod`) or a `privateKey`\n * (with its `algorithm`) — the two are mutually exclusive and enforced at\n * compile time.\n */\nexport type ClientCredentialsOptions =\n | ClientSecretCredentialsOptions\n | PrivateKeyJwtCredentialsOptions\n\nconst DEFAULT_REFRESH_BUFFER_SECONDS = 60\n\n/** Internal discriminant for the selected token-endpoint auth method. */\ntype TokenEndpointAuthMethod = ClientSecretAuthMethod | 'private_key_jwt'\n\n/**\n * Builds an RFC 6749 §2.3.1 HTTP Basic `Authorization` header value. The client\n * id and secret are each percent-encoded (RFC 3986, via `encodeURIComponent` —\n * space becomes `%20`, not `+`), which a conformant §2.3.1 decoder accepts, then\n * joined with a colon and Base64-encoded.\n */\nfunction basicAuthHeader(clientId: string, clientSecret: string): string {\n const credentials = `${encodeURIComponent(clientId)}:${encodeURIComponent(clientSecret)}`\n return `Basic ${btoa(credentials)}`\n}\n\nfunction normalizeToken(token: OAuthToken): OAuthToken {\n if (typeof token.expires_at === 'number' && token.expires_at > 0) {\n if (token.expires_at < 1e10) {\n return { ...token, expires_at: token.expires_at * 1000 }\n }\n return token\n }\n if (typeof token.expires_in === 'number' && token.expires_in > 0) {\n return { ...token, expires_at: Date.now() + token.expires_in * 1000 }\n }\n return token\n}\n\nfunction isExpiring(token: OAuthToken, bufferMs: number): boolean {\n if (token.expires_at == null) return false\n return token.expires_at - Date.now() <= bufferMs\n}\n\n/**\n * A persisted, single-flight token cache shared by every non-interactive token\n * provider ({@link ClientCredentials}, {@link JwtBearerAuth},\n * {@link EnterpriseManagedAuth}). It reads the store, returns a still-valid\n * token, and otherwise coalesces concurrent fetches into one call of the\n * provider's `fetcher`, normalizes the result (computing `expires_at`), and\n * persists it. Providers supply only the grant-specific network call — the\n * caching, expiry, and coalescing live here once, not per provider.\n */\nclass TokenCache {\n private _fetchPromise: Promise<OAuthToken> | null = null\n\n constructor(\n private readonly _store: KeyValueStore,\n private readonly _key: string,\n private readonly _bufferMs: number,\n ) {}\n\n async get(fetcher: () => Promise<OAuthToken>): Promise<OAuthToken> {\n const raw = await this._store.get(this._key)\n if (raw) {\n const normalized = normalizeToken(JSON.parse(raw) as OAuthToken)\n if (!isExpiring(normalized, this._bufferMs)) return normalized\n }\n this._fetchPromise ??= (async () => {\n const token = normalizeToken(await fetcher())\n if (!token.access_token) {\n throw new Error('token response missing access_token')\n }\n await this._store.set(this._key, JSON.stringify(token))\n return token\n })().finally(() => {\n this._fetchPromise = null\n })\n return this._fetchPromise\n }\n}\n\nexport class ClientCredentials implements AsyncHeaderAuth {\n readonly kind = 'client_credentials' as const\n\n private readonly _tokenEndpoint: string\n private readonly _clientId: string\n private readonly _scope?: string\n private readonly _authMethod: TokenEndpointAuthMethod\n /** Set for `client_secret_post` / `client_secret_basic`. */\n private readonly _clientSecret?: string\n /**\n * Set for `private_key_jwt`. The SDK's `createPrivateKeyJwtAuth` signs the\n * assertion and stamps `client_assertion` / `client_assertion_type` onto the\n * token-request params — we reuse it verbatim instead of hand-rolling JOSE.\n */\n private readonly _addClientAssertion?: AddClientAuthentication\n private readonly _cache: TokenCache\n\n constructor(options: ClientCredentialsOptions) {\n this._tokenEndpoint = options.tokenEndpoint\n this._clientId = options.clientId\n this._scope = options.scope\n const store = options.store ?? new InMemoryStore()\n const bufferMs =\n (options.refreshBufferSeconds ?? DEFAULT_REFRESH_BUFFER_SECONDS) * 1000\n this._cache = new TokenCache(store, `${this._tokenEndpoint}/token`, bufferMs)\n\n if (options.privateKey !== undefined) {\n this._authMethod = 'private_key_jwt'\n this._addClientAssertion = createPrivateKeyJwtAuth({\n issuer: options.clientId,\n subject: options.clientId,\n privateKey: options.privateKey,\n alg: options.algorithm,\n audience: options.audience,\n lifetimeSeconds: options.jwtLifetimeSeconds,\n claims: options.claims,\n })\n } else {\n this._authMethod = options.authMethod ?? 'client_secret_post'\n this._clientSecret = options.clientSecret\n }\n }\n\n async getHeaders(): Promise<Record<string, string>> {\n const token = await this._cache.get(() => this._fetchToken())\n const type = token.token_type?.trim() || 'Bearer'\n return { Authorization: `${type} ${token.access_token}` }\n }\n\n private async _fetchToken(): Promise<OAuthToken> {\n const params = new URLSearchParams({ grant_type: 'client_credentials' })\n const headers: Record<string, string> = {\n 'content-type': 'application/x-www-form-urlencoded',\n }\n\n if (this._authMethod === 'private_key_jwt') {\n // private_key_jwt: the SDK signs the assertion and stamps\n // client_assertion / client_assertion_type onto the params.\n if (this._scope) params.set('scope', this._scope)\n await this._addClientAssertion!(new Headers(), params, this._tokenEndpoint)\n } else if (this._authMethod === 'client_secret_basic') {\n // client_secret_basic: credentials go in the Authorization header only.\n if (this._scope) params.set('scope', this._scope)\n headers.Authorization = basicAuthHeader(this._clientId, this._clientSecret!)\n } else {\n // client_secret_post (default): credentials in the body. Field order is\n // kept identical to earlier releases so the request stays byte-for-byte\n // the same for existing callers.\n params.set('client_id', this._clientId)\n params.set('client_secret', this._clientSecret!)\n if (this._scope) params.set('scope', this._scope)\n }\n\n const response = await fetch(this._tokenEndpoint, {\n method: 'POST',\n headers,\n body: params.toString(),\n })\n\n if (!response.ok) {\n const detail = await response.text().catch(() => '')\n throw new Error(\n `ClientCredentials token fetch failed (${response.status})${detail ? `: ${detail}` : ''}`,\n )\n }\n\n const data = (await response.json()) as Partial<OAuthToken>\n if (!data.access_token) {\n throw new Error('ClientCredentials token response missing access_token')\n }\n return data as OAuthToken\n }\n}\n\n// ---------------------------------------------------------------------------\n// JwtBearerAuth — RFC 7523 §2.1 JWT-bearer grant (SEP-1933 workload identity)\n// ---------------------------------------------------------------------------\n\n/** A workload assertion: a signed JWT string, or an (async) factory for one. */\nexport type AssertionSource = string | (() => string | Promise<string>)\n\n/**\n * Configuration for {@link JwtBearerAuth}.\n *\n * The client presents a pre-issued, signed JWT (`assertion`) directly to the\n * token endpoint under `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer`\n * (RFC 7523 §2.1). No interactive authorization, no client secret by default —\n * this is the workload-identity-federation shape (SEP-1933): a workload proves\n * its identity with a JWT its runtime already minted (a Kubernetes projected\n * service-account token, a cloud instance-identity JWT, etc.).\n */\nexport interface JwtBearerOptions {\n /** The authorization server's token endpoint. */\n tokenEndpoint: string\n /**\n * The workload assertion (a signed JWT). Pass a string for a fixed assertion,\n * or a callback to mint/read a fresh one each time a token is fetched (the\n * usual case — workload JWTs are short-lived).\n */\n assertion: AssertionSource\n /** The client identifier registered for this workload. */\n clientId?: string\n /**\n * Token-endpoint client authentication. Default: `none` (public client — the\n * assertion itself is the credential, so no separate client secret is sent).\n */\n authMethod?: ClientAuthMethod\n /** Client secret, when `authMethod` is `client_secret_basic`/`_post`. */\n clientSecret?: string\n /** Requested scopes (space-separated). */\n scope?: string\n /**\n * Persistent token store. Default: in-memory. The cache key is derived from\n * `tokenEndpoint` alone, with no client identity in it — use one store per\n * credential identity. Do not share a persistent `store` across two\n * `JwtBearerAuth` instances that have different `clientId`/`assertion` but\n * the same `tokenEndpoint`; they will read and overwrite each other's\n * cached tokens.\n */\n store?: KeyValueStore\n /** How many seconds before expiry to proactively re-fetch. Default: 60. */\n refreshBufferSeconds?: number\n}\n\nexport class JwtBearerAuth implements AsyncHeaderAuth {\n readonly kind = 'jwt_bearer' as const\n\n private readonly _tokenEndpoint: string\n private readonly _assertion: AssertionSource\n private readonly _clientId?: string\n private readonly _authMethod: ClientAuthMethod\n private readonly _clientSecret?: string\n private readonly _scope?: string\n private readonly _cache: TokenCache\n\n constructor(options: JwtBearerOptions) {\n this._tokenEndpoint = options.tokenEndpoint\n this._assertion = options.assertion\n this._clientId = options.clientId\n this._authMethod = options.authMethod ?? 'none'\n this._clientSecret = options.clientSecret\n this._scope = options.scope\n const store = options.store ?? new InMemoryStore()\n const bufferMs =\n (options.refreshBufferSeconds ?? DEFAULT_REFRESH_BUFFER_SECONDS) * 1000\n this._cache = new TokenCache(store, `${this._tokenEndpoint}/jwt-bearer`, bufferMs)\n }\n\n async getHeaders(): Promise<Record<string, string>> {\n const token = await this._cache.get(() => this._fetchToken())\n const type = token.token_type?.trim() || 'Bearer'\n return { Authorization: `${type} ${token.access_token}` }\n }\n\n private async _fetchToken(): Promise<OAuthToken> {\n const assertion =\n typeof this._assertion === 'function' ? await this._assertion() : this._assertion\n // Reuse the SDK's RFC 7523 wire helper: it POSTs\n // grant_type=jwt-bearer + assertion and applies the chosen client auth.\n // A body rewrite is needed when a scope is configured (the helper takes no\n // scope param) or when no clientId is set (the helper's public-client path\n // always writes client_id, so we drop the empty value it would emit).\n const needsRewrite = this._scope !== undefined || this._clientId === undefined\n const tokens = await exchangeJwtAuthGrant({\n tokenEndpoint: this._tokenEndpoint,\n jwtAuthGrant: assertion,\n clientId: this._clientId ?? '',\n ...(this._clientSecret ? { clientSecret: this._clientSecret } : {}),\n authMethod: this._authMethod,\n ...(needsRewrite ? { fetchFn: this._rewriteBody() } : {}),\n })\n return tokens as OAuthToken\n }\n\n /**\n * Wraps fetch to fix up the token-request body the SDK helper builds:\n * appends `scope` when configured (RFC 7523 §2.1 allows it alongside the\n * assertion), and drops an empty `client_id` when no client identifier is set\n * (the helper's public-client path always writes one — we send no `client_id`\n * at all rather than `client_id=`).\n */\n private _rewriteBody() {\n return async (url: string | URL, init?: RequestInit): Promise<Response> => {\n const body = new URLSearchParams((init?.body as string) ?? '')\n if (this._scope !== undefined && !body.has('scope')) body.set('scope', this._scope)\n if (this._clientId === undefined && body.get('client_id') === '') {\n body.delete('client_id')\n }\n return fetch(url, { ...init, body: body.toString() })\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// EnterpriseManagedAuth — SEP-990 token exchange + JWT-bearer grant\n// ---------------------------------------------------------------------------\n\n/**\n * Configuration for {@link EnterpriseManagedAuth} (SEP-990, Enterprise-Managed\n * Authorization / Cross-App Access).\n *\n * The flow is two hops, both stable RFCs:\n * 1. **Token exchange** (RFC 8693) at the enterprise IdP: exchange the user's\n * OpenID Connect ID token for an *identity assertion JWT authorization\n * grant* (ID-JAG) scoped to the target MCP server.\n * 2. **JWT-bearer grant** (RFC 7523) at the MCP server's authorization server:\n * present the ID-JAG under `grant_type=jwt-bearer` to obtain the access\n * token.\n */\nexport interface EnterpriseManagedOptions {\n /** The MCP server's authorization-server token endpoint (step 2). */\n tokenEndpoint: string\n /** The MCP client identifier registered with the authorization server. */\n clientId: string\n /** The MCP client secret (default client auth is `client_secret_basic`). */\n clientSecret?: string\n /** Client-authentication method for step 2. Default: `client_secret_basic`. */\n authMethod?: ClientAuthMethod\n /**\n * The ID-JAG audience — the target authorization server's identifier. The\n * authorization server verifies the ID-JAG `aud` against this.\n */\n audience: string\n /**\n * The protected-resource identifier of the target MCP server (RFC 9728). The\n * authorization server verifies the ID-JAG `resource` against this.\n */\n resource: string\n /** The enterprise IdP's token endpoint (step 1). */\n idpTokenEndpoint: string\n /** The client identifier registered with the IdP for token exchange. */\n idpClientId: string\n /** The client secret for the IdP token exchange, if the IdP requires one. */\n idpClientSecret?: string\n /**\n * The user's OpenID Connect ID token (the `subject_token` of the exchange).\n * Pass a string, or a callback to read a fresh one each fetch.\n */\n idToken: AssertionSource\n /** Requested scopes (space-separated). */\n scope?: string\n /**\n * Persistent token store. Default: in-memory. The cache key is derived from\n * `tokenEndpoint` alone, with no client identity in it — use one store per\n * credential identity. Do not share a persistent `store` across two\n * `EnterpriseManagedAuth` instances that have different `clientId`/`idToken`\n * but the same `tokenEndpoint`; they will read and overwrite each other's\n * cached tokens.\n */\n store?: KeyValueStore\n /** How many seconds before expiry to proactively re-fetch. Default: 60. */\n refreshBufferSeconds?: number\n}\n\nexport class EnterpriseManagedAuth implements AsyncHeaderAuth {\n readonly kind = 'enterprise_managed' as const\n\n private readonly _options: EnterpriseManagedOptions\n private readonly _cache: TokenCache\n\n constructor(options: EnterpriseManagedOptions) {\n this._options = options\n const store = options.store ?? new InMemoryStore()\n const bufferMs =\n (options.refreshBufferSeconds ?? DEFAULT_REFRESH_BUFFER_SECONDS) * 1000\n this._cache = new TokenCache(store, `${options.tokenEndpoint}/enterprise-managed`, bufferMs)\n }\n\n async getHeaders(): Promise<Record<string, string>> {\n const token = await this._cache.get(() => this._fetchToken())\n const type = token.token_type?.trim() || 'Bearer'\n return { Authorization: `${type} ${token.access_token}` }\n }\n\n private async _fetchToken(): Promise<OAuthToken> {\n const o = this._options\n const idToken = typeof o.idToken === 'function' ? await o.idToken() : o.idToken\n // Step 1 — RFC 8693 token exchange at the IdP: ID token -> ID-JAG.\n const grant = await requestJwtAuthorizationGrant({\n tokenEndpoint: o.idpTokenEndpoint,\n audience: o.audience,\n resource: o.resource,\n idToken,\n clientId: o.idpClientId,\n ...(o.idpClientSecret ? { clientSecret: o.idpClientSecret } : {}),\n ...(o.scope ? { scope: o.scope } : {}),\n })\n // Step 2 — RFC 7523 JWT-bearer grant at the MCP authorization server:\n // present the ID-JAG for the access token.\n const tokens = await exchangeJwtAuthGrant({\n tokenEndpoint: o.tokenEndpoint,\n jwtAuthGrant: grant.jwtAuthGrant,\n clientId: o.clientId,\n ...(o.clientSecret ? { clientSecret: o.clientSecret } : {}),\n authMethod: o.authMethod ?? 'client_secret_basic',\n })\n return tokens as OAuthToken\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nasync function openBrowser(url: string): Promise<void> {\n const { spawn } = await import('child_process')\n if (process.platform === 'win32') {\n spawn('cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore' })\n } else if (process.platform === 'darwin') {\n spawn('open', [url], { detached: true, stdio: 'ignore' })\n } else {\n spawn('xdg-open', [url], { detached: true, stdio: 'ignore' })\n }\n}\n","// ---------------------------------------------------------------------------\n// Browser key-value stores — KeyValueStore implementations backed by the\n// browser's localStorage and IndexedDB. The browser globals are referenced\n// only inside methods so these modules stay importable under Node (they throw\n// only if actually used there).\n// ---------------------------------------------------------------------------\n\nimport type { KeyValueStore } from './auth.js'\n\n/**\n * KeyValueStore backed by `localStorage`. Synchronous and simple; suitable for\n * OAuth tokens and client registration state in single-page apps. Keys are\n * namespaced by a prefix to avoid collisions with other app state.\n */\nexport class LocalStorageStore implements KeyValueStore {\n private readonly _prefix: string\n\n constructor(prefix = 'fastmcp:') {\n this._prefix = prefix\n }\n\n async get(key: string): Promise<string | null> {\n return localStorage.getItem(this._prefix + key)\n }\n\n async set(key: string, value: string): Promise<void> {\n localStorage.setItem(this._prefix + key, value)\n }\n\n async delete(key: string): Promise<void> {\n localStorage.removeItem(this._prefix + key)\n }\n}\n\n/**\n * KeyValueStore backed by IndexedDB. Preferred when tokens should survive\n * outside the synchronous, size-limited localStorage (e.g. larger payloads or\n * stricter persistence). Opens the database per operation and closes it again.\n */\nexport class IndexedDBStore implements KeyValueStore {\n private readonly _dbName: string\n private readonly _storeName: string\n\n constructor(opts: { dbName?: string; storeName?: string } = {}) {\n this._dbName = opts.dbName ?? 'fastmcp'\n this._storeName = opts.storeName ?? 'auth'\n }\n\n private _open(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(this._dbName, 1)\n req.onupgradeneeded = () => {\n if (!req.result.objectStoreNames.contains(this._storeName)) {\n req.result.createObjectStore(this._storeName)\n }\n }\n req.onsuccess = () => resolve(req.result)\n req.onerror = () => reject(req.error ?? new Error('indexedDB.open failed'))\n })\n }\n\n private async _tx<T>(\n mode: IDBTransactionMode,\n fn: (store: IDBObjectStore) => IDBRequest,\n ): Promise<T> {\n const db = await this._open()\n try {\n return await new Promise<T>((resolve, reject) => {\n const req = fn(db.transaction(this._storeName, mode).objectStore(this._storeName))\n req.onsuccess = () => resolve(req.result as T)\n req.onerror = () => reject(req.error ?? new Error('indexedDB request failed'))\n })\n } finally {\n db.close()\n }\n }\n\n async get(key: string): Promise<string | null> {\n const value = await this._tx<string | undefined>('readonly', (s) => s.get(key))\n return value ?? null\n }\n\n async set(key: string, value: string): Promise<void> {\n await this._tx('readwrite', (s) => s.put(value, key))\n }\n\n async delete(key: string): Promise<void> {\n await this._tx('readwrite', (s) => s.delete(key))\n }\n}\n","import type { OAuthClientMetadata } from \"@modelcontextprotocol/server\";\n\n// ---------------------------------------------------------------------------\n// BrowserOAuth — OAuth authorization-code + PKCE flow for the browser.\n//\n// Extends the Node OAuth provider, reusing all of its PKCE / token / discovery\n// logic (which is already browser-safe), and replaces only the redirect\n// mechanism: instead of opening the system browser and listening on a localhost\n// HTTP callback server, it opens a popup (default) or navigates the tab, and\n// receives the authorization code via postMessage (popup) or the returned URL\n// (redirect). Because it `instanceof OAuth`, the Client connect flow\n// (connect → waitForCallback → finishAuth → reconnect) drives it unchanged.\n// ---------------------------------------------------------------------------\nimport { OAuth, type OAuthOptions } from './auth.js'\n\n/** postMessage payload sent by {@link handleOAuthCallback} back to the opener. */\nconst MESSAGE_TYPE = 'fastmcp:oauth'\n\nexport interface BrowserOAuthOptions\n extends Omit<OAuthOptions, 'callbackPort' | 'onRedirect'> {\n /**\n * Redirect URI registered with the provider. Must serve a page that calls\n * {@link handleOAuthCallback} (popup mode) or is your app route that reads the\n * returned `?code=` (redirect mode).\n */\n redirectUri: string\n /**\n * 'popup' (default) opens the authorization URL in a popup window and listens\n * for a postMessage from the callback page. 'redirect' navigates the whole\n * tab; resume with {@link BrowserOAuth.resumeFromRedirect} on return.\n */\n mode?: 'popup' | 'redirect'\n /** `window.open` features string for popup mode. */\n popupFeatures?: string\n}\n\nexport class BrowserOAuth extends OAuth {\n private readonly _redirectUri: string\n private readonly _mode: 'popup' | 'redirect'\n private readonly _popupFeatures: string\n private _popup: Window | null = null\n private _messageHandler: ((e: MessageEvent) => void) | null = null\n\n constructor(options: BrowserOAuthOptions) {\n super(options)\n this._redirectUri = options.redirectUri\n this._mode = options.mode ?? 'popup'\n this._popupFeatures = options.popupFeatures ?? 'width=600,height=720'\n }\n\n get redirectUrl(): string {\n return this._redirectUri\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return { ...super.clientMetadata, redirect_uris: [this._redirectUri] }\n }\n\n async redirectToAuthorization(authorizationUrl: URL): Promise<void> {\n if (this._mode === 'redirect') {\n // Navigation destroys this JS context; the app resumes via\n // resumeFromRedirect() on the return load.\n window.location.assign(authorizationUrl.toString())\n return\n }\n\n const expectedOrigin = new URL(this._redirectUri).origin\n this._messageHandler = (e: MessageEvent) => {\n if (e.origin !== expectedOrigin) return\n const data = e.data as { type?: string; code?: string; iss?: string; error?: string }\n if (data?.type !== MESSAGE_TYPE) return\n if (data.error) {\n this._rejectCallback(new Error(`OAuth authorization denied: ${data.error}`))\n } else if (data.code) {\n const params = new URLSearchParams({ code: data.code, ...(data.iss ? { iss: data.iss } : {}) })\n this._resolveCallback(params)\n }\n }\n window.addEventListener('message', this._messageHandler)\n // Arm the callback promise before opening so a fast provider can't race us.\n this._armCallbackPromise()\n this._popup = window.open(authorizationUrl.toString(), 'fastmcp-oauth', this._popupFeatures)\n if (!this._popup) {\n this._teardown()\n throw new Error(\n 'Failed to open OAuth popup — it was likely blocked. Trigger connect from a user gesture or use mode: \"redirect\".',\n )\n }\n }\n\n async waitForCallback(timeoutMs = 5 * 60 * 1000): Promise<URLSearchParams> {\n try {\n return await this._awaitCallback(timeoutMs)\n } finally {\n this._teardown()\n }\n }\n\n /**\n * Redirect-mode resume: parse the authorization callback params from a\n * returned URL (defaults to the current location). Returns the full\n * `URLSearchParams` (including `code` and, when present, `iss`) — pass\n * directly to `finishAuth()` — or `null` if there is no `code`. Throws if\n * the provider returned an error.\n */\n resumeFromRedirect(href: string = window.location.href): URLSearchParams | null {\n const params = new URL(href).searchParams\n const error = params.get('error_description') ?? params.get('error')\n if (error) throw new Error(`OAuth authorization denied: ${error}`)\n return params.has('code') ? params : null\n }\n\n private _teardown(): void {\n if (this._messageHandler) window.removeEventListener('message', this._messageHandler)\n this._messageHandler = null\n try {\n this._popup?.close()\n } catch {\n // Cross-origin popups may throw on close — ignore.\n }\n this._popup = null\n }\n}\n\n/**\n * Call from the redirect_uri page (popup mode) to deliver the authorization\n * code back to the opener window and close the popup.\n */\nexport function handleOAuthCallback(opts: { targetOrigin?: string } = {}): void {\n const params = new URLSearchParams(window.location.search)\n const code = params.get('code') ?? undefined\n const iss = params.get('iss') ?? undefined\n const error = params.get('error_description') ?? params.get('error') ?? undefined\n const target = opts.targetOrigin ?? window.location.origin\n window.opener?.postMessage({ type: MESSAGE_TYPE, code, iss, error }, target)\n window.close()\n}\n","import { InMemoryTransport, StreamableHTTPClientTransport, SSEClientTransport } from \"@modelcontextprotocol/client\";\nimport type { OAuthClientProvider, Transport, VersionNegotiationOptions } from \"@modelcontextprotocol/client\";\nimport { OAuth, BearerAuth, type AsyncHeaderAuth } from './auth.js'\n\n// ---------------------------------------------------------------------------\n// TransportResolutionOptions — cross-cutting knobs threaded through\n// resolveTransport / resolveEntryTransport (not just per-entry auth).\n// ---------------------------------------------------------------------------\n\nexport interface TransportResolutionOptions {\n /** See ClientOptions.legacySSE. Default false. */\n legacySSE?: boolean\n /** See ClientOptions.versionNegotiation. Used only to decide, for an\n * in-process McpServerLike input, whether a pinned-modern connection should\n * use the server's optional `_modernFetch` hook instead of the legacy-only\n * InMemoryTransport pair. */\n versionNegotiation?: VersionNegotiationOptions\n}\n\n// ---------------------------------------------------------------------------\n// Stdio transport — loaded lazily. The SDK's stdio module imports Node's\n// `child_process`, so a static import would pull Node built-ins into the\n// browser bundle. Importing it on demand keeps the client graph browser-safe.\n// ---------------------------------------------------------------------------\n\nasync function createStdioTransport(opts: {\n command: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n}): Promise<Transport> {\n const { StdioClientTransport } = await import(\n '@modelcontextprotocol/client/stdio'\n )\n return new StdioClientTransport(opts)\n}\n\n// ---------------------------------------------------------------------------\n// McpServerLike — structural interface for in-process servers.\n// Intentionally loose: avoids importing from the server module.\n// ---------------------------------------------------------------------------\n\nexport interface McpServerLike {\n connect(transport: Transport): Promise<void>\n /**\n * Optional modern-era (2026-07-28) in-process fetch entrypoint, for servers\n * built on `createMcpHandler` (e.g. `FastMCP`'s own `_modernFetch`).\n * `InMemoryTransport` — used by `connect()` above — is 2025-era only (the\n * legacy `Server`/session model); there is no in-process equivalent of a\n * real HTTP round trip for the modern era's stateless-per-request dispatch.\n * When present, and the caller pins modern era via\n * `versionNegotiation: { mode: { pin: '2026-07-28' } }`, the client builds a\n * `StreamableHTTPClientTransport` whose `fetch` calls this function directly\n * — no sockets, but otherwise the same code path a real HTTP connection\n * takes. Not used for `'auto'` or `'legacy'` modes: this server-side hook is\n * modern-only (mirrors `createMcpHandler(..., { legacy: 'reject' })`), so\n * auto-negotiation (which must be able to fall back to legacy) still goes\n * through `connect()` + `InMemoryTransport`, and stays legacy-only for\n * in-process servers until a dual-era in-process bridge exists.\n */\n _modernFetch?(request: Request, options?: unknown): Promise<Response>\n}\n\nfunction isMcpServerLike(value: unknown): value is McpServerLike {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'connect' in value &&\n typeof (value as Record<string, unknown>).connect === 'function'\n )\n}\n\n// ---------------------------------------------------------------------------\n// MCP config object — { mcpServers: { name: { url | command, ... } } }\n// ---------------------------------------------------------------------------\n\nexport type McpServerEntry =\n | { url: string; headers?: Record<string, string>; auth?: BearerAuth | OAuth | AsyncHeaderAuth | string }\n | { command: string; args?: string[]; env?: Record<string, string>; auth?: BearerAuth | OAuth | AsyncHeaderAuth | string }\n\n/** Values accepted in mcpServers: either a config object or an in-process server. */\nexport type McpServerValue = McpServerEntry | McpServerLike\n\nexport type McpConfig = {\n mcpServers: Record<string, McpServerValue>\n}\n\nfunction isMcpConfig(value: unknown): value is McpConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'mcpServers' in value &&\n typeof (value as McpConfig).mcpServers === 'object' &&\n (value as McpConfig).mcpServers !== null\n )\n}\n\n// ---------------------------------------------------------------------------\n// StdioTransport — configuration object for stdio subprocess connections.\n// Separate from the SDK's StdioClientTransport so callers work with a plain\n// config value rather than a live transport instance.\n// ---------------------------------------------------------------------------\n\nexport class StdioTransport {\n readonly command: string\n readonly args: string[]\n readonly env?: Record<string, string>\n readonly cwd?: string\n\n constructor(\n command: string,\n args: string[] = [],\n options?: { env?: Record<string, string>; cwd?: string },\n ) {\n this.command = command\n this.args = args\n this.env = options?.env\n this.cwd = options?.cwd\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientTransportInput — what the Client constructor accepts\n// ---------------------------------------------------------------------------\n\nexport type ClientTransportInput =\n | string // HTTP/HTTPS URL → auto-detect Streamable HTTP or SSE\n | McpServerLike // in-process server instance\n | McpConfig // { mcpServers: { ... } } config object\n | StdioTransport // explicit stdio subprocess config\n | Transport // pass-through — any SDK Transport (advanced)\n\n// ---------------------------------------------------------------------------\n// Resolved transport — what Client.connect() receives\n// ---------------------------------------------------------------------------\n\nexport type ResolvedTransport = {\n transport: Transport\n /**\n * Called before sdkClient.connect(transport). Used for in-process servers\n * that must be connected to their side of the InMemoryTransport first.\n */\n beforeConnect?: () => Promise<void>\n}\n\n// ---------------------------------------------------------------------------\n// Auth header injection helpers\n// ---------------------------------------------------------------------------\n\nfunction normalizeHeaders(headers: RequestInit['headers']): Record<string, string> {\n if (!headers) return {}\n if (headers instanceof Headers) return Object.fromEntries(headers.entries())\n if (Array.isArray(headers)) return Object.fromEntries(headers as string[][])\n return { ...(headers as Record<string, string>) }\n}\n\nfunction isAsyncAuth(\n auth: BearerAuth | OAuth | AsyncHeaderAuth,\n): auth is AsyncHeaderAuth {\n // ClientCredentials / JwtBearerAuth / EnterpriseManagedAuth all carry a\n // `kind` and acquire their token asynchronously — inject per request.\n // OAuth is now an OAuthClientProvider and is passed directly to the transport.\n return 'kind' in auth\n}\n\ntype HttpTransportOptions = {\n requestInit?: RequestInit\n fetch?: (url: string | URL, init?: RequestInit) => Promise<Response>\n eventSourceInit?: Record<string, unknown>\n authProvider?: OAuthClientProvider\n}\n\nfunction buildHttpOptions(\n auth: BearerAuth | OAuth | AsyncHeaderAuth | undefined,\n extraHeaders: Record<string, string> = {},\n): HttpTransportOptions {\n const hasExtra = Object.keys(extraHeaders).length > 0\n\n if (!auth && !hasExtra) return {}\n\n // OAuth implements OAuthClientProvider — hand it to the SDK transport which\n // handles the full auth flow (discovery, DCR, PKCE, token refresh, 401 retry).\n if (auth instanceof OAuth) {\n const opts: HttpTransportOptions = { authProvider: auth }\n // Extra headers are injected via requestInit (not Authorization — that's\n // managed by the authProvider).\n if (hasExtra) opts.requestInit = { headers: extraHeaders }\n return opts\n }\n\n if (auth && isAsyncAuth(auth)) {\n // Async token auth: inject the acquired token per-request via a custom fetch wrapper.\n const customFetch = async (\n url: string | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const authHeaders = await auth.getHeaders()\n return fetch(url, {\n ...init,\n headers: {\n ...authHeaders,\n ...extraHeaders,\n ...normalizeHeaders(init?.headers),\n },\n })\n }\n return { fetch: customFetch }\n }\n\n // Static auth (BearerAuth) or extra headers only.\n const staticHeaders: Record<string, string> = {\n ...(auth ? auth.getHeaders() : {}),\n ...extraHeaders,\n }\n return {\n requestInit: { headers: staticHeaders },\n // Also exposed for SSE's EventSource connection (eventsource npm pkg\n // accepts headers in EventSourceInit, unlike the browser API).\n eventSourceInit: { headers: staticHeaders },\n }\n}\n\n// ---------------------------------------------------------------------------\n// URL → SDK transport\n// ---------------------------------------------------------------------------\n\nlet sseDeprecationWarned = false\n\nfunction urlToTransport(\n url: URL,\n auth: BearerAuth | OAuth | AsyncHeaderAuth | undefined,\n extraHeaders: Record<string, string> = {},\n legacySSE = false,\n): Transport {\n const { requestInit, fetch: customFetch, eventSourceInit, authProvider } =\n buildHttpOptions(auth, extraHeaders)\n\n const segments = url.pathname.split('/')\n const isSSE = segments.includes('sse') || url.pathname.endsWith('/sse')\n\n if (isSSE) {\n if (!legacySSE) {\n throw new Error(\n `The URL \"${url}\" looks like an SSE endpoint, but SSE is deprecated by the MCP SDK ` +\n `(SSEClientTransport is marked @deprecated — prefer Streamable HTTP). Pass ` +\n `{ legacySSE: true } to ClientOptions to connect anyway.`,\n )\n }\n if (!sseDeprecationWarned) {\n sseDeprecationWarned = true\n console.warn(\n '[fastmcp-ts] Connecting over the deprecated SSE transport (legacySSE: true). ' +\n 'SSEClientTransport is marked @deprecated in the MCP SDK — migrate the server to ' +\n 'Streamable HTTP when possible.',\n )\n }\n return new SSEClientTransport(url, {\n ...(authProvider ? { authProvider } : {}),\n ...(requestInit ? { requestInit } : {}),\n ...(eventSourceInit ? { eventSourceInit } : {}),\n ...(customFetch ? { fetch: customFetch } : {}),\n })\n }\n\n return new StreamableHTTPClientTransport(url, {\n ...(authProvider ? { authProvider } : {}),\n ...(requestInit ? { requestInit } : {}),\n ...(customFetch ? { fetch: customFetch } : {}),\n })\n}\n\n// ---------------------------------------------------------------------------\n// In-process modern-era transport — see McpServerLike._modernFetch's docs.\n// ---------------------------------------------------------------------------\n\nconst IN_PROCESS_BASE_URL = 'http://in-process.local/mcp'\n\nfunction isPinnedModern(versionNegotiation: TransportResolutionOptions['versionNegotiation']): boolean {\n const mode = versionNegotiation?.mode\n return typeof mode === 'object' && mode !== null && 'pin' in mode\n}\n\nfunction modernFetchTransport(entry: McpServerLike): Transport {\n const modernFetch = entry._modernFetch!.bind(entry)\n // Adapt the (url, init) => Response shape StreamableHTTPClientTransport calls\n // its `fetch` option with to the (Request) => Response shape McpHttpHandler\n // (createMcpHandler's return value) exposes.\n const fetchAdapter = (url: string | URL, init?: RequestInit): Promise<Response> =>\n modernFetch(new Request(url, init))\n return new StreamableHTTPClientTransport(new URL(IN_PROCESS_BASE_URL), {\n fetch: fetchAdapter,\n })\n}\n\n// ---------------------------------------------------------------------------\n// resolveEntryTransport — resolves a single McpServerEntry to a transport.\n// Used by MultiServerClient to connect to each server independently.\n// ---------------------------------------------------------------------------\n\nexport async function resolveEntryTransport(\n entry: McpServerValue,\n auth?: BearerAuth | OAuth | AsyncHeaderAuth,\n options?: TransportResolutionOptions,\n): Promise<ResolvedTransport> {\n // In-process server (McpServerLike: has connect(transport)).\n if (isMcpServerLike(entry)) {\n if (isPinnedModern(options?.versionNegotiation) && entry._modernFetch) {\n return { transport: modernFetchTransport(entry) }\n }\n const [serverSide, clientSide] = InMemoryTransport.createLinkedPair()\n return {\n transport: clientSide,\n beforeConnect: () => entry.connect(serverSide),\n }\n }\n\n const entryAuth = resolveEntryAuth(entry.auth) ?? auth\n\n if ('url' in entry) {\n const url = new URL(entry.url)\n const extraHeaders = entry.headers ?? {}\n return { transport: urlToTransport(url, entryAuth, extraHeaders, options?.legacySSE) }\n }\n\n const cmd = entry as { command: string; args?: string[]; env?: Record<string, string> }\n return {\n transport: await createStdioTransport({\n command: cmd.command,\n args: cmd.args,\n env: cmd.env,\n }),\n }\n}\n\nfunction resolveEntryAuth(\n auth: BearerAuth | OAuth | AsyncHeaderAuth | string | undefined,\n): BearerAuth | OAuth | AsyncHeaderAuth | undefined {\n if (!auth) return undefined\n if (typeof auth === 'string') return new BearerAuth(auth)\n return auth\n}\n\n// ---------------------------------------------------------------------------\n// resolveTransport — internal; used by Client.connect()\n// ---------------------------------------------------------------------------\n\nexport async function resolveTransport(\n input: ClientTransportInput,\n auth?: BearerAuth | OAuth | AsyncHeaderAuth,\n options?: TransportResolutionOptions,\n): Promise<ResolvedTransport> {\n // 1. Our StdioTransport config class (check before the duck-type checks below).\n if (input instanceof StdioTransport) {\n return {\n transport: await createStdioTransport({\n command: input.command,\n args: input.args,\n env: input.env,\n cwd: input.cwd,\n }),\n }\n }\n\n // 2. URL string → auto-detect HTTP transport.\n if (typeof input === 'string') {\n const url = new URL(input)\n return { transport: urlToTransport(url, auth, {}, options?.legacySSE) }\n }\n\n // 3. Pass-through SDK Transport (has the Transport interface: start/close/send).\n if (\n typeof input === 'object' &&\n input !== null &&\n 'start' in input &&\n typeof (input as unknown as Record<string, unknown>).start === 'function'\n ) {\n return { transport: input as Transport }\n }\n\n // 4. MCP config object { mcpServers: { ... } } — use the first entry.\n if (isMcpConfig(input)) {\n const entries = Object.entries(input.mcpServers)\n if (entries.length === 0) throw new Error('mcpServers config is empty')\n const [, entry] = entries[0]!\n return await resolveEntryTransport(entry, auth, options)\n }\n\n // 5. In-process server (McpServerLike: has connect(transport)).\n if (isMcpServerLike(input)) {\n if (isPinnedModern(options?.versionNegotiation) && input._modernFetch) {\n return { transport: modernFetchTransport(input) }\n }\n const [serverSide, clientSide] = InMemoryTransport.createLinkedPair()\n return {\n transport: clientSide,\n beforeConnect: () => input.connect(serverSide),\n }\n }\n\n throw new Error(\n 'Unrecognized transport input: expected a URL string, FastMCP server instance, ' +\n 'mcpServers config object, StdioTransport, or SDK Transport',\n )\n}\n","import { UnauthorizedError, Client as SdkClient, LOG_LEVEL_META_KEY } from \"@modelcontextprotocol/client\";\nimport type {\n RequestOptions as SdkRequestOptions,\n McpSubscription,\n VersionNegotiationOptions,\n ProtocolEra,\n PriorDiscovery,\n InputRequiredOptions,\n ResponseCacheStore,\n Transport,\n} from \"@modelcontextprotocol/client\";\nimport { BearerAuth, OAuth } from './auth.js'\nimport type { AsyncHeaderAuth } from './auth.js'\nimport type { ClientHandlers, ListChangedHandler, ProgressHandler, ResourceUpdateHandler } from './handlers.js'\nimport { defaultLogHandler, defaultProgressHandler } from './handlers.js'\nimport type { CallToolOptions, IClient, RequestOptions } from './interfaces.js'\nimport type {\n CallToolResult,\n CompletionResult,\n ContentBlock,\n GetPromptResult,\n LoggingLevel,\n Prompt,\n Resource,\n TextResourceContents,\n BlobResourceContents,\n ResourceTemplate,\n Root,\n Tool,\n} from './results.js'\nimport type { ClientTransportInput, McpConfig } from './transports.js'\nimport { resolveTransport } from './transports.js'\nimport type { MultiServerOptions } from './multi-server.js'\nimport { MultiServerClient } from './multi-server.js'\n\n// ---------------------------------------------------------------------------\n// Error type\n// ---------------------------------------------------------------------------\n\nexport class ToolCallError extends Error {\n readonly content: ContentBlock[]\n\n constructor(message: string, content: ContentBlock[]) {\n super(message)\n this.name = 'ToolCallError'\n this.content = content\n }\n}\n\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface ClientDefaultOptions {\n /** Global fallback timeout in seconds for all requests. */\n timeout?: number\n tool?: { timeout?: number }\n resource?: { timeout?: number }\n prompt?: { timeout?: number }\n}\n\n/** A single element of the roots option: a URI string or a full Root object. */\nexport type RootInput = string | Root\n\n/**\n * Static list of roots, or an async callback invoked on each roots/list request.\n * URI strings are normalised to file:// URIs automatically; relative paths are\n * resolved against process.cwd().\n */\nexport type RootsValue = RootInput[] | (() => RootInput[] | Promise<RootInput[]>)\n\nexport interface ClientOptions {\n /**\n * Authentication to attach to HTTP requests.\n * A plain string is treated as a Bearer token.\n */\n auth?: BearerAuth | OAuth | AsyncHeaderAuth | string\n handlers?: ClientHandlers\n /**\n * Filesystem roots to advertise to the server.\n * Accepts a static array of strings / Root objects, or an async callback\n * invoked on each roots/list request (useful for dynamic root sets).\n */\n roots?: RootsValue\n /**\n * When true (default), the MCP initialize handshake is performed\n * automatically inside connect().\n */\n autoInitialize?: boolean\n defaultOptions?: ClientDefaultOptions\n /**\n * Opt-in protocol version negotiation (protocol revision 2026-07-28 and later).\n * The default is `'legacy'`: connect() runs the plain 2025 sequence, byte-identical\n * to today's behavior (no probe, no new headers). Pass `{ mode: 'auto' }` to probe\n * with `server/discover` and use the modern era when the server supports it\n * (falling back to legacy otherwise), or `{ mode: { pin: '2026-07-28' } }` to\n * require the modern era outright. See `getProtocolEra()` to read the negotiated\n * result after connecting.\n */\n versionNegotiation?: VersionNegotiationOptions\n /**\n * A cached era verdict from a previous connection to the same server, so\n * connect() can skip the `server/discover` probe entirely. Takes precedence\n * over `versionNegotiation`. `{ kind: 'modern', discover }` adopts a prior\n * `DiscoverResult` with zero round trips; `{ kind: 'legacy' }` skips the probe\n * and runs the plain legacy `initialize` handshake. Freshness is the caller's\n * responsibility — a stale modern verdict fails loudly at the first request; a\n * stale legacy verdict succeeds silently forever. Reuse only within one\n * authorization context.\n */\n prior?: PriorDiscovery\n /**\n * Multi-round-trip auto-fulfilment (protocol revision 2026-07-28). On the\n * modern era, servers obtain client input (elicitation, sampling, roots) by\n * answering a request with an `input_required` result instead of a\n * server→client request. By default the client fulfils these automatically\n * through the same `handlers.sampling`/`handlers.elicitation` callbacks,\n * retrying up to `maxRounds` times. Set `autoFulfill: false` for manual mode.\n * Has no effect on legacy-era connections. Passed through verbatim to the SDK\n * client.\n */\n inputRequired?: InputRequiredOptions\n /**\n * The response-cache store backing cacheable results (SEP-2549 `ttlMs`/\n * `cacheScope` hints on `listTools`/`listResources`/`listResourceTemplates`/\n * `listPrompts`/`readResource`). Defaults to a fresh in-memory store per\n * client (the SDK's own default) when omitted. Passed through verbatim.\n */\n responseCacheStore?: ResponseCacheStore\n /**\n * Opaque per-principal identifier for response-cache writes whose\n * server-reported `cacheScope` is `'private'`. Set this to a stable identity\n * of the authorization context (e.g. the auth subject) when one\n * `responseCacheStore` backs several principals. Passed through verbatim.\n */\n cachePartition?: string\n /**\n * TTL (ms) applied when a cacheable result arrives without a `ttlMs` field.\n * Default `0` (never served from cache, but still stored). Passed through\n * verbatim.\n */\n defaultCacheTtlMs?: number\n /**\n * Allow the deprecated SSE transport when a target URL's path indicates SSE\n * (e.g. ends in `/sse`). Default `false` — such URLs throw a clear error\n * pointing at Streamable HTTP and this flag, rather than silently connecting\n * over a transport the MCP SDK itself marks `@deprecated`. When enabled, a\n * one-time deprecation warning is logged via `console.warn`.\n */\n legacySSE?: boolean\n}\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\ntype OptionalHandlerKeys =\n | 'sampling'\n | 'elicitation'\n | 'onToolsListChanged'\n | 'onResourcesListChanged'\n | 'onPromptsListChanged'\n\nexport class Client implements IClient {\n private _sdkClient: SdkClient | null = null\n private _refCount = 0\n private _connectPromise: Promise<void> | null = null\n private readonly _resourceSubscriptions = new Map<string, ResourceUpdateHandler>()\n /** The modern-era (2026-07-28) `subscriptions/listen` stream backing all active\n * resource subscriptions — resources/subscribe and resources/unsubscribe are\n * 2025-only RPCs, physically absent from the modern method registry. Unused\n * (stays undefined) on a legacy connection. */\n private _resourceListenSubscription: McpSubscription | undefined\n /** The live SDK transport captured at connect(). Its `finishAuth()` redeems the\n * authorization code both during connect-time recovery and a post-connect\n * step-up re-authorization. */\n private _transport: Transport | undefined\n /** Single-flight guard for a post-connect re-authorization round: concurrent\n * interactive-OAuth 401s share one `waitForCallback`→`finishAuth` round rather\n * than each opening its own. Cleared when the round settles. */\n private _reauthPromise: Promise<void> | null = null\n /** Max post-connect re-authorization rounds per request (see `_reauthRetry`):\n * 1 for ordinary step-up, 2 to also cover SEP-2352 authorization-server\n * migration (the AS changes mid-request). Bounded so a genuinely unauthorized\n * request cannot loop forever. */\n private static readonly _MAX_REAUTH_ROUNDS = 2\n\n private readonly _input: ClientTransportInput\n private readonly _auth: BearerAuth | OAuth | AsyncHeaderAuth | undefined\n private readonly _handlers: Required<Omit<ClientHandlers, OptionalHandlerKeys>> &\n Pick<ClientHandlers, OptionalHandlerKeys>\n private readonly _roots: (() => Promise<Root[]>) | undefined\n private readonly _autoInitialize: boolean\n private readonly _versionNegotiation: VersionNegotiationOptions | undefined\n private readonly _prior: PriorDiscovery | undefined\n private readonly _inputRequired: InputRequiredOptions | undefined\n private readonly _responseCacheStore: ResponseCacheStore | undefined\n private readonly _cachePartition: string | undefined\n private readonly _defaultCacheTtlMs: number | undefined\n private readonly _legacySSE: boolean\n /** Set by setLogLevel() on a modern-era connection (where logging/setLevel is\n * not a wire method) — threaded into `_meta[LOG_LEVEL_META_KEY]` on every\n * subsequent request. Unused on legacy era, where setLogLevel() still sends\n * the real `logging/setLevel` RPC. */\n private _logLevel: LoggingLevel | undefined\n private readonly _defaultOptions: ClientDefaultOptions\n\n constructor(input: ClientTransportInput, options?: ClientOptions) {\n this._input = input\n this._auth = resolveAuth(options?.auth)\n this._handlers = {\n log: options?.handlers?.log ?? defaultLogHandler,\n progress: options?.handlers?.progress ?? defaultProgressHandler,\n sampling: options?.handlers?.sampling,\n elicitation: options?.handlers?.elicitation,\n onToolsListChanged: options?.handlers?.onToolsListChanged,\n onResourcesListChanged: options?.handlers?.onResourcesListChanged,\n onPromptsListChanged: options?.handlers?.onPromptsListChanged,\n }\n this._roots = options?.roots ? normalizeRootsOption(options.roots) : undefined\n this._autoInitialize = options?.autoInitialize ?? true\n this._versionNegotiation = options?.versionNegotiation\n this._prior = options?.prior\n this._inputRequired = options?.inputRequired\n this._responseCacheStore = options?.responseCacheStore\n this._cachePartition = options?.cachePartition\n this._defaultCacheTtlMs = options?.defaultCacheTtlMs\n this._legacySSE = options?.legacySSE ?? false\n this._defaultOptions = options?.defaultOptions ?? {}\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n async connect(): Promise<void> {\n this._refCount++\n\n // If another concurrent connect() is in progress, wait for it.\n if (this._connectPromise) {\n await this._connectPromise\n return\n }\n\n // Already connected — just bump the ref count.\n if (this._sdkClient) return\n\n this._connectPromise = this._doConnect().finally(() => {\n this._connectPromise = null\n })\n\n try {\n await this._connectPromise\n } catch (err) {\n this._refCount = Math.max(0, this._refCount - 1)\n throw err\n }\n }\n\n private async _doConnect(): Promise<void> {\n const sdkClient = new SdkClient(\n { name: 'fastmcp-ts', version: '1.0.0' },\n {\n capabilities: this._buildCapabilities(),\n listChanged: this._buildListChangedConfig(),\n ...(this._versionNegotiation ? { versionNegotiation: this._versionNegotiation } : {}),\n ...(this._inputRequired ? { inputRequired: this._inputRequired } : {}),\n ...(this._responseCacheStore ? { responseCacheStore: this._responseCacheStore } : {}),\n ...(this._cachePartition !== undefined ? { cachePartition: this._cachePartition } : {}),\n ...(this._defaultCacheTtlMs !== undefined\n ? { defaultCacheTtlMs: this._defaultCacheTtlMs }\n : {}),\n },\n )\n\n this._registerHandlers(sdkClient)\n\n const { transport, beforeConnect } = await resolveTransport(this._input, this._auth, {\n legacySSE: this._legacySSE,\n versionNegotiation: this._versionNegotiation,\n })\n\n // Bind the server URL into the OAuth provider before the SDK transport\n // reads clientMetadata or tokens() so storage keys are properly namespaced.\n if (this._auth instanceof OAuth) {\n const serverUrl = this._extractServerUrl()\n if (serverUrl) this._auth._bind(serverUrl)\n }\n\n if (beforeConnect) await beforeConnect()\n\n this._transport = transport\n try {\n await sdkClient.connect(transport, this._prior ? { prior: this._prior } : undefined)\n } catch (err) {\n if (err instanceof UnauthorizedError && this._auth instanceof OAuth) {\n // The SDK opened the browser and is waiting for the user to authorize.\n // Wait for the callback to receive the full callback params (code +,\n // when present, the RFC 9207 `iss` parameter), then finish auth on the\n // original transport (it holds the discovery/PKCE context) to exchange\n // the code for tokens. Passing URLSearchParams (rather than a bare\n // code string) lets the SDK validate `iss` against the recorded\n // issuer before redeeming the code.\n const callbackParams = await this._auth.waitForCallback()\n await this._finishAuth(transport, callbackParams)\n // The original transport is already started and cannot be reconnected;\n // build a fresh one for the authenticated attempt. It reads the tokens\n // finishAuth stored in the auth provider.\n const retry = await resolveTransport(this._input, this._auth)\n if (retry.beforeConnect) await retry.beforeConnect()\n this._transport = retry.transport\n await sdkClient.connect(retry.transport)\n } else {\n throw err\n }\n }\n\n this._sdkClient = sdkClient\n }\n\n private _extractServerUrl(): string | undefined {\n const input = this._input\n if (typeof input === 'string') return input\n if (\n typeof input === 'object' &&\n input !== null &&\n 'mcpServers' in input\n ) {\n const entries = Object.entries(\n (input as { mcpServers: Record<string, { url?: string }> }).mcpServers,\n )\n if (entries.length > 0) {\n const [, entry] = entries[0]!\n if (entry && 'url' in entry && typeof entry.url === 'string') {\n return entry.url\n }\n }\n }\n return undefined\n }\n\n async close(): Promise<void> {\n this._refCount = Math.max(0, this._refCount - 1)\n if (this._refCount > 0) return\n\n // Close explicitly (and first) so its closure reason is 'local', not 'remote' —\n // otherwise the resource-subscription robustness handler above would try to\n // re-listen through a client that is already torn down.\n if (this._resourceListenSubscription) {\n await this._resourceListenSubscription.close().catch(() => {})\n this._resourceListenSubscription = undefined\n }\n\n const sdk = this._sdkClient\n this._sdkClient = null\n if (sdk) await sdk.close()\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close()\n }\n\n isConnected(): boolean {\n return this._sdkClient !== null\n }\n\n /** Creates a connected MultiServerClient when given a multi-entry McpConfig. */\n static async connect(input: McpConfig, options?: MultiServerOptions): Promise<MultiServerClient>\n /** Creates a connected Client for a single-server transport. Use with `await using` for automatic cleanup. */\n static async connect(input: ClientTransportInput, options?: ClientOptions): Promise<Client>\n static async connect(\n input: ClientTransportInput | McpConfig,\n options?: ClientOptions | MultiServerOptions,\n ): Promise<Client | MultiServerClient> {\n if (\n typeof input === 'object' &&\n input !== null &&\n 'mcpServers' in input &&\n Object.keys((input as McpConfig).mcpServers).length > 1\n ) {\n return MultiServerClient.connect(input as McpConfig, options as MultiServerOptions)\n }\n const client = new Client(input as ClientTransportInput, options as ClientOptions)\n await client.connect()\n return client\n }\n\n // -------------------------------------------------------------------------\n // Core protocol\n // -------------------------------------------------------------------------\n\n /**\n * Liveness check. On a legacy-era connection this sends the `ping` RPC. On a\n * modern (2026-07-28) connection `ping` is not a wire method — the era's\n * registry deliberately excludes it — so this sends `server/discover`\n * instead: any successful response is equally strong liveness evidence, and\n * `discover()` is the SDK-native modern equivalent (rather than a\n * hand-rolled substitute). Returns `false` only on legacy `ping`'s own\n * result; a modern-era failure throws, matching `ping()`'s existing\n * throw-on-failure contract.\n */\n async ping(options?: RequestOptions): Promise<boolean> {\n if (this.getProtocolEra() === 'modern') {\n await this._reauthRetry(() => this._sdk().discover(this._toSdkOptions(options)))\n return true\n }\n await this._reauthRetry(() => this._sdk().ping(this._toSdkOptions(options)))\n return true\n }\n\n /**\n * The protocol era negotiated at connect(): `'modern'` for 2026-07-28 (per-request\n * envelope), `'legacy'` for 2025-11-25 and earlier (the `initialize` handshake).\n * `undefined` before connect(). See `ClientOptions.versionNegotiation`.\n */\n getProtocolEra(): ProtocolEra | undefined {\n return this._sdkClient?.getProtocolEra()\n }\n\n // -------------------------------------------------------------------------\n // Tools (IToolsClient)\n // -------------------------------------------------------------------------\n\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listTools(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.tool?.timeout),\n ),\n )\n return result.tools as Tool[]\n }\n\n async callTool<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const raw = await this.callToolRaw<TData>(name, args, options)\n if (raw.isError) {\n const message =\n (raw.content as Array<{ type: string; text?: string }>)\n .filter((c) => c.type === 'text')\n .map((c) => c.text ?? '')\n .join('\\n') || 'Tool returned an error'\n throw new ToolCallError(message, raw.content)\n }\n return raw\n }\n\n /** Returns the full result including isError without throwing. */\n async callToolRaw<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const sdkOptions = this._toSdkOptions(\n options,\n options?.onProgress,\n this._defaultOptions.tool?.timeout,\n )\n const result = await this._reauthRetry(() =>\n this._sdk().callTool({ name, arguments: args ?? {}, ...this._metaParams() }, sdkOptions),\n )\n return {\n content: result.content as ContentBlock[],\n structuredContent: (result.structuredContent as TData | undefined) ?? null,\n isError: result.isError === true,\n }\n }\n\n // -------------------------------------------------------------------------\n // Resources (IResourcesClient)\n // -------------------------------------------------------------------------\n\n async listResources(options?: RequestOptions): Promise<Resource[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listResources(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n return result.resources as Resource[]\n }\n\n async listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listResourceTemplates(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n return result.resourceTemplates as ResourceTemplate[]\n }\n\n async readResource(\n uri: string,\n options?: RequestOptions,\n ): Promise<Array<TextResourceContents | BlobResourceContents>> {\n const result = await this._reauthRetry(() =>\n this._sdk().readResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n return result.contents\n }\n\n /** Returns the raw SDK ReadResourceResult without unwrapping. */\n async readResourceRaw(uri: string, options?: RequestOptions) {\n return this._reauthRetry(() =>\n this._sdk().readResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n }\n\n /**\n * Subscribes to change notifications for a resource URI. `handler` fires whenever\n * the server sends a matching update, on either protocol era: on a legacy\n * (2025-era) connection via the `resources/subscribe` RPC and unsolicited\n * `notifications/resources/updated` push, or on a modern (2026-07-28) connection\n * via a `subscriptions/listen` stream opted into `resourceSubscriptions` — both\n * dispatch to the same `notifications/resources/updated` handler registered in\n * `_registerHandlers`, so this method is the only era-aware part.\n */\n async subscribeResource(\n uri: string,\n handler: ResourceUpdateHandler,\n options?: RequestOptions,\n ): Promise<void> {\n this._resourceSubscriptions.set(uri, handler)\n if (this._sdk().getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscription()\n } else {\n await this._reauthRetry(() =>\n this._sdk().subscribeResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n }\n }\n\n async unsubscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n this._resourceSubscriptions.delete(uri)\n if (this._sdk().getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscription()\n } else {\n await this._reauthRetry(() =>\n this._sdk().unsubscribeResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n }\n }\n\n /**\n * Re-opens the modern-era resource-subscription listen stream with the current\n * set of subscribed URIs. `listen()` has no in-place filter update, so every\n * subscribe/unsubscribe on a modern connection closes the existing stream (if\n * any) and opens a fresh one — `subscribeResource`/`unsubscribeResource` are not\n * expected to be called at a high frequency, so this is not a hot path.\n */\n private async _refreshResourceListenSubscription(): Promise<void> {\n if (this._resourceListenSubscription) {\n await this._resourceListenSubscription.close()\n this._resourceListenSubscription = undefined\n }\n const uris = [...this._resourceSubscriptions.keys()]\n if (uris.length === 0) return\n\n // The modern subscribeResource/unsubscribeResource leg: opening the\n // `subscriptions/listen` stream is a server-auth-gated request, so it steps\n // up on a post-connect 401 like every other request method.\n const subscription = await this._reauthRetry(() =>\n this._sdk().listen({ resourceSubscriptions: uris }),\n )\n this._resourceListenSubscription = subscription\n\n // Robustness: an unexpected disconnect ('remote') re-establishes the stream so\n // resource-update delivery survives a dropped connection. A deliberate\n // server-side close ('graceful') is respected — the server chose to end it, and\n // re-listening would fight that decision. A close we triggered ourselves\n // ('local' — e.g. this same method superseding it above) needs no action; the\n // subscription-identity check also protects against acting on a stale handle.\n void subscription.closed.then((reason) => {\n if (reason === 'remote' && this._resourceListenSubscription === subscription) {\n this._resourceListenSubscription = undefined\n void this._refreshResourceListenSubscription().catch(() => {})\n }\n })\n }\n\n // -------------------------------------------------------------------------\n // Prompts (IPromptsClient)\n // -------------------------------------------------------------------------\n\n async listPrompts(options?: RequestOptions): Promise<Prompt[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listPrompts(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n ),\n )\n return result.prompts as Prompt[]\n }\n\n async getPrompt(\n name: string,\n args?: Record<string, string>,\n options?: RequestOptions,\n ): Promise<GetPromptResult> {\n const result = await this._reauthRetry(() =>\n this._sdk().getPrompt(\n { name, arguments: args, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n ),\n )\n return result as GetPromptResult\n }\n\n // -------------------------------------------------------------------------\n // Completion\n // -------------------------------------------------------------------------\n\n async complete(\n ref: { type: 'ref/prompt'; name: string } | { type: 'ref/resource'; uri: string },\n argument: { name: string; value: string },\n context?: { arguments?: Record<string, string> },\n options?: RequestOptions,\n ): Promise<CompletionResult> {\n const result = await this._reauthRetry(() =>\n this._sdk().complete(\n { ref, argument, ...(context ? { context } : {}), ...this._metaParams() },\n this._toSdkOptions(options),\n ),\n )\n return result.completion as CompletionResult\n }\n\n // -------------------------------------------------------------------------\n // Logging\n // -------------------------------------------------------------------------\n\n /**\n * Sets the minimum severity level for log messages sent by the server. On a\n * legacy-era connection this sends the `logging/setLevel` RPC, unchanged. On\n * a modern (2026-07-28) connection `logging/setLevel` is deprecated (SEP-2577)\n * and physically absent from the era's registry — there is no RPC to send.\n * Instead, the level is recorded and threaded into\n * `_meta['io.modelcontextprotocol/logLevel']` on every subsequent request via\n * `_metaParams()`, per request; user-supplied `_meta` still wins if a caller\n * passes one explicitly (there is no such call site in this class today).\n */\n async setLogLevel(level: LoggingLevel, options?: RequestOptions): Promise<void> {\n if (this.getProtocolEra() === 'modern') {\n this._logLevel = level\n return\n }\n await this._reauthRetry(() =>\n this._sdk().setLoggingLevel(level, this._toSdkOptions(options)),\n )\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private _sdk(): SdkClient {\n if (!this._sdkClient) {\n throw new Error('Client is not connected. Call connect() first.')\n }\n return this._sdkClient\n }\n\n /**\n * Runs a post-connect SDK request and, when it rejects with the SDK's\n * `UnauthorizedError` under an interactive {@link OAuth} provider, performs a\n * bounded number of step-up re-authorization rounds — the same\n * `waitForCallback`→`finishAuth` machinery `connect()` uses — retrying the\n * request after each.\n *\n * This closes the post-connect gap for interactive OAuth: a request that 401s\n * (missing/expired token) or 403s with an `insufficient_scope` challenge (a\n * broader scope is required for that operation) drives the SDK transport to\n * issue a fresh, scope-honoring authorization request and re-throw\n * `UnauthorizedError` — the transport picks the challenged/union scope itself\n * (`extractWWWAuthenticateParams` + `computeScopeUnion`); this wrapper only\n * completes the interrupted round and retries.\n *\n * The bound is {@link Client._MAX_REAUTH_ROUNDS}. One round covers ordinary\n * step-up (a single 401/403). Two rounds cover SEP-2352 authorization-server\n * migration: the first authenticated request flips the MCP server to a new\n * authorization server (its Protected Resource Metadata now lists a different\n * issuer), so the very next request 401s and must re-discover, re-register, and\n * re-authorize at the NEW server — a second round on the same wrapped request.\n * Beyond the bound the `UnauthorizedError` propagates, so a genuinely\n * unauthorized request never loops forever.\n *\n * Each round is single-flight: concurrent 401s share one `_reauthPromise`, and\n * each caller retries its own request after it resolves — a burst never opens\n * multiple browsers.\n *\n * Non-interactive auth is never re-authorized here — the original error\n * propagates unchanged. `BearerAuth` and custom headers carry no interactive\n * step, and a {@link ClientCredentials} scope failure is a machine-to-machine\n * misconfiguration (no user, no browser), not a step-up flow.\n * `MultiServerClient` configures no interactive OAuth by design, so this path\n * stays inert there.\n *\n * Every outbound request method routes through this wrapper, with one\n * exception: {@link Client.notifyRootsChanged} calls the SDK directly. It sends\n * a notification, not a request, so there is no response to 401/403 and\n * nothing to retry.\n *\n * `BrowserOAuth` (`extends OAuth`) is covered by the same guard, and its\n * `waitForCallback` is sound for a post-connect round — `redirectToAuthorization`\n * arms the callback promise before the transport re-throws. Two browser-only\n * caveats apply, honestly: in **popup** mode `window.open` needs a user gesture,\n * so a step-up fired from a request not within one is blocked and the re-auth\n * error propagates (call from a click); **redirect** mode navigates the whole\n * tab away (`window.location.assign`), destroying this in-flight retry — the app\n * recovers via `resumeFromRedirect()` on the return load and a fresh request,\n * not by this wrapper. The migration second round inherits the popup caveat: it\n * runs outside the original user gesture, so under `BrowserOAuth` popup mode it\n * hits the user-gesture block and surfaces as that error rather than opening a\n * second popup.\n */\n private async _reauthRetry<T>(op: () => Promise<T>): Promise<T> {\n let rounds = 0\n for (;;) {\n try {\n return await op()\n } catch (err) {\n if (!(err instanceof UnauthorizedError) || !(this._auth instanceof OAuth)) throw err\n // Bounded — see _MAX_REAUTH_ROUNDS. Beyond the bound the error propagates\n // so a genuinely unauthorized request never loops forever.\n if (rounds >= Client._MAX_REAUTH_ROUNDS) throw err\n rounds++\n await this._reauthorize(this._auth)\n }\n }\n }\n\n /** Single-flight wrapper around one re-authorization round. */\n private async _reauthorize(auth: OAuth): Promise<void> {\n this._reauthPromise ??= this._doReauthorize(auth).finally(() => {\n this._reauthPromise = null\n })\n await this._reauthPromise\n }\n\n /**\n * One re-authorization round: await the authorization callback the SDK\n * transport already armed (its 401/403 handling ran discovery + opened the\n * browser with the challenged scope), then `finishAuth()` redeems the code for\n * the broader-scope token on the live transport. The very next request reads\n * that token via the transport's per-request bearer-token bridge.\n *\n * After redeeming, the cached discovery state is invalidated so that the NEXT\n * authorization leg re-discovers the Protected Resource Metadata from scratch.\n * The SDK's `auth()` otherwise pins to the authorization server it first cached\n * and re-fetches PRM only when it has none — so it never notices a SEP-2352\n * migration (PRM `authorization_servers` changing to a new issuer). Clearing it\n * here (after the current round's callback leg has already consumed it) makes a\n * subsequent 401 re-run discovery, land on the new server, and register there.\n * Re-discovery is idempotent when the server has NOT migrated, so ordinary\n * step-up and token-refresh rounds are unaffected beyond one extra metadata\n * fetch.\n */\n private async _doReauthorize(auth: OAuth): Promise<void> {\n const callbackParams = await auth.waitForCallback()\n // `_transport` is always set post-connect (assigned in _doConnect before\n // `_sdkClient`), and this round only ever runs after a successful request —\n // so the guard is theoretical. It stays only to keep the type non-null\n // without a non-null assertion; a missing transport silently no-ops rather\n // than throwing, which is the safer degradation if that invariant ever breaks.\n if (this._transport) await this._finishAuth(this._transport, callbackParams)\n await auth.invalidateCredentials('discovery')\n }\n\n /**\n * Redeems the authorization callback params for tokens on `transport`, if it\n * exposes `finishAuth` (StreamableHTTP and SSE do). Shared by connect-time\n * recovery and post-connect step-up. Passing `URLSearchParams` (not a bare\n * code) lets the SDK validate the RFC 9207 `iss` before redeeming.\n */\n private async _finishAuth(transport: Transport, params: URLSearchParams): Promise<void> {\n if (\n 'finishAuth' in transport &&\n typeof (transport as Record<string, unknown>).finishAuth === 'function'\n ) {\n await (transport as { finishAuth(p: URLSearchParams): Promise<void> }).finishAuth(params)\n }\n }\n\n /**\n * The `_meta` override to merge into an outbound request's params — carries\n * `_logLevel` (set by setLogLevel() on a modern-era connection) so it rides\n * along on every subsequent request. Returns `undefined` (not `{}`) when\n * there is nothing to attach, so `{...this._metaParams()}` is a no-op and\n * callers that pass no params at all can keep passing `undefined` unchanged.\n */\n private _metaParams(): { _meta: Record<string, unknown> } | undefined {\n if (this._logLevel !== undefined && this.getProtocolEra() === 'modern') {\n return { _meta: { [LOG_LEVEL_META_KEY]: this._logLevel } }\n }\n return undefined\n }\n\n private _toSdkOptions(\n options?: RequestOptions,\n overrideProgress?: ProgressHandler,\n scopedTimeoutSeconds?: number,\n ): SdkRequestOptions {\n const timeoutSeconds =\n options?.timeout ?? scopedTimeoutSeconds ?? this._defaultOptions.timeout\n const progressHandler = overrideProgress ?? this._handlers.progress\n\n const sdkOptions: SdkRequestOptions = {}\n if (timeoutSeconds != null) sdkOptions.timeout = timeoutSeconds * 1000\n if (options?.signal) sdkOptions.signal = options.signal\n if (progressHandler) {\n sdkOptions.onprogress = ({ progress, total, message }) => {\n void progressHandler(progress, total, message)\n }\n }\n return sdkOptions\n }\n\n private _buildCapabilities() {\n return {\n ...(this._handlers.sampling ? { sampling: { tools: {} } } : {}),\n ...(this._handlers.elicitation ? { elicitation: {} } : {}),\n ...(this._roots ? { roots: { listChanged: true } } : {}),\n }\n }\n\n private _buildListChangedConfig() {\n const { onToolsListChanged, onResourcesListChanged, onPromptsListChanged } = this._handlers\n if (!onToolsListChanged && !onResourcesListChanged && !onPromptsListChanged) return undefined\n\n const adapt = <T>(h: ListChangedHandler<T>) => ({\n onChanged: (err: Error | null, items: T[] | null) => { void h.onChanged(err, items) },\n ...(h.autoRefresh !== undefined ? { autoRefresh: h.autoRefresh } : {}),\n ...(h.debounceMs !== undefined ? { debounceMs: h.debounceMs } : {}),\n })\n\n return {\n ...(onToolsListChanged ? { tools: adapt(onToolsListChanged) } : {}),\n ...(onResourcesListChanged ? { resources: adapt(onResourcesListChanged) } : {}),\n ...(onPromptsListChanged ? { prompts: adapt(onPromptsListChanged) } : {}),\n }\n }\n\n private _registerHandlers(sdk: SdkClient): void {\n // Log notifications from the server\n sdk.setNotificationHandler('notifications/message', (notification) => {\n void this._handlers.log({\n level: notification.params.level,\n logger: notification.params.logger ?? undefined,\n data: notification.params.data,\n })\n })\n\n // Resource update notifications (for active subscriptions)\n sdk.setNotificationHandler('notifications/resources/updated', (notification) => {\n const handler = this._resourceSubscriptions.get(notification.params.uri)\n if (handler) void handler(notification.params.uri)\n })\n\n // Sampling: server requests an LLM completion from the client\n if (this._handlers.sampling) {\n const samplingHandler = this._handlers.sampling\n sdk.setRequestHandler('sampling/createMessage', async (request) => {\n return samplingHandler(request.params)\n })\n }\n\n // Elicitation: server requests structured user input\n if (this._handlers.elicitation) {\n const elicitationHandler = this._handlers.elicitation\n sdk.setRequestHandler('elicitation/create', async (request) => {\n return elicitationHandler(request.params)\n })\n }\n\n // Roots: server requests the client's accessible filesystem roots\n if (this._roots) {\n const getRoots = this._roots\n sdk.setRequestHandler('roots/list', async () => ({\n roots: await getRoots(),\n }))\n }\n }\n\n // -------------------------------------------------------------------------\n // Roots\n // -------------------------------------------------------------------------\n\n /**\n * Notify the connected server that the client's roots list has changed.\n * The server should re-issue a roots/list request to get the updated list.\n */\n async notifyRootsChanged(): Promise<void> {\n await this._sdk().sendRootsListChanged()\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction resolveAuth(\n auth: BearerAuth | OAuth | AsyncHeaderAuth | string | undefined,\n): BearerAuth | OAuth | AsyncHeaderAuth | undefined {\n if (!auth) return undefined\n if (typeof auth === 'string') return new BearerAuth(auth)\n return auth\n}\n\nfunction normalizeRootsOption(roots: RootsValue): () => Promise<Root[]> {\n if (typeof roots === 'function') {\n return async () => Promise.all((await roots()).map(normalizeRootInput))\n }\n return async () => Promise.all(roots.map(normalizeRootInput))\n}\n\nasync function normalizeRootInput(input: RootInput): Promise<Root> {\n if (typeof input === 'string') return { uri: await normalizeRootUri(input) }\n return { ...input, uri: await normalizeRootUri(input.uri) }\n}\n\nasync function normalizeRootUri(input: string): Promise<string> {\n // Already a URI (file://, http://, ...) — pass through with no Node import.\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(input)) return input\n // A bare filesystem path requires Node to resolve against the cwd.\n if (typeof process === 'undefined' || !process.versions?.node) {\n throw new Error(\n `Cannot normalize filesystem root \"${input}\" in a browser. Pass a file:// URI instead.`,\n )\n }\n const { resolve } = await import('node:path')\n const { pathToFileURL } = await import('node:url')\n return pathToFileURL(resolve(input)).href\n}\n","import type { LoggingLevel, RequestOptions as SdkRequestOptions } from \"@modelcontextprotocol/server\";\nimport { Client as SdkClient, LOG_LEVEL_META_KEY } from '@modelcontextprotocol/client'\nimport type { McpSubscription, VersionNegotiationOptions, ProtocolEra } from '@modelcontextprotocol/client'\nimport type { BearerAuth, OAuth, ClientCredentials } from './auth.js'\nimport type { ClientHandlers, LogHandler, ProgressHandler, ResourceUpdateHandler } from './handlers.js'\nimport { defaultLogHandler, defaultProgressHandler } from './handlers.js'\nimport type { CallToolOptions, IClient, RequestOptions } from './interfaces.js'\nimport type {\n CallToolResult,\n CompletionResult,\n ContentBlock,\n GetPromptResult,\n Prompt,\n Resource,\n TextResourceContents,\n BlobResourceContents,\n ResourceTemplate,\n Tool,\n} from './results.js'\nimport type { McpConfig, McpServerValue } from './transports.js'\nimport { resolveEntryTransport } from './transports.js'\nimport type { ClientDefaultOptions } from './client.js'\nimport { ToolCallError } from './client.js'\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface MultiServerOptions {\n handlers?: ClientHandlers\n /** file:// URIs to advertise to all servers as accessible roots. */\n roots?: string[]\n defaultOptions?: ClientDefaultOptions\n /**\n * Opt-in protocol version negotiation, applied identically to every server\n * in the config (protocol revision 2026-07-28 and later). See\n * `ClientOptions.versionNegotiation` on the single-server `Client` — same\n * semantics, just applied per sub-client here since each connected server\n * negotiates its own era independently. Default `'legacy'`.\n */\n versionNegotiation?: VersionNegotiationOptions\n}\n\n// ---------------------------------------------------------------------------\n// MultiServerClient\n// ---------------------------------------------------------------------------\n\nexport class MultiServerClient implements IClient {\n private _clients: Map<string, SdkClient> = new Map()\n private _connectPromise: Promise<void> | null = null\n private _connected = false\n\n /** URI (or namespaced template URI) → server name, populated by list calls */\n private _uriMap: Map<string, string> = new Map()\n\n private readonly _config: McpConfig\n private readonly _handlers: {\n log: LogHandler\n progress: ProgressHandler\n sampling?: ClientHandlers['sampling']\n elicitation?: ClientHandlers['elicitation']\n }\n private readonly _roots: string[] | undefined\n private readonly _defaultOptions: ClientDefaultOptions\n private readonly _versionNegotiation: VersionNegotiationOptions | undefined\n private _resourceSubscriptions: Map<string, ResourceUpdateHandler> = new Map()\n /** Modern-era (2026-07-28) subscriptions/listen streams, one per server that\n * currently has active resource subscriptions — see Client's own field of the\n * same purpose for the full rationale. Keyed by server name since each\n * connected server negotiates its own era independently. */\n private _resourceListenSubscriptions: Map<string, McpSubscription> = new Map()\n /** Per-server log level set by setLogLevel() for servers negotiated to modern\n * era — see Client's own field of the same purpose for the full rationale.\n * Keyed by server name since each connected server negotiates its own era\n * independently and may therefore need (or not need) meta-threading. */\n private _logLevels: Map<string, LoggingLevel> = new Map()\n\n constructor(config: McpConfig, options?: MultiServerOptions) {\n this._config = config\n this._handlers = {\n log: options?.handlers?.log ?? defaultLogHandler,\n progress: options?.handlers?.progress ?? defaultProgressHandler,\n sampling: options?.handlers?.sampling,\n elicitation: options?.handlers?.elicitation,\n }\n this._versionNegotiation = options?.versionNegotiation\n this._roots = options?.roots\n this._defaultOptions = options?.defaultOptions ?? {}\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n async connect(): Promise<void> {\n if (this._connected) return\n if (this._connectPromise) {\n await this._connectPromise\n return\n }\n\n this._connectPromise = this._doConnect().finally(() => {\n this._connectPromise = null\n })\n\n await this._connectPromise\n }\n\n private async _doConnect(): Promise<void> {\n const entries = Object.entries(this._config.mcpServers)\n if (entries.length === 0) throw new Error('mcpServers config is empty')\n\n const connected: Array<[string, SdkClient]> = []\n\n try {\n await Promise.all(\n entries.map(async ([name, entry]) => {\n const sdk = this._buildSdkClient()\n this._registerHandlers(sdk)\n const { transport, beforeConnect } = await resolveEntryTransport(\n entry as McpServerValue,\n undefined,\n { versionNegotiation: this._versionNegotiation },\n )\n if (beforeConnect) await beforeConnect()\n await sdk.connect(transport)\n connected.push([name, sdk])\n }),\n )\n } catch (err) {\n // Roll back any connections that succeeded before the failure.\n await Promise.allSettled(connected.map(([, sdk]) => sdk.close()))\n throw err\n }\n\n for (const [name, sdk] of connected) {\n this._clients.set(name, sdk)\n }\n\n this._connected = true\n }\n\n async close(): Promise<void> {\n if (!this._connected) return\n this._connected = false\n this._uriMap.clear()\n // Close explicitly (and first) so each closure reason is 'local', not 'remote' —\n // see Client.close()'s equivalent ordering for the full rationale.\n await Promise.allSettled(\n [...this._resourceListenSubscriptions.values()].map((sub) => sub.close()),\n )\n this._resourceListenSubscriptions.clear()\n await Promise.allSettled([...this._clients.values()].map((sdk) => sdk.close()))\n this._clients.clear()\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close()\n }\n\n isConnected(): boolean {\n return this._connected\n }\n\n static async connect(\n config: McpConfig,\n options?: MultiServerOptions,\n ): Promise<MultiServerClient> {\n const client = new MultiServerClient(config, options)\n await client.connect()\n return client\n }\n\n // -------------------------------------------------------------------------\n // Core protocol\n // -------------------------------------------------------------------------\n\n /**\n * The protocol era negotiated with a specific named server: `'modern'` for\n * 2026-07-28, `'legacy'` for 2025-11-25 and earlier, `undefined` if the\n * server name is unknown or not yet connected. See\n * `MultiServerOptions.versionNegotiation` — the same mode is requested of\n * every server, but each negotiates (and may land on) its own era\n * independently, so this is necessarily per-server rather than a single\n * client-wide value.\n */\n getProtocolEra(serverName: string): ProtocolEra | undefined {\n return this._clients.get(serverName)?.getProtocolEra()\n }\n\n /** See Client.ping's docs — the same era-routing applies here, per server,\n * since each connected server negotiates its own era independently. */\n async ping(options?: RequestOptions): Promise<boolean> {\n this._assertConnected()\n await Promise.all(\n [...this._clients.values()].map((sdk) =>\n sdk.getProtocolEra() === 'modern'\n ? sdk.discover(this._toSdkOptions(options))\n : sdk.ping(this._toSdkOptions(options)),\n ),\n )\n return true\n }\n\n // -------------------------------------------------------------------------\n // Tools\n // -------------------------------------------------------------------------\n\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listTools(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.tool?.timeout),\n )\n return (r.tools as Tool[]).map((t) => ({ ...t, name: `${name}_${t.name}` }))\n }),\n )\n return results.flat()\n }\n\n async callTool<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const raw = await this.callToolRaw<TData>(name, args, options)\n if (raw.isError) {\n const message =\n (raw.content as Array<{ type: string; text?: string }>)\n .filter((c) => c.type === 'text')\n .map((c) => c.text ?? '')\n .join('\\n') || 'Tool returned an error'\n throw new ToolCallError(message, raw.content)\n }\n return raw\n }\n\n async callToolRaw<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const { serverName, localName } = this._parseNamespacedName(name)\n const sdk = this._sdkForServer(serverName)\n const sdkOptions = this._toSdkOptions(\n options,\n options?.onProgress,\n this._defaultOptions.tool?.timeout,\n )\n const result = await sdk.callTool(\n { name: localName, arguments: args ?? {}, ...this._metaParamsFor(serverName) },\n sdkOptions,\n )\n return {\n content: result.content as ContentBlock[],\n structuredContent: (result.structuredContent as TData | undefined) ?? null,\n isError: result.isError === true,\n }\n }\n\n // -------------------------------------------------------------------------\n // Resources\n // -------------------------------------------------------------------------\n\n async listResources(options?: RequestOptions): Promise<Resource[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listResources(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n const resources = r.resources as Resource[]\n for (const res of resources) {\n this._uriMap.set(res.uri, name)\n }\n return resources.map((res) => ({\n ...res,\n name: res.name ? `${name}_${res.name}` : res.name,\n }))\n }),\n )\n return results.flat()\n }\n\n async listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listResourceTemplates(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n const templates = r.resourceTemplates as ResourceTemplate[]\n for (const tmpl of templates) {\n this._uriMap.set(tmpl.uriTemplate, name)\n }\n return templates.map((tmpl) => ({\n ...tmpl,\n name: tmpl.name ? `${name}_${tmpl.name}` : tmpl.name,\n }))\n }),\n )\n return results.flat()\n }\n\n async readResource(\n uri: string,\n options?: RequestOptions,\n ): Promise<Array<TextResourceContents | BlobResourceContents>> {\n this._assertConnected()\n const sdkOptions = this._toSdkOptions(\n options,\n undefined,\n this._defaultOptions.resource?.timeout,\n )\n\n // Fast path: URI was seen during a previous list call.\n const knownServer = this._uriMap.get(uri)\n if (knownServer) {\n const sdk = this._clients.get(knownServer)!\n const result = await sdk.readResource({ uri, ...this._metaParamsFor(knownServer) }, sdkOptions)\n return result.contents\n }\n\n // Fallback: try each server in order, return the first success.\n const errors: unknown[] = []\n for (const [name, sdk] of this._clients) {\n try {\n const result = await sdk.readResource({ uri, ...this._metaParamsFor(name) }, sdkOptions)\n return result.contents\n } catch (err) {\n errors.push(err)\n }\n }\n throw new Error(\n `Resource not found on any server: ${uri}\\n` +\n errors.map((e) => String(e)).join('\\n'),\n )\n }\n\n // -------------------------------------------------------------------------\n // Prompts\n // -------------------------------------------------------------------------\n\n async listPrompts(options?: RequestOptions): Promise<Prompt[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listPrompts(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n )\n return (r.prompts as Prompt[]).map((p) => ({ ...p, name: `${name}_${p.name}` }))\n }),\n )\n return results.flat()\n }\n\n async getPrompt(\n name: string,\n args?: Record<string, string>,\n options?: RequestOptions,\n ): Promise<GetPromptResult> {\n const { serverName, localName } = this._parseNamespacedName(name)\n const sdk = this._sdkForServer(serverName)\n const result = await sdk.getPrompt(\n { name: localName, arguments: args, ...this._metaParamsFor(serverName) },\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n )\n return result as GetPromptResult\n }\n\n // -------------------------------------------------------------------------\n // Resource subscriptions\n // -------------------------------------------------------------------------\n\n /** See Client.subscribeResource's docs — the same era-routing applies here,\n * per server, since each connected server negotiates its own era. */\n async subscribeResource(\n uri: string,\n handler: ResourceUpdateHandler,\n options?: RequestOptions,\n ): Promise<void> {\n this._assertConnected()\n this._resourceSubscriptions.set(uri, handler)\n const serverName = this._uriMap.get(uri)\n if (serverName) {\n const sdk = this._clients.get(serverName)!\n if (sdk.getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscriptionForServer(serverName)\n } else {\n await sdk.subscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n }\n return\n }\n // Fallback: the URI's owning server isn't known yet (listResources() was never\n // called). Only legacy-era servers can be probed this way — the validating\n // resources/subscribe RPC either succeeds (that server owns the URI) or throws;\n // listen() has no equivalent per-URI validation, so a modern-era server can't be\n // ruled in or out by trying it, and is skipped in this fallback.\n const errors: unknown[] = []\n for (const [name, sdk] of this._clients) {\n if (sdk.getProtocolEra() === 'modern') continue\n try {\n await sdk.subscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n this._uriMap.set(uri, name)\n return\n } catch (err) {\n errors.push(err)\n }\n }\n throw new Error(`Subscribe failed on all servers:\\n${errors.map(String).join('\\n')}`)\n }\n\n async unsubscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n this._assertConnected()\n this._resourceSubscriptions.delete(uri)\n const serverName = this._uriMap.get(uri)\n if (serverName) {\n const sdk = this._clients.get(serverName)!\n if (sdk.getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscriptionForServer(serverName)\n } else {\n await sdk.unsubscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n }\n return\n }\n await Promise.allSettled(\n [...this._clients.values()]\n .filter((sdk) => sdk.getProtocolEra() !== 'modern')\n .map((sdk) =>\n sdk.unsubscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n ),\n )\n }\n\n /** Re-opens server-scoped listen stream for its currently-subscribed URIs — see\n * Client's own private method of the same purpose for the full rationale. */\n private async _refreshResourceListenSubscriptionForServer(serverName: string): Promise<void> {\n const existing = this._resourceListenSubscriptions.get(serverName)\n if (existing) {\n await existing.close()\n this._resourceListenSubscriptions.delete(serverName)\n }\n const uris = [...this._resourceSubscriptions.keys()].filter(\n (uri) => this._uriMap.get(uri) === serverName,\n )\n if (uris.length === 0) return\n\n const sdk = this._clients.get(serverName)!\n const subscription = await sdk.listen({ resourceSubscriptions: uris })\n this._resourceListenSubscriptions.set(serverName, subscription)\n\n void subscription.closed.then((reason) => {\n if (reason === 'remote' && this._resourceListenSubscriptions.get(serverName) === subscription) {\n this._resourceListenSubscriptions.delete(serverName)\n void this._refreshResourceListenSubscriptionForServer(serverName).catch(() => {})\n }\n })\n }\n\n // -------------------------------------------------------------------------\n // Completion\n // -------------------------------------------------------------------------\n\n async complete(\n ref: { type: 'ref/prompt'; name: string } | { type: 'ref/resource'; uri: string },\n argument: { name: string; value: string },\n context?: { arguments?: Record<string, string> },\n options?: RequestOptions,\n ): Promise<CompletionResult> {\n this._assertConnected()\n const sdkOptions = this._toSdkOptions(options)\n\n if (ref.type === 'ref/prompt') {\n const { serverName, localName } = this._parseNamespacedName(ref.name)\n const sdk = this._sdkForServer(serverName)\n const result = await sdk.complete(\n {\n ref: { type: 'ref/prompt', name: localName },\n argument,\n ...(context ? { context } : {}),\n ...this._metaParamsFor(serverName),\n },\n sdkOptions,\n )\n return result.completion as CompletionResult\n }\n\n const serverName = this._uriMap.get(ref.uri)\n if (serverName) {\n const result = await this._clients.get(serverName)!.complete(\n { ref, argument, ...(context ? { context } : {}), ...this._metaParamsFor(serverName) },\n sdkOptions,\n )\n return result.completion as CompletionResult\n }\n\n const errors: unknown[] = []\n for (const [name, sdk] of this._clients) {\n try {\n const result = await sdk.complete(\n { ref, argument, ...(context ? { context } : {}), ...this._metaParamsFor(name) },\n sdkOptions,\n )\n return result.completion as CompletionResult\n } catch (err) {\n errors.push(err)\n }\n }\n throw new Error(`Completion failed on all servers:\\n${errors.map(String).join('\\n')}`)\n }\n\n // -------------------------------------------------------------------------\n // Logging\n // -------------------------------------------------------------------------\n\n /** See Client.setLogLevel's docs — the same era-routing applies here, per\n * server: legacy sends the real `logging/setLevel` RPC; modern records the\n * level and threads it into `_meta` on that server's subsequent requests via\n * `_metaParamsFor`, since `logging/setLevel` is absent from the modern wire\n * registry (SEP-2577). */\n async setLogLevel(level: LoggingLevel, options?: RequestOptions): Promise<void> {\n this._assertConnected()\n await Promise.all(\n [...this._clients.entries()].map(([name, sdk]) => {\n if (sdk.getProtocolEra() === 'modern') {\n this._logLevels.set(name, level)\n return undefined\n }\n return sdk.setLoggingLevel(level, this._toSdkOptions(options))\n }),\n )\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private _assertConnected(): void {\n if (!this._connected) {\n throw new Error('MultiServerClient is not connected. Call connect() first.')\n }\n }\n\n private _parseNamespacedName(name: string): { serverName: string; localName: string } {\n // Sort longest-first so that server names like \"my_server\" are matched\n // before the shorter prefix \"my\".\n const serverNames = [...this._clients.keys()].sort((a, b) => b.length - a.length)\n for (const serverName of serverNames) {\n const prefix = `${serverName}_`\n if (name.startsWith(prefix)) {\n return { serverName, localName: name.slice(prefix.length) }\n }\n }\n throw new Error(\n `Tool/prompt name \"${name}\" has no server namespace prefix. ` +\n `Expected format: \"<serverName>_<name>\".`,\n )\n }\n\n private _sdkForServer(serverName: string): SdkClient {\n const sdk = this._clients.get(serverName)\n if (!sdk) {\n throw new Error(\n `No server named \"${serverName}\" in this MultiServerClient. ` +\n `Known servers: ${[...this._clients.keys()].join(', ')}.`,\n )\n }\n return sdk\n }\n\n private _buildSdkClient(): SdkClient {\n return new SdkClient(\n { name: 'fastmcp-ts', version: '1.0.0' },\n {\n capabilities: this._buildCapabilities(),\n ...(this._versionNegotiation ? { versionNegotiation: this._versionNegotiation } : {}),\n },\n )\n }\n\n private _buildCapabilities() {\n return {\n ...(this._handlers.sampling ? { sampling: { tools: {} } } : {}),\n ...(this._handlers.elicitation ? { elicitation: {} } : {}),\n ...(this._roots ? { roots: { listChanged: false } } : {}),\n }\n }\n\n private _registerHandlers(sdk: SdkClient): void {\n sdk.setNotificationHandler('notifications/message', (notification) => {\n void this._handlers.log({\n level: notification.params.level,\n logger: notification.params.logger ?? undefined,\n data: notification.params.data,\n })\n })\n\n sdk.setNotificationHandler('notifications/resources/updated', (notification) => {\n const handler = this._resourceSubscriptions.get(notification.params.uri)\n if (handler) void handler(notification.params.uri)\n })\n\n if (this._handlers.sampling) {\n const h = this._handlers.sampling\n sdk.setRequestHandler('sampling/createMessage', async (req) => h(req.params))\n }\n\n if (this._handlers.elicitation) {\n const h = this._handlers.elicitation\n sdk.setRequestHandler('elicitation/create', async (req) => h(req.params))\n }\n\n if (this._roots) {\n const roots = this._roots\n sdk.setRequestHandler('roots/list', async () => ({\n roots: roots.map((uri) => ({ uri })),\n }))\n }\n }\n\n /** See Client._metaParams's docs — the same purpose, per server name, since\n * each connected server may be on a different era and have a different\n * recorded log level (or none). */\n private _metaParamsFor(serverName: string): { _meta: Record<string, unknown> } | undefined {\n const level = this._logLevels.get(serverName)\n if (level === undefined) return undefined\n return { _meta: { [LOG_LEVEL_META_KEY]: level } }\n }\n\n private _toSdkOptions(\n options?: RequestOptions,\n overrideProgress?: ProgressHandler,\n scopedTimeoutSeconds?: number,\n ): SdkRequestOptions {\n const timeoutSeconds =\n options?.timeout ?? scopedTimeoutSeconds ?? this._defaultOptions.timeout\n const progressHandler = overrideProgress ?? this._handlers.progress\n\n const sdkOptions: SdkRequestOptions = {}\n if (timeoutSeconds != null) sdkOptions.timeout = timeoutSeconds * 1000\n if (options?.signal) sdkOptions.signal = options.signal\n if (progressHandler) {\n sdkOptions.onprogress = ({ progress, total, message }) => {\n void progressHandler(progress, total, message)\n }\n }\n return sdkOptions\n }\n}\n","export type Result<T, E = Error> =\n | { ok: true; value: T }\n | { ok: false; error: E }\n\nexport async function toResult<T, E = Error>(\n fn: Promise<T> | (() => Promise<T>),\n): Promise<Result<T, E>> {\n try {\n const value = await (typeof fn === 'function' ? fn() : fn)\n return { ok: true, value }\n } catch (error) {\n return { ok: false, error: error as E }\n }\n}\n","import type { ModelPreferences } from \"@modelcontextprotocol/server\";\nimport type { SamplingHandler } from '../handlers.js'\n\nexport type { SamplingHandler }\n\n/**\n * Resolve a concrete model name from the server's modelPreferences.\n * A plain string always uses that model; a function inspects the preferences.\n */\nexport type ModelSelector = string | ((prefs: ModelPreferences | undefined) => string)\n\n/** Called with each text token as it is streamed from the provider. */\nexport type OnTokenCallback = (token: string) => void\n\nexport interface SamplingAdapterOptions {\n /** Override or replace the model selection logic. */\n modelSelector?: ModelSelector\n /** Fired for each streamed text token. Tool-use deltas are not surfaced. */\n onToken?: OnTokenCallback\n}\n\n/** Implemented by all sampling adapters. */\nexport interface SamplingAdapter {\n asHandler(): SamplingHandler\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\nexport function resolveModel(\n prefs: ModelPreferences | undefined,\n selector: ModelSelector | undefined,\n defaultModel: string,\n): string {\n if (!selector) {\n return prefs?.hints?.[0]?.name ?? defaultModel\n }\n if (typeof selector === 'string') return selector\n return selector(prefs)\n}\n","import type { SamplingMessage, Tool, ToolChoice, CreateMessageRequestParams } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingAdapter, SamplingAdapterOptions, ModelSelector, OnTokenCallback } from './types.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport { resolveModel } from './types.js'\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface GenericCompletionParams {\n model: string\n messages: SamplingMessage[]\n system?: string\n /** Defaulted to 1024 when absent in the original request. */\n maxTokens: number\n temperature?: number\n stopSequences?: string[]\n tools?: Tool[]\n toolChoice?: ToolChoice\n onToken?: OnTokenCallback\n}\n\nexport type GenericCompletionFn = (\n params: GenericCompletionParams,\n) => Promise<AnySamplingResult>\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\n/**\n * Contribution template. Wraps any async function into a SamplingHandler.\n *\n * The adapter resolves the model from modelPreferences, defaults maxTokens,\n * and threads onToken through. Message format conversion, tool translation,\n * and streaming are the caller's responsibility.\n *\n * Example:\n * ```ts\n * const adapter = new GenericSamplingAdapter(async ({ model, messages }) => {\n * const text = await myLlm.complete(model, messages)\n * return { role: 'assistant', content: { type: 'text', text }, model, stopReason: 'endTurn' }\n * })\n * ```\n */\nexport class GenericSamplingAdapter implements SamplingAdapter {\n private readonly _fn: GenericCompletionFn\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n fn: GenericCompletionFn,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._fn = fn\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'unknown',\n )\n return this._fn({\n model,\n messages: params.messages,\n system: params.systemPrompt,\n maxTokens: params.maxTokens ?? 1024,\n temperature: params.temperature,\n stopSequences: params.stopSequences,\n tools: params.tools,\n toolChoice: params.toolChoice,\n onToken: this._options.onToken,\n })\n }\n }\n}\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type {\n ContentBlockParam,\n ToolResultBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type { CreateMessageRequestParams, SamplingMessage, Tool, ToolChoice, ToolUseContent } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport type { SamplingAdapter, SamplingAdapterOptions } from './types.js'\nimport { resolveModel } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Message translation\n// ---------------------------------------------------------------------------\n\nfunction toBlocks(content: SamplingMessage['content']): ContentBlockParam[] {\n const items = Array.isArray(content) ? content : [content]\n const out: ContentBlockParam[] = []\n\n for (const block of items) {\n if (block.type === 'text') {\n out.push({ type: 'text', text: block.text })\n } else if (block.type === 'image') {\n out.push({\n type: 'image',\n source: {\n type: 'base64',\n media_type: block.mimeType as Anthropic.Base64ImageSource['media_type'],\n data: block.data,\n },\n })\n } else if (block.type === 'tool_use') {\n out.push({\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input as Record<string, unknown>,\n })\n } else if (block.type === 'tool_result') {\n const resultContent: ToolResultBlockParam['content'] = block.content.flatMap((c) =>\n c.type === 'text' ? [{ type: 'text' as const, text: c.text }] : [],\n )\n out.push({\n type: 'tool_result',\n tool_use_id: block.toolUseId,\n content: resultContent,\n is_error: block.isError,\n })\n }\n // audio: not supported by Anthropic messages API — skip\n }\n return out\n}\n\nfunction toAnthropicMessages(messages: SamplingMessage[]): Anthropic.MessageParam[] {\n return messages.map((m) => ({\n role: m.role as 'user' | 'assistant',\n content: toBlocks(m.content),\n }))\n}\n\nfunction toAnthropicTools(tools: Tool[]): Anthropic.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n input_schema: t.inputSchema as Anthropic.Tool['input_schema'],\n }))\n}\n\nfunction toAnthropicToolChoice(\n choice: ToolChoice | undefined,\n): Anthropic.MessageCreateParams['tool_choice'] {\n if (!choice) return undefined\n if (choice.mode === 'required') return { type: 'any' }\n return { type: 'auto' }\n}\n\n// ---------------------------------------------------------------------------\n// Response mapping\n// ---------------------------------------------------------------------------\n\nfunction mapStopReason(reason: string | null | undefined): string {\n if (reason === 'end_turn') return 'endTurn'\n if (reason === 'stop_sequence') return 'stopSequence'\n if (reason === 'max_tokens') return 'maxTokens'\n if (reason === 'tool_use') return 'toolUse'\n return reason ?? 'endTurn'\n}\n\nfunction buildResult(message: Anthropic.Message): AnySamplingResult {\n const stopReason = mapStopReason(message.stop_reason)\n\n if (stopReason === 'toolUse') {\n const content = message.content.flatMap((block): ToolUseContent[] => {\n if (block.type === 'tool_use') {\n return [{\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input as Record<string, unknown>,\n }]\n }\n return []\n })\n return { role: 'assistant', model: message.model, stopReason, content }\n }\n\n const textBlock = message.content.find((b) => b.type === 'text')\n const text = textBlock?.type === 'text' ? textBlock.text : ''\n return { role: 'assistant', model: message.model, stopReason, content: { type: 'text', text } }\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport class AnthropicSamplingAdapter implements SamplingAdapter {\n private readonly _client: Anthropic\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n client: Anthropic,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._client = client\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'claude-opus-4-5',\n )\n\n const omitTools = params.toolChoice?.mode === 'none'\n const tools = !omitTools && params.tools?.length\n ? toAnthropicTools(params.tools)\n : undefined\n const toolChoice = tools ? toAnthropicToolChoice(params.toolChoice) : undefined\n const onToken = this._options.onToken\n\n const stream = this._client.messages.stream({\n model,\n messages: toAnthropicMessages(params.messages),\n max_tokens: params.maxTokens ?? 1024,\n ...(params.systemPrompt !== undefined ? { system: params.systemPrompt } : {}),\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences?.length ? { stop_sequences: params.stopSequences } : {}),\n ...(tools ? { tools } : {}),\n ...(toolChoice ? { tool_choice: toolChoice } : {}),\n })\n\n if (onToken) {\n stream.on('text', (text) => { onToken(text) })\n }\n\n const message = await stream.finalMessage()\n return buildResult(message)\n }\n }\n}\n","import type OpenAI from 'openai'\nimport type { CreateMessageRequestParams, SamplingMessage, Tool, ToolChoice, ToolUseContent } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport type { SamplingAdapter, SamplingAdapterOptions } from './types.js'\nimport { resolveModel } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Message translation\n// ---------------------------------------------------------------------------\n\ntype OAIMessage = OpenAI.Chat.ChatCompletionMessageParam\n\nfunction toContentParts(\n content: SamplingMessage['content'],\n): string | OpenAI.Chat.ChatCompletionContentPart[] {\n const items = Array.isArray(content) ? content : [content]\n // Collapse single text block to a plain string for simplicity\n if (items.length === 1 && items[0].type === 'text') return items[0].text\n\n return items.flatMap((block): OpenAI.Chat.ChatCompletionContentPart[] => {\n if (block.type === 'text') {\n return [{ type: 'text', text: block.text }]\n } else if (block.type === 'image') {\n return [{\n type: 'image_url',\n image_url: { url: `data:${block.mimeType};base64,${block.data}` },\n }]\n }\n return []\n })\n}\n\nfunction toOpenAIMessages(\n messages: SamplingMessage[],\n systemPrompt: string | undefined,\n): OAIMessage[] {\n const out: OAIMessage[] = []\n\n if (systemPrompt) {\n out.push({ role: 'system', content: systemPrompt })\n }\n\n for (const m of messages) {\n const items = Array.isArray(m.content) ? m.content : [m.content]\n\n // tool_use blocks → assistant message with tool_calls\n const toolUseItems = items.filter((b) => b.type === 'tool_use')\n if (toolUseItems.length > 0) {\n out.push({\n role: 'assistant',\n tool_calls: toolUseItems.map((b) => {\n if (b.type !== 'tool_use') throw new Error('unreachable')\n return {\n id: b.id,\n type: 'function' as const,\n function: { name: b.name, arguments: JSON.stringify(b.input) },\n }\n }),\n })\n continue\n }\n\n // tool_result blocks → tool messages\n const toolResultItems = items.filter((b) => b.type === 'tool_result')\n if (toolResultItems.length > 0) {\n for (const b of toolResultItems) {\n if (b.type !== 'tool_result') continue\n const text = b.content\n .filter((c) => c.type === 'text')\n .map((c) => (c.type === 'text' ? c.text : ''))\n .join('\\n')\n out.push({ role: 'tool', tool_call_id: b.toolUseId, content: text })\n }\n continue\n }\n\n const role = m.role as 'user' | 'assistant'\n const content = toContentParts(m.content)\n if (role === 'user') {\n out.push({ role, content: content as OpenAI.Chat.ChatCompletionUserMessageParam['content'] })\n } else {\n out.push({ role, content: typeof content === 'string' ? content : '' })\n }\n }\n\n return out\n}\n\nfunction toOpenAITools(tools: Tool[]): OpenAI.Chat.ChatCompletionTool[] {\n return tools.map((t) => ({\n type: 'function' as const,\n function: {\n name: t.name,\n ...(t.description ? { description: t.description } : {}),\n parameters: t.inputSchema as OpenAI.FunctionParameters,\n },\n }))\n}\n\nfunction toOpenAIToolChoice(\n choice: ToolChoice | undefined,\n): OpenAI.Chat.ChatCompletionToolChoiceOption | undefined {\n if (!choice) return undefined\n if (choice.mode === 'required') return 'required'\n if (choice.mode === 'none') return 'none'\n return 'auto'\n}\n\n// ---------------------------------------------------------------------------\n// Response mapping\n// ---------------------------------------------------------------------------\n\nfunction mapFinishReason(reason: string | null | undefined): string {\n if (reason === 'stop') return 'endTurn'\n if (reason === 'length') return 'maxTokens'\n if (reason === 'tool_calls') return 'toolUse'\n return 'endTurn'\n}\n\nfunction buildResult(completion: OpenAI.Chat.ChatCompletion): AnySamplingResult {\n const choice = completion.choices[0]\n const stopReason = mapFinishReason(choice?.finish_reason)\n const model = completion.model\n\n if (stopReason === 'toolUse') {\n const calls = choice.message.tool_calls ?? []\n const content: ToolUseContent[] = calls.flatMap((tc) => {\n // tc is ChatCompletionMessageToolCall (union); filter to function type\n if (tc.type !== 'function') return []\n const fn = (tc as { type: 'function'; id: string; function: { name: string; arguments: string } }).function\n return [{\n type: 'tool_use' as const,\n id: tc.id,\n name: fn.name,\n input: JSON.parse(fn.arguments) as Record<string, unknown>,\n }]\n })\n return { role: 'assistant', model, stopReason, content }\n }\n\n const text = choice.message.content ?? ''\n return { role: 'assistant', model, stopReason, content: { type: 'text', text } }\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport class OpenAISamplingAdapter implements SamplingAdapter {\n private readonly _client: OpenAI\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n client: OpenAI,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._client = client\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'gpt-4o',\n )\n\n const omitTools = params.toolChoice?.mode === 'none'\n const tools = !omitTools && params.tools?.length\n ? toOpenAITools(params.tools)\n : undefined\n const toolChoice = tools ? toOpenAIToolChoice(params.toolChoice) : undefined\n const onToken = this._options.onToken\n\n const stream = this._client.chat.completions.stream({\n model,\n messages: toOpenAIMessages(params.messages, params.systemPrompt),\n max_completion_tokens: params.maxTokens ?? 1024,\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences?.length ? { stop: params.stopSequences } : {}),\n ...(tools ? { tools } : {}),\n ...(toolChoice !== undefined ? { tool_choice: toolChoice } : {}),\n })\n\n if (onToken) {\n stream.on('content', (delta) => { onToken(delta) })\n }\n\n const completion = await stream.finalChatCompletion()\n return buildResult(completion)\n }\n }\n}\n","import type { GoogleGenAI } from '@google/genai'\nimport type {\n GenerateContentConfig,\n GenerateContentResponse,\n} from '@google/genai'\nimport type { CreateMessageRequestParams, SamplingMessage, Tool, ToolChoice, ToolUseContent } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport type { SamplingAdapter, SamplingAdapterOptions } from './types.js'\nimport { resolveModel } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Title pruning\n// ---------------------------------------------------------------------------\n\n/**\n * Removes 'title' from all property definitions in a JSON Schema object.\n * Gemini emits MALFORMED_FUNCTION_CALL when property titles are present.\n */\nfunction pruneTitle(schema: Record<string, unknown>): Record<string, unknown> {\n const { title: _dropped, ...rest } = schema\n if (rest.properties && typeof rest.properties === 'object') {\n rest.properties = Object.fromEntries(\n Object.entries(rest.properties as Record<string, unknown>).map(([k, v]) => [\n k,\n pruneTitle(v as Record<string, unknown>),\n ]),\n )\n }\n return rest\n}\n\n// ---------------------------------------------------------------------------\n// Message translation\n// ---------------------------------------------------------------------------\n\nfunction toGeminiRole(role: 'user' | 'assistant'): 'user' | 'model' {\n return role === 'assistant' ? 'model' : 'user'\n}\n\n/** Build an id→name map from prior tool_use blocks so tool_result can reference by name. */\nfunction buildToolNameMap(messages: SamplingMessage[]): Map<string, string> {\n const map = new Map<string, string>()\n for (const m of messages) {\n const items = Array.isArray(m.content) ? m.content : [m.content]\n for (const b of items) {\n if (b.type === 'tool_use') map.set(b.id, b.name)\n }\n }\n return map\n}\n\nfunction toGeminiContents(\n messages: SamplingMessage[],\n toolNameById: Map<string, string>,\n): object[] {\n return messages.map((m) => {\n const items = Array.isArray(m.content) ? m.content : [m.content]\n const parts = items.flatMap((block): object[] => {\n if (block.type === 'text') {\n return [{ text: block.text }]\n } else if (block.type === 'image') {\n return [{ inlineData: { data: block.data, mimeType: block.mimeType } }]\n } else if (block.type === 'tool_use') {\n return [{ functionCall: { name: block.name, args: block.input } }]\n } else if (block.type === 'tool_result') {\n const name = toolNameById.get(block.toolUseId) ?? block.toolUseId\n const text = block.content\n .filter((c) => c.type === 'text')\n .map((c) => (c.type === 'text' ? c.text : ''))\n .join('\\n')\n return [{ functionResponse: { name, response: { content: text } } }]\n }\n return []\n })\n return { role: toGeminiRole(m.role as 'user' | 'assistant'), parts }\n })\n}\n\nfunction toGeminiFunctionDeclarations(tools: Tool[]): object[] {\n return tools.map((t) => ({\n name: t.name,\n ...(t.description ? { description: t.description } : {}),\n parameters: pruneTitle(t.inputSchema as Record<string, unknown>),\n }))\n}\n\nfunction toGeminiToolConfig(choice: ToolChoice | undefined): object | undefined {\n if (!choice) return undefined\n const mode =\n choice.mode === 'required' ? 'ANY' :\n choice.mode === 'none' ? 'NONE' :\n 'AUTO'\n return { functionCallingConfig: { mode } }\n}\n\n// ---------------------------------------------------------------------------\n// Response mapping\n// ---------------------------------------------------------------------------\n\nfunction buildResult(response: GenerateContentResponse, model: string): AnySamplingResult {\n const functionCalls = response.functionCalls\n\n if (functionCalls?.length) {\n const content: ToolUseContent[] = functionCalls.map((fc, i) => ({\n type: 'tool_use' as const,\n id: fc.id ?? `tool-${i}`,\n name: fc.name ?? '',\n input: (fc.args ?? {}) as Record<string, unknown>,\n }))\n return { role: 'assistant', model, stopReason: 'toolUse', content }\n }\n\n const candidate = response.candidates?.[0]\n const finishReason = candidate?.finishReason\n const stopReason =\n finishReason === 'MAX_TOKENS' ? 'maxTokens' :\n 'endTurn'\n\n const text = response.text ?? ''\n return { role: 'assistant', model, stopReason, content: { type: 'text', text } }\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport class GoogleSamplingAdapter implements SamplingAdapter {\n private readonly _client: GoogleGenAI\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n client: GoogleGenAI,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._client = client\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'gemini-2.0-flash',\n )\n\n const toolNameById = buildToolNameMap(params.messages)\n const contents = toGeminiContents(params.messages, toolNameById)\n const onToken = this._options.onToken\n\n const omitTools = params.toolChoice?.mode === 'none'\n const functionDeclarations = !omitTools && params.tools?.length\n ? toGeminiFunctionDeclarations(params.tools)\n : undefined\n const toolConfig = !omitTools ? toGeminiToolConfig(params.toolChoice) : undefined\n\n const config: GenerateContentConfig = {\n maxOutputTokens: params.maxTokens ?? 1024,\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences?.length ? { stopSequences: params.stopSequences } : {}),\n ...(params.systemPrompt\n ? { systemInstruction: { parts: [{ text: params.systemPrompt }] } }\n : {}),\n ...(functionDeclarations ? { tools: [{ functionDeclarations }] } : {}),\n ...(toolConfig ? { toolConfig } : {}),\n }\n\n const stream = await this._client.models.generateContentStream({\n model,\n contents: contents as Parameters<typeof this._client.models.generateContentStream>[0]['contents'],\n config,\n })\n\n let lastChunk: GenerateContentResponse | undefined\n for await (const chunk of stream) {\n lastChunk = chunk\n if (onToken) {\n const text = chunk.text\n if (text) onToken(text)\n }\n }\n\n return buildResult(lastChunk!, model)\n }\n }\n}\n"],"mappings":"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","names":["SdkClient","LOG_LEVEL_META_KEY","serverName","SdkClient","LOG_LEVEL_META_KEY","buildResult","buildResult"]}
|
|
1
|
+
{"version":3,"sources":["../src/client/handlers.ts","../src/client/auth.ts","../src/client/browser-stores.ts","../src/client/browser-oauth.ts","../src/client/transports.ts","../src/client/client.ts","../src/client/capabilities.ts","../src/client/multi-server.ts","../src/client/utils.ts","../src/client/sampling/types.ts","../src/client/sampling/generic.ts","../src/client/sampling/anthropic.ts","../src/client/sampling/openai.ts","../src/client/sampling/google.ts"],"sourcesContent":["import type { LoggingLevel, CreateMessageRequestParams, ElicitRequestParams, ElicitResult, Tool, Resource, Prompt } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from './results.js'\n\nexport type LogMessage = {\n level: LoggingLevel\n logger?: string\n data: unknown\n}\n\nexport type LogHandler = (message: LogMessage) => void | Promise<void>\n\nexport type ProgressHandler = (\n progress: number,\n total?: number,\n message?: string,\n) => void | Promise<void>\n\nexport type SamplingHandler = (\n params: CreateMessageRequestParams,\n) => AnySamplingResult | Promise<AnySamplingResult>\n\nexport type ElicitationHandler = (\n params: ElicitRequestParams,\n) => ElicitResult | Promise<ElicitResult>\n\nexport type ResourceUpdateHandler = (uri: string) => void | Promise<void>\n\n/**\n * Config for receiving server-initiated list-change notifications.\n * Set debounceMs: 0 in tests for instant delivery.\n */\nexport type ListChangedHandler<T> = {\n onChanged: (error: Error | null, items: T[] | null) => void | Promise<void>\n /** Whether to auto-fetch the updated list before calling onChanged. Default: true. */\n autoRefresh?: boolean\n /** Debounce window in ms. Default: 300. Set to 0 to disable. */\n debounceMs?: number\n}\n\nexport interface ClientHandlers {\n log?: LogHandler\n progress?: ProgressHandler\n sampling?: SamplingHandler\n elicitation?: ElicitationHandler\n onToolsListChanged?: ListChangedHandler<Tool>\n onResourcesListChanged?: ListChangedHandler<Resource>\n onPromptsListChanged?: ListChangedHandler<Prompt>\n}\n\nexport function defaultLogHandler(message: LogMessage): void {\n const prefix = message.logger ? `[${message.logger}]` : '[server]'\n const data =\n typeof message.data === 'string' ? message.data : JSON.stringify(message.data)\n const text = `${prefix} ${data}`\n const level = message.level\n if (level === 'debug') {\n console.debug(text)\n } else if (level === 'warning') {\n console.warn(text)\n } else if (\n level === 'error' ||\n level === 'critical' ||\n level === 'alert' ||\n level === 'emergency'\n ) {\n console.error(text)\n } else {\n console.info(text)\n }\n}\n\nexport function defaultProgressHandler(\n progress: number,\n total?: number,\n message?: string,\n): void {\n const pct = total != null ? ` (${Math.round((progress / total) * 100)}%)` : ''\n const msg = message ? ` — ${message}` : ''\n console.debug(\n `progress: ${progress}${total != null ? `/${total}` : ''}${pct}${msg}`,\n )\n}\n","import {\n validateClientMetadataUrl,\n createPrivateKeyJwtAuth,\n requestJwtAuthorizationGrant,\n exchangeJwtAuthGrant,\n type OAuthClientProvider,\n type OAuthClientInformationContext,\n type OAuthDiscoveryState,\n type OAuthClientMetadata,\n type StoredOAuthClientInformation,\n type StoredOAuthTokens,\n type AddClientAuthentication,\n type ClientAuthMethod,\n} from \"@modelcontextprotocol/client\";\n\n// ---------------------------------------------------------------------------\n// OAuthToken — internal type used by ClientCredentials for expiry tracking.\n// Not the SDK's OAuthTokens: we track expires_at in milliseconds.\n// ---------------------------------------------------------------------------\n\nexport type OAuthToken = {\n access_token: string\n token_type?: string\n refresh_token?: string\n /** Unix timestamp in milliseconds (normalized internally). */\n expires_at?: number\n /** Seconds until expiry — used to compute expires_at on receipt. */\n expires_in?: number\n scope?: string\n}\n\n// ---------------------------------------------------------------------------\n// AsyncHeaderAuth — the shape of a token-acquiring auth provider\n// ---------------------------------------------------------------------------\n\n/**\n * An auth provider that acquires a token asynchronously and injects it as a\n * request header per request. {@link ClientCredentials}, {@link JwtBearerAuth},\n * and {@link EnterpriseManagedAuth} all implement it. The transport recognizes\n * these by their `kind` discriminant and injects `getHeaders()` on every\n * request via a custom fetch wrapper (unlike static `BearerAuth`, whose header\n * never changes, or interactive `OAuth`, which the SDK transport drives itself).\n */\nexport interface AsyncHeaderAuth {\n readonly kind: string\n getHeaders(): Promise<Record<string, string>>\n}\n\n// ---------------------------------------------------------------------------\n// KeyValueStore — single persistence interface for all auth state\n// ---------------------------------------------------------------------------\n\nexport type KeyValueStore = {\n get(key: string): Promise<string | null>\n set(key: string, value: string): Promise<void>\n delete(key: string): Promise<void>\n}\n\n// ---------------------------------------------------------------------------\n// InMemoryStore\n// ---------------------------------------------------------------------------\n\nexport class InMemoryStore implements KeyValueStore {\n private readonly _map = new Map<string, string>()\n\n async get(key: string): Promise<string | null> {\n return this._map.get(key) ?? null\n }\n\n async set(key: string, value: string): Promise<void> {\n this._map.set(key, value)\n }\n\n async delete(key: string): Promise<void> {\n this._map.delete(key)\n }\n}\n\n// ---------------------------------------------------------------------------\n// FileTokenStorage\n// ---------------------------------------------------------------------------\n\nexport class FileTokenStorage implements KeyValueStore {\n private readonly _explicitPath?: string\n private _resolvedPath?: string\n\n constructor(path?: string) {\n this._explicitPath = path\n }\n\n private async _path(): Promise<string> {\n if (this._resolvedPath) return this._resolvedPath\n if (this._explicitPath) return (this._resolvedPath = this._explicitPath)\n const { homedir } = await import('os')\n const { join } = await import('path')\n return (this._resolvedPath = join(homedir(), '.fastmcp', 'tokens.json'))\n }\n\n private async _readAll(): Promise<Record<string, string>> {\n const fs = await import('fs/promises')\n try {\n const raw = await fs.readFile(await this._path(), 'utf8')\n const parsed: unknown = JSON.parse(raw)\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n return parsed as Record<string, string>\n }\n return {}\n } catch {\n return {}\n }\n }\n\n private async _writeAll(data: Record<string, string>): Promise<void> {\n const fs = await import('fs/promises')\n const { dirname } = await import('path')\n const path = await this._path()\n await fs.mkdir(dirname(path), { recursive: true })\n const tmp = `${path}.tmp`\n await fs.writeFile(tmp, JSON.stringify(data, null, 2), 'utf8')\n await fs.rename(tmp, path)\n }\n\n async get(key: string): Promise<string | null> {\n const data = await this._readAll()\n return data[key] ?? null\n }\n\n async set(key: string, value: string): Promise<void> {\n const data = await this._readAll()\n data[key] = value\n await this._writeAll(data)\n }\n\n async delete(key: string): Promise<void> {\n const data = await this._readAll()\n if (!(key in data)) return\n delete data[key]\n await this._writeAll(data)\n }\n}\n\n// ---------------------------------------------------------------------------\n// OAuth — implements OAuthClientProvider (authorization code + PKCE flow)\n// ---------------------------------------------------------------------------\n\nexport interface OAuthOptions {\n /** Pre-registered client ID. When set, Dynamic Client Registration is skipped. */\n clientId?: string\n /** Pre-registered client secret. */\n clientSecret?: string\n /** Requested OAuth scopes (space-separated string or array). */\n scopes?: string | string[]\n /** Client name used in Dynamic Client Registration. Default: \"FastMCP Client\". */\n clientName?: string\n /** Persistent key-value store for tokens, client info, and discovery state. Default: in-memory. */\n store?: KeyValueStore\n /**\n * Port for the local OAuth callback server. Default: 8765.\n * The port must be consistent across calls because it is registered as the\n * redirect_uri during Dynamic Client Registration.\n */\n callbackPort?: number\n /**\n * Override how the authorization URL is opened. When not provided the\n * system browser is launched. Inject a no-op or mock here for testing.\n */\n onRedirect?: (url: URL) => void | Promise<void>\n /**\n * Client ID Metadata Document URL (SEP-991 / CIMD) — an HTTPS URL, with a\n * non-root path, that serves this client's metadata document. When the\n * authorization server advertises `client_id_metadata_document_supported`,\n * the SDK's `auth()` orchestrator uses this URL directly as the `client_id`\n * and skips Dynamic Client Registration entirely. Falls back to normal DCR\n * (or `clientId`, if set) when the server doesn't support CIMD. Validated\n * eagerly in the constructor.\n */\n clientMetadataUrl?: string\n}\n\nexport class OAuth implements OAuthClientProvider {\n private _serverUrl = ''\n private readonly _clientId?: string\n private readonly _clientSecret?: string\n private readonly _scopes?: string\n private readonly _clientName: string\n private readonly _store: KeyValueStore\n private readonly _callbackPort: number\n private readonly _onRedirect?: (url: URL) => void | Promise<void>\n readonly clientMetadataUrl?: string\n\n private _codeVerifier: string | undefined\n protected _callbackPromise: Promise<URLSearchParams> | null = null\n protected _callbackResolve: ((params: URLSearchParams) => void) | null = null\n protected _callbackReject: ((err: Error) => void) | null = null\n private _callbackServer: { close(): void } | null = null\n private _actualCallbackPort: number | null = null\n\n constructor(options: OAuthOptions = {}) {\n this._clientId = options.clientId\n this._clientSecret = options.clientSecret\n this._scopes = Array.isArray(options.scopes)\n ? options.scopes.join(' ')\n : options.scopes\n this._clientName = options.clientName ?? 'FastMCP Client'\n this._store = options.store ?? new InMemoryStore()\n this._callbackPort = options.callbackPort ?? 8765\n this._onRedirect = options.onRedirect\n // SEP-991: validated eagerly so a malformed clientMetadataUrl fails fast\n // at construction rather than deep inside the auth() flow.\n validateClientMetadataUrl(options.clientMetadataUrl)\n this.clientMetadataUrl = options.clientMetadataUrl\n }\n\n /**\n * Binds the MCP server URL so that all storage keys are namespaced by it.\n * Called by Client before connecting.\n */\n _bind(serverUrl: string): void {\n this._serverUrl = serverUrl\n }\n\n // ---- OAuthClientProvider interface ----\n\n get redirectUrl(): string | URL {\n const port = this._actualCallbackPort ?? this._callbackPort\n return `http://localhost:${port}/callback`\n }\n\n get clientMetadata(): OAuthClientMetadata {\n const port = this._actualCallbackPort ?? this._callbackPort\n return {\n redirect_uris: [`http://localhost:${port}/callback`],\n token_endpoint_auth_method: this._clientSecret ? 'client_secret_post' : 'none',\n // grant_types is intentionally omitted: the SDK's resolveClientMetadata()\n // defaults interactive providers (those with a redirectUrl, like this one)\n // to ['authorization_code', 'refresh_token'] (SEP-2207) — authorization\n // servers that gate refresh-token issuance on the registered grant types\n // need 'refresh_token' present to ever issue one during DCR. Setting this\n // explicitly here would suppress that default (an explicit field is never\n // overwritten) and could silently prevent refresh tokens from being\n // issued, even though this class fully supports using one once present.\n response_types: ['code'],\n client_name: this._clientName,\n ...(this._scopes ? { scope: this._scopes } : {}),\n }\n }\n\n async clientInformation(\n ctx?: OAuthClientInformationContext,\n ): Promise<StoredOAuthClientInformation | undefined> {\n if (this._clientId) {\n return {\n client_id: this._clientId,\n ...(this._clientSecret ? { client_secret: this._clientSecret } : {}),\n }\n }\n const issuer = ctx?.issuer ?? (await this._lastIssuer())\n const raw = await this._store.get(this._key('client_info', issuer))\n if (!raw) return undefined\n return JSON.parse(raw) as StoredOAuthClientInformation\n }\n\n async saveClientInformation(\n info: StoredOAuthClientInformation,\n ctx?: OAuthClientInformationContext,\n ): Promise<void> {\n if (this._clientId) return // pre-registered — never overwrite with DCR response\n if (ctx?.issuer) await this._rememberIssuer(ctx.issuer)\n await this._store.set(this._key('client_info', ctx?.issuer), JSON.stringify(info))\n }\n\n async tokens(ctx?: OAuthClientInformationContext): Promise<StoredOAuthTokens | undefined> {\n // Per SEP-2352: the per-request bearer-token read (adaptOAuthProvider's\n // token() bridge) calls this with no ctx at all, so it must resolve the\n // most-recently-saved token set rather than returning undefined.\n const issuer = ctx?.issuer ?? (await this._lastIssuer())\n const raw = await this._store.get(this._key('tokens', issuer))\n if (!raw) return undefined\n return JSON.parse(raw) as StoredOAuthTokens\n }\n\n async saveTokens(tokens: StoredOAuthTokens, ctx?: OAuthClientInformationContext): Promise<void> {\n if (ctx?.issuer) await this._rememberIssuer(ctx.issuer)\n await this._store.set(this._key('tokens', ctx?.issuer), JSON.stringify(tokens))\n }\n\n async redirectToAuthorization(authorizationUrl: URL): Promise<void> {\n this._armCallbackPromise()\n await this._startCallbackServer()\n if (this._onRedirect) {\n await this._onRedirect(authorizationUrl)\n } else {\n await openBrowser(authorizationUrl.toString())\n }\n }\n\n /**\n * Creates the pending-callback promise that {@link waitForCallback} awaits.\n * Subclasses (e.g. BrowserOAuth) call this before opening their own redirect.\n */\n protected _armCallbackPromise(): void {\n this._callbackPromise = new Promise<URLSearchParams>((resolve, reject) => {\n this._callbackResolve = resolve\n this._callbackReject = reject\n })\n // Suppress unhandled-rejection warnings — the promise is observed via Promise.race.\n this._callbackPromise.catch(() => {})\n }\n\n /** Resolves the pending callback with the full authorization callback params. */\n protected _resolveCallback(params: URLSearchParams): void {\n this._callbackResolve?.(params)\n }\n\n /** Rejects the pending callback with an error. */\n protected _rejectCallback(err: Error): void {\n this._callbackReject?.(err)\n }\n\n /**\n * Races the pending callback promise against a timeout and clears the\n * promise state. Subclasses reuse this and add their own teardown.\n */\n protected async _awaitCallback(timeoutMs: number): Promise<URLSearchParams> {\n if (!this._callbackPromise) {\n throw new Error('No pending OAuth callback — call redirectToAuthorization() first')\n }\n const timeout = new Promise<never>((_, reject) =>\n setTimeout(\n () => reject(new Error('OAuth callback timed out waiting for authorization')),\n timeoutMs,\n ),\n )\n try {\n return await Promise.race([this._callbackPromise, timeout])\n } finally {\n this._callbackPromise = null\n this._callbackResolve = null\n this._callbackReject = null\n }\n }\n\n saveCodeVerifier(codeVerifier: string): void {\n this._codeVerifier = codeVerifier\n }\n\n codeVerifier(): string {\n if (this._codeVerifier === undefined) {\n throw new Error('No PKCE code verifier has been saved')\n }\n return this._codeVerifier\n }\n\n async invalidateCredentials(\n scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery',\n ): Promise<void> {\n const issuer = await this._lastIssuer()\n if (scope === 'all' || scope === 'tokens') {\n await this._store.delete(this._key('tokens', issuer))\n await this._store.delete(this._key('tokens')) // pre-issuer-keying entries, if any\n }\n if (scope === 'all' || scope === 'client') {\n await this._store.delete(this._key('client_info', issuer))\n await this._store.delete(this._key('client_info'))\n }\n if (scope === 'all' || scope === 'verifier') {\n this._codeVerifier = undefined\n }\n if (scope === 'all' || scope === 'discovery') {\n await this._store.delete(this._key('discovery'))\n }\n }\n\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this._store.set(this._key('discovery'), JSON.stringify(state))\n }\n\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n const raw = await this._store.get(this._key('discovery'))\n if (!raw) return undefined\n return JSON.parse(raw) as OAuthDiscoveryState\n }\n\n // ---- Internal helpers ----\n\n /**\n * Returns the actual port the callback server bound to.\n * Only populated after redirectToAuthorization() has been called.\n */\n get callbackServerPort(): number | null {\n return this._actualCallbackPort\n }\n\n /**\n * Waits for the OAuth authorization code to arrive via the callback server,\n * then stops the server and resolves with the full callback `URLSearchParams`\n * (including `code` and, when present, the RFC 9207 `iss` parameter).\n *\n * Must be called after the UnauthorizedError thrown by connect() is caught.\n * Pass the result directly to the transport's `finishAuth(callbackParams)`.\n */\n async waitForCallback(timeoutMs = 5 * 60 * 1000): Promise<URLSearchParams> {\n try {\n return await this._awaitCallback(timeoutMs)\n } finally {\n this._stopCallbackServer()\n }\n }\n\n private _key(type: string, issuer?: string): string {\n return issuer ? `${issuer}/${type}` : `${this._serverUrl}/${type}`\n }\n\n /** Storage key for the \"last issuer seen for this server\" pointer (SEP-2352). */\n private _issuerPointerKey(): string {\n return `${this._serverUrl}/issuer`\n }\n\n /**\n * Remembers the resolved authorization-server issuer for this MCP server,\n * so later no-ctx reads (e.g. the transport's per-request bearer-token read)\n * know which issuer-keyed credential set to return.\n */\n private async _rememberIssuer(issuer: string): Promise<void> {\n await this._store.set(this._issuerPointerKey(), issuer)\n }\n\n private async _lastIssuer(): Promise<string | undefined> {\n return (await this._store.get(this._issuerPointerKey())) ?? undefined\n }\n\n private async _startCallbackServer(): Promise<void> {\n if (this._callbackServer) return\n const http = await import('http')\n await new Promise<void>((resolve, reject) => {\n const server = http.createServer((req, res) => {\n const url = new URL(req.url ?? '/', `http://localhost`)\n const error = url.searchParams.get('error')\n if (error && this._callbackReject) {\n const description = url.searchParams.get('error_description') ?? error\n this._callbackReject(new Error(`OAuth authorization denied: ${description}`))\n res.writeHead(200, { 'content-type': 'text/html' })\n res.end(\n '<html><body><h1>Authorization denied</h1><p>You may close this tab.</p></body></html>',\n )\n return\n }\n const code = url.searchParams.get('code')\n if (code && this._callbackResolve) {\n this._callbackResolve(url.searchParams)\n res.writeHead(200, { 'content-type': 'text/html' })\n res.end(\n '<html><body><h1>Authorization complete</h1><p>You may close this tab.</p></body></html>',\n )\n } else {\n res.writeHead(400)\n res.end('Missing code parameter')\n }\n })\n server.on('error', reject)\n server.listen(this._callbackPort, () => {\n const addr = server.address()\n if (addr && typeof addr !== 'string') {\n this._actualCallbackPort = addr.port\n }\n this._callbackServer = server\n resolve()\n })\n })\n }\n\n private _stopCallbackServer(): void {\n this._callbackServer?.close()\n this._callbackServer = null\n this._actualCallbackPort = null\n }\n}\n\n// ---------------------------------------------------------------------------\n// BearerAuth\n// ---------------------------------------------------------------------------\n\nexport class BearerAuth {\n private readonly _token: string\n\n constructor(token: string) {\n // Strip any existing Bearer prefix to avoid double-prepending\n this._token = token.startsWith('Bearer ') ? token.slice(7) : token\n }\n\n getHeaders(): Record<string, string> {\n return { Authorization: `Bearer ${this._token}` }\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientCredentials — OAuth 2.0 client credentials grant (machine-to-machine)\n// ---------------------------------------------------------------------------\n\n/** Token-endpoint authentication method for a shared client secret. */\nexport type ClientSecretAuthMethod = 'client_secret_post' | 'client_secret_basic'\n\n/** Fields common to every {@link ClientCredentials} configuration. */\ninterface ClientCredentialsBaseOptions {\n tokenEndpoint: string\n clientId: string\n scope?: string\n /**\n * Persistent token store. Default: in-memory. The cache key is derived from\n * `tokenEndpoint` alone, with no client identity in it — use one store per\n * credential identity. Do not share a persistent `store` across two\n * `ClientCredentials` instances that have different `clientId`/`clientSecret`/\n * `privateKey` but the same `tokenEndpoint`; they will read and overwrite\n * each other's cached tokens.\n */\n store?: KeyValueStore\n /** How many seconds before expiry to proactively re-fetch. Default: 60. */\n refreshBufferSeconds?: number\n}\n\n/**\n * Shared-secret configuration for {@link ClientCredentials}.\n *\n * `authMethod` selects how the secret reaches the token endpoint:\n * - `client_secret_post` (default) — `client_id` and `client_secret` in the\n * POST body. Unchanged from earlier releases.\n * - `client_secret_basic` — an RFC 6749 §2.3.1 HTTP Basic `Authorization`\n * header. Nothing secret goes in the body.\n */\nexport interface ClientSecretCredentialsOptions extends ClientCredentialsBaseOptions {\n clientSecret: string\n /** Token-endpoint authentication method. Default: `client_secret_post`. */\n authMethod?: ClientSecretAuthMethod\n privateKey?: never\n algorithm?: never\n}\n\n/**\n * `private_key_jwt` configuration for {@link ClientCredentials} (RFC 7523 /\n * SEP-1046): the client proves its identity with a signed JWT `client_assertion`\n * instead of a shared secret. The assertion is signed by the SDK's own\n * `private_key_jwt` machinery — no secret is ever sent to the token endpoint.\n */\nexport interface PrivateKeyJwtCredentialsOptions extends ClientCredentialsBaseOptions {\n /** Signing key: a PEM (PKCS#8) string, its bytes, or a JWK object. */\n privateKey: string | Uint8Array | Record<string, unknown>\n /** JWS signing algorithm, e.g. `ES256` or `RS256`. */\n algorithm: string\n /**\n * The assertion's `aud` claim. Required — there is no safe default, because\n * this provider does no discovery and cannot learn the authorization server's\n * identity on its own. RFC 7523 §3 recommends the authorization server's\n * `issuer` identifier; some servers instead verify against the token endpoint\n * URL. Set whichever your server checks (issuer is the more common choice).\n */\n audience: string\n /** Assertion lifetime in seconds. Default: 300. */\n jwtLifetimeSeconds?: number\n /** Extra claims merged over the standard `iss`/`sub`/`aud`/`exp`/`iat`/`jti`. */\n claims?: Record<string, unknown>\n clientSecret?: never\n authMethod?: never\n}\n\n/**\n * Configuration for {@link ClientCredentials}. A discriminated union: supply\n * either a `clientSecret` (with an optional `authMethod`) or a `privateKey`\n * (with its `algorithm`) — the two are mutually exclusive and enforced at\n * compile time.\n */\nexport type ClientCredentialsOptions =\n | ClientSecretCredentialsOptions\n | PrivateKeyJwtCredentialsOptions\n\nconst DEFAULT_REFRESH_BUFFER_SECONDS = 60\n\n/** Internal discriminant for the selected token-endpoint auth method. */\ntype TokenEndpointAuthMethod = ClientSecretAuthMethod | 'private_key_jwt'\n\n/**\n * Builds an RFC 6749 §2.3.1 HTTP Basic `Authorization` header value. The client\n * id and secret are each percent-encoded (RFC 3986, via `encodeURIComponent` —\n * space becomes `%20`, not `+`), which a conformant §2.3.1 decoder accepts, then\n * joined with a colon and Base64-encoded.\n */\nfunction basicAuthHeader(clientId: string, clientSecret: string): string {\n const credentials = `${encodeURIComponent(clientId)}:${encodeURIComponent(clientSecret)}`\n return `Basic ${btoa(credentials)}`\n}\n\nfunction normalizeToken(token: OAuthToken): OAuthToken {\n if (typeof token.expires_at === 'number' && token.expires_at > 0) {\n if (token.expires_at < 1e10) {\n return { ...token, expires_at: token.expires_at * 1000 }\n }\n return token\n }\n if (typeof token.expires_in === 'number' && token.expires_in > 0) {\n return { ...token, expires_at: Date.now() + token.expires_in * 1000 }\n }\n return token\n}\n\nfunction isExpiring(token: OAuthToken, bufferMs: number): boolean {\n if (token.expires_at == null) return false\n return token.expires_at - Date.now() <= bufferMs\n}\n\n/**\n * A persisted, single-flight token cache shared by every non-interactive token\n * provider ({@link ClientCredentials}, {@link JwtBearerAuth},\n * {@link EnterpriseManagedAuth}). It reads the store, returns a still-valid\n * token, and otherwise coalesces concurrent fetches into one call of the\n * provider's `fetcher`, normalizes the result (computing `expires_at`), and\n * persists it. Providers supply only the grant-specific network call — the\n * caching, expiry, and coalescing live here once, not per provider.\n */\nclass TokenCache {\n private _fetchPromise: Promise<OAuthToken> | null = null\n\n constructor(\n private readonly _store: KeyValueStore,\n private readonly _key: string,\n private readonly _bufferMs: number,\n ) {}\n\n async get(fetcher: () => Promise<OAuthToken>): Promise<OAuthToken> {\n const raw = await this._store.get(this._key)\n if (raw) {\n const normalized = normalizeToken(JSON.parse(raw) as OAuthToken)\n if (!isExpiring(normalized, this._bufferMs)) return normalized\n }\n this._fetchPromise ??= (async () => {\n const token = normalizeToken(await fetcher())\n if (!token.access_token) {\n throw new Error('token response missing access_token')\n }\n await this._store.set(this._key, JSON.stringify(token))\n return token\n })().finally(() => {\n this._fetchPromise = null\n })\n return this._fetchPromise\n }\n}\n\nexport class ClientCredentials implements AsyncHeaderAuth {\n readonly kind = 'client_credentials' as const\n\n private readonly _tokenEndpoint: string\n private readonly _clientId: string\n private readonly _scope?: string\n private readonly _authMethod: TokenEndpointAuthMethod\n /** Set for `client_secret_post` / `client_secret_basic`. */\n private readonly _clientSecret?: string\n /**\n * Set for `private_key_jwt`. The SDK's `createPrivateKeyJwtAuth` signs the\n * assertion and stamps `client_assertion` / `client_assertion_type` onto the\n * token-request params — we reuse it verbatim instead of hand-rolling JOSE.\n */\n private readonly _addClientAssertion?: AddClientAuthentication\n private readonly _cache: TokenCache\n\n constructor(options: ClientCredentialsOptions) {\n this._tokenEndpoint = options.tokenEndpoint\n this._clientId = options.clientId\n this._scope = options.scope\n const store = options.store ?? new InMemoryStore()\n const bufferMs =\n (options.refreshBufferSeconds ?? DEFAULT_REFRESH_BUFFER_SECONDS) * 1000\n this._cache = new TokenCache(store, `${this._tokenEndpoint}/token`, bufferMs)\n\n if (options.privateKey !== undefined) {\n this._authMethod = 'private_key_jwt'\n this._addClientAssertion = createPrivateKeyJwtAuth({\n issuer: options.clientId,\n subject: options.clientId,\n privateKey: options.privateKey,\n alg: options.algorithm,\n audience: options.audience,\n lifetimeSeconds: options.jwtLifetimeSeconds,\n claims: options.claims,\n })\n } else {\n this._authMethod = options.authMethod ?? 'client_secret_post'\n this._clientSecret = options.clientSecret\n }\n }\n\n async getHeaders(): Promise<Record<string, string>> {\n const token = await this._cache.get(() => this._fetchToken())\n const type = token.token_type?.trim() || 'Bearer'\n return { Authorization: `${type} ${token.access_token}` }\n }\n\n private async _fetchToken(): Promise<OAuthToken> {\n const params = new URLSearchParams({ grant_type: 'client_credentials' })\n const headers: Record<string, string> = {\n 'content-type': 'application/x-www-form-urlencoded',\n }\n\n if (this._authMethod === 'private_key_jwt') {\n // private_key_jwt: the SDK signs the assertion and stamps\n // client_assertion / client_assertion_type onto the params.\n if (this._scope) params.set('scope', this._scope)\n await this._addClientAssertion!(new Headers(), params, this._tokenEndpoint)\n } else if (this._authMethod === 'client_secret_basic') {\n // client_secret_basic: credentials go in the Authorization header only.\n if (this._scope) params.set('scope', this._scope)\n headers.Authorization = basicAuthHeader(this._clientId, this._clientSecret!)\n } else {\n // client_secret_post (default): credentials in the body. Field order is\n // kept identical to earlier releases so the request stays byte-for-byte\n // the same for existing callers.\n params.set('client_id', this._clientId)\n params.set('client_secret', this._clientSecret!)\n if (this._scope) params.set('scope', this._scope)\n }\n\n const response = await fetch(this._tokenEndpoint, {\n method: 'POST',\n headers,\n body: params.toString(),\n })\n\n if (!response.ok) {\n const detail = await response.text().catch(() => '')\n throw new Error(\n `ClientCredentials token fetch failed (${response.status})${detail ? `: ${detail}` : ''}`,\n )\n }\n\n const data = (await response.json()) as Partial<OAuthToken>\n if (!data.access_token) {\n throw new Error('ClientCredentials token response missing access_token')\n }\n return data as OAuthToken\n }\n}\n\n// ---------------------------------------------------------------------------\n// JwtBearerAuth — RFC 7523 §2.1 JWT-bearer grant (SEP-1933 workload identity)\n// ---------------------------------------------------------------------------\n\n/** A workload assertion: a signed JWT string, or an (async) factory for one. */\nexport type AssertionSource = string | (() => string | Promise<string>)\n\n/**\n * Configuration for {@link JwtBearerAuth}.\n *\n * The client presents a pre-issued, signed JWT (`assertion`) directly to the\n * token endpoint under `grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer`\n * (RFC 7523 §2.1). No interactive authorization, no client secret by default —\n * this is the workload-identity-federation shape (SEP-1933): a workload proves\n * its identity with a JWT its runtime already minted (a Kubernetes projected\n * service-account token, a cloud instance-identity JWT, etc.).\n */\nexport interface JwtBearerOptions {\n /** The authorization server's token endpoint. */\n tokenEndpoint: string\n /**\n * The workload assertion (a signed JWT). Pass a string for a fixed assertion,\n * or a callback to mint/read a fresh one each time a token is fetched (the\n * usual case — workload JWTs are short-lived).\n */\n assertion: AssertionSource\n /** The client identifier registered for this workload. */\n clientId?: string\n /**\n * Token-endpoint client authentication. Default: `none` (public client — the\n * assertion itself is the credential, so no separate client secret is sent).\n */\n authMethod?: ClientAuthMethod\n /** Client secret, when `authMethod` is `client_secret_basic`/`_post`. */\n clientSecret?: string\n /** Requested scopes (space-separated). */\n scope?: string\n /**\n * Persistent token store. Default: in-memory. The cache key is derived from\n * `tokenEndpoint` alone, with no client identity in it — use one store per\n * credential identity. Do not share a persistent `store` across two\n * `JwtBearerAuth` instances that have different `clientId`/`assertion` but\n * the same `tokenEndpoint`; they will read and overwrite each other's\n * cached tokens.\n */\n store?: KeyValueStore\n /** How many seconds before expiry to proactively re-fetch. Default: 60. */\n refreshBufferSeconds?: number\n}\n\nexport class JwtBearerAuth implements AsyncHeaderAuth {\n readonly kind = 'jwt_bearer' as const\n\n private readonly _tokenEndpoint: string\n private readonly _assertion: AssertionSource\n private readonly _clientId?: string\n private readonly _authMethod: ClientAuthMethod\n private readonly _clientSecret?: string\n private readonly _scope?: string\n private readonly _cache: TokenCache\n\n constructor(options: JwtBearerOptions) {\n this._tokenEndpoint = options.tokenEndpoint\n this._assertion = options.assertion\n this._clientId = options.clientId\n this._authMethod = options.authMethod ?? 'none'\n this._clientSecret = options.clientSecret\n this._scope = options.scope\n const store = options.store ?? new InMemoryStore()\n const bufferMs =\n (options.refreshBufferSeconds ?? DEFAULT_REFRESH_BUFFER_SECONDS) * 1000\n this._cache = new TokenCache(store, `${this._tokenEndpoint}/jwt-bearer`, bufferMs)\n }\n\n async getHeaders(): Promise<Record<string, string>> {\n const token = await this._cache.get(() => this._fetchToken())\n const type = token.token_type?.trim() || 'Bearer'\n return { Authorization: `${type} ${token.access_token}` }\n }\n\n private async _fetchToken(): Promise<OAuthToken> {\n const assertion =\n typeof this._assertion === 'function' ? await this._assertion() : this._assertion\n // Reuse the SDK's RFC 7523 wire helper: it POSTs\n // grant_type=jwt-bearer + assertion and applies the chosen client auth.\n // A body rewrite is needed when a scope is configured (the helper takes no\n // scope param) or when no clientId is set (the helper's public-client path\n // always writes client_id, so we drop the empty value it would emit).\n const needsRewrite = this._scope !== undefined || this._clientId === undefined\n const tokens = await exchangeJwtAuthGrant({\n tokenEndpoint: this._tokenEndpoint,\n jwtAuthGrant: assertion,\n clientId: this._clientId ?? '',\n ...(this._clientSecret ? { clientSecret: this._clientSecret } : {}),\n authMethod: this._authMethod,\n ...(needsRewrite ? { fetchFn: this._rewriteBody() } : {}),\n })\n return tokens as OAuthToken\n }\n\n /**\n * Wraps fetch to fix up the token-request body the SDK helper builds:\n * appends `scope` when configured (RFC 7523 §2.1 allows it alongside the\n * assertion), and drops an empty `client_id` when no client identifier is set\n * (the helper's public-client path always writes one — we send no `client_id`\n * at all rather than `client_id=`).\n */\n private _rewriteBody() {\n return async (url: string | URL, init?: RequestInit): Promise<Response> => {\n const body = new URLSearchParams((init?.body as string) ?? '')\n if (this._scope !== undefined && !body.has('scope')) body.set('scope', this._scope)\n if (this._clientId === undefined && body.get('client_id') === '') {\n body.delete('client_id')\n }\n return fetch(url, { ...init, body: body.toString() })\n }\n }\n}\n\n// ---------------------------------------------------------------------------\n// EnterpriseManagedAuth — SEP-990 token exchange + JWT-bearer grant\n// ---------------------------------------------------------------------------\n\n/**\n * Configuration for {@link EnterpriseManagedAuth} (SEP-990, Enterprise-Managed\n * Authorization / Cross-App Access).\n *\n * The flow is two hops, both stable RFCs:\n * 1. **Token exchange** (RFC 8693) at the enterprise IdP: exchange the user's\n * OpenID Connect ID token for an *identity assertion JWT authorization\n * grant* (ID-JAG) scoped to the target MCP server.\n * 2. **JWT-bearer grant** (RFC 7523) at the MCP server's authorization server:\n * present the ID-JAG under `grant_type=jwt-bearer` to obtain the access\n * token.\n */\nexport interface EnterpriseManagedOptions {\n /** The MCP server's authorization-server token endpoint (step 2). */\n tokenEndpoint: string\n /** The MCP client identifier registered with the authorization server. */\n clientId: string\n /** The MCP client secret (default client auth is `client_secret_basic`). */\n clientSecret?: string\n /** Client-authentication method for step 2. Default: `client_secret_basic`. */\n authMethod?: ClientAuthMethod\n /**\n * The ID-JAG audience — the target authorization server's identifier. The\n * authorization server verifies the ID-JAG `aud` against this.\n */\n audience: string\n /**\n * The protected-resource identifier of the target MCP server (RFC 9728). The\n * authorization server verifies the ID-JAG `resource` against this.\n */\n resource: string\n /** The enterprise IdP's token endpoint (step 1). */\n idpTokenEndpoint: string\n /** The client identifier registered with the IdP for token exchange. */\n idpClientId: string\n /** The client secret for the IdP token exchange, if the IdP requires one. */\n idpClientSecret?: string\n /**\n * The user's OpenID Connect ID token (the `subject_token` of the exchange).\n * Pass a string, or a callback to read a fresh one each fetch.\n */\n idToken: AssertionSource\n /** Requested scopes (space-separated). */\n scope?: string\n /**\n * Persistent token store. Default: in-memory. The cache key is derived from\n * `tokenEndpoint` alone, with no client identity in it — use one store per\n * credential identity. Do not share a persistent `store` across two\n * `EnterpriseManagedAuth` instances that have different `clientId`/`idToken`\n * but the same `tokenEndpoint`; they will read and overwrite each other's\n * cached tokens.\n */\n store?: KeyValueStore\n /** How many seconds before expiry to proactively re-fetch. Default: 60. */\n refreshBufferSeconds?: number\n}\n\nexport class EnterpriseManagedAuth implements AsyncHeaderAuth {\n readonly kind = 'enterprise_managed' as const\n\n private readonly _options: EnterpriseManagedOptions\n private readonly _cache: TokenCache\n\n constructor(options: EnterpriseManagedOptions) {\n this._options = options\n const store = options.store ?? new InMemoryStore()\n const bufferMs =\n (options.refreshBufferSeconds ?? DEFAULT_REFRESH_BUFFER_SECONDS) * 1000\n this._cache = new TokenCache(store, `${options.tokenEndpoint}/enterprise-managed`, bufferMs)\n }\n\n async getHeaders(): Promise<Record<string, string>> {\n const token = await this._cache.get(() => this._fetchToken())\n const type = token.token_type?.trim() || 'Bearer'\n return { Authorization: `${type} ${token.access_token}` }\n }\n\n private async _fetchToken(): Promise<OAuthToken> {\n const o = this._options\n const idToken = typeof o.idToken === 'function' ? await o.idToken() : o.idToken\n // Step 1 — RFC 8693 token exchange at the IdP: ID token -> ID-JAG.\n const grant = await requestJwtAuthorizationGrant({\n tokenEndpoint: o.idpTokenEndpoint,\n audience: o.audience,\n resource: o.resource,\n idToken,\n clientId: o.idpClientId,\n ...(o.idpClientSecret ? { clientSecret: o.idpClientSecret } : {}),\n ...(o.scope ? { scope: o.scope } : {}),\n })\n // Step 2 — RFC 7523 JWT-bearer grant at the MCP authorization server:\n // present the ID-JAG for the access token.\n const tokens = await exchangeJwtAuthGrant({\n tokenEndpoint: o.tokenEndpoint,\n jwtAuthGrant: grant.jwtAuthGrant,\n clientId: o.clientId,\n ...(o.clientSecret ? { clientSecret: o.clientSecret } : {}),\n authMethod: o.authMethod ?? 'client_secret_basic',\n })\n return tokens as OAuthToken\n }\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nasync function openBrowser(url: string): Promise<void> {\n const { spawn } = await import('child_process')\n if (process.platform === 'win32') {\n spawn('cmd', ['/c', 'start', '', url], { detached: true, stdio: 'ignore' })\n } else if (process.platform === 'darwin') {\n spawn('open', [url], { detached: true, stdio: 'ignore' })\n } else {\n spawn('xdg-open', [url], { detached: true, stdio: 'ignore' })\n }\n}\n","// ---------------------------------------------------------------------------\n// Browser key-value stores — KeyValueStore implementations backed by the\n// browser's localStorage and IndexedDB. The browser globals are referenced\n// only inside methods so these modules stay importable under Node (they throw\n// only if actually used there).\n// ---------------------------------------------------------------------------\n\nimport type { KeyValueStore } from './auth.js'\n\n/**\n * KeyValueStore backed by `localStorage`. Synchronous and simple; suitable for\n * OAuth tokens and client registration state in single-page apps. Keys are\n * namespaced by a prefix to avoid collisions with other app state.\n */\nexport class LocalStorageStore implements KeyValueStore {\n private readonly _prefix: string\n\n constructor(prefix = 'fastmcp:') {\n this._prefix = prefix\n }\n\n async get(key: string): Promise<string | null> {\n return localStorage.getItem(this._prefix + key)\n }\n\n async set(key: string, value: string): Promise<void> {\n localStorage.setItem(this._prefix + key, value)\n }\n\n async delete(key: string): Promise<void> {\n localStorage.removeItem(this._prefix + key)\n }\n}\n\n/**\n * KeyValueStore backed by IndexedDB. Preferred when tokens should survive\n * outside the synchronous, size-limited localStorage (e.g. larger payloads or\n * stricter persistence). Opens the database per operation and closes it again.\n */\nexport class IndexedDBStore implements KeyValueStore {\n private readonly _dbName: string\n private readonly _storeName: string\n\n constructor(opts: { dbName?: string; storeName?: string } = {}) {\n this._dbName = opts.dbName ?? 'fastmcp'\n this._storeName = opts.storeName ?? 'auth'\n }\n\n private _open(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const req = indexedDB.open(this._dbName, 1)\n req.onupgradeneeded = () => {\n if (!req.result.objectStoreNames.contains(this._storeName)) {\n req.result.createObjectStore(this._storeName)\n }\n }\n req.onsuccess = () => resolve(req.result)\n req.onerror = () => reject(req.error ?? new Error('indexedDB.open failed'))\n })\n }\n\n private async _tx<T>(\n mode: IDBTransactionMode,\n fn: (store: IDBObjectStore) => IDBRequest,\n ): Promise<T> {\n const db = await this._open()\n try {\n return await new Promise<T>((resolve, reject) => {\n const req = fn(db.transaction(this._storeName, mode).objectStore(this._storeName))\n req.onsuccess = () => resolve(req.result as T)\n req.onerror = () => reject(req.error ?? new Error('indexedDB request failed'))\n })\n } finally {\n db.close()\n }\n }\n\n async get(key: string): Promise<string | null> {\n const value = await this._tx<string | undefined>('readonly', (s) => s.get(key))\n return value ?? null\n }\n\n async set(key: string, value: string): Promise<void> {\n await this._tx('readwrite', (s) => s.put(value, key))\n }\n\n async delete(key: string): Promise<void> {\n await this._tx('readwrite', (s) => s.delete(key))\n }\n}\n","import type { OAuthClientMetadata } from \"@modelcontextprotocol/server\";\n\n// ---------------------------------------------------------------------------\n// BrowserOAuth — OAuth authorization-code + PKCE flow for the browser.\n//\n// Extends the Node OAuth provider, reusing all of its PKCE / token / discovery\n// logic (which is already browser-safe), and replaces only the redirect\n// mechanism: instead of opening the system browser and listening on a localhost\n// HTTP callback server, it opens a popup (default) or navigates the tab, and\n// receives the authorization code via postMessage (popup) or the returned URL\n// (redirect). Because it `instanceof OAuth`, the Client connect flow\n// (connect → waitForCallback → finishAuth → reconnect) drives it unchanged.\n// ---------------------------------------------------------------------------\nimport { OAuth, type OAuthOptions } from './auth.js'\n\n/** postMessage payload sent by {@link handleOAuthCallback} back to the opener. */\nconst MESSAGE_TYPE = 'fastmcp:oauth'\n\nexport interface BrowserOAuthOptions\n extends Omit<OAuthOptions, 'callbackPort' | 'onRedirect'> {\n /**\n * Redirect URI registered with the provider. Must serve a page that calls\n * {@link handleOAuthCallback} (popup mode) or is your app route that reads the\n * returned `?code=` (redirect mode).\n */\n redirectUri: string\n /**\n * 'popup' (default) opens the authorization URL in a popup window and listens\n * for a postMessage from the callback page. 'redirect' navigates the whole\n * tab; resume with {@link BrowserOAuth.resumeFromRedirect} on return.\n */\n mode?: 'popup' | 'redirect'\n /** `window.open` features string for popup mode. */\n popupFeatures?: string\n}\n\nexport class BrowserOAuth extends OAuth {\n private readonly _redirectUri: string\n private readonly _mode: 'popup' | 'redirect'\n private readonly _popupFeatures: string\n private _popup: Window | null = null\n private _messageHandler: ((e: MessageEvent) => void) | null = null\n\n constructor(options: BrowserOAuthOptions) {\n super(options)\n this._redirectUri = options.redirectUri\n this._mode = options.mode ?? 'popup'\n this._popupFeatures = options.popupFeatures ?? 'width=600,height=720'\n }\n\n get redirectUrl(): string {\n return this._redirectUri\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return { ...super.clientMetadata, redirect_uris: [this._redirectUri] }\n }\n\n async redirectToAuthorization(authorizationUrl: URL): Promise<void> {\n if (this._mode === 'redirect') {\n // Navigation destroys this JS context; the app resumes via\n // resumeFromRedirect() on the return load.\n window.location.assign(authorizationUrl.toString())\n return\n }\n\n const expectedOrigin = new URL(this._redirectUri).origin\n this._messageHandler = (e: MessageEvent) => {\n if (e.origin !== expectedOrigin) return\n const data = e.data as { type?: string; code?: string; iss?: string; error?: string }\n if (data?.type !== MESSAGE_TYPE) return\n if (data.error) {\n this._rejectCallback(new Error(`OAuth authorization denied: ${data.error}`))\n } else if (data.code) {\n const params = new URLSearchParams({ code: data.code, ...(data.iss ? { iss: data.iss } : {}) })\n this._resolveCallback(params)\n }\n }\n window.addEventListener('message', this._messageHandler)\n // Arm the callback promise before opening so a fast provider can't race us.\n this._armCallbackPromise()\n this._popup = window.open(authorizationUrl.toString(), 'fastmcp-oauth', this._popupFeatures)\n if (!this._popup) {\n this._teardown()\n throw new Error(\n 'Failed to open OAuth popup — it was likely blocked. Trigger connect from a user gesture or use mode: \"redirect\".',\n )\n }\n }\n\n async waitForCallback(timeoutMs = 5 * 60 * 1000): Promise<URLSearchParams> {\n try {\n return await this._awaitCallback(timeoutMs)\n } finally {\n this._teardown()\n }\n }\n\n /**\n * Redirect-mode resume: parse the authorization callback params from a\n * returned URL (defaults to the current location). Returns the full\n * `URLSearchParams` (including `code` and, when present, `iss`) — pass\n * directly to `finishAuth()` — or `null` if there is no `code`. Throws if\n * the provider returned an error.\n */\n resumeFromRedirect(href: string = window.location.href): URLSearchParams | null {\n const params = new URL(href).searchParams\n const error = params.get('error_description') ?? params.get('error')\n if (error) throw new Error(`OAuth authorization denied: ${error}`)\n return params.has('code') ? params : null\n }\n\n private _teardown(): void {\n if (this._messageHandler) window.removeEventListener('message', this._messageHandler)\n this._messageHandler = null\n try {\n this._popup?.close()\n } catch {\n // Cross-origin popups may throw on close — ignore.\n }\n this._popup = null\n }\n}\n\n/**\n * Call from the redirect_uri page (popup mode) to deliver the authorization\n * code back to the opener window and close the popup.\n */\nexport function handleOAuthCallback(opts: { targetOrigin?: string } = {}): void {\n const params = new URLSearchParams(window.location.search)\n const code = params.get('code') ?? undefined\n const iss = params.get('iss') ?? undefined\n const error = params.get('error_description') ?? params.get('error') ?? undefined\n const target = opts.targetOrigin ?? window.location.origin\n window.opener?.postMessage({ type: MESSAGE_TYPE, code, iss, error }, target)\n window.close()\n}\n","import { InMemoryTransport, StreamableHTTPClientTransport, SSEClientTransport } from \"@modelcontextprotocol/client\";\nimport type { OAuthClientProvider, Transport, VersionNegotiationOptions } from \"@modelcontextprotocol/client\";\nimport { OAuth, BearerAuth, type AsyncHeaderAuth } from './auth.js'\n\n// ---------------------------------------------------------------------------\n// TransportResolutionOptions — cross-cutting knobs threaded through\n// resolveTransport / resolveEntryTransport (not just per-entry auth).\n// ---------------------------------------------------------------------------\n\nexport interface TransportResolutionOptions {\n /** See ClientOptions.legacySSE. Default false. */\n legacySSE?: boolean\n /** See ClientOptions.versionNegotiation. Used only to decide, for an\n * in-process McpServerLike input, whether a pinned-modern connection should\n * use the server's optional `_modernFetch` hook instead of the legacy-only\n * InMemoryTransport pair. */\n versionNegotiation?: VersionNegotiationOptions\n}\n\n// ---------------------------------------------------------------------------\n// Stdio transport — loaded lazily. The SDK's stdio module imports Node's\n// `child_process`, so a static import would pull Node built-ins into the\n// browser bundle. Importing it on demand keeps the client graph browser-safe.\n// ---------------------------------------------------------------------------\n\nasync function createStdioTransport(opts: {\n command: string\n args?: string[]\n env?: Record<string, string>\n cwd?: string\n}): Promise<Transport> {\n const { StdioClientTransport } = await import(\n '@modelcontextprotocol/client/stdio'\n )\n return new StdioClientTransport(opts)\n}\n\n// ---------------------------------------------------------------------------\n// McpServerLike — structural interface for in-process servers.\n// Intentionally loose: avoids importing from the server module.\n// ---------------------------------------------------------------------------\n\nexport interface McpServerLike {\n connect(transport: Transport): Promise<void>\n /**\n * Optional modern-era (2026-07-28) in-process fetch entrypoint, for servers\n * built on `createMcpHandler` (e.g. `FastMCP`'s own `_modernFetch`).\n * `InMemoryTransport` — used by `connect()` above — is 2025-era only (the\n * legacy `Server`/session model); there is no in-process equivalent of a\n * real HTTP round trip for the modern era's stateless-per-request dispatch.\n * When present, and the caller pins modern era via\n * `versionNegotiation: { mode: { pin: '2026-07-28' } }`, the client builds a\n * `StreamableHTTPClientTransport` whose `fetch` calls this function directly\n * — no sockets, but otherwise the same code path a real HTTP connection\n * takes. Not used for `'auto'` or `'legacy'` modes: this server-side hook is\n * modern-only (mirrors `createMcpHandler(..., { legacy: 'reject' })`), so\n * auto-negotiation (which must be able to fall back to legacy) still goes\n * through `connect()` + `InMemoryTransport`, and stays legacy-only for\n * in-process servers until a dual-era in-process bridge exists.\n */\n _modernFetch?(request: Request, options?: unknown): Promise<Response>\n}\n\nfunction isMcpServerLike(value: unknown): value is McpServerLike {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'connect' in value &&\n typeof (value as Record<string, unknown>).connect === 'function'\n )\n}\n\n// ---------------------------------------------------------------------------\n// MCP config object — { mcpServers: { name: { url | command, ... } } }\n// ---------------------------------------------------------------------------\n\nexport type McpServerEntry =\n | { url: string; headers?: Record<string, string>; auth?: BearerAuth | OAuth | AsyncHeaderAuth | string }\n | { command: string; args?: string[]; env?: Record<string, string>; auth?: BearerAuth | OAuth | AsyncHeaderAuth | string }\n\n/** Values accepted in mcpServers: either a config object or an in-process server. */\nexport type McpServerValue = McpServerEntry | McpServerLike\n\nexport type McpConfig = {\n mcpServers: Record<string, McpServerValue>\n}\n\nfunction isMcpConfig(value: unknown): value is McpConfig {\n return (\n typeof value === 'object' &&\n value !== null &&\n 'mcpServers' in value &&\n typeof (value as McpConfig).mcpServers === 'object' &&\n (value as McpConfig).mcpServers !== null\n )\n}\n\n// ---------------------------------------------------------------------------\n// StdioTransport — configuration object for stdio subprocess connections.\n// Separate from the SDK's StdioClientTransport so callers work with a plain\n// config value rather than a live transport instance.\n// ---------------------------------------------------------------------------\n\nexport class StdioTransport {\n readonly command: string\n readonly args: string[]\n readonly env?: Record<string, string>\n readonly cwd?: string\n\n constructor(\n command: string,\n args: string[] = [],\n options?: { env?: Record<string, string>; cwd?: string },\n ) {\n this.command = command\n this.args = args\n this.env = options?.env\n this.cwd = options?.cwd\n }\n}\n\n// ---------------------------------------------------------------------------\n// ClientTransportInput — what the Client constructor accepts\n// ---------------------------------------------------------------------------\n\nexport type ClientTransportInput =\n | string // HTTP/HTTPS URL → auto-detect Streamable HTTP or SSE\n | McpServerLike // in-process server instance\n | McpConfig // { mcpServers: { ... } } config object\n | StdioTransport // explicit stdio subprocess config\n | Transport // pass-through — any SDK Transport (advanced)\n\n// ---------------------------------------------------------------------------\n// Resolved transport — what Client.connect() receives\n// ---------------------------------------------------------------------------\n\nexport type ResolvedTransport = {\n transport: Transport\n /**\n * Called before sdkClient.connect(transport). Used for in-process servers\n * that must be connected to their side of the InMemoryTransport first.\n */\n beforeConnect?: () => Promise<void>\n}\n\n// ---------------------------------------------------------------------------\n// Auth header injection helpers\n// ---------------------------------------------------------------------------\n\nfunction normalizeHeaders(headers: RequestInit['headers']): Record<string, string> {\n if (!headers) return {}\n if (headers instanceof Headers) return Object.fromEntries(headers.entries())\n if (Array.isArray(headers)) return Object.fromEntries(headers as string[][])\n return { ...(headers as Record<string, string>) }\n}\n\nfunction isAsyncAuth(\n auth: BearerAuth | OAuth | AsyncHeaderAuth,\n): auth is AsyncHeaderAuth {\n // ClientCredentials / JwtBearerAuth / EnterpriseManagedAuth all carry a\n // `kind` and acquire their token asynchronously — inject per request.\n // OAuth is now an OAuthClientProvider and is passed directly to the transport.\n return 'kind' in auth\n}\n\ntype HttpTransportOptions = {\n requestInit?: RequestInit\n fetch?: (url: string | URL, init?: RequestInit) => Promise<Response>\n eventSourceInit?: Record<string, unknown>\n authProvider?: OAuthClientProvider\n}\n\nfunction buildHttpOptions(\n auth: BearerAuth | OAuth | AsyncHeaderAuth | undefined,\n extraHeaders: Record<string, string> = {},\n): HttpTransportOptions {\n const hasExtra = Object.keys(extraHeaders).length > 0\n\n if (!auth && !hasExtra) return {}\n\n // OAuth implements OAuthClientProvider — hand it to the SDK transport which\n // handles the full auth flow (discovery, DCR, PKCE, token refresh, 401 retry).\n if (auth instanceof OAuth) {\n const opts: HttpTransportOptions = { authProvider: auth }\n // Extra headers are injected via requestInit (not Authorization — that's\n // managed by the authProvider).\n if (hasExtra) opts.requestInit = { headers: extraHeaders }\n return opts\n }\n\n if (auth && isAsyncAuth(auth)) {\n // Async token auth: inject the acquired token per-request via a custom fetch wrapper.\n const customFetch = async (\n url: string | URL,\n init?: RequestInit,\n ): Promise<Response> => {\n const authHeaders = await auth.getHeaders()\n return fetch(url, {\n ...init,\n headers: {\n ...authHeaders,\n ...extraHeaders,\n ...normalizeHeaders(init?.headers),\n },\n })\n }\n return { fetch: customFetch }\n }\n\n // Static auth (BearerAuth) or extra headers only.\n const staticHeaders: Record<string, string> = {\n ...(auth ? auth.getHeaders() : {}),\n ...extraHeaders,\n }\n return {\n requestInit: { headers: staticHeaders },\n // Also exposed for SSE's EventSource connection (eventsource npm pkg\n // accepts headers in EventSourceInit, unlike the browser API).\n eventSourceInit: { headers: staticHeaders },\n }\n}\n\n// ---------------------------------------------------------------------------\n// URL → SDK transport\n// ---------------------------------------------------------------------------\n\nlet sseDeprecationWarned = false\n\nfunction urlToTransport(\n url: URL,\n auth: BearerAuth | OAuth | AsyncHeaderAuth | undefined,\n extraHeaders: Record<string, string> = {},\n legacySSE = false,\n): Transport {\n const { requestInit, fetch: customFetch, eventSourceInit, authProvider } =\n buildHttpOptions(auth, extraHeaders)\n\n const segments = url.pathname.split('/')\n const isSSE = segments.includes('sse') || url.pathname.endsWith('/sse')\n\n if (isSSE) {\n if (!legacySSE) {\n throw new Error(\n `The URL \"${url}\" looks like an SSE endpoint, but SSE is deprecated by the MCP SDK ` +\n `(SSEClientTransport is marked @deprecated — prefer Streamable HTTP). Pass ` +\n `{ legacySSE: true } to ClientOptions to connect anyway.`,\n )\n }\n if (!sseDeprecationWarned) {\n sseDeprecationWarned = true\n console.warn(\n '[fastmcp-ts] Connecting over the deprecated SSE transport (legacySSE: true). ' +\n 'SSEClientTransport is marked @deprecated in the MCP SDK — migrate the server to ' +\n 'Streamable HTTP when possible.',\n )\n }\n return new SSEClientTransport(url, {\n ...(authProvider ? { authProvider } : {}),\n ...(requestInit ? { requestInit } : {}),\n ...(eventSourceInit ? { eventSourceInit } : {}),\n ...(customFetch ? { fetch: customFetch } : {}),\n })\n }\n\n return new StreamableHTTPClientTransport(url, {\n ...(authProvider ? { authProvider } : {}),\n ...(requestInit ? { requestInit } : {}),\n ...(customFetch ? { fetch: customFetch } : {}),\n })\n}\n\n// ---------------------------------------------------------------------------\n// In-process modern-era transport — see McpServerLike._modernFetch's docs.\n// ---------------------------------------------------------------------------\n\nconst IN_PROCESS_BASE_URL = 'http://in-process.local/mcp'\n\nfunction isPinnedModern(versionNegotiation: TransportResolutionOptions['versionNegotiation']): boolean {\n const mode = versionNegotiation?.mode\n return typeof mode === 'object' && mode !== null && 'pin' in mode\n}\n\nfunction modernFetchTransport(entry: McpServerLike): Transport {\n const modernFetch = entry._modernFetch!.bind(entry)\n // Adapt the (url, init) => Response shape StreamableHTTPClientTransport calls\n // its `fetch` option with to the (Request) => Response shape McpHttpHandler\n // (createMcpHandler's return value) exposes.\n const fetchAdapter = (url: string | URL, init?: RequestInit): Promise<Response> =>\n modernFetch(new Request(url, init))\n return new StreamableHTTPClientTransport(new URL(IN_PROCESS_BASE_URL), {\n fetch: fetchAdapter,\n })\n}\n\n// ---------------------------------------------------------------------------\n// resolveEntryTransport — resolves a single McpServerEntry to a transport.\n// Used by MultiServerClient to connect to each server independently.\n// ---------------------------------------------------------------------------\n\nexport async function resolveEntryTransport(\n entry: McpServerValue,\n auth?: BearerAuth | OAuth | AsyncHeaderAuth,\n options?: TransportResolutionOptions,\n): Promise<ResolvedTransport> {\n // In-process server (McpServerLike: has connect(transport)).\n if (isMcpServerLike(entry)) {\n if (isPinnedModern(options?.versionNegotiation) && entry._modernFetch) {\n return { transport: modernFetchTransport(entry) }\n }\n const [serverSide, clientSide] = InMemoryTransport.createLinkedPair()\n return {\n transport: clientSide,\n beforeConnect: () => entry.connect(serverSide),\n }\n }\n\n const entryAuth = resolveEntryAuth(entry.auth) ?? auth\n\n if ('url' in entry) {\n const url = new URL(entry.url)\n const extraHeaders = entry.headers ?? {}\n return { transport: urlToTransport(url, entryAuth, extraHeaders, options?.legacySSE) }\n }\n\n const cmd = entry as { command: string; args?: string[]; env?: Record<string, string> }\n return {\n transport: await createStdioTransport({\n command: cmd.command,\n args: cmd.args,\n env: cmd.env,\n }),\n }\n}\n\nfunction resolveEntryAuth(\n auth: BearerAuth | OAuth | AsyncHeaderAuth | string | undefined,\n): BearerAuth | OAuth | AsyncHeaderAuth | undefined {\n if (!auth) return undefined\n if (typeof auth === 'string') return new BearerAuth(auth)\n return auth\n}\n\n// ---------------------------------------------------------------------------\n// resolveTransport — internal; used by Client.connect()\n// ---------------------------------------------------------------------------\n\nexport async function resolveTransport(\n input: ClientTransportInput,\n auth?: BearerAuth | OAuth | AsyncHeaderAuth,\n options?: TransportResolutionOptions,\n): Promise<ResolvedTransport> {\n // 1. Our StdioTransport config class (check before the duck-type checks below).\n if (input instanceof StdioTransport) {\n return {\n transport: await createStdioTransport({\n command: input.command,\n args: input.args,\n env: input.env,\n cwd: input.cwd,\n }),\n }\n }\n\n // 2. URL string → auto-detect HTTP transport.\n if (typeof input === 'string') {\n const url = new URL(input)\n return { transport: urlToTransport(url, auth, {}, options?.legacySSE) }\n }\n\n // 3. Pass-through SDK Transport (has the Transport interface: start/close/send).\n if (\n typeof input === 'object' &&\n input !== null &&\n 'start' in input &&\n typeof (input as unknown as Record<string, unknown>).start === 'function'\n ) {\n return { transport: input as Transport }\n }\n\n // 4. MCP config object { mcpServers: { ... } } — use the first entry.\n if (isMcpConfig(input)) {\n const entries = Object.entries(input.mcpServers)\n if (entries.length === 0) throw new Error('mcpServers config is empty')\n const [, entry] = entries[0]!\n return await resolveEntryTransport(entry, auth, options)\n }\n\n // 5. In-process server (McpServerLike: has connect(transport)).\n if (isMcpServerLike(input)) {\n if (isPinnedModern(options?.versionNegotiation) && input._modernFetch) {\n return { transport: modernFetchTransport(input) }\n }\n const [serverSide, clientSide] = InMemoryTransport.createLinkedPair()\n return {\n transport: clientSide,\n beforeConnect: () => input.connect(serverSide),\n }\n }\n\n throw new Error(\n 'Unrecognized transport input: expected a URL string, FastMCP server instance, ' +\n 'mcpServers config object, StdioTransport, or SDK Transport',\n )\n}\n","import { UnauthorizedError, Client as SdkClient, LOG_LEVEL_META_KEY } from \"@modelcontextprotocol/client\";\nimport type {\n ClientCapabilities,\n RequestOptions as SdkRequestOptions,\n McpSubscription,\n VersionNegotiationOptions,\n ProtocolEra,\n PriorDiscovery,\n InputRequiredOptions,\n ResponseCacheStore,\n Transport,\n Implementation,\n ServerCapabilities,\n} from \"@modelcontextprotocol/client\";\nimport { BearerAuth, OAuth } from './auth.js'\nimport { buildClientCapabilities } from './capabilities.js'\nimport type { AsyncHeaderAuth } from './auth.js'\nimport type { ClientHandlers, ListChangedHandler, ProgressHandler, ResourceUpdateHandler } from './handlers.js'\nimport { defaultLogHandler, defaultProgressHandler } from './handlers.js'\nimport type { CallToolOptions, IClient, RequestOptions } from './interfaces.js'\nimport type {\n ClientDefaultOptions,\n ClientOptions,\n RootInput,\n RootsValue,\n} from './options.js'\nimport type {\n CallToolResult,\n CompletionResult,\n ContentBlock,\n GetPromptResult,\n LoggingLevel,\n Prompt,\n Resource,\n TextResourceContents,\n BlobResourceContents,\n ResourceTemplate,\n Root,\n Tool,\n} from './results.js'\nimport type { ClientTransportInput, McpConfig } from './transports.js'\nimport { resolveTransport } from './transports.js'\nimport type { MultiServerOptions } from './multi-server.js'\nimport { MultiServerClient } from './multi-server.js'\n\n// ---------------------------------------------------------------------------\n// Error type\n// ---------------------------------------------------------------------------\n\nexport class ToolCallError extends Error {\n readonly content: ContentBlock[]\n\n constructor(message: string, content: ContentBlock[]) {\n super(message)\n this.name = 'ToolCallError'\n this.content = content\n }\n}\n\n// ---------------------------------------------------------------------------\n// Client\n// ---------------------------------------------------------------------------\n\ntype OptionalHandlerKeys =\n | 'sampling'\n | 'elicitation'\n | 'onToolsListChanged'\n | 'onResourcesListChanged'\n | 'onPromptsListChanged'\n\nexport class Client implements IClient {\n private _sdkClient: SdkClient | null = null\n private _refCount = 0\n private _connectPromise: Promise<void> | null = null\n private readonly _resourceSubscriptions = new Map<string, ResourceUpdateHandler>()\n /** The modern-era (2026-07-28) `subscriptions/listen` stream backing all active\n * resource subscriptions — resources/subscribe and resources/unsubscribe are\n * 2025-only RPCs, physically absent from the modern method registry. Unused\n * (stays undefined) on a legacy connection. */\n private _resourceListenSubscription: McpSubscription | undefined\n /** The live SDK transport captured at connect(). Its `finishAuth()` redeems the\n * authorization code both during connect-time recovery and a post-connect\n * step-up re-authorization. */\n private _transport: Transport | undefined\n /** Single-flight guard for a post-connect re-authorization round: concurrent\n * interactive-OAuth 401s share one `waitForCallback`→`finishAuth` round rather\n * than each opening its own. Cleared when the round settles. */\n private _reauthPromise: Promise<void> | null = null\n /** Max post-connect re-authorization rounds per request (see `_reauthRetry`):\n * 1 for ordinary step-up, 2 to also cover SEP-2352 authorization-server\n * migration (the AS changes mid-request). Bounded so a genuinely unauthorized\n * request cannot loop forever. */\n private static readonly _MAX_REAUTH_ROUNDS = 2\n\n private readonly _input: ClientTransportInput\n private readonly _auth: BearerAuth | OAuth | AsyncHeaderAuth | undefined\n private readonly _handlers: Required<Omit<ClientHandlers, OptionalHandlerKeys>> &\n Pick<ClientHandlers, OptionalHandlerKeys>\n private readonly _roots: (() => Promise<Root[]>) | undefined\n private readonly _capabilities: ClientCapabilities\n private readonly _autoInitialize: boolean\n private readonly _versionNegotiation: VersionNegotiationOptions\n private readonly _prior: PriorDiscovery | undefined\n private readonly _inputRequired: InputRequiredOptions | undefined\n private readonly _responseCacheStore: ResponseCacheStore | undefined\n private readonly _cachePartition: string | undefined\n private readonly _defaultCacheTtlMs: number | undefined\n private readonly _legacySSE: boolean\n /** Set by setLogLevel() on a modern-era connection (where logging/setLevel is\n * not a wire method) — threaded into `_meta[LOG_LEVEL_META_KEY]` on every\n * subsequent request. Unused on legacy era, where setLogLevel() still sends\n * the real `logging/setLevel` RPC. */\n private _logLevel: LoggingLevel | undefined\n private readonly _defaultOptions: ClientDefaultOptions\n\n constructor(input: ClientTransportInput, options?: ClientOptions) {\n this._input = input\n this._auth = resolveAuth(options?.auth)\n this._handlers = {\n log: options?.handlers?.log ?? defaultLogHandler,\n progress: options?.handlers?.progress ?? defaultProgressHandler,\n sampling: options?.handlers?.sampling,\n elicitation: options?.handlers?.elicitation,\n onToolsListChanged: options?.handlers?.onToolsListChanged,\n onResourcesListChanged: options?.handlers?.onResourcesListChanged,\n onPromptsListChanged: options?.handlers?.onPromptsListChanged,\n }\n this._roots = options?.roots ? normalizeRootsOption(options.roots) : undefined\n this._capabilities = buildClientCapabilities(options?.capabilities, {\n sampling: this._handlers.sampling !== undefined,\n elicitation: this._handlers.elicitation !== undefined,\n rootsListChanged: this._roots === undefined ? undefined : true,\n })\n this._autoInitialize = options?.autoInitialize ?? true\n this._versionNegotiation = options?.versionNegotiation ?? { mode: 'auto' }\n this._prior = options?.prior\n this._inputRequired = options?.inputRequired\n this._responseCacheStore = options?.responseCacheStore\n this._cachePartition = options?.cachePartition\n this._defaultCacheTtlMs = options?.defaultCacheTtlMs\n this._legacySSE = options?.legacySSE ?? false\n this._defaultOptions = options?.defaultOptions ?? {}\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n async connect(): Promise<void> {\n this._refCount++\n\n // If another concurrent connect() is in progress, wait for it.\n if (this._connectPromise) {\n await this._connectPromise\n return\n }\n\n // Already connected — just bump the ref count.\n if (this._sdkClient) return\n\n this._connectPromise = this._doConnect().finally(() => {\n this._connectPromise = null\n })\n\n try {\n await this._connectPromise\n } catch (err) {\n this._refCount = Math.max(0, this._refCount - 1)\n throw err\n }\n }\n\n private async _doConnect(): Promise<void> {\n const sdkClient = new SdkClient(\n { name: 'fastmcp-ts', version: '1.0.0' },\n {\n capabilities: this._capabilities,\n listChanged: this._buildListChangedConfig(),\n versionNegotiation: this._versionNegotiation,\n ...(this._inputRequired ? { inputRequired: this._inputRequired } : {}),\n ...(this._responseCacheStore ? { responseCacheStore: this._responseCacheStore } : {}),\n ...(this._cachePartition !== undefined ? { cachePartition: this._cachePartition } : {}),\n ...(this._defaultCacheTtlMs !== undefined\n ? { defaultCacheTtlMs: this._defaultCacheTtlMs }\n : {}),\n },\n )\n\n this._registerHandlers(sdkClient)\n\n const { transport, beforeConnect } = await resolveTransport(this._input, this._auth, {\n legacySSE: this._legacySSE,\n versionNegotiation: this._versionNegotiation,\n })\n\n // Bind the server URL into the OAuth provider before the SDK transport\n // reads clientMetadata or tokens() so storage keys are properly namespaced.\n if (this._auth instanceof OAuth) {\n const serverUrl = this._extractServerUrl()\n if (serverUrl) this._auth._bind(serverUrl)\n }\n\n if (beforeConnect) await beforeConnect()\n\n this._transport = transport\n try {\n await sdkClient.connect(transport, this._prior ? { prior: this._prior } : undefined)\n } catch (err) {\n if (err instanceof UnauthorizedError && this._auth instanceof OAuth) {\n // The SDK opened the browser and is waiting for the user to authorize.\n // Wait for the callback to receive the full callback params (code +,\n // when present, the RFC 9207 `iss` parameter), then finish auth on the\n // original transport (it holds the discovery/PKCE context) to exchange\n // the code for tokens. Passing URLSearchParams (rather than a bare\n // code string) lets the SDK validate `iss` against the recorded\n // issuer before redeeming the code.\n const callbackParams = await this._auth.waitForCallback()\n await this._finishAuth(transport, callbackParams)\n // The original transport is already started and cannot be reconnected;\n // build a fresh one for the authenticated attempt. It reads the tokens\n // finishAuth stored in the auth provider. Pass the same resolution\n // options as the primary attempt so the retry keeps the SSE opt-in and\n // the era-negotiation mode.\n const retry = await resolveTransport(this._input, this._auth, {\n legacySSE: this._legacySSE,\n versionNegotiation: this._versionNegotiation,\n })\n if (retry.beforeConnect) await retry.beforeConnect()\n this._transport = retry.transport\n await sdkClient.connect(retry.transport)\n } else {\n throw err\n }\n }\n\n this._sdkClient = sdkClient\n }\n\n private _extractServerUrl(): string | undefined {\n const input = this._input\n if (typeof input === 'string') return input\n if (\n typeof input === 'object' &&\n input !== null &&\n 'mcpServers' in input\n ) {\n const entries = Object.entries(\n (input as { mcpServers: Record<string, { url?: string }> }).mcpServers,\n )\n if (entries.length > 0) {\n const [, entry] = entries[0]!\n if (entry && 'url' in entry && typeof entry.url === 'string') {\n return entry.url\n }\n }\n }\n return undefined\n }\n\n async close(): Promise<void> {\n this._refCount = Math.max(0, this._refCount - 1)\n if (this._refCount > 0) return\n\n // Close explicitly (and first) so its closure reason is 'local', not 'remote' —\n // otherwise the resource-subscription robustness handler above would try to\n // re-listen through a client that is already torn down.\n if (this._resourceListenSubscription) {\n await this._resourceListenSubscription.close().catch(() => {})\n this._resourceListenSubscription = undefined\n }\n\n const sdk = this._sdkClient\n this._sdkClient = null\n if (sdk) await sdk.close()\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close()\n }\n\n isConnected(): boolean {\n return this._sdkClient !== null\n }\n\n /** Creates a connected MultiServerClient when given a multi-entry McpConfig. */\n static async connect(input: McpConfig, options?: MultiServerOptions): Promise<MultiServerClient>\n /** Creates a connected Client for a single-server transport. Use with `await using` for automatic cleanup. */\n static async connect(input: ClientTransportInput, options?: ClientOptions): Promise<Client>\n static async connect(\n input: ClientTransportInput | McpConfig,\n options?: ClientOptions | MultiServerOptions,\n ): Promise<Client | MultiServerClient> {\n if (\n typeof input === 'object' &&\n input !== null &&\n 'mcpServers' in input &&\n Object.keys((input as McpConfig).mcpServers).length > 1\n ) {\n return MultiServerClient.connect(input as McpConfig, options as MultiServerOptions)\n }\n const client = new Client(input as ClientTransportInput, options as ClientOptions)\n await client.connect()\n return client\n }\n\n // -------------------------------------------------------------------------\n // Core protocol\n // -------------------------------------------------------------------------\n\n /**\n * Liveness check. On a legacy-era connection this sends the `ping` RPC. On a\n * modern (2026-07-28) connection `ping` is not a wire method — the era's\n * registry deliberately excludes it — so this sends `server/discover`\n * instead: any successful response is equally strong liveness evidence, and\n * `discover()` is the SDK-native modern equivalent (rather than a\n * hand-rolled substitute). Returns `false` only on legacy `ping`'s own\n * result; a modern-era failure throws, matching `ping()`'s existing\n * throw-on-failure contract.\n */\n async ping(options?: RequestOptions): Promise<boolean> {\n if (this.getProtocolEra() === 'modern') {\n await this._reauthRetry(() => this._sdk().discover(this._toSdkOptions(options)))\n return true\n }\n await this._reauthRetry(() => this._sdk().ping(this._toSdkOptions(options)))\n return true\n }\n\n /**\n * The protocol era negotiated at connect(): `'modern'` for 2026-07-28 (per-request\n * envelope), `'legacy'` for 2025-11-25 and earlier (the `initialize` handshake).\n * `undefined` before connect(). See `ClientOptions.versionNegotiation`.\n */\n getProtocolEra(): ProtocolEra | undefined {\n return this._sdkClient?.getProtocolEra()\n }\n\n /**\n * The connected server's self-reported identity (`serverInfo`: name, version,\n * and optional title / websiteUrl / icons), when it identified itself. On a\n * legacy connection it comes from the `initialize` result, where it is\n * required. On a modern (2026-07-28) connection it comes from the\n * `server/discover` result's metadata — FastMCP servers advertise it there,\n * but an anonymous modern server may omit it, leaving this `undefined`.\n * `undefined` before connect().\n */\n getServerInfo(): Implementation | undefined {\n return this._sdkClient?.getServerVersion()\n }\n\n /**\n * The server's `instructions` string, when the server provided one — from\n * the legacy `initialize` result or, on a modern (2026-07-28) connection,\n * from the `server/discover` result. `undefined` otherwise and before\n * connect().\n */\n getInstructions(): string | undefined {\n return this._sdkClient?.getInstructions()\n }\n\n /**\n * The capabilities the server advertised during connection — on the legacy\n * `initialize` result, or on the `server/discover` result for a modern\n * (2026-07-28) connection. `undefined` before connect().\n */\n getServerCapabilities(): ServerCapabilities | undefined {\n return this._sdkClient?.getServerCapabilities()\n }\n\n // -------------------------------------------------------------------------\n // Tools (IToolsClient)\n // -------------------------------------------------------------------------\n\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listTools(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.tool?.timeout),\n ),\n )\n return result.tools as Tool[]\n }\n\n async callTool<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const raw = await this.callToolRaw<TData>(name, args, options)\n if (raw.isError) {\n const message =\n (raw.content as Array<{ type: string; text?: string }>)\n .filter((c) => c.type === 'text')\n .map((c) => c.text ?? '')\n .join('\\n') || 'Tool returned an error'\n throw new ToolCallError(message, raw.content)\n }\n return raw\n }\n\n /** Returns the full result including isError without throwing. */\n async callToolRaw<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const sdkOptions = this._toSdkOptions(\n options,\n options?.onProgress,\n this._defaultOptions.tool?.timeout,\n )\n const result = await this._reauthRetry(() =>\n this._sdk().callTool({ name, arguments: args ?? {}, ...this._metaParams() }, sdkOptions),\n )\n return {\n content: result.content as ContentBlock[],\n structuredContent: (result.structuredContent as TData | undefined) ?? null,\n isError: result.isError === true,\n }\n }\n\n // -------------------------------------------------------------------------\n // Resources (IResourcesClient)\n // -------------------------------------------------------------------------\n\n async listResources(options?: RequestOptions): Promise<Resource[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listResources(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n return result.resources as Resource[]\n }\n\n async listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listResourceTemplates(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n return result.resourceTemplates as ResourceTemplate[]\n }\n\n async readResource(\n uri: string,\n options?: RequestOptions,\n ): Promise<Array<TextResourceContents | BlobResourceContents>> {\n const result = await this._reauthRetry(() =>\n this._sdk().readResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n return result.contents\n }\n\n /** Returns the raw SDK ReadResourceResult without unwrapping. */\n async readResourceRaw(uri: string, options?: RequestOptions) {\n return this._reauthRetry(() =>\n this._sdk().readResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n }\n\n /**\n * Subscribes to change notifications for a resource URI. `handler` fires whenever\n * the server sends a matching update, on either protocol era: on a legacy\n * (2025-era) connection via the `resources/subscribe` RPC and unsolicited\n * `notifications/resources/updated` push, or on a modern (2026-07-28) connection\n * via a `subscriptions/listen` stream opted into `resourceSubscriptions` — both\n * dispatch to the same `notifications/resources/updated` handler registered in\n * `_registerHandlers`, so this method is the only era-aware part.\n */\n async subscribeResource(\n uri: string,\n handler: ResourceUpdateHandler,\n options?: RequestOptions,\n ): Promise<void> {\n this._resourceSubscriptions.set(uri, handler)\n if (this._sdk().getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscription()\n } else {\n await this._reauthRetry(() =>\n this._sdk().subscribeResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n }\n }\n\n async unsubscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n this._resourceSubscriptions.delete(uri)\n if (this._sdk().getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscription()\n } else {\n await this._reauthRetry(() =>\n this._sdk().unsubscribeResource(\n { uri, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n )\n }\n }\n\n /**\n * Re-opens the modern-era resource-subscription listen stream with the current\n * set of subscribed URIs. `listen()` has no in-place filter update, so every\n * subscribe/unsubscribe on a modern connection closes the existing stream (if\n * any) and opens a fresh one — `subscribeResource`/`unsubscribeResource` are not\n * expected to be called at a high frequency, so this is not a hot path.\n */\n private async _refreshResourceListenSubscription(): Promise<void> {\n if (this._resourceListenSubscription) {\n await this._resourceListenSubscription.close()\n this._resourceListenSubscription = undefined\n }\n const uris = [...this._resourceSubscriptions.keys()]\n if (uris.length === 0) return\n\n // The modern subscribeResource/unsubscribeResource leg: opening the\n // `subscriptions/listen` stream is a server-auth-gated request, so it steps\n // up on a post-connect 401 like every other request method.\n const subscription = await this._reauthRetry(() =>\n this._sdk().listen({ resourceSubscriptions: uris }),\n )\n this._resourceListenSubscription = subscription\n\n // Robustness: an unexpected disconnect ('remote') re-establishes the stream so\n // resource-update delivery survives a dropped connection. A deliberate\n // server-side close ('graceful') is respected — the server chose to end it, and\n // re-listening would fight that decision. A close we triggered ourselves\n // ('local' — e.g. this same method superseding it above) needs no action; the\n // subscription-identity check also protects against acting on a stale handle.\n void subscription.closed.then((reason) => {\n if (reason === 'remote' && this._resourceListenSubscription === subscription) {\n this._resourceListenSubscription = undefined\n void this._refreshResourceListenSubscription().catch(() => {})\n }\n })\n }\n\n // -------------------------------------------------------------------------\n // Prompts (IPromptsClient)\n // -------------------------------------------------------------------------\n\n async listPrompts(options?: RequestOptions): Promise<Prompt[]> {\n const result = await this._reauthRetry(() =>\n this._sdk().listPrompts(\n this._metaParams(),\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n ),\n )\n return result.prompts as Prompt[]\n }\n\n async getPrompt(\n name: string,\n args?: Record<string, string>,\n options?: RequestOptions,\n ): Promise<GetPromptResult> {\n const result = await this._reauthRetry(() =>\n this._sdk().getPrompt(\n { name, arguments: args, ...this._metaParams() },\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n ),\n )\n return result as GetPromptResult\n }\n\n // -------------------------------------------------------------------------\n // Completion\n // -------------------------------------------------------------------------\n\n async complete(\n ref: { type: 'ref/prompt'; name: string } | { type: 'ref/resource'; uri: string },\n argument: { name: string; value: string },\n context?: { arguments?: Record<string, string> },\n options?: RequestOptions,\n ): Promise<CompletionResult> {\n const result = await this._reauthRetry(() =>\n this._sdk().complete(\n { ref, argument, ...(context ? { context } : {}), ...this._metaParams() },\n this._toSdkOptions(options),\n ),\n )\n return result.completion as CompletionResult\n }\n\n // -------------------------------------------------------------------------\n // Logging\n // -------------------------------------------------------------------------\n\n /**\n * Sets the minimum severity level for log messages sent by the server. On a\n * legacy-era connection this sends the `logging/setLevel` RPC, unchanged. On\n * a modern (2026-07-28) connection `logging/setLevel` is deprecated (SEP-2577)\n * and physically absent from the era's registry — there is no RPC to send.\n * Instead, the level is recorded and threaded into\n * `_meta['io.modelcontextprotocol/logLevel']` on every subsequent request via\n * `_metaParams()`, per request; user-supplied `_meta` still wins if a caller\n * passes one explicitly (there is no such call site in this class today).\n */\n async setLogLevel(level: LoggingLevel, options?: RequestOptions): Promise<void> {\n if (this.getProtocolEra() === 'modern') {\n this._logLevel = level\n return\n }\n await this._reauthRetry(() =>\n this._sdk().setLoggingLevel(level, this._toSdkOptions(options)),\n )\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private _sdk(): SdkClient {\n if (!this._sdkClient) {\n throw new Error('Client is not connected. Call connect() first.')\n }\n return this._sdkClient\n }\n\n /**\n * Runs a post-connect SDK request and, when it rejects with the SDK's\n * `UnauthorizedError` under an interactive {@link OAuth} provider, performs a\n * bounded number of step-up re-authorization rounds — the same\n * `waitForCallback`→`finishAuth` machinery `connect()` uses — retrying the\n * request after each.\n *\n * This closes the post-connect gap for interactive OAuth: a request that 401s\n * (missing/expired token) or 403s with an `insufficient_scope` challenge (a\n * broader scope is required for that operation) drives the SDK transport to\n * issue a fresh, scope-honoring authorization request and re-throw\n * `UnauthorizedError` — the transport picks the challenged/union scope itself\n * (`extractWWWAuthenticateParams` + `computeScopeUnion`); this wrapper only\n * completes the interrupted round and retries.\n *\n * The bound is {@link Client._MAX_REAUTH_ROUNDS}. One round covers ordinary\n * step-up (a single 401/403). Two rounds cover SEP-2352 authorization-server\n * migration: the first authenticated request flips the MCP server to a new\n * authorization server (its Protected Resource Metadata now lists a different\n * issuer), so the very next request 401s and must re-discover, re-register, and\n * re-authorize at the NEW server — a second round on the same wrapped request.\n * Beyond the bound the `UnauthorizedError` propagates, so a genuinely\n * unauthorized request never loops forever.\n *\n * Each round is single-flight: concurrent 401s share one `_reauthPromise`, and\n * each caller retries its own request after it resolves — a burst never opens\n * multiple browsers.\n *\n * Non-interactive auth is never re-authorized here — the original error\n * propagates unchanged. `BearerAuth` and custom headers carry no interactive\n * step, and a {@link ClientCredentials} scope failure is a machine-to-machine\n * misconfiguration (no user, no browser), not a step-up flow.\n * `MultiServerClient` configures no interactive OAuth by design, so this path\n * stays inert there.\n *\n * Every outbound request method routes through this wrapper, with one\n * exception: {@link Client.notifyRootsChanged} calls the SDK directly. It sends\n * a notification, not a request, so there is no response to 401/403 and\n * nothing to retry.\n *\n * `BrowserOAuth` (`extends OAuth`) is covered by the same guard, and its\n * `waitForCallback` is sound for a post-connect round — `redirectToAuthorization`\n * arms the callback promise before the transport re-throws. Two browser-only\n * caveats apply, honestly: in **popup** mode `window.open` needs a user gesture,\n * so a step-up fired from a request not within one is blocked and the re-auth\n * error propagates (call from a click); **redirect** mode navigates the whole\n * tab away (`window.location.assign`), destroying this in-flight retry — the app\n * recovers via `resumeFromRedirect()` on the return load and a fresh request,\n * not by this wrapper. The migration second round inherits the popup caveat: it\n * runs outside the original user gesture, so under `BrowserOAuth` popup mode it\n * hits the user-gesture block and surfaces as that error rather than opening a\n * second popup.\n */\n private async _reauthRetry<T>(op: () => Promise<T>): Promise<T> {\n let rounds = 0\n for (;;) {\n try {\n return await op()\n } catch (err) {\n if (!(err instanceof UnauthorizedError) || !(this._auth instanceof OAuth)) throw err\n // Bounded — see _MAX_REAUTH_ROUNDS. Beyond the bound the error propagates\n // so a genuinely unauthorized request never loops forever.\n if (rounds >= Client._MAX_REAUTH_ROUNDS) throw err\n rounds++\n await this._reauthorize(this._auth)\n }\n }\n }\n\n /** Single-flight wrapper around one re-authorization round. */\n private async _reauthorize(auth: OAuth): Promise<void> {\n this._reauthPromise ??= this._doReauthorize(auth).finally(() => {\n this._reauthPromise = null\n })\n await this._reauthPromise\n }\n\n /**\n * One re-authorization round: await the authorization callback the SDK\n * transport already armed (its 401/403 handling ran discovery + opened the\n * browser with the challenged scope), then `finishAuth()` redeems the code for\n * the broader-scope token on the live transport. The very next request reads\n * that token via the transport's per-request bearer-token bridge.\n *\n * After redeeming, the cached discovery state is invalidated so that the NEXT\n * authorization leg re-discovers the Protected Resource Metadata from scratch.\n * The SDK's `auth()` otherwise pins to the authorization server it first cached\n * and re-fetches PRM only when it has none — so it never notices a SEP-2352\n * migration (PRM `authorization_servers` changing to a new issuer). Clearing it\n * here (after the current round's callback leg has already consumed it) makes a\n * subsequent 401 re-run discovery, land on the new server, and register there.\n * Re-discovery is idempotent when the server has NOT migrated, so ordinary\n * step-up and token-refresh rounds are unaffected beyond one extra metadata\n * fetch.\n */\n private async _doReauthorize(auth: OAuth): Promise<void> {\n const callbackParams = await auth.waitForCallback()\n // `_transport` is always set post-connect (assigned in _doConnect before\n // `_sdkClient`), and this round only ever runs after a successful request —\n // so the guard is theoretical. It stays only to keep the type non-null\n // without a non-null assertion; a missing transport silently no-ops rather\n // than throwing, which is the safer degradation if that invariant ever breaks.\n if (this._transport) await this._finishAuth(this._transport, callbackParams)\n await auth.invalidateCredentials('discovery')\n }\n\n /**\n * Redeems the authorization callback params for tokens on `transport`, if it\n * exposes `finishAuth` (StreamableHTTP and SSE do). Shared by connect-time\n * recovery and post-connect step-up. Passing `URLSearchParams` (not a bare\n * code) lets the SDK validate the RFC 9207 `iss` before redeeming.\n */\n private async _finishAuth(transport: Transport, params: URLSearchParams): Promise<void> {\n if (\n 'finishAuth' in transport &&\n typeof (transport as Record<string, unknown>).finishAuth === 'function'\n ) {\n await (transport as { finishAuth(p: URLSearchParams): Promise<void> }).finishAuth(params)\n }\n }\n\n /**\n * The `_meta` override to merge into an outbound request's params — carries\n * `_logLevel` (set by setLogLevel() on a modern-era connection) so it rides\n * along on every subsequent request. Returns `undefined` (not `{}`) when\n * there is nothing to attach, so `{...this._metaParams()}` is a no-op and\n * callers that pass no params at all can keep passing `undefined` unchanged.\n */\n private _metaParams(): { _meta: Record<string, unknown> } | undefined {\n if (this._logLevel !== undefined && this.getProtocolEra() === 'modern') {\n return { _meta: { [LOG_LEVEL_META_KEY]: this._logLevel } }\n }\n return undefined\n }\n\n private _toSdkOptions(\n options?: RequestOptions,\n overrideProgress?: ProgressHandler,\n scopedTimeoutSeconds?: number,\n ): SdkRequestOptions {\n const timeoutSeconds =\n options?.timeout ?? scopedTimeoutSeconds ?? this._defaultOptions.timeout\n const progressHandler = overrideProgress ?? this._handlers.progress\n\n const sdkOptions: SdkRequestOptions = {}\n if (timeoutSeconds != null) sdkOptions.timeout = timeoutSeconds * 1000\n if (options?.signal) sdkOptions.signal = options.signal\n if (progressHandler) {\n sdkOptions.onprogress = ({ progress, total, message }) => {\n void progressHandler(progress, total, message)\n }\n }\n return sdkOptions\n }\n\n private _buildListChangedConfig() {\n const { onToolsListChanged, onResourcesListChanged, onPromptsListChanged } = this._handlers\n if (!onToolsListChanged && !onResourcesListChanged && !onPromptsListChanged) return undefined\n\n const adapt = <T>(h: ListChangedHandler<T>) => ({\n onChanged: (err: Error | null, items: T[] | null) => { void h.onChanged(err, items) },\n ...(h.autoRefresh !== undefined ? { autoRefresh: h.autoRefresh } : {}),\n ...(h.debounceMs !== undefined ? { debounceMs: h.debounceMs } : {}),\n })\n\n return {\n ...(onToolsListChanged ? { tools: adapt(onToolsListChanged) } : {}),\n ...(onResourcesListChanged ? { resources: adapt(onResourcesListChanged) } : {}),\n ...(onPromptsListChanged ? { prompts: adapt(onPromptsListChanged) } : {}),\n }\n }\n\n private _registerHandlers(sdk: SdkClient): void {\n // Log notifications from the server\n sdk.setNotificationHandler('notifications/message', (notification) => {\n void this._handlers.log({\n level: notification.params.level,\n logger: notification.params.logger ?? undefined,\n data: notification.params.data,\n })\n })\n\n // Resource update notifications (for active subscriptions)\n sdk.setNotificationHandler('notifications/resources/updated', (notification) => {\n const handler = this._resourceSubscriptions.get(notification.params.uri)\n if (handler) void handler(notification.params.uri)\n })\n\n // Sampling: server requests an LLM completion from the client\n if (this._handlers.sampling) {\n const samplingHandler = this._handlers.sampling\n sdk.setRequestHandler('sampling/createMessage', async (request) => {\n return samplingHandler(request.params)\n })\n }\n\n // Elicitation: server requests structured user input\n if (this._handlers.elicitation) {\n const elicitationHandler = this._handlers.elicitation\n sdk.setRequestHandler('elicitation/create', async (request) => {\n return elicitationHandler(request.params)\n })\n }\n\n // Roots: server requests the client's accessible filesystem roots\n if (this._roots) {\n const getRoots = this._roots\n sdk.setRequestHandler('roots/list', async () => ({\n roots: await getRoots(),\n }))\n }\n }\n\n // -------------------------------------------------------------------------\n // Roots\n // -------------------------------------------------------------------------\n\n /**\n * Notify the connected server that the client's roots list has changed.\n * The server should re-issue a roots/list request to get the updated list.\n */\n async notifyRootsChanged(): Promise<void> {\n await this._sdk().sendRootsListChanged()\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction resolveAuth(\n auth: BearerAuth | OAuth | AsyncHeaderAuth | string | undefined,\n): BearerAuth | OAuth | AsyncHeaderAuth | undefined {\n if (!auth) return undefined\n if (typeof auth === 'string') return new BearerAuth(auth)\n return auth\n}\n\nfunction normalizeRootsOption(roots: RootsValue): () => Promise<Root[]> {\n if (typeof roots === 'function') {\n return async () => Promise.all((await roots()).map(normalizeRootInput))\n }\n return async () => Promise.all(roots.map(normalizeRootInput))\n}\n\nasync function normalizeRootInput(input: RootInput): Promise<Root> {\n if (typeof input === 'string') return { uri: await normalizeRootUri(input) }\n return { ...input, uri: await normalizeRootUri(input.uri) }\n}\n\nasync function normalizeRootUri(input: string): Promise<string> {\n // Already a URI (file://, http://, ...) — pass through with no Node import.\n if (/^[a-z][a-z0-9+.-]*:\\/\\//i.test(input)) return input\n // A bare filesystem path requires Node to resolve against the cwd.\n if (typeof process === 'undefined' || !process.versions?.node) {\n throw new Error(\n `Cannot normalize filesystem root \"${input}\" in a browser. Pass a file:// URI instead.`,\n )\n }\n const { resolve } = await import('node:path')\n const { pathToFileURL } = await import('node:url')\n return pathToFileURL(resolve(input)).href\n}\n","import type { ClientCapabilities } from '@modelcontextprotocol/client'\n\ninterface InferredClientCapabilities {\n sampling: boolean\n elicitation: boolean\n rootsListChanged?: boolean\n}\n\nexport function buildClientCapabilities(\n supplied: ClientCapabilities | undefined,\n inferred: InferredClientCapabilities,\n): ClientCapabilities {\n const capabilities: ClientCapabilities = { ...supplied }\n\n if (inferred.sampling) {\n capabilities.sampling = {\n ...supplied?.sampling,\n tools: supplied?.sampling?.tools ?? {},\n }\n }\n\n if (inferred.elicitation) {\n const elicitation = supplied?.elicitation\n capabilities.elicitation = elicitation\n ? { ...elicitation, form: elicitation.form ?? {} }\n : {}\n }\n\n if (inferred.rootsListChanged !== undefined) {\n capabilities.roots = {\n ...supplied?.roots,\n listChanged: inferred.rootsListChanged,\n }\n }\n\n return capabilities\n}\n","import type { LoggingLevel, RequestOptions as SdkRequestOptions } from \"@modelcontextprotocol/server\";\nimport { Client as SdkClient, LOG_LEVEL_META_KEY } from '@modelcontextprotocol/client'\nimport type { ClientCapabilities, McpSubscription, VersionNegotiationOptions, ProtocolEra } from '@modelcontextprotocol/client'\nimport type { BearerAuth, OAuth, ClientCredentials } from './auth.js'\nimport { buildClientCapabilities } from './capabilities.js'\nimport type { ClientHandlers, LogHandler, ProgressHandler, ResourceUpdateHandler } from './handlers.js'\nimport { defaultLogHandler, defaultProgressHandler } from './handlers.js'\nimport type { CallToolOptions, IClient, RequestOptions } from './interfaces.js'\nimport type {\n CallToolResult,\n CompletionResult,\n ContentBlock,\n GetPromptResult,\n Prompt,\n Resource,\n TextResourceContents,\n BlobResourceContents,\n ResourceTemplate,\n Tool,\n} from './results.js'\nimport type { McpConfig, McpServerValue } from './transports.js'\nimport { resolveEntryTransport } from './transports.js'\nimport type { ClientDefaultOptions } from './options.js'\nimport { ToolCallError } from './client.js'\n// ---------------------------------------------------------------------------\n// Options\n// ---------------------------------------------------------------------------\n\nexport interface MultiServerOptions {\n handlers?: ClientHandlers\n /**\n * Additional capabilities to advertise to every server. FastMCP combines\n * them with capabilities inferred from handlers and roots.\n */\n capabilities?: ClientCapabilities\n /** file:// URIs to advertise to all servers as accessible roots. */\n roots?: string[]\n defaultOptions?: ClientDefaultOptions\n /**\n * Protocol version negotiation, applied identically to every server in the\n * config (protocol revision 2026-07-28 and later). See\n * `ClientOptions.versionNegotiation` on the single-server `Client` — same\n * semantics, just applied per sub-client here since each connected server\n * negotiates its own era independently. Default `{ mode: 'auto' }`: each\n * sub-client probes its server once and falls back to legacy when the\n * server offers no modern era; `{ mode: 'legacy' }` opts every connection\n * out of the probe.\n */\n versionNegotiation?: VersionNegotiationOptions\n}\n\n// ---------------------------------------------------------------------------\n// MultiServerClient\n// ---------------------------------------------------------------------------\n\nexport class MultiServerClient implements IClient {\n private _clients: Map<string, SdkClient> = new Map()\n private _connectPromise: Promise<void> | null = null\n private _connected = false\n\n /** URI (or namespaced template URI) → server name, populated by list calls */\n private _uriMap: Map<string, string> = new Map()\n\n private readonly _config: McpConfig\n private readonly _handlers: {\n log: LogHandler\n progress: ProgressHandler\n sampling?: ClientHandlers['sampling']\n elicitation?: ClientHandlers['elicitation']\n }\n private readonly _roots: string[] | undefined\n private readonly _capabilities: ClientCapabilities\n private readonly _defaultOptions: ClientDefaultOptions\n private readonly _versionNegotiation: VersionNegotiationOptions\n private _resourceSubscriptions: Map<string, ResourceUpdateHandler> = new Map()\n /** Modern-era (2026-07-28) subscriptions/listen streams, one per server that\n * currently has active resource subscriptions — see Client's own field of the\n * same purpose for the full rationale. Keyed by server name since each\n * connected server negotiates its own era independently. */\n private _resourceListenSubscriptions: Map<string, McpSubscription> = new Map()\n /** Per-server log level set by setLogLevel() for servers negotiated to modern\n * era — see Client's own field of the same purpose for the full rationale.\n * Keyed by server name since each connected server negotiates its own era\n * independently and may therefore need (or not need) meta-threading. */\n private _logLevels: Map<string, LoggingLevel> = new Map()\n\n constructor(config: McpConfig, options?: MultiServerOptions) {\n this._config = config\n this._handlers = {\n log: options?.handlers?.log ?? defaultLogHandler,\n progress: options?.handlers?.progress ?? defaultProgressHandler,\n sampling: options?.handlers?.sampling,\n elicitation: options?.handlers?.elicitation,\n }\n this._versionNegotiation = options?.versionNegotiation ?? { mode: 'auto' }\n this._roots = options?.roots\n this._capabilities = buildClientCapabilities(options?.capabilities, {\n sampling: this._handlers.sampling !== undefined,\n elicitation: this._handlers.elicitation !== undefined,\n rootsListChanged: this._roots === undefined ? undefined : false,\n })\n this._defaultOptions = options?.defaultOptions ?? {}\n }\n\n // -------------------------------------------------------------------------\n // Lifecycle\n // -------------------------------------------------------------------------\n\n async connect(): Promise<void> {\n if (this._connected) return\n if (this._connectPromise) {\n await this._connectPromise\n return\n }\n\n this._connectPromise = this._doConnect().finally(() => {\n this._connectPromise = null\n })\n\n await this._connectPromise\n }\n\n private async _doConnect(): Promise<void> {\n const entries = Object.entries(this._config.mcpServers)\n if (entries.length === 0) throw new Error('mcpServers config is empty')\n\n const connected: Array<[string, SdkClient]> = []\n\n try {\n await Promise.all(\n entries.map(async ([name, entry]) => {\n const sdk = this._buildSdkClient()\n this._registerHandlers(sdk)\n const { transport, beforeConnect } = await resolveEntryTransport(\n entry as McpServerValue,\n undefined,\n { versionNegotiation: this._versionNegotiation },\n )\n if (beforeConnect) await beforeConnect()\n await sdk.connect(transport)\n connected.push([name, sdk])\n }),\n )\n } catch (err) {\n // Roll back any connections that succeeded before the failure.\n await Promise.allSettled(connected.map(([, sdk]) => sdk.close()))\n throw err\n }\n\n for (const [name, sdk] of connected) {\n this._clients.set(name, sdk)\n }\n\n this._connected = true\n }\n\n async close(): Promise<void> {\n if (!this._connected) return\n this._connected = false\n this._uriMap.clear()\n // Close explicitly (and first) so each closure reason is 'local', not 'remote' —\n // see Client.close()'s equivalent ordering for the full rationale.\n await Promise.allSettled(\n [...this._resourceListenSubscriptions.values()].map((sub) => sub.close()),\n )\n this._resourceListenSubscriptions.clear()\n await Promise.allSettled([...this._clients.values()].map((sdk) => sdk.close()))\n this._clients.clear()\n }\n\n async [Symbol.asyncDispose](): Promise<void> {\n await this.close()\n }\n\n isConnected(): boolean {\n return this._connected\n }\n\n static async connect(\n config: McpConfig,\n options?: MultiServerOptions,\n ): Promise<MultiServerClient> {\n const client = new MultiServerClient(config, options)\n await client.connect()\n return client\n }\n\n // -------------------------------------------------------------------------\n // Core protocol\n // -------------------------------------------------------------------------\n\n /**\n * The protocol era negotiated with a specific named server: `'modern'` for\n * 2026-07-28, `'legacy'` for 2025-11-25 and earlier, `undefined` if the\n * server name is unknown or not yet connected. See\n * `MultiServerOptions.versionNegotiation` — the same mode is requested of\n * every server, but each negotiates (and may land on) its own era\n * independently, so this is necessarily per-server rather than a single\n * client-wide value.\n */\n getProtocolEra(serverName: string): ProtocolEra | undefined {\n return this._clients.get(serverName)?.getProtocolEra()\n }\n\n /** See Client.ping's docs — the same era-routing applies here, per server,\n * since each connected server negotiates its own era independently. */\n async ping(options?: RequestOptions): Promise<boolean> {\n this._assertConnected()\n await Promise.all(\n [...this._clients.values()].map((sdk) =>\n sdk.getProtocolEra() === 'modern'\n ? sdk.discover(this._toSdkOptions(options))\n : sdk.ping(this._toSdkOptions(options)),\n ),\n )\n return true\n }\n\n // -------------------------------------------------------------------------\n // Tools\n // -------------------------------------------------------------------------\n\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listTools(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.tool?.timeout),\n )\n return (r.tools as Tool[]).map((t) => ({ ...t, name: `${name}_${t.name}` }))\n }),\n )\n return results.flat()\n }\n\n async callTool<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const raw = await this.callToolRaw<TData>(name, args, options)\n if (raw.isError) {\n const message =\n (raw.content as Array<{ type: string; text?: string }>)\n .filter((c) => c.type === 'text')\n .map((c) => c.text ?? '')\n .join('\\n') || 'Tool returned an error'\n throw new ToolCallError(message, raw.content)\n }\n return raw\n }\n\n async callToolRaw<TData = unknown>(\n name: string,\n args?: Record<string, unknown>,\n options?: CallToolOptions,\n ): Promise<CallToolResult<TData>> {\n const { serverName, localName } = this._parseNamespacedName(name)\n const sdk = this._sdkForServer(serverName)\n const sdkOptions = this._toSdkOptions(\n options,\n options?.onProgress,\n this._defaultOptions.tool?.timeout,\n )\n const result = await sdk.callTool(\n { name: localName, arguments: args ?? {}, ...this._metaParamsFor(serverName) },\n sdkOptions,\n )\n return {\n content: result.content as ContentBlock[],\n structuredContent: (result.structuredContent as TData | undefined) ?? null,\n isError: result.isError === true,\n }\n }\n\n // -------------------------------------------------------------------------\n // Resources\n // -------------------------------------------------------------------------\n\n async listResources(options?: RequestOptions): Promise<Resource[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listResources(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n const resources = r.resources as Resource[]\n for (const res of resources) {\n this._uriMap.set(res.uri, name)\n }\n return resources.map((res) => ({\n ...res,\n name: res.name ? `${name}_${res.name}` : res.name,\n }))\n }),\n )\n return results.flat()\n }\n\n async listResourceTemplates(options?: RequestOptions): Promise<ResourceTemplate[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listResourceTemplates(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n const templates = r.resourceTemplates as ResourceTemplate[]\n for (const tmpl of templates) {\n this._uriMap.set(tmpl.uriTemplate, name)\n }\n return templates.map((tmpl) => ({\n ...tmpl,\n name: tmpl.name ? `${name}_${tmpl.name}` : tmpl.name,\n }))\n }),\n )\n return results.flat()\n }\n\n async readResource(\n uri: string,\n options?: RequestOptions,\n ): Promise<Array<TextResourceContents | BlobResourceContents>> {\n this._assertConnected()\n const sdkOptions = this._toSdkOptions(\n options,\n undefined,\n this._defaultOptions.resource?.timeout,\n )\n\n // Fast path: URI was seen during a previous list call.\n const knownServer = this._uriMap.get(uri)\n if (knownServer) {\n const sdk = this._clients.get(knownServer)!\n const result = await sdk.readResource({ uri, ...this._metaParamsFor(knownServer) }, sdkOptions)\n return result.contents\n }\n\n // Fallback: try each server in order, return the first success.\n const errors: unknown[] = []\n for (const [name, sdk] of this._clients) {\n try {\n const result = await sdk.readResource({ uri, ...this._metaParamsFor(name) }, sdkOptions)\n return result.contents\n } catch (err) {\n errors.push(err)\n }\n }\n throw new Error(\n `Resource not found on any server: ${uri}\\n` +\n errors.map((e) => String(e)).join('\\n'),\n )\n }\n\n // -------------------------------------------------------------------------\n // Prompts\n // -------------------------------------------------------------------------\n\n async listPrompts(options?: RequestOptions): Promise<Prompt[]> {\n this._assertConnected()\n const results = await Promise.all(\n [...this._clients.entries()].map(async ([name, sdk]) => {\n const r = await sdk.listPrompts(\n this._metaParamsFor(name),\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n )\n return (r.prompts as Prompt[]).map((p) => ({ ...p, name: `${name}_${p.name}` }))\n }),\n )\n return results.flat()\n }\n\n async getPrompt(\n name: string,\n args?: Record<string, string>,\n options?: RequestOptions,\n ): Promise<GetPromptResult> {\n const { serverName, localName } = this._parseNamespacedName(name)\n const sdk = this._sdkForServer(serverName)\n const result = await sdk.getPrompt(\n { name: localName, arguments: args, ...this._metaParamsFor(serverName) },\n this._toSdkOptions(options, undefined, this._defaultOptions.prompt?.timeout),\n )\n return result as GetPromptResult\n }\n\n // -------------------------------------------------------------------------\n // Resource subscriptions\n // -------------------------------------------------------------------------\n\n /** See Client.subscribeResource's docs — the same era-routing applies here,\n * per server, since each connected server negotiates its own era. */\n async subscribeResource(\n uri: string,\n handler: ResourceUpdateHandler,\n options?: RequestOptions,\n ): Promise<void> {\n this._assertConnected()\n this._resourceSubscriptions.set(uri, handler)\n const serverName = this._uriMap.get(uri)\n if (serverName) {\n const sdk = this._clients.get(serverName)!\n if (sdk.getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscriptionForServer(serverName)\n } else {\n await sdk.subscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n }\n return\n }\n // Fallback: the URI's owning server isn't known yet (listResources() was never\n // called). Only legacy-era servers can be probed this way — the validating\n // resources/subscribe RPC either succeeds (that server owns the URI) or throws;\n // listen() has no equivalent per-URI validation, so a modern-era server can't be\n // ruled in or out by trying it, and is skipped in this fallback.\n const errors: unknown[] = []\n for (const [name, sdk] of this._clients) {\n if (sdk.getProtocolEra() === 'modern') continue\n try {\n await sdk.subscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n this._uriMap.set(uri, name)\n return\n } catch (err) {\n errors.push(err)\n }\n }\n throw new Error(`Subscribe failed on all servers:\\n${errors.map(String).join('\\n')}`)\n }\n\n async unsubscribeResource(uri: string, options?: RequestOptions): Promise<void> {\n this._assertConnected()\n this._resourceSubscriptions.delete(uri)\n const serverName = this._uriMap.get(uri)\n if (serverName) {\n const sdk = this._clients.get(serverName)!\n if (sdk.getProtocolEra() === 'modern') {\n await this._refreshResourceListenSubscriptionForServer(serverName)\n } else {\n await sdk.unsubscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n )\n }\n return\n }\n await Promise.allSettled(\n [...this._clients.values()]\n .filter((sdk) => sdk.getProtocolEra() !== 'modern')\n .map((sdk) =>\n sdk.unsubscribeResource(\n { uri },\n this._toSdkOptions(options, undefined, this._defaultOptions.resource?.timeout),\n ),\n ),\n )\n }\n\n /** Re-opens server-scoped listen stream for its currently-subscribed URIs — see\n * Client's own private method of the same purpose for the full rationale. */\n private async _refreshResourceListenSubscriptionForServer(serverName: string): Promise<void> {\n const existing = this._resourceListenSubscriptions.get(serverName)\n if (existing) {\n await existing.close()\n this._resourceListenSubscriptions.delete(serverName)\n }\n const uris = [...this._resourceSubscriptions.keys()].filter(\n (uri) => this._uriMap.get(uri) === serverName,\n )\n if (uris.length === 0) return\n\n const sdk = this._clients.get(serverName)!\n const subscription = await sdk.listen({ resourceSubscriptions: uris })\n this._resourceListenSubscriptions.set(serverName, subscription)\n\n void subscription.closed.then((reason) => {\n if (reason === 'remote' && this._resourceListenSubscriptions.get(serverName) === subscription) {\n this._resourceListenSubscriptions.delete(serverName)\n void this._refreshResourceListenSubscriptionForServer(serverName).catch(() => {})\n }\n })\n }\n\n // -------------------------------------------------------------------------\n // Completion\n // -------------------------------------------------------------------------\n\n async complete(\n ref: { type: 'ref/prompt'; name: string } | { type: 'ref/resource'; uri: string },\n argument: { name: string; value: string },\n context?: { arguments?: Record<string, string> },\n options?: RequestOptions,\n ): Promise<CompletionResult> {\n this._assertConnected()\n const sdkOptions = this._toSdkOptions(options)\n\n if (ref.type === 'ref/prompt') {\n const { serverName, localName } = this._parseNamespacedName(ref.name)\n const sdk = this._sdkForServer(serverName)\n const result = await sdk.complete(\n {\n ref: { type: 'ref/prompt', name: localName },\n argument,\n ...(context ? { context } : {}),\n ...this._metaParamsFor(serverName),\n },\n sdkOptions,\n )\n return result.completion as CompletionResult\n }\n\n const serverName = this._uriMap.get(ref.uri)\n if (serverName) {\n const result = await this._clients.get(serverName)!.complete(\n { ref, argument, ...(context ? { context } : {}), ...this._metaParamsFor(serverName) },\n sdkOptions,\n )\n return result.completion as CompletionResult\n }\n\n const errors: unknown[] = []\n for (const [name, sdk] of this._clients) {\n try {\n const result = await sdk.complete(\n { ref, argument, ...(context ? { context } : {}), ...this._metaParamsFor(name) },\n sdkOptions,\n )\n return result.completion as CompletionResult\n } catch (err) {\n errors.push(err)\n }\n }\n throw new Error(`Completion failed on all servers:\\n${errors.map(String).join('\\n')}`)\n }\n\n // -------------------------------------------------------------------------\n // Logging\n // -------------------------------------------------------------------------\n\n /** See Client.setLogLevel's docs — the same era-routing applies here, per\n * server: legacy sends the real `logging/setLevel` RPC; modern records the\n * level and threads it into `_meta` on that server's subsequent requests via\n * `_metaParamsFor`, since `logging/setLevel` is absent from the modern wire\n * registry (SEP-2577). */\n async setLogLevel(level: LoggingLevel, options?: RequestOptions): Promise<void> {\n this._assertConnected()\n await Promise.all(\n [...this._clients.entries()].map(([name, sdk]) => {\n if (sdk.getProtocolEra() === 'modern') {\n this._logLevels.set(name, level)\n return undefined\n }\n return sdk.setLoggingLevel(level, this._toSdkOptions(options))\n }),\n )\n }\n\n // -------------------------------------------------------------------------\n // Private helpers\n // -------------------------------------------------------------------------\n\n private _assertConnected(): void {\n if (!this._connected) {\n throw new Error('MultiServerClient is not connected. Call connect() first.')\n }\n }\n\n private _parseNamespacedName(name: string): { serverName: string; localName: string } {\n // Sort longest-first so that server names like \"my_server\" are matched\n // before the shorter prefix \"my\".\n const serverNames = [...this._clients.keys()].sort((a, b) => b.length - a.length)\n for (const serverName of serverNames) {\n const prefix = `${serverName}_`\n if (name.startsWith(prefix)) {\n return { serverName, localName: name.slice(prefix.length) }\n }\n }\n throw new Error(\n `Tool/prompt name \"${name}\" has no server namespace prefix. ` +\n `Expected format: \"<serverName>_<name>\".`,\n )\n }\n\n private _sdkForServer(serverName: string): SdkClient {\n const sdk = this._clients.get(serverName)\n if (!sdk) {\n throw new Error(\n `No server named \"${serverName}\" in this MultiServerClient. ` +\n `Known servers: ${[...this._clients.keys()].join(', ')}.`,\n )\n }\n return sdk\n }\n\n private _buildSdkClient(): SdkClient {\n return new SdkClient(\n { name: 'fastmcp-ts', version: '1.0.0' },\n {\n capabilities: this._capabilities,\n versionNegotiation: this._versionNegotiation,\n },\n )\n }\n\n private _registerHandlers(sdk: SdkClient): void {\n sdk.setNotificationHandler('notifications/message', (notification) => {\n void this._handlers.log({\n level: notification.params.level,\n logger: notification.params.logger ?? undefined,\n data: notification.params.data,\n })\n })\n\n sdk.setNotificationHandler('notifications/resources/updated', (notification) => {\n const handler = this._resourceSubscriptions.get(notification.params.uri)\n if (handler) void handler(notification.params.uri)\n })\n\n if (this._handlers.sampling) {\n const h = this._handlers.sampling\n sdk.setRequestHandler('sampling/createMessage', async (req) => h(req.params))\n }\n\n if (this._handlers.elicitation) {\n const h = this._handlers.elicitation\n sdk.setRequestHandler('elicitation/create', async (req) => h(req.params))\n }\n\n if (this._roots) {\n const roots = this._roots\n sdk.setRequestHandler('roots/list', async () => ({\n roots: roots.map((uri) => ({ uri })),\n }))\n }\n }\n\n /** See Client._metaParams's docs — the same purpose, per server name, since\n * each connected server may be on a different era and have a different\n * recorded log level (or none). */\n private _metaParamsFor(serverName: string): { _meta: Record<string, unknown> } | undefined {\n const level = this._logLevels.get(serverName)\n if (level === undefined) return undefined\n return { _meta: { [LOG_LEVEL_META_KEY]: level } }\n }\n\n private _toSdkOptions(\n options?: RequestOptions,\n overrideProgress?: ProgressHandler,\n scopedTimeoutSeconds?: number,\n ): SdkRequestOptions {\n const timeoutSeconds =\n options?.timeout ?? scopedTimeoutSeconds ?? this._defaultOptions.timeout\n const progressHandler = overrideProgress ?? this._handlers.progress\n\n const sdkOptions: SdkRequestOptions = {}\n if (timeoutSeconds != null) sdkOptions.timeout = timeoutSeconds * 1000\n if (options?.signal) sdkOptions.signal = options.signal\n if (progressHandler) {\n sdkOptions.onprogress = ({ progress, total, message }) => {\n void progressHandler(progress, total, message)\n }\n }\n return sdkOptions\n }\n}\n","export type Result<T, E = Error> =\n | { ok: true; value: T }\n | { ok: false; error: E }\n\nexport async function toResult<T, E = Error>(\n fn: Promise<T> | (() => Promise<T>),\n): Promise<Result<T, E>> {\n try {\n const value = await (typeof fn === 'function' ? fn() : fn)\n return { ok: true, value }\n } catch (error) {\n return { ok: false, error: error as E }\n }\n}\n","import type { ModelPreferences } from \"@modelcontextprotocol/server\";\nimport type { SamplingHandler } from '../handlers.js'\n\nexport type { SamplingHandler }\n\n/**\n * Resolve a concrete model name from the server's modelPreferences.\n * A plain string always uses that model; a function inspects the preferences.\n */\nexport type ModelSelector = string | ((prefs: ModelPreferences | undefined) => string)\n\n/** Called with each text token as it is streamed from the provider. */\nexport type OnTokenCallback = (token: string) => void\n\nexport interface SamplingAdapterOptions {\n /** Override or replace the model selection logic. */\n modelSelector?: ModelSelector\n /** Fired for each streamed text token. Tool-use deltas are not surfaced. */\n onToken?: OnTokenCallback\n}\n\n/** Implemented by all sampling adapters. */\nexport interface SamplingAdapter {\n asHandler(): SamplingHandler\n}\n\n// ---------------------------------------------------------------------------\n// Shared helpers\n// ---------------------------------------------------------------------------\n\nexport function resolveModel(\n prefs: ModelPreferences | undefined,\n selector: ModelSelector | undefined,\n defaultModel: string,\n): string {\n if (!selector) {\n return prefs?.hints?.[0]?.name ?? defaultModel\n }\n if (typeof selector === 'string') return selector\n return selector(prefs)\n}\n","import type { SamplingMessage, Tool, ToolChoice, CreateMessageRequestParams } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingAdapter, SamplingAdapterOptions, ModelSelector, OnTokenCallback } from './types.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport { resolveModel } from './types.js'\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface GenericCompletionParams {\n model: string\n messages: SamplingMessage[]\n system?: string\n /** Defaulted to 1024 when absent in the original request. */\n maxTokens: number\n temperature?: number\n stopSequences?: string[]\n tools?: Tool[]\n toolChoice?: ToolChoice\n onToken?: OnTokenCallback\n}\n\nexport type GenericCompletionFn = (\n params: GenericCompletionParams,\n) => Promise<AnySamplingResult>\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\n/**\n * Contribution template. Wraps any async function into a SamplingHandler.\n *\n * The adapter resolves the model from modelPreferences, defaults maxTokens,\n * and threads onToken through. Message format conversion, tool translation,\n * and streaming are the caller's responsibility.\n *\n * Example:\n * ```ts\n * const adapter = new GenericSamplingAdapter(async ({ model, messages }) => {\n * const text = await myLlm.complete(model, messages)\n * return { role: 'assistant', content: { type: 'text', text }, model, stopReason: 'endTurn' }\n * })\n * ```\n */\nexport class GenericSamplingAdapter implements SamplingAdapter {\n private readonly _fn: GenericCompletionFn\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n fn: GenericCompletionFn,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._fn = fn\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'unknown',\n )\n return this._fn({\n model,\n messages: params.messages,\n system: params.systemPrompt,\n maxTokens: params.maxTokens ?? 1024,\n temperature: params.temperature,\n stopSequences: params.stopSequences,\n tools: params.tools,\n toolChoice: params.toolChoice,\n onToken: this._options.onToken,\n })\n }\n }\n}\n","import type Anthropic from '@anthropic-ai/sdk'\nimport type {\n ContentBlockParam,\n ToolResultBlockParam,\n} from '@anthropic-ai/sdk/resources/messages'\nimport type { CreateMessageRequestParams, SamplingMessage, Tool, ToolChoice, ToolUseContent } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport type { SamplingAdapter, SamplingAdapterOptions } from './types.js'\nimport { resolveModel } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Message translation\n// ---------------------------------------------------------------------------\n\nfunction toBlocks(content: SamplingMessage['content']): ContentBlockParam[] {\n const items = Array.isArray(content) ? content : [content]\n const out: ContentBlockParam[] = []\n\n for (const block of items) {\n if (block.type === 'text') {\n out.push({ type: 'text', text: block.text })\n } else if (block.type === 'image') {\n out.push({\n type: 'image',\n source: {\n type: 'base64',\n media_type: block.mimeType as Anthropic.Base64ImageSource['media_type'],\n data: block.data,\n },\n })\n } else if (block.type === 'tool_use') {\n out.push({\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input as Record<string, unknown>,\n })\n } else if (block.type === 'tool_result') {\n const resultContent: ToolResultBlockParam['content'] = block.content.flatMap((c) =>\n c.type === 'text' ? [{ type: 'text' as const, text: c.text }] : [],\n )\n out.push({\n type: 'tool_result',\n tool_use_id: block.toolUseId,\n content: resultContent,\n is_error: block.isError,\n })\n }\n // audio: not supported by Anthropic messages API — skip\n }\n return out\n}\n\nfunction toAnthropicMessages(messages: SamplingMessage[]): Anthropic.MessageParam[] {\n return messages.map((m) => ({\n role: m.role as 'user' | 'assistant',\n content: toBlocks(m.content),\n }))\n}\n\nfunction toAnthropicTools(tools: Tool[]): Anthropic.Tool[] {\n return tools.map((t) => ({\n name: t.name,\n description: t.description ?? '',\n input_schema: t.inputSchema as Anthropic.Tool['input_schema'],\n }))\n}\n\nfunction toAnthropicToolChoice(\n choice: ToolChoice | undefined,\n): Anthropic.MessageCreateParams['tool_choice'] {\n if (!choice) return undefined\n if (choice.mode === 'required') return { type: 'any' }\n return { type: 'auto' }\n}\n\n// ---------------------------------------------------------------------------\n// Response mapping\n// ---------------------------------------------------------------------------\n\nfunction mapStopReason(reason: string | null | undefined): string {\n if (reason === 'end_turn') return 'endTurn'\n if (reason === 'stop_sequence') return 'stopSequence'\n if (reason === 'max_tokens') return 'maxTokens'\n if (reason === 'tool_use') return 'toolUse'\n return reason ?? 'endTurn'\n}\n\nfunction buildResult(message: Anthropic.Message): AnySamplingResult {\n const stopReason = mapStopReason(message.stop_reason)\n\n if (stopReason === 'toolUse') {\n const content = message.content.flatMap((block): ToolUseContent[] => {\n if (block.type === 'tool_use') {\n return [{\n type: 'tool_use',\n id: block.id,\n name: block.name,\n input: block.input as Record<string, unknown>,\n }]\n }\n return []\n })\n return { role: 'assistant', model: message.model, stopReason, content }\n }\n\n const textBlock = message.content.find((b) => b.type === 'text')\n const text = textBlock?.type === 'text' ? textBlock.text : ''\n return { role: 'assistant', model: message.model, stopReason, content: { type: 'text', text } }\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport class AnthropicSamplingAdapter implements SamplingAdapter {\n private readonly _client: Anthropic\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n client: Anthropic,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._client = client\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'claude-opus-4-5',\n )\n\n const omitTools = params.toolChoice?.mode === 'none'\n const tools = !omitTools && params.tools?.length\n ? toAnthropicTools(params.tools)\n : undefined\n const toolChoice = tools ? toAnthropicToolChoice(params.toolChoice) : undefined\n const onToken = this._options.onToken\n\n const stream = this._client.messages.stream({\n model,\n messages: toAnthropicMessages(params.messages),\n max_tokens: params.maxTokens ?? 1024,\n ...(params.systemPrompt !== undefined ? { system: params.systemPrompt } : {}),\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences?.length ? { stop_sequences: params.stopSequences } : {}),\n ...(tools ? { tools } : {}),\n ...(toolChoice ? { tool_choice: toolChoice } : {}),\n })\n\n if (onToken) {\n stream.on('text', (text) => { onToken(text) })\n }\n\n const message = await stream.finalMessage()\n return buildResult(message)\n }\n }\n}\n","import type OpenAI from 'openai'\nimport type { CreateMessageRequestParams, SamplingMessage, Tool, ToolChoice, ToolUseContent } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport type { SamplingAdapter, SamplingAdapterOptions } from './types.js'\nimport { resolveModel } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Message translation\n// ---------------------------------------------------------------------------\n\ntype OAIMessage = OpenAI.Chat.ChatCompletionMessageParam\n\nfunction toContentParts(\n content: SamplingMessage['content'],\n): string | OpenAI.Chat.ChatCompletionContentPart[] {\n const items = Array.isArray(content) ? content : [content]\n // Collapse single text block to a plain string for simplicity\n if (items.length === 1 && items[0].type === 'text') return items[0].text\n\n return items.flatMap((block): OpenAI.Chat.ChatCompletionContentPart[] => {\n if (block.type === 'text') {\n return [{ type: 'text', text: block.text }]\n } else if (block.type === 'image') {\n return [{\n type: 'image_url',\n image_url: { url: `data:${block.mimeType};base64,${block.data}` },\n }]\n }\n return []\n })\n}\n\nfunction toOpenAIMessages(\n messages: SamplingMessage[],\n systemPrompt: string | undefined,\n): OAIMessage[] {\n const out: OAIMessage[] = []\n\n if (systemPrompt) {\n out.push({ role: 'system', content: systemPrompt })\n }\n\n for (const m of messages) {\n const items = Array.isArray(m.content) ? m.content : [m.content]\n\n // tool_use blocks → assistant message with tool_calls\n const toolUseItems = items.filter((b) => b.type === 'tool_use')\n if (toolUseItems.length > 0) {\n out.push({\n role: 'assistant',\n tool_calls: toolUseItems.map((b) => {\n if (b.type !== 'tool_use') throw new Error('unreachable')\n return {\n id: b.id,\n type: 'function' as const,\n function: { name: b.name, arguments: JSON.stringify(b.input) },\n }\n }),\n })\n continue\n }\n\n // tool_result blocks → tool messages\n const toolResultItems = items.filter((b) => b.type === 'tool_result')\n if (toolResultItems.length > 0) {\n for (const b of toolResultItems) {\n if (b.type !== 'tool_result') continue\n const text = b.content\n .filter((c) => c.type === 'text')\n .map((c) => (c.type === 'text' ? c.text : ''))\n .join('\\n')\n out.push({ role: 'tool', tool_call_id: b.toolUseId, content: text })\n }\n continue\n }\n\n const role = m.role as 'user' | 'assistant'\n const content = toContentParts(m.content)\n if (role === 'user') {\n out.push({ role, content: content as OpenAI.Chat.ChatCompletionUserMessageParam['content'] })\n } else {\n out.push({ role, content: typeof content === 'string' ? content : '' })\n }\n }\n\n return out\n}\n\nfunction toOpenAITools(tools: Tool[]): OpenAI.Chat.ChatCompletionTool[] {\n return tools.map((t) => ({\n type: 'function' as const,\n function: {\n name: t.name,\n ...(t.description ? { description: t.description } : {}),\n parameters: t.inputSchema as OpenAI.FunctionParameters,\n },\n }))\n}\n\nfunction toOpenAIToolChoice(\n choice: ToolChoice | undefined,\n): OpenAI.Chat.ChatCompletionToolChoiceOption | undefined {\n if (!choice) return undefined\n if (choice.mode === 'required') return 'required'\n if (choice.mode === 'none') return 'none'\n return 'auto'\n}\n\n// ---------------------------------------------------------------------------\n// Response mapping\n// ---------------------------------------------------------------------------\n\nfunction mapFinishReason(reason: string | null | undefined): string {\n if (reason === 'stop') return 'endTurn'\n if (reason === 'length') return 'maxTokens'\n if (reason === 'tool_calls') return 'toolUse'\n return 'endTurn'\n}\n\nfunction buildResult(completion: OpenAI.Chat.ChatCompletion): AnySamplingResult {\n const choice = completion.choices[0]\n const stopReason = mapFinishReason(choice?.finish_reason)\n const model = completion.model\n\n if (stopReason === 'toolUse') {\n const calls = choice.message.tool_calls ?? []\n const content: ToolUseContent[] = calls.flatMap((tc) => {\n // tc is ChatCompletionMessageToolCall (union); filter to function type\n if (tc.type !== 'function') return []\n const fn = (tc as { type: 'function'; id: string; function: { name: string; arguments: string } }).function\n return [{\n type: 'tool_use' as const,\n id: tc.id,\n name: fn.name,\n input: JSON.parse(fn.arguments) as Record<string, unknown>,\n }]\n })\n return { role: 'assistant', model, stopReason, content }\n }\n\n const text = choice.message.content ?? ''\n return { role: 'assistant', model, stopReason, content: { type: 'text', text } }\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport class OpenAISamplingAdapter implements SamplingAdapter {\n private readonly _client: OpenAI\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n client: OpenAI,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._client = client\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'gpt-4o',\n )\n\n const omitTools = params.toolChoice?.mode === 'none'\n const tools = !omitTools && params.tools?.length\n ? toOpenAITools(params.tools)\n : undefined\n const toolChoice = tools ? toOpenAIToolChoice(params.toolChoice) : undefined\n const onToken = this._options.onToken\n\n const stream = this._client.chat.completions.stream({\n model,\n messages: toOpenAIMessages(params.messages, params.systemPrompt),\n max_completion_tokens: params.maxTokens ?? 1024,\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences?.length ? { stop: params.stopSequences } : {}),\n ...(tools ? { tools } : {}),\n ...(toolChoice !== undefined ? { tool_choice: toolChoice } : {}),\n })\n\n if (onToken) {\n stream.on('content', (delta) => { onToken(delta) })\n }\n\n const completion = await stream.finalChatCompletion()\n return buildResult(completion)\n }\n }\n}\n","import type { GoogleGenAI } from '@google/genai'\nimport type {\n GenerateContentConfig,\n GenerateContentResponse,\n} from '@google/genai'\nimport type { CreateMessageRequestParams, SamplingMessage, Tool, ToolChoice, ToolUseContent } from \"@modelcontextprotocol/server\";\nimport type { AnySamplingResult } from '../results.js'\nimport type { SamplingHandler } from '../handlers.js'\nimport type { SamplingAdapter, SamplingAdapterOptions } from './types.js'\nimport { resolveModel } from './types.js'\n\n// ---------------------------------------------------------------------------\n// Title pruning\n// ---------------------------------------------------------------------------\n\n/**\n * Removes 'title' from all property definitions in a JSON Schema object.\n * Gemini emits MALFORMED_FUNCTION_CALL when property titles are present.\n */\nfunction pruneTitle(schema: Record<string, unknown>): Record<string, unknown> {\n const { title: _dropped, ...rest } = schema\n if (rest.properties && typeof rest.properties === 'object') {\n rest.properties = Object.fromEntries(\n Object.entries(rest.properties as Record<string, unknown>).map(([k, v]) => [\n k,\n pruneTitle(v as Record<string, unknown>),\n ]),\n )\n }\n return rest\n}\n\n// ---------------------------------------------------------------------------\n// Message translation\n// ---------------------------------------------------------------------------\n\nfunction toGeminiRole(role: 'user' | 'assistant'): 'user' | 'model' {\n return role === 'assistant' ? 'model' : 'user'\n}\n\n/** Build an id→name map from prior tool_use blocks so tool_result can reference by name. */\nfunction buildToolNameMap(messages: SamplingMessage[]): Map<string, string> {\n const map = new Map<string, string>()\n for (const m of messages) {\n const items = Array.isArray(m.content) ? m.content : [m.content]\n for (const b of items) {\n if (b.type === 'tool_use') map.set(b.id, b.name)\n }\n }\n return map\n}\n\nfunction toGeminiContents(\n messages: SamplingMessage[],\n toolNameById: Map<string, string>,\n): object[] {\n return messages.map((m) => {\n const items = Array.isArray(m.content) ? m.content : [m.content]\n const parts = items.flatMap((block): object[] => {\n if (block.type === 'text') {\n return [{ text: block.text }]\n } else if (block.type === 'image') {\n return [{ inlineData: { data: block.data, mimeType: block.mimeType } }]\n } else if (block.type === 'tool_use') {\n return [{ functionCall: { name: block.name, args: block.input } }]\n } else if (block.type === 'tool_result') {\n const name = toolNameById.get(block.toolUseId) ?? block.toolUseId\n const text = block.content\n .filter((c) => c.type === 'text')\n .map((c) => (c.type === 'text' ? c.text : ''))\n .join('\\n')\n return [{ functionResponse: { name, response: { content: text } } }]\n }\n return []\n })\n return { role: toGeminiRole(m.role as 'user' | 'assistant'), parts }\n })\n}\n\nfunction toGeminiFunctionDeclarations(tools: Tool[]): object[] {\n return tools.map((t) => ({\n name: t.name,\n ...(t.description ? { description: t.description } : {}),\n parameters: pruneTitle(t.inputSchema as Record<string, unknown>),\n }))\n}\n\nfunction toGeminiToolConfig(choice: ToolChoice | undefined): object | undefined {\n if (!choice) return undefined\n const mode =\n choice.mode === 'required' ? 'ANY' :\n choice.mode === 'none' ? 'NONE' :\n 'AUTO'\n return { functionCallingConfig: { mode } }\n}\n\n// ---------------------------------------------------------------------------\n// Response mapping\n// ---------------------------------------------------------------------------\n\nfunction buildResult(response: GenerateContentResponse, model: string): AnySamplingResult {\n const functionCalls = response.functionCalls\n\n if (functionCalls?.length) {\n const content: ToolUseContent[] = functionCalls.map((fc, i) => ({\n type: 'tool_use' as const,\n id: fc.id ?? `tool-${i}`,\n name: fc.name ?? '',\n input: (fc.args ?? {}) as Record<string, unknown>,\n }))\n return { role: 'assistant', model, stopReason: 'toolUse', content }\n }\n\n const candidate = response.candidates?.[0]\n const finishReason = candidate?.finishReason\n const stopReason =\n finishReason === 'MAX_TOKENS' ? 'maxTokens' :\n 'endTurn'\n\n const text = response.text ?? ''\n return { role: 'assistant', model, stopReason, content: { type: 'text', text } }\n}\n\n// ---------------------------------------------------------------------------\n// Adapter\n// ---------------------------------------------------------------------------\n\nexport class GoogleSamplingAdapter implements SamplingAdapter {\n private readonly _client: GoogleGenAI\n private readonly _options: SamplingAdapterOptions & { defaultModel?: string }\n\n constructor(\n client: GoogleGenAI,\n options?: SamplingAdapterOptions & { defaultModel?: string },\n ) {\n this._client = client\n this._options = options ?? {}\n }\n\n asHandler(): SamplingHandler {\n return async (params: CreateMessageRequestParams): Promise<AnySamplingResult> => {\n const model = resolveModel(\n params.modelPreferences,\n this._options.modelSelector,\n this._options.defaultModel ?? 'gemini-2.0-flash',\n )\n\n const toolNameById = buildToolNameMap(params.messages)\n const contents = toGeminiContents(params.messages, toolNameById)\n const onToken = this._options.onToken\n\n const omitTools = params.toolChoice?.mode === 'none'\n const functionDeclarations = !omitTools && params.tools?.length\n ? toGeminiFunctionDeclarations(params.tools)\n : undefined\n const toolConfig = !omitTools ? toGeminiToolConfig(params.toolChoice) : undefined\n\n const config: GenerateContentConfig = {\n maxOutputTokens: params.maxTokens ?? 1024,\n ...(params.temperature !== undefined ? { temperature: params.temperature } : {}),\n ...(params.stopSequences?.length ? { stopSequences: params.stopSequences } : {}),\n ...(params.systemPrompt\n ? { systemInstruction: { parts: [{ text: params.systemPrompt }] } }\n : {}),\n ...(functionDeclarations ? { tools: [{ functionDeclarations }] } : {}),\n ...(toolConfig ? { toolConfig } : {}),\n }\n\n const stream = await this._client.models.generateContentStream({\n model,\n contents: contents as Parameters<typeof this._client.models.generateContentStream>[0]['contents'],\n config,\n })\n\n let lastChunk: GenerateContentResponse | undefined\n for await (const chunk of stream) {\n lastChunk = chunk\n if (onToken) {\n const text = chunk.text\n if (text) onToken(text)\n }\n }\n\n return buildResult(lastChunk!, model)\n }\n }\n}\n"],"mappings":"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","names":["SdkClient","LOG_LEVEL_META_KEY","serverName","SdkClient","LOG_LEVEL_META_KEY","buildResult","buildResult"]}
|