@mcp-use/client 2.2.0 → 2.2.1

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/logging.ts","../../src/react/rpc-logger.ts","../../src/core/skills.ts","../../src/react/types.ts","../../src/react/useMcp.ts","../../src/auth/popup.ts","../../src/transport/http.ts","../../src/auth/flow.ts","../../src/utils/json-schema-validator.ts","../../src/transport/base.ts","../../src/telemetry/connector-telemetry.ts","../../src/utils/version.ts","../../src/core/config.ts","../../src/auth/browser.ts","../../src/auth/storage.ts","../../src/auth/session-store.ts","../../src/auth/url.ts","../../src/core/browser.ts","../../src/telemetry/telemetry.ts","../../src/telemetry/events.ts","../../src/telemetry/tel-fetch.ts","../../src/core/base.ts","../../src/core/session.ts","../../src/telemetry/client-telemetry.ts","../../src/utils/favicon.ts","../../src/react/useMcp-helpers.ts","../../src/react/useMcp-operations.ts","../../src/react/token-expiry.ts","../../src/auth/callback.ts","../../src/react/index.ts","../../src/react/McpClientProvider.tsx","../../src/react/useMcpServerQueues.ts","../../src/react/storage.ts","../../src/react/view/ext-apps-bridge.ts","../../src/react/view/ViewRenderer.tsx","../../src/react/view/parse-custom-props.ts","../../src/react/view/inject-openai-file-apis.ts","../../src/react/view/initialized-sync.ts","../../src/react/view/resolve-view-resource.ts","../../src/react/view/sandbox-blob-url.ts","../../src/react/view/use-display-mode.ts","../../src/react/view/view-host-policy.ts","../../src/react/view/view-detection.ts"],"sourcesContent":["export type LogLevel =\n | \"silent\"\n | \"error\"\n | \"warn\"\n | \"info\"\n | \"http\"\n | \"verbose\"\n | \"debug\"\n | \"silly\";\n\ntype LogFormat = \"minimal\" | \"detailed\" | \"emoji\";\n\nconst LEVELS = [\n \"silent\",\n \"error\",\n \"warn\",\n \"info\",\n \"http\",\n \"verbose\",\n \"debug\",\n \"silly\",\n] as const satisfies readonly LogLevel[];\n\nconst EMOJI: Record<LogLevel, string> = {\n silent: \"\",\n error: \"❌\",\n warn: \"⚠️\",\n info: \"ℹ️\",\n http: \"🌐\",\n verbose: \"📝\",\n debug: \"🔍\",\n silly: \"🤪\",\n};\n\nfunction envLevel(): LogLevel {\n let raw: string | undefined;\n try {\n raw =\n typeof process !== \"undefined\"\n ? (process.env?.MCP_USE_LOG_LEVEL ?? process.env?.DEBUG)\n : undefined;\n } catch {\n // Deno may deny env access.\n }\n const v = raw?.trim().toLowerCase();\n if (v === \"2\") return \"debug\";\n if (v && (LEVELS as readonly string[]).includes(v)) return v as LogLevel;\n return \"info\";\n}\n\nclass SimpleConsoleLogger {\n constructor(\n private name = \"mcp-use\",\n public level: LogLevel = \"info\",\n public format: LogFormat = \"minimal\"\n ) {}\n\n private write(level: LogLevel, message: string, args: unknown[]): void {\n if (\n this.level === \"silent\" ||\n LEVELS.indexOf(level) > LEVELS.indexOf(this.level)\n ) {\n return;\n }\n const extra = args\n .map((a) => {\n if (typeof a === \"string\") return a;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \");\n const full = extra ? `${message} ${extra}` : message;\n const ts = new Date().toLocaleTimeString(\"en-US\", { hour12: false });\n const label = this.format === \"minimal\" ? level : level.toUpperCase();\n const emoji = this.format === \"emoji\" ? ` ${EMOJI[level]}` : \"\";\n const line = `${ts} [${this.name}]${emoji} ${label}: ${full}`;\n const fn =\n level === \"error\"\n ? console.error\n : level === \"warn\"\n ? console.warn\n : level === \"info\"\n ? console.info\n : level === \"debug\"\n ? console.debug\n : console.log;\n fn(line);\n }\n\n error = (m: string, ...a: unknown[]) => this.write(\"error\", m, a);\n warn = (m: string, ...a: unknown[]) => this.write(\"warn\", m, a);\n info = (m: string, ...a: unknown[]) => this.write(\"info\", m, a);\n debug = (m: string, ...a: unknown[]) => this.write(\"debug\", m, a);\n http = (m: string, ...a: unknown[]) => this.write(\"http\", m, a);\n verbose = (m: string, ...a: unknown[]) => this.write(\"verbose\", m, a);\n silly = (m: string, ...a: unknown[]) => this.write(\"silly\", m, a);\n\n setFormat(format: LogFormat): void {\n this.format = format;\n }\n}\n\nexport class Logger {\n private static instances: Record<string, SimpleConsoleLogger> = {};\n private static currentFormat: LogFormat = \"minimal\";\n private static currentLevel: LogLevel | undefined;\n\n static get(name = \"mcp-use\"): SimpleConsoleLogger {\n return (this.instances[name] ??= new SimpleConsoleLogger(\n name,\n this.currentLevel ?? envLevel(),\n this.currentFormat\n ));\n }\n\n static configure({\n level = envLevel(),\n format = \"minimal\",\n }: { level?: LogLevel; format?: LogFormat } = {}): void {\n this.currentLevel = level;\n this.currentFormat = format;\n for (const log of Object.values(this.instances)) {\n log.level = level;\n log.format = format;\n }\n }\n\n static setDebug(enabled: boolean | 0 | 1 | 2): void {\n const level: LogLevel =\n enabled === 2 || enabled === true ? \"debug\" : \"info\";\n this.currentLevel = level;\n for (const log of Object.values(this.instances)) log.level = level;\n try {\n if (typeof process !== \"undefined\" && process.env) {\n process.env.MCP_USE_LOG_LEVEL = level;\n }\n } catch {\n // optional\n }\n }\n\n static setFormat(format: LogFormat): void {\n this.configure({ format });\n }\n}\n\n/** Default package logger used by client and connector operations. */\nexport const logger = Logger.get();\n","import type {\n JSONRPCMessage,\n MessageExtraInfo,\n Transport,\n TransportSendOptions,\n} from \"@modelcontextprotocol/client\";\nimport { Logger } from \"../utils/logging.js\";\n\nconst logger = Logger.get(\"RpcLogger\");\n\n/** One JSON-RPC message captured by the React transport logger. */\nexport interface RpcLogEntry {\n /** Identifier of the server that sent or received the message. */\n serverId: string;\n /** Message direction relative to the client. */\n direction: \"send\" | \"receive\";\n /** ISO 8601 timestamp recorded when the message was observed. */\n timestamp: string;\n /** Captured JSON-RPC message. */\n message: JSONRPCMessage;\n}\n\n/**\n * Simple in-memory RPC log storage\n * Stores RPC messages for debugging purposes\n */\nclass RpcLogStore {\n private logs: RpcLogEntry[] = [];\n private listeners: Set<(entry: RpcLogEntry) => void> = new Set();\n private maxLogs = 1000;\n\n publish(entry: RpcLogEntry): void {\n logger.debug(\n \"[RPC Logger] Publishing log:\",\n entry.direction,\n entry.serverId,\n (entry.message as any)?.method\n );\n this.logs.push(entry);\n\n // Prune old logs\n if (this.logs.length > this.maxLogs) {\n this.logs = this.logs.slice(-this.maxLogs);\n }\n\n logger.debug(\n \"[RPC Logger] Total logs:\",\n this.logs.length,\n \"Listeners:\",\n this.listeners.size\n );\n\n // Notify listeners\n this.listeners.forEach((listener) => {\n try {\n listener(entry);\n } catch (err) {\n logger.error(\"[RPC Logger] Listener error:\", err);\n }\n });\n }\n\n subscribe(listener: (entry: RpcLogEntry) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n getLogsForServer(serverId: string): RpcLogEntry[] {\n return this.logs.filter((log) => log.serverId === serverId);\n }\n\n getAllLogs(): RpcLogEntry[] {\n return [...this.logs];\n }\n\n clear(serverId?: string): void {\n if (serverId) {\n this.logs = this.logs.filter((log) => log.serverId !== serverId);\n } else {\n this.logs = [];\n }\n }\n}\n\n// Global store instance\nconst rpcLogStore = new RpcLogStore();\n\n/**\n * Retrieve RPC log entries for the specified server.\n *\n * @param serverId - The server identifier to filter logs by\n * @returns All `RpcLogEntry` objects associated with `serverId`\n */\nexport function getRpcLogs(serverId: string): RpcLogEntry[] {\n return rpcLogStore.getLogsForServer(serverId);\n}\n\n/**\n * Retrieve all stored RPC log entries.\n *\n * @returns A shallow copy of the array of `RpcLogEntry` objects representing all logs\n */\nexport function getAllRpcLogs(): RpcLogEntry[] {\n return rpcLogStore.getAllLogs();\n}\n\n/**\n * Subscribe to receive RPC log entries as they are published.\n *\n * @param listener - Function invoked with each new `RpcLogEntry`\n * @returns A function that unsubscribes the listener when called\n */\nexport function subscribeToRpcLogs(\n listener: (entry: RpcLogEntry) => void\n): () => void {\n return rpcLogStore.subscribe(listener);\n}\n\n/**\n * Remove stored RPC log entries for a specific server or all servers.\n *\n * @param serverId - The server identifier whose logs should be removed. If omitted, clears all logs.\n */\nexport function clearRpcLogs(serverId?: string): void {\n rpcLogStore.clear(serverId);\n}\n\n/**\n * Create a Transport wrapper that records every sent and received JSON-RPC message tagged with the given server ID.\n *\n * @param transport - The Transport instance to wrap and forward calls to\n * @param serverId - Identifier used to attribute created log entries to a specific server\n * @returns A Transport instance that forwards operations to the provided transport and records each message as a log entry with direction `send` or `receive`\n */\nexport function wrapTransportForLogging(\n transport: Transport,\n serverId: string\n): Transport {\n class LoggingTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n\n constructor(private readonly inner: Transport) {\n // Intercept incoming messages\n this.inner.onmessage = (\n message: JSONRPCMessage,\n extra?: MessageExtraInfo\n ) => {\n // Log RPC message\n rpcLogStore.publish({\n serverId,\n direction: \"receive\",\n timestamp: new Date().toISOString(),\n message,\n });\n this.onmessage?.(message, extra);\n };\n\n this.inner.onclose = () => {\n this.onclose?.();\n };\n\n this.inner.onerror = (error: Error) => {\n this.onerror?.(error);\n };\n }\n\n async start(): Promise<void> {\n if (typeof (this.inner as any).start === \"function\") {\n await (this.inner as any).start();\n }\n }\n\n async send(\n message: JSONRPCMessage,\n options?: TransportSendOptions\n ): Promise<void> {\n // Log RPC message\n rpcLogStore.publish({\n serverId,\n direction: \"send\",\n timestamp: new Date().toISOString(),\n message,\n });\n await this.inner.send(message as any, options as any);\n }\n\n async close(): Promise<void> {\n await this.inner.close();\n }\n\n get sessionId(): string | undefined {\n return (this.inner as any).sessionId;\n }\n\n setProtocolVersion?(version: string): void {\n if (typeof this.inner.setProtocolVersion === \"function\") {\n this.inner.setProtocolVersion(version);\n }\n }\n }\n\n return new LoggingTransport(transport);\n}\n","/** Experimental Skills over MCP extension identifier. */\nexport const SKILLS_EXTENSION_ID = \"io.modelcontextprotocol/skills\" as const;\n\n/** One immutable resource advertised by a remote skill. */\nexport interface SkillResource {\n /** Absolute MCP resource URI. */\n uri: string;\n /** SHA-256 digest of the raw resource bytes. */\n digest: string;\n}\n\n/** One skill catalog entry returned by `skills/list` or `skills/get`. */\nexport interface Skill {\n /** URI of the skill's root `SKILL.md`. */\n uri: string;\n /** Verbatim parsed YAML frontmatter. */\n frontmatter: Record<string, unknown>;\n /** Complete resource manifest when the server exposes a static skill. */\n resources?: SkillResource[];\n}\n\n/** Paginated result returned by `skills/list`. */\nexport interface SkillsListResult {\n skills: Skill[];\n nextCursor?: string;\n}\n\n/** Result returned by `skills/get`. */\nexport interface SkillGetResult {\n skill: Skill;\n}\n\n/** One child returned by `resources/directory/read`. */\nexport interface SkillDirectoryEntry {\n uri: string;\n name?: string;\n mimeType?: string;\n}\n\n/** Paginated result returned by `resources/directory/read`. */\nexport interface SkillDirectoryReadResult {\n resources: SkillDirectoryEntry[];\n nextCursor?: string;\n}\n","import type {\n ClientOptions,\n CompleteRequestParams,\n CompleteResult,\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n Notification,\n OAuthClientProvider,\n ProtocolEra,\n Transport,\n Prompt,\n Resource,\n // v2 exports the resource-template type as `ResourceTemplateType` (the bare\n // `ResourceTemplate` name is the server package's class).\n ResourceTemplateType as ResourceTemplate,\n Tool,\n VersionNegotiationMode,\n} from \"@modelcontextprotocol/client\";\nimport type { BaseMCPClient } from \"../core/base.js\";\nimport type { MCPAuthorizationInfo } from \"../core/session.js\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\n\n/** Proxy configuration for routing MCP traffic through a proxy server. */\nexport interface ProxyConfig {\n /** Proxy server address (e.g. \"http://localhost:3001/inspector/api/proxy\"). */\n proxyAddress?: string;\n /** Additional headers to include in proxied requests. */\n headers?: Record<string, string>;\n /**\n * @deprecated Use `headers` instead.\n */\n customHeaders?: Record<string, string>;\n}\n\n/**\n * SDK-level reconnection options for streamable HTTP transports.\n * Controls the retry behavior of the underlying `StreamableHTTPClientTransport`.\n */\nexport type ReconnectionOptions = {\n /** Maximum delay between reconnection attempts in ms (default: 30000) */\n maxReconnectionDelay?: number;\n /** Initial delay before first reconnection attempt in ms (default: 1000) */\n initialReconnectionDelay?: number;\n /** Multiplier applied to delay after each failed attempt (default: 1.5) */\n reconnectionDelayGrowFactor?: number;\n /** Maximum number of reconnection retries (default: 2) */\n maxRetries?: number;\n};\n\n/** Configures the {@link useMcp} hook and its browser connection lifecycle. */\nexport type UseMcpOptions = {\n /** The /sse URL of your remote MCP server */\n url?: string;\n /** Enable/disable the connection (similar to TanStack Query). When false, no connection will be attempted (default: true) */\n enabled?: boolean;\n /** Proxy configuration for routing through a proxy server */\n proxyConfig?: ProxyConfig;\n /**\n * OAuth proxy base URL (e.g. `https://inspector.example.com/inspector/api/oauth`)\n * used to route OAuth requests (`.well-known` discovery, DCR, token exchange)\n * through a transparent server-side proxy — bypassing browser CORS against\n * third-party identity providers — WITHOUT proxying MCP traffic itself.\n *\n * The proxy is transparent: it forwards requests and responses unmodified, so\n * the SDK's authorization-server issuer validation (RFC 8414 §3.3) still\n * passes. When omitted, the OAuth proxy URL is derived from\n * `proxyConfig.proxyAddress` (replacing a trailing `/proxy` with `/oauth`),\n * preserving the existing behavior for fully-proxied connections.\n */\n oauthProxyUrl?: string;\n /**\n * Connection policy for proxy routing.\n * - `auto`: start direct and use `autoProxyFallback` after a qualifying failure\n * - `direct`: never use `proxyConfig` and never fall back\n * - `proxy`: use `proxyConfig` immediately and never fall back\n *\n * When omitted, `proxyConfig` retains its legacy immediate-proxy behavior,\n * except when `autoProxyFallback` explicitly requests a direct-first attempt.\n */\n connectionMode?: \"auto\" | \"direct\" | \"proxy\";\n /**\n * Enable automatic proxy fallback when direct connection fails\n * When enabled, if a direct connection fails with FastMCP or CORS errors,\n * automatically retries using the proxy configuration\n *\n * Can be:\n * - `true`: Enable with `proxyConfig.proxyAddress`\n * - `false`: Disable automatic fallback (default)\n * - `{ enabled: boolean, proxyAddress?: string }`: Custom configuration\n *\n * @defaultValue false\n *\n * @example\n * ```typescript\n * // Use default proxy\n * useMcp({ url: '...', autoProxyFallback: true })\n *\n * // Use custom proxy\n * useMcp({\n * url: '...',\n * autoProxyFallback: {\n * enabled: true,\n * proxyAddress: 'https://my-proxy.com/api/proxy'\n * }\n * })\n * ```\n */\n autoProxyFallback?:\n | boolean\n | {\n /** Whether fallback is enabled. */\n enabled?: boolean;\n /** Proxy endpoint used after a qualifying direct failure. */\n proxyAddress?: string;\n };\n /** Custom callback URL for OAuth redirect (defaults to /oauth/callback on the current origin) */\n callbackUrl?: string;\n /** Storage key prefix for OAuth data in localStorage (defaults to \"mcp:auth\") */\n storageKeyPrefix?: string;\n /** Headers that can be used to bypass auth */\n headers?: Record<string, string>;\n /**\n * Log level for console output.\n * Set to 'silent' to suppress ALL console logging (the `mcp.log` state array is still populated).\n * @defaultValue `\"silent\"`\n */\n logLevel?:\n | \"silent\"\n | \"error\"\n | \"warn\"\n | \"info\"\n | \"http\"\n | \"verbose\"\n | \"debug\"\n | \"silly\";\n /** Auto retry connection if initial connection fails, with delay in ms (default: false) */\n autoRetry?: boolean | number;\n /**\n * Auto reconnect if an established connection is lost.\n *\n * Can be:\n * - `boolean`: Enable/disable with default 3000ms delay and 10s health check\n * - `number`: Reconnect delay in ms (enables health checks with defaults)\n * - `object`: Full configuration for reconnection and health checks\n *\n * @defaultValue `true` with a 3000 ms initial delay\n */\n autoReconnect?:\n | boolean\n | number\n | {\n /** Whether to enable automatic reconnection (default: true) */\n enabled?: boolean;\n /** Delay in ms before reconnection attempt (default: 3000) */\n initialDelay?: number;\n /**\n * Interval in ms for health check polling via HEAD requests.\n * Set to `false` to disable health checks entirely.\n * @defaultValue `10000`\n */\n healthCheckInterval?: number | false;\n /**\n * Time in ms without a successful health check before triggering reconnect.\n * @defaultValue `30000`\n */\n healthCheckTimeout?: number;\n };\n /** SDK-level reconnection options for the streamable HTTP transport */\n reconnectionOptions?: ReconnectionOptions;\n /** Popup window features string (dimensions and behavior) for OAuth */\n popupFeatures?: string;\n /**\n * Prevent automatic authentication popup/redirect on initial connection (default: true)\n * When true, the connection will enter 'pending_auth' state and wait for user to call authenticate()\n * Set to true to show a modal/button before triggering OAuth instead of auto-redirecting\n */\n preventAutoAuth?: boolean;\n /**\n * Detect OAuth protected-resource metadata after an anonymous connection so\n * mixed-auth servers can offer optional authentication without blocking use.\n * @defaultValue true\n */\n detectMixedAuth?: boolean;\n /**\n * Use full-page redirect for OAuth instead of popup window (default: false)\n * Redirect flow avoids popup blockers and provides better UX on mobile.\n * Set to true to use redirect flow instead of popup.\n */\n useRedirectFlow?: boolean;\n /**\n * Callback function that is invoked just before the authentication popup window is opened.\n * Only used when useRedirectFlow is false (popup mode).\n * @param url - The URL that will be opened in the popup.\n * @param features - The features string for the popup window.\n */\n onPopupWindow?: (\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void;\n /**\n * Additional client options passed to the underlying MCP SDK Client.\n * Use `capabilities.views: true` as shorthand for the MCP Apps UI extension,\n * or set `capabilities.extensions` directly.\n *\n * @example\n * ```typescript\n * useMcp({\n * url: '...',\n * clientOptions: {\n * capabilities: {\n * views: true,\n * },\n * },\n * })\n * ```\n */\n clientOptions?: Omit<ClientOptions, \"capabilities\"> & {\n /** MCP capabilities advertised by the underlying SDK client. */\n capabilities?: NonNullable<ClientOptions[\"capabilities\"]> & {\n /** Whether to advertise the MCP Apps UI extension shorthand. */\n views?: boolean;\n };\n };\n /**\n * Protocol version negotiation mode passed to the underlying SDK `Client`.\n * - `\"auto\"` (default): probe with `server/discover` to detect modern (2026-07-28)\n * servers, falling back to the 2025 handshake against legacy servers.\n * - `\"legacy\"`: classic 2025 `initialize` handshake, no probe.\n * - `{ pin: \"2026-07-28\" }`: modern era only, no fallback.\n */\n protocolNegotiation?: VersionNegotiationMode;\n /** Connection timeout in milliseconds for establishing initial connection (default: 30000 / 30 seconds) */\n timeout?: number;\n /** Optional callback to wrap the transport before passing it to the Client. Useful for logging, monitoring, or other transport-level interceptors. */\n wrapTransport?: (transport: Transport, serverId: string) => Transport;\n /** Stable identifier supplied to `wrapTransport`; defaults to `url`. */\n serverId?: string;\n /** Callback function that is invoked when a notification is received from the MCP server */\n onNotification?: (notification: Notification) => void;\n /**\n * Optional callback function to handle sampling requests from servers.\n * When provided, the client will declare sampling capability and handle\n * `sampling/createMessage` requests by calling this callback.\n *\n * @deprecated Sampling is deprecated by the 2026 protocol. Retained for v1\n * push requests and v2 multi-round-trip compatibility.\n */\n onSampling?: (\n params: SamplingCreateMessageParams\n ) => Promise<SamplingCreateMessageResult>;\n /**\n * Optional callback function to handle elicitation requests from servers.\n * When provided, the client will declare elicitation capability and handle\n * `elicitation/create` requests by calling this callback.\n *\n * Elicitation allows servers to request additional information from users:\n * - Form mode: Collect structured data with JSON schema validation\n * - URL mode: Direct users to external URLs for sensitive interactions\n */\n onElicitation?: (\n params: ElicitRequestFormParams | ElicitRequestURLParams\n ) => Promise<ElicitResult>;\n /** Client information advertised while establishing the MCP connection. */\n clientInfo?: {\n /** Stable programmatic client name. */\n name: string;\n /** Optional human-readable client title. */\n title?: string;\n /** Client version. */\n version: string;\n /** Optional human-readable client description. */\n description?: string;\n /** Icons representing the client. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Public website describing the client. */\n websiteUrl?: string;\n };\n /**\n * Optional custom fetch function to use for all MCP HTTP requests.\n *\n * When provided, this replaces the default global `fetch` for transport-level\n * requests. Useful for adding custom auth retry logic, logging, or proxying.\n *\n * @example\n * ```typescript\n * useMcp({\n * url: 'http://localhost:3000/mcp',\n * fetch: myCustomFetch,\n * })\n * ```\n */\n fetch?: typeof globalThis.fetch;\n /**\n * Optional external OAuth client provider.\n *\n * When provided, useMcp will use this provider directly instead of creating\n * BrowserOAuthClientProvider internally. This is useful for headless/testing\n * runtimes where popup/redirect flows are not available.\n */\n authProvider?: OAuthClientProvider;\n /**\n * OAuth client registration settings.\n *\n * Use this when the upstream auth server does **not** support Dynamic Client\n * Registration — for example, MCP servers running in proxy mode against\n * Slack, WorkOS, or similar providers. Prefer `clientMetadataUrl` when the\n * authorization server advertises CIMD support; the SDK falls back to DCR\n * when appropriate.\n *\n * @example\n * ```typescript\n * useMcp({\n * url: 'https://mcp.example.com',\n * oauth: {\n * clientId: 'my-preregistered-client-id',\n * clientMetadataUrl: 'https://app.example.com/oauth/client-metadata.json',\n * scope: 'openid profile email',\n * },\n * })\n * ```\n */\n oauth?: {\n /** Pre-registered OAuth client_id. */\n clientId?: string;\n /**\n * Public HTTPS OAuth Client ID Metadata Document URL (CIMD).\n * The document must contain a matching client_id and redirect_uris.\n */\n clientMetadataUrl?: string;\n /** OAuth scope string included in the authorize request. */\n scope?: string;\n };\n};\n\n/**\n * Serializable configuration for one server managed by `McpClientProvider`.\n * Pass this to `addServer` / `updateServer`.\n */\nexport interface McpServerConfig extends Omit<\n UseMcpOptions,\n \"onSampling\" | \"onElicitation\" | \"onNotification\"\n> {\n /** Optional user-facing alias. `server.name` always comes from MCP server metadata. */\n displayName?: string;\n /** Optional callback invoked when the provider queues sampling. */\n onSamplingRequest?: (request: PendingSamplingRequest) => void;\n /** Optional callback invoked when the provider queues elicitation. */\n onElicitationRequest?: (request: PendingElicitationRequest) => void;\n /** Optional callback invoked when the provider receives a notification. */\n onNotificationReceived?: (notification: McpNotification) => void;\n}\n\n/** @deprecated Use {@link McpServerConfig} */\nexport type McpServerOptions = McpServerConfig;\n\n/** Non-secret connection settings that built-in providers may persist. */\nexport type PersistedMcpServerConfig = Pick<\n McpServerConfig,\n | \"url\"\n | \"displayName\"\n | \"enabled\"\n | \"oauthProxyUrl\"\n | \"connectionMode\"\n | \"autoProxyFallback\"\n | \"callbackUrl\"\n | \"storageKeyPrefix\"\n | \"logLevel\"\n | \"autoRetry\"\n | \"autoReconnect\"\n | \"reconnectionOptions\"\n | \"popupFeatures\"\n | \"preventAutoAuth\"\n | \"detectMixedAuth\"\n | \"useRedirectFlow\"\n | \"protocolNegotiation\"\n | \"timeout\"\n | \"clientInfo\"\n> & {\n /** Proxy endpoint only. Proxy authorization headers are runtime-only. */\n proxyConfig?: Pick<ProxyConfig, \"proxyAddress\">;\n /** Public OAuth registration settings only. */\n oauth?: {\n /** Pre-registered public OAuth client identifier. */\n clientId?: string;\n /** Public OAuth Client ID Metadata Document URL. */\n clientMetadataUrl?: string;\n /** Space-delimited OAuth scopes. */\n scope?: string;\n };\n};\n\n/** Notification received from one managed MCP server. */\nexport interface McpNotification {\n /** Unique notification identifier generated by the provider. */\n id: string;\n /** MCP notification method name. */\n method: string;\n /** Optional notification parameters. */\n params?: Record<string, unknown>;\n /** Unix timestamp in milliseconds when the notification was received. */\n timestamp: number;\n /** Whether the consumer has marked the notification as read. */\n read: boolean;\n}\n\n/** A server sampling request awaiting UI or application approval. */\nexport interface PendingSamplingRequest {\n /** Unique request identifier generated by the provider. */\n id: string;\n /** Sampling request received from the server. */\n request: {\n /** Sampling JSON-RPC method name. */\n method: \"sampling/createMessage\";\n /** Sampling request parameters. */\n params: SamplingCreateMessageParams;\n };\n /** Unix timestamp in milliseconds when the request was received. */\n timestamp: number;\n /** Name of the server that issued the request. */\n serverName: string;\n}\n\n/** A server elicitation request awaiting UI or application approval. */\nexport interface PendingElicitationRequest {\n /** Unique request identifier generated by the provider. */\n id: string;\n /** Form or URL elicitation request received from the server. */\n request: ElicitRequestFormParams | ElicitRequestURLParams;\n /** Unix timestamp in milliseconds when the request was received. */\n timestamp: number;\n /** Name of the server that issued the request. */\n serverName: string;\n}\n\n/** Reactive state and operations returned by {@link useMcp}. */\nexport type UseMcpResult = {\n /** Name advertised by the connected MCP server. */\n name: string;\n\n /** List of tools available from the connected MCP server */\n tools: Tool[];\n /** List of resources available from the connected MCP server */\n resources: Resource[];\n /** List of resource templates available from the connected MCP server */\n resourceTemplates: ResourceTemplate[];\n /** List of prompts available from the connected MCP server */\n prompts: Prompt[];\n /** Skills advertised through the experimental Skills over MCP extension. */\n skills: import(\"../core/skills.js\").Skill[];\n /** Server information normalized for the active connection. */\n serverInfo?: {\n /** Optional human-readable server title. */\n title?: string;\n /** Stable server name. */\n name: string;\n /** Server version. */\n version?: string;\n /** Optional human-readable server description. */\n description?: string;\n /** Public website describing the server. */\n websiteUrl?: string;\n /** Icons advertised by the server. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Base64-encoded favicon auto-detected from server domain */\n icon?: string;\n };\n /** Server capabilities normalized for the active connection. */\n capabilities?: Record<string, unknown>;\n /** Optional server instructions advertised for the active connection. */\n instructions?: string;\n /** Protocol extension metadata normalized from the server capabilities. */\n extensions: Record<string, unknown>;\n /**\n * Negotiated MCP protocol era for the active connection:\n * - 'legacy': 2025-era server; lifecycle is managed internally.\n * - 'modern': 2026-07-28-era server, stateless per-request.\n * `undefined` until a connection has negotiated.\n */\n protocolEra?: ProtocolEra;\n /** Negotiated MCP protocol version string (e.g. '2025-06-18', '2026-07-28'). */\n protocolVersion?: string;\n /**\n * The current state of the MCP connection:\n * - 'discovering': Checking server existence and capabilities (including auth requirements).\n * - 'pending_auth': Authentication is required but auto-popup was prevented. User action needed.\n * - 'authenticating': Authentication is required and the process (e.g., popup) has been initiated.\n * - 'ready': Connected and ready for tool calls.\n * - 'failed': Connection or authentication failed. Check the `error` property.\n */\n state: \"discovering\" | \"pending_auth\" | \"authenticating\" | \"ready\" | \"failed\";\n /** If the state is 'failed', this provides the error message */\n error?: string;\n /**\n * If authentication requires user interaction (e.g., popup was blocked),\n * this URL can be presented to the user to complete authentication manually in a new tab.\n */\n authUrl?: string;\n /**\n * OAuth tokens if authentication was completed\n * Available when state is 'ready' and OAuth was used\n */\n authTokens?: {\n /** OAuth access token. */\n access_token: string;\n /** OAuth token type, commonly `\"Bearer\"`. */\n token_type: string;\n /** Unix timestamp in seconds when the access token expires. */\n expires_at?: number;\n /** OAuth refresh token, when issued. */\n refresh_token?: string;\n /** Space-delimited OAuth scopes granted to the token. */\n scope?: string;\n /** Canonical protected-resource URL required by some token refresh flows. */\n resource?: string;\n /**\n * OAuth token endpoint resolved during discovery (when available). Lets\n * consumers persist it so a backend can proactively refresh the token.\n */\n token_endpoint?: string;\n /**\n * OAuth client id (from Dynamic Client Registration or a static client).\n * Most token endpoints require it on refresh, so consumers can persist it\n * for server-side proactive refresh.\n */\n client_id?: string;\n /** OAuth client secret, when the provider issued a confidential client. */\n client_secret?: string;\n };\n /** OAuth availability discovered for an anonymously connected server. */\n authorization?: MCPAuthorizationInfo;\n /** Array of internal log messages (useful for debugging) */\n log: {\n /** Log severity. */\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n /** Human-readable log message. */\n message: string;\n /** Unix timestamp in milliseconds when the entry was created. */\n timestamp: number;\n }[];\n /**\n * Function to call a tool on the MCP server.\n * @param name - The name of the tool to call.\n * @param args - Optional arguments for the tool.\n * @param options - Optional request options including timeout configuration.\n * @returns A promise that resolves with the tool's result.\n * @throws If the client is not in the 'ready' state or the call fails.\n *\n * @example\n * ```typescript\n * // Simple tool call\n * const result = await mcp.callTool('my-tool', { arg: 'value' })\n *\n * // Tool call with extended timeout (e.g., for tools that trigger sampling)\n * const result = await mcp.callTool('analyze-sentiment', { text: 'Hello' }, {\n * timeout: 300000, // 5 minutes\n * resetTimeoutOnProgress: true // Reset timeout when progress notifications are received\n * })\n * ```\n */\n callTool: (\n name: string,\n args?: Record<string, unknown>,\n options?: {\n /** Timeout in milliseconds for this tool call (default: 60000 / 60 seconds) */\n timeout?: number;\n /** Maximum total timeout in milliseconds, even with progress resets */\n maxTotalTimeout?: number;\n /** Reset the timeout when progress notifications are received (default: false) */\n resetTimeoutOnProgress?: boolean;\n /** AbortSignal to cancel the request */\n signal?: AbortSignal;\n }\n ) => Promise<any>;\n /**\n * Function to list resources from the MCP server.\n * @returns A promise that resolves when resources are refreshed.\n * @throws If the client is not in the 'ready' state.\n */\n listResources: () => Promise<void>;\n /**\n * Function to read a resource from the MCP server.\n * @param uri - The URI of the resource to read.\n * @returns A promise that resolves with the resource contents.\n * @throws If the client is not in the 'ready' state or the read fails.\n */\n readResource: (uri: string) => Promise<{\n /** Content blocks returned for the resource. */\n contents: Array<{\n /** URI of the returned resource content. */\n uri: string;\n /** Content media type. */\n mimeType?: string;\n /** UTF-8 text content. */\n text?: string;\n /** Base64-encoded binary content. */\n blob?: string;\n }>;\n }>;\n /** Refresh the complete paginated skill catalog. */\n listSkills: () => Promise<void>;\n /** Resolve one skill by its canonical URI. */\n getSkill: (\n uri: string\n ) => Promise<import(\"../core/skills.js\").SkillGetResult>;\n /** Read one non-recursive directory in a remote skill. */\n readResourceDirectory: (\n uri: string,\n cursor?: string\n ) => Promise<import(\"../core/skills.js\").SkillDirectoryReadResult>;\n /**\n * Function to list prompts from the MCP server.\n * @returns A promise that resolves when prompts are refreshed.\n * @throws If the client is not in the 'ready' state.\n */\n listPrompts: () => Promise<void>;\n /**\n * Function to get a specific prompt from the MCP server.\n * @param name - The name of the prompt to get.\n * @param args - Optional arguments for the prompt.\n * @returns A promise that resolves with the prompt messages.\n * @throws If the client is not in the 'ready' state or the get fails.\n */\n getPrompt: (\n name: string,\n args?: Record<string, string>\n ) => Promise<{\n /** Messages produced from the prompt template. */\n messages: Array<{\n /** Conversation role for the prompt message. */\n role: \"user\" | \"assistant\";\n /** Prompt message content. */\n content: {\n /** MCP content block type. */\n type: string;\n /** Text value for text content blocks. */\n text?: string;\n [key: string]: any;\n };\n }>;\n }>;\n /**\n * Request completion suggestions for a prompt or resource template argument.\n * @param params - Completion request parameters specifying the ref and argument to complete.\n * @returns A promise that resolves with completion suggestions from the server.\n * @throws If the client is not in the 'ready' state or the completion request fails.\n */\n complete: (params: CompleteRequestParams) => Promise<CompleteResult>;\n /**\n * Refresh the tools list from the server.\n * Called automatically when notifications/tools/list_changed is received.\n * Can also be called manually for explicit refresh.\n */\n refreshTools: () => Promise<void>;\n /**\n * Refresh the resources list from the server.\n * Called automatically when notifications/resources/list_changed is received.\n * Can also be called manually for explicit refresh.\n */\n refreshResources: () => Promise<void>;\n /**\n * Refresh the resource templates list from the server.\n * Can be called manually for explicit refresh.\n */\n refreshResourceTemplates: () => Promise<void>;\n /**\n * Refresh the prompts list from the server.\n * Called automatically when notifications/prompts/list_changed is received.\n * Can also be called manually for explicit refresh.\n */\n refreshPrompts: () => Promise<void>;\n /**\n * Refresh all lists (tools, resources, resource templates, prompts) from the server.\n * Useful after reconnection or for manual refresh.\n */\n refreshAll: () => Promise<void>;\n /** Manually attempts to reconnect if the state is 'failed'. */\n retry: () => void;\n /** Disconnects the client from the MCP server. */\n disconnect: () => Promise<void>;\n /**\n * Manually triggers the authentication process. Useful if the initial attempt failed\n * due to a blocked popup, allowing the user to initiate it via a button click.\n * @returns A promise that resolves with the authorization URL opened (or intended to be opened),\n * or undefined if auth cannot be started.\n */\n authenticate: () => Promise<void>;\n /** Clears all stored authentication data (tokens, client info, etc.) for this server URL from localStorage. */\n clearStorage: () => void;\n /**\n * Ensure the server icon is loaded and available in serverInfo\n * Returns a promise that resolves when the icon is ready\n * Use this before server creation to guarantee the icon is available\n *\n * @returns Promise that resolves with the base64 icon or null if not available\n *\n * @example\n * ```typescript\n * // Wait for icon before creating server\n * const icon = await mcp.ensureIconLoaded();\n * // Now mcp.serverInfo.icon is guaranteed to be set (if icon exists)\n * ```\n */\n ensureIconLoaded: () => Promise<string | null>;\n /**\n * The underlying runtime-neutral MCP client instance.\n * Use this to create an MCPAgent for AI chat functionality.\n *\n * @example\n * ```typescript\n * import { MCPAgent } from \"@mcp-use/agent\"\n * import { ChatOpenAI } from '@langchain/openai'\n *\n * const mcp = useMcp({ url: 'http://localhost:3000/mcp' })\n * const llm = new ChatOpenAI({ model: 'gpt-4' })\n *\n * const agent = new MCPAgent({ llm, client: mcp.client })\n * await agent.initialize()\n *\n * for await (const event of agent.streamEvents('Hello')) {\n * console.log(event)\n * }\n * ```\n */\n client: BaseMCPClient | null;\n};\n\n/**\n * Connected MCP server: non-secret settings, live runtime headers, and state.\n * Returned from `useMcpClient().servers`.\n */\ntype LiveMcpServerConfig = Omit<PersistedMcpServerConfig, \"proxyConfig\"> & {\n /** Runtime HTTP headers. These values are never persisted. */\n headers?: Record<string, string>;\n /** Live proxy configuration, including runtime-only headers. */\n proxyConfig?: ProxyConfig;\n /** SDK client options used by the active connection. */\n clientOptions?: McpServerConfig[\"clientOptions\"];\n};\n\nexport interface McpServer extends LiveMcpServerConfig, UseMcpResult {\n /** Stable provider-managed server identifier. */\n id: string;\n /** Notifications received from this server. */\n notifications: McpNotification[];\n /** Number of notifications not yet marked as read. */\n unreadNotificationCount: number;\n /** Marks one notification as read. */\n markNotificationRead: (id: string) => void;\n /** Marks every notification as read. */\n markAllNotificationsRead: () => void;\n /** Removes every notification from local state. */\n clearNotifications: () => void;\n /** Sampling requests awaiting an application decision. */\n pendingSamplingRequests: PendingSamplingRequest[];\n /** Approves a pending sampling request with a result. */\n approveSampling: (\n requestId: string,\n result: SamplingCreateMessageResult\n ) => void;\n /** Rejects a pending sampling request. */\n rejectSampling: (requestId: string, error?: string) => void;\n /** Elicitation requests awaiting an application decision. */\n pendingElicitationRequests: PendingElicitationRequest[];\n /** Approves a pending elicitation request with a result. */\n approveElicitation: (requestId: string, result: ElicitResult) => void;\n /** Rejects a pending elicitation request. */\n rejectElicitation: (requestId: string, error?: string) => void;\n /**\n * Merge connection-affecting config and reconnect when it changed.\n * Prefer this over context `updateServer(id, …)` when you already hold the server.\n */\n updateConfig: (config: Partial<McpServerConfig>) => Promise<void>;\n /** Set HTTP headers on the connection config and reconnect. */\n setHeaders: (headers: Record<string, string> | undefined) => Promise<void>;\n /** Rename the server without disconnecting. */\n setDisplayName: (displayName: string) => Promise<void>;\n /** Disconnect and reconnect with the current config. */\n reconnect: () => Promise<void>;\n}\n\nconst PERSISTED_SERVER_CONFIG_KEYS = [\n \"url\",\n \"displayName\",\n \"enabled\",\n \"oauthProxyUrl\",\n \"connectionMode\",\n \"autoProxyFallback\",\n \"callbackUrl\",\n \"storageKeyPrefix\",\n \"logLevel\",\n \"autoRetry\",\n \"autoReconnect\",\n \"reconnectionOptions\",\n \"popupFeatures\",\n \"preventAutoAuth\",\n \"detectMixedAuth\",\n \"useRedirectFlow\",\n \"protocolNegotiation\",\n \"timeout\",\n \"clientInfo\",\n] as const satisfies readonly (keyof PersistedMcpServerConfig)[];\n\n/**\n * Extracts the non-secret subset safe for provider storage.\n *\n * @param source - Server configuration or live managed server.\n * @returns A new persistable configuration object.\n */\nexport function pickPersistedServerConfig(\n source: McpServerConfig | McpServer\n): PersistedMcpServerConfig {\n const out: PersistedMcpServerConfig = {};\n for (const key of PERSISTED_SERVER_CONFIG_KEYS) {\n const value = source[key];\n if (value !== undefined) {\n (out as Record<string, unknown>)[key] = value;\n }\n }\n if (source.proxyConfig?.proxyAddress !== undefined) {\n out.proxyConfig = { proxyAddress: source.proxyConfig.proxyAddress };\n }\n if (source.oauth) {\n const oauth: NonNullable<PersistedMcpServerConfig[\"oauth\"]> = {};\n if (source.oauth.clientId !== undefined) {\n oauth.clientId = source.oauth.clientId;\n }\n if (source.oauth.clientMetadataUrl !== undefined) {\n oauth.clientMetadataUrl = source.oauth.clientMetadataUrl;\n }\n if (source.oauth.scope !== undefined) {\n oauth.scope = source.oauth.scope;\n }\n if (Object.keys(oauth).length > 0) {\n out.oauth = oauth;\n }\n }\n return out;\n}\n\n/**\n * Extracts connection settings, including runtime-only values, from a server.\n *\n * @param source - Server configuration or live managed server.\n * @returns A new live configuration object.\n */\nexport function pickLiveServerConfig(\n source: McpServerConfig | McpServer\n): LiveMcpServerConfig {\n return {\n ...pickPersistedServerConfig(source),\n ...(source.headers !== undefined ? { headers: source.headers } : {}),\n ...(source.proxyConfig !== undefined\n ? { proxyConfig: source.proxyConfig }\n : {}),\n ...(source.clientOptions !== undefined\n ? { clientOptions: source.clientOptions }\n : {}),\n };\n}\n\n/**\n * Removes credentials, callbacks, and runtime-only values before storage.\n *\n * @param config - Configuration to sanitize.\n * @returns A new persistable configuration object.\n */\nexport function toPersistedServerConfig(\n config: McpServerConfig\n): PersistedMcpServerConfig {\n return pickPersistedServerConfig(config);\n}\n","// useMcp.ts\nimport { auth } from \"@modelcontextprotocol/client\";\nimport type {\n OAuthClientProvider,\n Prompt,\n ProtocolEra,\n Resource,\n ResourceTemplateType as ResourceTemplate,\n Tool,\n Transport,\n} from \"@modelcontextprotocol/client\";\nimport {\n runAuthPopup,\n MCP_AUTH_BROADCAST_CHANNEL,\n MCP_AUTH_CALLBACK_MESSAGE_TYPE,\n type McpAuthCallbackMessage,\n} from \"../auth/popup.js\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { BrowserMCPClient } from \"../core/browser.js\";\nimport { resolveClientOptions } from \"../core/config.js\";\nimport { Logger, type LogLevel } from \"../utils/logging.js\";\nimport type { MCPConnection } from \"../core/session.js\";\nimport { Tel } from \"../telemetry/telemetry-browser.js\";\nimport { isUnauthorized } from \"../auth/flow.js\";\nimport { assert } from \"./useMcp-helpers.js\";\nimport type { ProxyConfig } from \"./types.js\";\nimport { sanitizeUrl } from \"../auth/url.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\nimport {\n createBrowserOAuthProvider,\n deriveOAuthClientConfigFromClientInfo,\n isOAuthDiscoveryFailure,\n startConnectionHealthMonitoring,\n USE_MCP_SERVER_NAME,\n} from \"./useMcp-helpers.js\";\nimport type { UseMcpOptions, UseMcpResult } from \"./types.js\";\nimport { loadServerIcon } from \"./useMcp-helpers.js\";\nimport { useMcpOperations } from \"./useMcp-operations.js\";\nimport { getOAuthTokenExpiry } from \"./token-expiry.js\";\nimport { SKILLS_EXTENSION_ID } from \"../core/skills.js\";\n\nconst DEFAULT_RECONNECT_DELAY = 3000;\nconst DEFAULT_RETRY_DELAY = 5000;\n\n// Streamable HTTP is the only supported remote transport.\ntype TransportType = \"http\";\n\ntype UseMcpAuthProvider = OAuthClientProvider & {\n tokens?: () => Promise<\n | {\n access_token?: string;\n token_type?: string;\n refresh_token?: string;\n scope?: string;\n [key: string]: unknown;\n }\n | undefined\n >;\n clearStorage?: () => number;\n getLastAttemptedAuthUrl?: () => string | null | undefined;\n getTokenEndpoint?: () => Promise<string | null>;\n getResource?: () => Promise<string | null>;\n getClientCredentials?: () => Promise<{\n client_id: string;\n client_secret?: string;\n } | null>;\n /**\n * Returns a `fetch` scoped to this provider that routes OAuth requests\n * through the configured OAuth proxy (bypassing CORS) while leaving the\n * global `fetch` untouched. Passed to the SDK transport / `auth()` so proxy\n * behavior is confined to this server's connection.\n */\n getProxyFetch?: (baseFetch?: typeof fetch) => typeof fetch | undefined;\n serverUrl?: string;\n /** localStorage key for a given suffix (e.g. \"tokens\"). */\n getKey?: (keySuffix: string) => string;\n /** Stable hash of the server URL, used to scope OAuth result messages. */\n serverUrlHash?: string;\n};\n\ntype UseMcpInternalOptions = UseMcpOptions & {\n _initialServerInfo?: {\n name?: string;\n version?: string;\n title?: string;\n websiteUrl?: string;\n icons?: Array<{ src: string; mimeType?: string }>;\n icon?: string;\n };\n};\n\n/**\n * React hook for connecting to and interacting with MCP servers\n *\n * Provides a complete interface for MCP server connections including:\n * - Automatic connection management with reconnection\n * - OAuth authentication with automatic token refresh\n * - Tool, resource, and prompt access\n * - AI chat functionality with conversation memory\n * - Streamable HTTP transport\n *\n * @param options - Configuration options for the MCP connection\n * @returns MCP connection state and methods\n *\n * @example\n * ```typescript\n * const mcp = useMcp({\n * url: 'http://localhost:3000/mcp',\n * headers: { Authorization: 'Bearer YOUR_API_KEY' }\n * })\n *\n * // Wait for connection\n * useEffect(() => {\n * if (mcp.state === 'ready') {\n * console.log('Connected!', mcp.tools)\n * }\n * }, [mcp.state])\n *\n * // Call a tool\n * const result = await mcp.callTool('send-email', { to: 'user@example.com' })\n * ```\n */\nexport function useMcp(options: UseMcpInternalOptions): UseMcpResult {\n const {\n url,\n enabled = true,\n callbackUrl = typeof window !== \"undefined\"\n ? sanitizeUrl(\n new URL(\"/oauth/callback\", window.location.origin).toString()\n )\n : \"/oauth/callback\",\n storageKeyPrefix = \"mcp:auth\",\n authProvider: providedAuthProvider,\n headers: headersOption,\n proxyConfig,\n oauthProxyUrl: oauthProxyUrlOption,\n connectionMode,\n autoProxyFallback = false,\n logLevel: logLevelOption = \"silent\",\n autoRetry = false,\n autoReconnect = true,\n reconnectionOptions,\n preventAutoAuth = true, // Default to true - require explicit user action for OAuth\n detectMixedAuth = true,\n useRedirectFlow = false, // Default to false for backward compatibility (use popup)\n onPopupWindow,\n timeout = 30000, // 30 seconds default for connection timeout\n wrapTransport,\n serverId,\n fetch: customFetch,\n clientOptions,\n protocolNegotiation,\n onNotification,\n onSampling: onSamplingOption,\n onElicitation: onElicitationOption,\n oauth: oauthOptions,\n } = options;\n const transportType: TransportType = \"http\";\n const requestedProxyAddress = proxyConfig?.proxyAddress;\n\n const oauthClientId = oauthOptions?.clientId?.trim() || undefined;\n const oauthClientMetadataUrl =\n oauthOptions?.clientMetadataUrl?.trim() || undefined;\n const oauthScope = oauthOptions?.scope?.trim() || undefined;\n const staticClientInfo = useMemo(\n () => (oauthClientId ? { client_id: oauthClientId } : undefined),\n [oauthClientId]\n );\n\n // Create a per-instance logger so multiple useMcp instances don't clobber each other's log level.\n // Each instance gets its own named logger keyed by URL (or a fallback).\n const instanceLogger = useMemo(() => {\n const name = `useMcp:${url || \"no-url\"}`;\n const inst = Logger.get(name);\n // Configure the per-instance level when requested.\n if (logLevelOption) {\n inst.level = logLevelOption as LogLevel;\n }\n return inst;\n }, [url, logLevelOption]);\n\n const headers = headersOption ?? {};\n const effectiveClientOptions = useMemo(\n () => resolveClientOptions(clientOptions),\n [clientOptions]\n );\n\n const onSampling = onSamplingOption;\n const onElicitation = onElicitationOption;\n // Build clientInfo with defaults, merging with provided clientInfo\n const defaultClientInfo = useMemo(\n () => ({\n name: \"mcp-use\",\n title: \"mcp-use\",\n version: getPackageVersion(),\n description:\n \"mcp-use is a complete TypeScript framework for building and using MCP\",\n icons: [\n {\n src: \"https://mcp-use.com/logo.png\",\n },\n ],\n websiteUrl: \"https://mcp-use.com\",\n }),\n []\n );\n\n const mergedClientInfo = useMemo(\n () =>\n options.clientInfo\n ? { ...defaultClientInfo, ...options.clientInfo }\n : defaultClientInfo,\n [options.clientInfo, defaultClientInfo]\n );\n\n // Derive OAuth client registration config from clientInfo.\n const derivedOAuthClientConfig = useMemo(\n () => deriveOAuthClientConfigFromClientInfo(mergedClientInfo),\n [mergedClientInfo]\n );\n\n const oauthClientConfig = derivedOAuthClientConfig;\n\n // Parse autoProxyFallback configuration\n const autoProxyFallbackConfig = useMemo(() => {\n // Explicit Direct and Proxy modes never fall back. Direct must stay direct,\n // while Proxy already starts on the configured gateway.\n if (connectionMode === \"direct\" || connectionMode === \"proxy\") {\n return { enabled: false, proxyAddress: undefined };\n }\n if (!autoProxyFallback) {\n return { enabled: false, proxyAddress: undefined };\n }\n if (typeof autoProxyFallback === \"boolean\") {\n const proxyAddress = proxyConfig?.proxyAddress;\n return {\n enabled: autoProxyFallback && Boolean(proxyAddress),\n proxyAddress,\n };\n }\n const proxyAddress =\n autoProxyFallback.proxyAddress ?? proxyConfig?.proxyAddress;\n return {\n enabled: autoProxyFallback.enabled !== false && Boolean(proxyAddress),\n proxyAddress,\n };\n }, [autoProxyFallback, connectionMode, proxyConfig]);\n\n // Normalize autoReconnect into a consistent config object\n const autoReconnectConfig = useMemo(() => {\n if (autoReconnect === false) {\n return {\n enabled: false,\n initialDelay: 0,\n healthCheckInterval: false as const,\n healthCheckTimeout: 30000,\n };\n }\n if (autoReconnect === true) {\n return {\n enabled: true,\n initialDelay: DEFAULT_RECONNECT_DELAY,\n healthCheckInterval: 10000,\n healthCheckTimeout: 30000,\n };\n }\n if (typeof autoReconnect === \"number\") {\n return {\n enabled: true,\n initialDelay: autoReconnect,\n healthCheckInterval: 10000,\n healthCheckTimeout: 30000,\n };\n }\n return {\n enabled: autoReconnect.enabled !== false,\n initialDelay: autoReconnect.initialDelay ?? DEFAULT_RECONNECT_DELAY,\n healthCheckInterval: autoReconnect.healthCheckInterval ?? 10000,\n healthCheckTimeout: autoReconnect.healthCheckTimeout ?? 30000,\n };\n }, [autoReconnect]);\n\n // Runtime proxy config is set only after automatic direct -> proxy fallback.\n const [effectiveProxyConfig, setEffectiveProxyConfig] = useState<\n ProxyConfig | undefined\n >(undefined);\n\n // Reset runtime fallback when the requested connection changes.\n useEffect(() => {\n setEffectiveProxyConfig(undefined);\n }, [\n url,\n requestedProxyAddress,\n connectionMode,\n autoProxyFallbackConfig.proxyAddress,\n ]);\n\n const activeProxyConfig = useMemo(() => {\n const hasCurrentAutoFallback =\n autoProxyFallbackConfig.enabled &&\n effectiveProxyConfig?.proxyAddress ===\n autoProxyFallbackConfig.proxyAddress;\n if (hasCurrentAutoFallback && effectiveProxyConfig) {\n const latestHeaders = proxyConfig?.headers ?? {};\n return {\n ...effectiveProxyConfig,\n headers: {\n ...latestHeaders,\n ...(effectiveProxyConfig.headers ?? {}),\n },\n };\n }\n\n // Auto always starts direct, even when proxyConfig supplies the fallback\n // address. Direct also ignores stale proxyConfig left by older persisted\n // Inspector configurations. Without an explicit mode, preserve the\n // low-level API's immediate-proxy behavior unless fallback was requested.\n const startsDirect =\n connectionMode === \"auto\" ||\n connectionMode === \"direct\" ||\n (connectionMode === undefined && autoProxyFallbackConfig.enabled);\n return startsDirect ? undefined : proxyConfig;\n }, [\n effectiveProxyConfig,\n proxyConfig,\n connectionMode,\n autoProxyFallbackConfig.enabled,\n autoProxyFallbackConfig.proxyAddress,\n ]);\n\n const gatewayUrl = activeProxyConfig?.proxyAddress;\n const proxyHeaders = activeProxyConfig?.headers ?? {};\n\n // OAuth provider should ALWAYS use the original target URL for OAuth discovery,\n // not the proxy URL. The proxy is only used for making the actual HTTP requests.\n const effectiveOAuthUrl = useMemo(() => {\n return url || \"\";\n }, [url]);\n\n // Merge proxy headers with custom headers (custom headers take precedence)\n const allHeaders = useMemo(\n () => ({ ...proxyHeaders, ...headers }),\n [proxyHeaders, headers]\n );\n\n const [state, setState] = useState<UseMcpResult[\"state\"]>(\"discovering\");\n const [tools, setTools] = useState<Tool[]>([]);\n const [resources, setResources] = useState<Resource[]>([]);\n const [resourceTemplates, setResourceTemplates] = useState<\n ResourceTemplate[]\n >([]);\n const [prompts, setPrompts] = useState<Prompt[]>([]);\n const [skills, setSkills] = useState<import(\"../core/skills.js\").Skill[]>([]);\n const [serverInfo, setServerInfo] = useState<UseMcpResult[\"serverInfo\"]>(\n // Only use cached metadata if it has at least a name\n options._initialServerInfo?.name\n ? (options._initialServerInfo as UseMcpResult[\"serverInfo\"])\n : undefined\n );\n const [capabilities, setCapabilities] = useState<Record<string, any>>();\n const [protocolEra, setProtocolEra] = useState<ProtocolEra | undefined>(\n undefined\n );\n const [protocolVersion, setProtocolVersion] = useState<string | undefined>(\n undefined\n );\n const [instructions, setInstructions] = useState<string | undefined>();\n const [extensions, setExtensions] = useState<Record<string, unknown>>({});\n const [error, setError] = useState<string | undefined>(undefined);\n const [log, setLog] = useState<UseMcpResult[\"log\"]>([]);\n const [authUrl, setAuthUrl] = useState<string | undefined>(undefined);\n const [authTokens, setAuthTokens] =\n useState<UseMcpResult[\"authTokens\"]>(undefined);\n const [authorization, setAuthorization] =\n useState<UseMcpResult[\"authorization\"]>(undefined);\n\n const clientRef = useRef<BrowserMCPClient | null>(null);\n const connectionRef = useRef<MCPConnection | null>(null);\n const authProviderRef = useRef<UseMcpAuthProvider | null>(\n (providedAuthProvider as UseMcpAuthProvider | undefined) ?? null\n );\n const iconLoadingPromiseRef = useRef<Promise<string | null> | null>(null);\n const connectingRef = useRef<boolean>(false);\n const isMountedRef = useRef<boolean>(true);\n const connectAttemptRef = useRef<number>(0);\n /** Bumped at the start of each connect(); disconnect only clears clientRef if epoch unchanged. */\n const connectEpochRef = useRef(0);\n const authTimeoutRef = useRef<number | null>(null);\n const retryScheduledRef = useRef<boolean>(false);\n /**\n * True while a manual `authenticate()` popup flow owns the OAuth result.\n * The always-on `mcp_auth_callback` listener defers to the popup runner\n * during this window so a single completion doesn't trigger two reconnects.\n */\n const popupFlowActiveRef = useRef<boolean>(false);\n\n // --- Refs for values used in callbacks ---\n const stateRef = useRef(state);\n const authorizationRef = useRef(authorization);\n const authorizationServerUrlRef = useRef(url);\n authorizationRef.current = authorization;\n const autoReconnectRef = useRef(autoReconnect);\n const successfulTransportRef = useRef<TransportType | null>(null);\n // Forward refs for functions (declared later) to avoid circular dependencies\n const connectRef = useRef<(() => Promise<void>) | null>(null);\n const failConnectionRef = useRef<\n ((message: string, error?: Error) => void) | null\n >(null);\n\n // Reverse-request / notification callbacks must stay fresh without putting\n // their React identities into connect()'s dependency list (which would\n // reconnect whenever a parent re-creates inline handlers).\n //\n // Presence and implementation are tracked separately for reverse requests:\n // the current presence refs determine capabilities on the next normal\n // connect, while implementation refs retain the last defined handler so an\n // already-advertised live connection does not start failing merely because its\n // callback prop was removed before that reconnect.\n const onSamplingRef = useRef(onSampling);\n const onElicitationRef = useRef(onElicitation);\n const hasSamplingCallbackRef = useRef(onSampling !== undefined);\n const hasElicitationCallbackRef = useRef(onElicitation !== undefined);\n const onNotificationRef = useRef(onNotification);\n if (onSampling !== undefined) {\n onSamplingRef.current = onSampling;\n }\n if (onElicitation !== undefined) {\n onElicitationRef.current = onElicitation;\n }\n hasSamplingCallbackRef.current = onSampling !== undefined;\n hasElicitationCallbackRef.current = onElicitation !== undefined;\n onNotificationRef.current = onNotification;\n\n // Stable proxies passed to addServer notification wiring. Capability\n // advertisement uses current presence at connect time; once wired, reverse\n // requests dispatch to the latest defined implementation retained above.\n const stableOnSampling = useCallback<\n NonNullable<UseMcpOptions[\"onSampling\"]>\n >(async (params) => {\n // This proxy is only wired when a callback exists, and the implementation\n // ref is intentionally never cleared during that live connection.\n return onSamplingRef.current!(params);\n }, []);\n const stableOnElicitation = useCallback<\n NonNullable<UseMcpOptions[\"onElicitation\"]>\n >(async (params) => {\n return onElicitationRef.current!(params);\n }, []);\n const stableOnNotification = useCallback(\n (notification: Parameters<NonNullable<typeof onNotification>>[0]) => {\n onNotificationRef.current?.(notification);\n },\n []\n );\n\n /**\n * Effect: Keep refs in sync with state values\n * Allows callbacks to access latest state without re-creating them\n */\n useEffect(() => {\n stateRef.current = state;\n autoReconnectRef.current = autoReconnect;\n }, [state, autoReconnect]);\n\n useEffect(() => {\n authProviderRef.current =\n (providedAuthProvider as UseMcpAuthProvider | undefined) ?? null;\n }, [providedAuthProvider]);\n\n // --- Stable Callbacks ---\n /**\n * Add a log entry to the connection log.\n * Console output is routed through the per-instance logger so that\n * the configured logLevel / silent mode is respected.\n * The log state array is always populated for programmatic access.\n * @internal\n */\n const addLog = useCallback(\n (\n level: UseMcpResult[\"log\"][0][\"level\"],\n message: string,\n ...args: unknown[]\n ) => {\n const fullMessage =\n args.length > 0\n ? `${message} ${args.map((arg) => JSON.stringify(arg)).join(\" \")}`\n : message;\n // Route through per-instance logger so logLevel/silent is respected\n const logMsg = `[useMcp] ${fullMessage}`;\n switch (level) {\n case \"error\":\n instanceLogger.error(logMsg);\n break;\n case \"warn\":\n instanceLogger.warn(logMsg);\n break;\n case \"info\":\n instanceLogger.info(logMsg);\n break;\n case \"debug\":\n instanceLogger.debug(logMsg);\n break;\n default:\n instanceLogger.info(logMsg);\n }\n if (isMountedRef.current) {\n setLog((prevLog: UseMcpResult[\"log\"]) => [\n ...prevLog.slice(-100),\n { level, message: fullMessage, timestamp: Date.now() },\n ]);\n }\n },\n [instanceLogger]\n );\n\n const onAuthorizationRequired = useCallback(\n (authError: unknown) => {\n const preparedAuthUrl =\n authProviderRef.current?.getLastAttemptedAuthUrl?.() ?? undefined;\n addLog(\n \"info\",\n \"This server requires OAuth for the requested operation; waiting for authentication.\",\n authError\n );\n const authorizationRequired = {\n ...(authorizationRef.current ?? { mode: \"mixed\" as const }),\n authenticated: false,\n };\n authorizationRef.current = authorizationRequired;\n setAuthorization(authorizationRequired);\n if (preparedAuthUrl) setAuthUrl(preparedAuthUrl);\n },\n [addLog]\n );\n\n const connectionOperations = useMcpOperations({\n stateRef,\n connectionRef,\n hasClient: () => clientRef.current !== null,\n isMounted: () => isMountedRef.current,\n setTools,\n setResources,\n setResourceTemplates,\n setPrompts,\n setSkills,\n addLog,\n onAuthorizationRequired,\n });\n\n /**\n * Disconnect from the MCP server and clean up resources\n * @param quiet - If true, suppresses log messages\n */\n const disconnect = useCallback(\n async (quiet = false) => {\n if (!quiet) addLog(\"info\", \"Disconnecting...\");\n connectingRef.current = false;\n if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);\n authTimeoutRef.current = null;\n\n const epochAtStart = connectEpochRef.current;\n const clientToClose = clientRef.current;\n if (clientToClose) {\n try {\n const serverName = USE_MCP_SERVER_NAME;\n const connection =\n clientToClose === clientRef.current ? connectionRef.current : null;\n\n // Clean up health check monitoring if it exists\n if (connection && (connection as any)._healthCheckCleanup) {\n (connection as any)._healthCheckCleanup();\n (connection as any)._healthCheckCleanup = null;\n }\n\n // Only try to close if a connection exists (avoids noisy warning logs)\n if (connection) {\n await clientToClose.closeSession(serverName);\n }\n } catch (err) {\n if (!quiet) addLog(\"warn\", \"Error closing connection:\", err);\n }\n }\n // A newer connect() (e.g. dashboard environment / URL change) may have\n // bumped the epoch — possibly reusing the same client instance — while\n // closeSession was in flight. If so, this disconnect is stale: it must\n // neither null the (now newer) clientRef nor reset the live state.\n const supersededByNewerConnect = connectEpochRef.current !== epochAtStart;\n\n if (clientRef.current === clientToClose && !supersededByNewerConnect) {\n clientRef.current = null;\n connectionRef.current = null;\n }\n\n if (isMountedRef.current && !quiet && !supersededByNewerConnect) {\n setState(\"discovering\");\n setTools([]);\n setResources([]);\n setResourceTemplates([]);\n setPrompts([]);\n setSkills([]);\n setError(undefined);\n setAuthUrl(undefined);\n setAuthTokens(undefined);\n setServerInfo(undefined);\n setCapabilities(undefined);\n setProtocolEra(undefined);\n setProtocolVersion(undefined);\n setInstructions(undefined);\n setExtensions({});\n }\n },\n [addLog]\n );\n\n /**\n * Mark connection as failed with an error message\n * @internal\n * @returns true if automatic fallback was triggered (caller should not set failed state)\n */\n const failConnection = useCallback(\n (errorMessage: string, connectionError?: Error): boolean => {\n addLog(\"error\", errorMessage, connectionError ?? \"\");\n\n // Extract HTTP status code from error if available\n const errorCode =\n connectionError && \"code\" in connectionError\n ? (connectionError as any).code\n : undefined;\n\n // Check if we should try automatic proxy fallback\n // Don't use a ref to track this - it causes issues with React strict mode\n // where multiple instances share the same ref but have different state\n const shouldTryProxyFallback =\n autoProxyFallbackConfig.enabled && !activeProxyConfig?.proxyAddress; // Only fallback if not already using proxy\n\n // Detect CORS errors (these can't have status codes, so check message)\n const isCorsError =\n errorMessage.includes(\"CORS\") ||\n errorMessage.includes(\"blocked by CORS policy\") ||\n errorMessage.includes(\"Failed to fetch\");\n\n // HTTP 400 errors typically indicate session/protocol incompatibility that a proxy can resolve\n // (e.g., FastMCP missing session ID, streamable HTTP issues)\n const is400Error = errorCode === 400;\n\n // Other 4xx errors that might benefit from proxy fallback (except auth errors)\n const hasOther4xxError =\n typeof errorCode === \"number\" && errorCode >= 404 && errorCode < 500;\n\n // Don't fallback on auth errors (proxy won't help with authentication)\n const isAuthError = errorCode === 401 || errorCode === 403;\n\n const shouldFallback =\n shouldTryProxyFallback &&\n (isCorsError || is400Error || hasOther4xxError) &&\n !isAuthError;\n\n if (shouldFallback) {\n const errorType = isCorsError\n ? \"CORS error\"\n : is400Error\n ? \"HTTP 400 (Bad Request)\"\n : \"HTTP 4xx error\";\n addLog(\n \"info\",\n `Direct connection failed with ${errorType}. Trying with proxy...`\n );\n\n // Clear client/auth refs to force fresh initialization with proxy.\n // Keep externally provided auth providers intact. Synchronous clear;\n // reconnect is deferred via setTimeout below, so no disconnect race.\n clientRef.current = null;\n if (!providedAuthProvider) {\n authProviderRef.current = null;\n }\n addLog(\"debug\", \"Cleared client and auth provider for proxy fallback\");\n\n // Set proxy configuration and trigger reconnect\n setEffectiveProxyConfig({\n proxyAddress: autoProxyFallbackConfig.proxyAddress!,\n });\n\n // Explicitly set state back to \"discovering\" to prevent showing failed state\n // This ensures smooth UX during automatic retry\n if (isMountedRef.current) {\n setState(\"discovering\");\n }\n\n // Trigger reconnection after a brief delay\n setTimeout(() => {\n if (isMountedRef.current) {\n connectRef.current?.();\n }\n }, 1000);\n\n return true; // Signal that we're retrying - caller should not set failed state\n }\n\n // Normal failure handling\n if (isMountedRef.current) {\n addLog(\"info\", \"Setting state to FAILED:\", errorMessage);\n setState(\"failed\");\n setError(errorMessage);\n const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (manualUrl) {\n setAuthUrl(manualUrl);\n addLog(\n \"info\",\n \"Manual authentication URL may be available.\",\n manualUrl\n );\n }\n }\n connectingRef.current = false;\n\n // Track failed connection\n if (url) {\n Tel.getInstance()\n .trackUseMcpConnection({\n url,\n transportType: transportType,\n success: false,\n errorType: connectionError?.name || \"UnknownError\",\n hasOAuth: !!authProviderRef.current,\n hasSampling: hasSamplingCallbackRef.current,\n hasElicitation: hasElicitationCallbackRef.current,\n })\n .catch(() => {});\n }\n\n return false; // Not retrying, connection actually failed\n },\n [\n addLog,\n url,\n transportType,\n autoProxyFallbackConfig,\n activeProxyConfig,\n providedAuthProvider,\n ]\n );\n\n /**\n * Connect to the MCP server over streamable HTTP.\n * @internal\n */\n const connect = useCallback(async () => {\n // Don't connect if not enabled or no URL provided\n if (!enabled || !url) {\n addLog(\n \"debug\",\n enabled\n ? \"No server URL provided, skipping connection.\"\n : \"Connection disabled via enabled flag.\"\n );\n return;\n }\n\n if (connectingRef.current) {\n addLog(\"debug\", \"Connection attempt already in progress.\");\n return;\n }\n if (!isMountedRef.current) {\n addLog(\"debug\", \"Connect called after unmount, aborting.\");\n return;\n }\n\n connectingRef.current = true;\n connectEpochRef.current += 1;\n connectAttemptRef.current += 1;\n if (authorizationServerUrlRef.current !== url) {\n authorizationServerUrlRef.current = url;\n authorizationRef.current = undefined;\n setAuthorization(undefined);\n }\n setError(undefined);\n setAuthUrl(undefined);\n successfulTransportRef.current = null;\n setState(\"discovering\");\n setTools([]);\n setResources([]);\n setResourceTemplates([]);\n setPrompts([]);\n setSkills([]);\n setServerInfo(undefined);\n setCapabilities(undefined);\n setProtocolEra(undefined);\n setProtocolVersion(undefined);\n setInstructions(undefined);\n setExtensions({});\n addLog(\n \"info\",\n `Connecting attempt #${connectAttemptRef.current} to ${url}...`\n );\n\n // NOTE: We intentionally do NOT clear OAuth storage before connecting.\n // The clearStorage() function clears tokens and client_info which should\n // persist across connections. Clearing them would force re-authentication\n // even when valid tokens exist from a previous OAuth flow.\n //\n // Stale state/verifier items are cleaned up:\n // - By the callback handler after successful token exchange\n // - By the unmount cleanup when OAuth flow is interrupted\n // - By the state expiry check in the callback handler\n\n if (!authProviderRef.current) {\n const { provider, oauthProxyUrl } = createBrowserOAuthProvider({\n effectiveOAuthUrl,\n storageKeyPrefix,\n oauthClientConfig,\n callbackUrl,\n preventAutoAuth,\n useRedirectFlow,\n gatewayUrl,\n oauthProxyUrl: oauthProxyUrlOption,\n onPopupWindow,\n proxyOAuthRequests: true,\n staticClientInfo,\n clientMetadataUrl: oauthClientMetadataUrl,\n scope: oauthScope,\n });\n authProviderRef.current = provider;\n if (oauthProxyUrl) {\n addLog(\"debug\", `OAuth BFF enabled: ${oauthProxyUrl}`);\n }\n addLog(\n \"debug\",\n `BrowserOAuthClientProvider initialized with URL: ${effectiveOAuthUrl}, proxy: ${oauthProxyUrl ? \"enabled\" : \"disabled\"}, gateway: ${gatewayUrl ? \"enabled\" : \"disabled\"}`\n );\n }\n if (!clientRef.current) {\n clientRef.current = new BrowserMCPClient();\n addLog(\"debug\", \"BrowserMCPClient initialized in connect.\");\n } else {\n addLog(\"debug\", \"BrowserMCPClient already exists, reusing.\");\n }\n\n const tryConnectWithTransport = async (\n transportTypeParam: TransportType\n ): Promise<\"success\" | \"fallback\" | \"auth_redirect\" | \"failed\"> => {\n // Check if component unmounted\n if (!isMountedRef.current) {\n addLog(\"debug\", \"Connection attempt aborted - component unmounted\");\n return \"failed\";\n }\n\n addLog(\n \"info\",\n `Attempting connection with transport: ${transportTypeParam}`\n );\n addLog(\n \"debug\",\n `Client ref status at start of tryConnectWithTransport: ${clientRef.current ? \"initialized\" : \"NULL\"}`\n );\n\n try {\n const serverName = USE_MCP_SERVER_NAME;\n\n // Build server config\n const serverConfig: any = {\n url: url, // Use original URL, not transformed proxy URL\n timeout,\n clientInfo: mergedClientInfo,\n // Pass a fetch that scopes OAuth-proxy routing to this server's\n // transport/auth calls. getProxyFetch wraps `customFetch` (e.g. the\n // OAuth retry fetch for scope step-up), bypasses the browser cache\n // for OAuth metadata, and optionally routes OAuth through the BFF.\n // It never mutates the global fetch.\n ...(() => {\n const scopedFetch =\n authProviderRef.current?.getProxyFetch?.(customFetch) ??\n customFetch;\n return scopedFetch ? { fetch: scopedFetch } : {};\n })(),\n // Pass clientOptions for custom capabilities (e.g., MCP Apps extension)\n ...(effectiveClientOptions && {\n clientOptions: effectiveClientOptions,\n }),\n // Protocol era negotiation mode (\"legacy\" | \"auto\" | { pin }); the\n // connector defaults to automatic v1/v2 negotiation.\n ...(protocolNegotiation !== undefined && { protocolNegotiation }),\n detectMixedAuth,\n // Pass user-configurable reconnection options, or when autoReconnect\n // is disabled, disable SDK transport reconnection to prevent\n // unwanted GET polling requests\n ...(reconnectionOptions\n ? { reconnectionOptions }\n : autoReconnect === false\n ? { reconnectionOptions: { maxRetries: 0 } }\n : {}),\n };\n\n // Add gateway URL if using proxy\n if (gatewayUrl) {\n serverConfig.gatewayUrl = gatewayUrl;\n addLog(\n \"debug\",\n `Using proxy gateway: ${gatewayUrl} for target: ${url}`\n );\n }\n\n // Add custom headers if provided (includes proxy headers)\n if (allHeaders && Object.keys(allHeaders).length > 0) {\n serverConfig.headers = allHeaders;\n }\n\n // Client should be initialized by the parent connect() function\n // If it's not AND component is still mounted, this is a programming error\n if (!clientRef.current) {\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted - component unmounted, client cleaned up\"\n );\n return \"failed\";\n }\n const initError = new Error(\n \"Client not initialized - this is a bug in the connection flow\"\n );\n addLog(\n \"error\",\n \"Client ref is null in tryConnectWithTransport but component is still mounted\"\n );\n throw initError;\n }\n\n // Add server to client with OAuth provider.\n // Pass stable proxies (when a callback is present) so capability\n // advertisement happens on initial connect, while dispatch always\n // reaches the latest React handler via refs — even after reconnects\n // that reuse a connect() closure created with a different identity.\n clientRef.current.addServer(serverName, {\n ...serverConfig,\n authProvider: authProviderRef.current,\n onSampling: hasSamplingCallbackRef.current\n ? stableOnSampling\n : undefined,\n onElicitation: hasElicitationCallbackRef.current\n ? stableOnElicitation\n : undefined,\n onNotification: (\n notification: Parameters<typeof stableOnNotification>[0]\n ) => {\n addLog(\n \"debug\",\n \"Notification received:\",\n notification.method,\n notification\n );\n stableOnNotification(notification);\n\n if (notification.method === \"notifications/tools/list_changed\") {\n addLog(\"info\", \"Tools list changed, auto-refreshing...\");\n connectionOperations\n .refreshTools()\n .catch((err) =>\n addLog(\"warn\", \"Auto-refresh tools failed:\", err)\n );\n } else if (\n notification.method === \"notifications/resources/list_changed\"\n ) {\n addLog(\"info\", \"Resources list changed, auto-refreshing...\");\n const clientInfoExtensions = (\n mergedClientInfo as {\n capabilities?: { extensions?: Record<string, unknown> };\n }\n ).capabilities?.extensions;\n const optionExtensions = (\n effectiveClientOptions?.capabilities as\n | { extensions?: Record<string, unknown> }\n | undefined\n )?.extensions;\n const supportsSkills =\n optionExtensions?.[SKILLS_EXTENSION_ID] !== undefined ||\n clientInfoExtensions?.[SKILLS_EXTENSION_ID] !== undefined;\n Promise.all([\n connectionOperations.refreshResources(),\n ...(supportsSkills\n ? [connectionOperations.refreshSkills()]\n : []),\n ]).catch((err) =>\n addLog(\"warn\", \"Auto-refresh resources failed:\", err)\n );\n } else if (\n notification.method === \"notifications/prompts/list_changed\"\n ) {\n addLog(\"info\", \"Prompts list changed, auto-refreshing...\");\n connectionOperations\n .refreshPrompts()\n .catch((err) =>\n addLog(\"warn\", \"Auto-refresh prompts failed:\", err)\n );\n }\n },\n wrapTransport: wrapTransport\n ? (transport: Transport) => {\n addLog(\n \"debug\",\n \"Applying transport wrapper for server:\",\n serverName,\n \"url:\",\n url\n );\n return wrapTransport(transport, serverId ?? url);\n }\n : undefined,\n });\n\n // MCPClient owns protocol negotiation and any legacy initialization.\n // Modern connections remain stateless and are not initialized twice.\n const connection = await clientRef.current.connect(serverName);\n connectionRef.current = connection;\n\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted after connection creation - component unmounted\"\n );\n return \"failed\";\n }\n\n addLog(\"info\", \"✅ Successfully connected to MCP server\");\n addLog(\"info\", \"Server info:\", connection.info.server);\n addLog(\"info\", \"Server capabilities:\", connection.info.capabilities);\n\n // Only set up monitoring if autoReconnect is enabled and health checks are not disabled\n if (\n autoReconnectConfig.enabled &&\n autoReconnectConfig.healthCheckInterval !== false\n ) {\n const cleanup = startConnectionHealthMonitoring({\n gatewayUrl,\n url,\n allHeaders,\n getAuthHeaders: async (): Promise<Record<string, string>> => {\n try {\n const tokens = await authProviderRef.current?.tokens?.();\n if (tokens?.access_token) {\n const tokenType = tokens.token_type || \"bearer\";\n return {\n Authorization: `${tokenType.charAt(0).toUpperCase() + tokenType.slice(1)} ${tokens.access_token}`,\n };\n }\n } catch {\n // Intentionally empty - fall through to return {}\n }\n return {};\n },\n isMountedRef,\n stateRef,\n autoReconnectRef,\n setState,\n addLog,\n connect,\n defaultReconnectDelay: autoReconnectConfig.initialDelay,\n healthCheckIntervalMs: autoReconnectConfig.healthCheckInterval,\n healthCheckTimeoutMs: autoReconnectConfig.healthCheckTimeout,\n });\n\n // Store cleanup function for later\n (connection as any)._healthCheckCleanup = cleanup;\n }\n\n // Track successful connection\n Tel.getInstance()\n .trackUseMcpConnection({\n url,\n transportType: transportTypeParam,\n success: true,\n hasOAuth: !!authProviderRef.current,\n hasSampling: hasSamplingCallbackRef.current,\n hasElicitation: hasElicitationCallbackRef.current,\n })\n .catch(() => {});\n\n // Get tools, resources, and prompts through the protocol-neutral connection.\n setTools(connection.tools || []);\n\n const {\n server: serverInfo,\n capabilities,\n protocolEra,\n protocolVersion,\n instructions,\n extensions,\n authorization: connectionAuthorization,\n } = connection.info;\n\n if (connectionAuthorization) {\n setAuthorization(connectionAuthorization);\n authorizationRef.current = connectionAuthorization;\n }\n setProtocolEra(protocolEra);\n setProtocolVersion(protocolVersion);\n setInstructions(instructions);\n setExtensions(extensions);\n\n if (serverInfo) {\n addLog(\"debug\", \"Server info:\", serverInfo);\n setServerInfo(serverInfo);\n iconLoadingPromiseRef.current = loadServerIcon({\n serverInfo,\n url,\n isMounted: () => isMountedRef.current,\n setServerInfo,\n addLog,\n });\n }\n if (capabilities) {\n addLog(\"debug\", \"Server capabilities:\", capabilities);\n setCapabilities(capabilities);\n }\n\n // Tools and normalized connection metadata are sufficient for a usable\n // connection. Auxiliary inventories must populate progressively rather\n // than extending the ready-state critical path.\n successfulTransportRef.current = transportTypeParam;\n setState(\"ready\");\n // Optional OAuth metadata is not part of anonymous MCP readiness. Give\n // React a chance to paint the ready state before starting its network\n // fallbacks, which may legitimately return 404 for public servers.\n const discoverAuthorizationAfterReady = () => {\n if (!isMountedRef.current || connectionRef.current !== connection) {\n return;\n }\n const authorizationDiscovery = connection.discoverAuthorization?.();\n if (authorizationDiscovery) {\n void authorizationDiscovery.then((discovered) => {\n if (\n !discovered ||\n !isMountedRef.current ||\n connectionRef.current !== connection\n ) {\n return;\n }\n authorizationRef.current = discovered;\n setAuthorization(discovered);\n });\n }\n };\n if (typeof globalThis.requestAnimationFrame === \"function\") {\n globalThis.requestAnimationFrame(() => {\n setTimeout(discoverAuthorizationAfterReady, 0);\n });\n } else {\n setTimeout(discoverAuthorizationAfterReady, 0);\n }\n\n // Capability advertisements in the wild are not always granular: a\n // server may support resources/list while returning Method not found\n // for resources/templates/list. Inventory failures must not tear down\n // an otherwise healthy MCP connection.\n const [resourcesResult, promptsResult, templatesResult] =\n await Promise.all([\n connection.listAllResources().catch((error) => {\n addLog(\"warn\", \"Failed to load initial resources:\", error);\n return { resources: [] };\n }),\n connection.listPrompts().catch((error) => {\n addLog(\"warn\", \"Failed to load initial prompts:\", error);\n return { prompts: [] };\n }),\n connection.supports(\"resources\")\n ? connection.listResourceTemplates().catch((error) => {\n addLog(\n \"warn\",\n \"Failed to load initial resource templates:\",\n error\n );\n return { resourceTemplates: [] };\n })\n : Promise.resolve({ resourceTemplates: [] }),\n ]);\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted after discovery - component unmounted\"\n );\n return \"failed\";\n }\n setResources(resourcesResult.resources || []);\n setPrompts(promptsResult.prompts || []);\n setResourceTemplates(templatesResult.resourceTemplates || []);\n\n // Skills are another auxiliary inventory and populate progressively.\n if (isMountedRef.current) {\n if (extensions[\"io.modelcontextprotocol/skills\"] !== undefined) {\n try {\n const result = await connection.listAllSkills();\n if (isMountedRef.current) setSkills(result.skills);\n } catch (error) {\n addLog(\"warn\", \"Failed to load initial skills:\", error);\n if (isMountedRef.current) setSkills([]);\n }\n } else {\n setSkills([]);\n }\n }\n\n // Get OAuth tokens if authentication was used\n if (authProviderRef.current) {\n let tokens: Awaited<\n ReturnType<NonNullable<UseMcpAuthProvider[\"tokens\"]>>\n >;\n try {\n tokens = await authProviderRef.current.tokens?.();\n } catch (error) {\n // The MCP connection is already usable. Token projection is\n // supplemental state and must not tear down a ready connection.\n addLog(\"warn\", \"Failed to read OAuth tokens:\", error);\n tokens = undefined;\n }\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted after token fetch for auth tokens - component unmounted\"\n );\n return \"failed\";\n }\n if (tokens?.access_token) {\n if (authorizationRef.current?.mode === \"mixed\") {\n const authenticatedAuthorization = {\n ...authorizationRef.current,\n authenticated: true,\n };\n setAuthorization(authenticatedAuthorization);\n authorizationRef.current = authenticatedAuthorization;\n }\n const expiresAt = getOAuthTokenExpiry(tokens);\n\n // Best-effort: resolve the OAuth token endpoint + client credentials\n // so consumers can persist them for server-side proactive refresh.\n // Never blocks auth.\n let tokenEndpoint: string | null = null;\n let resource: string | null = null;\n let clientCreds: {\n client_id: string;\n client_secret?: string;\n } | null = null;\n try {\n tokenEndpoint =\n (await authProviderRef.current.getTokenEndpoint?.()) ?? null;\n } catch {\n tokenEndpoint = null;\n }\n try {\n resource =\n (await authProviderRef.current.getResource?.()) ?? null;\n } catch {\n resource = null;\n }\n try {\n clientCreds =\n (await authProviderRef.current.getClientCredentials?.()) ??\n null;\n } catch {\n clientCreds = null;\n }\n\n if (!isMountedRef.current) {\n addLog(\"debug\", \"Skipping state update - component unmounted\");\n return \"failed\";\n }\n setAuthTokens({\n access_token: tokens.access_token,\n token_type: tokens.token_type || \"Bearer\",\n expires_at: expiresAt,\n refresh_token: tokens.refresh_token,\n scope: tokens.scope,\n ...(tokenEndpoint ? { token_endpoint: tokenEndpoint } : {}),\n ...(resource ? { resource } : {}),\n ...(clientCreds?.client_id\n ? { client_id: clientCreds.client_id }\n : {}),\n ...(clientCreds?.client_secret\n ? { client_secret: clientCreds.client_secret }\n : {}),\n });\n }\n }\n\n return \"success\";\n } catch (err: unknown) {\n const error = err as Error & { code?: number; message?: string };\n const errorMessage = error?.message || String(err);\n\n // A prepared authorization URL means OAuth discovery already succeeded on\n // an earlier pass. A later failure (token refresh, SSE fallback, or a\n // metadata probe that fell back to the transport origin) must NOT be\n // misclassified as \"server does not support OAuth\" — that drops us to\n // `failed` and hides the Authenticate button. When we already have a\n // stored auth URL and an OAuth provider, surface `pending_auth` instead.\n const preparedAuthUrl =\n authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (preparedAuthUrl && authProviderRef.current && preventAutoAuth) {\n addLog(\n \"info\",\n \"OAuth already discovered (stored auth URL present); awaiting manual authentication.\"\n );\n if (isMountedRef.current) {\n setState(\"pending_auth\");\n setAuthUrl(preparedAuthUrl);\n }\n connectingRef.current = false;\n return \"auth_redirect\";\n }\n\n // Check if OAuth discovery failed (indicates server doesn't support OAuth)\n // This happens when a 401 triggers OAuth discovery but the server has no OAuth endpoints\n const oauthDiscoveryFailed = isOAuthDiscoveryFailure(err);\n\n // Check if this is a 401 error\n const is401Error = isUnauthorized(err);\n\n // If OAuth discovery failed with custom headers provided, this was likely a 401 with wrong credentials\n // The error message might say \"404\" (from OAuth endpoint attempts) but the root cause was 401\n if (\n oauthDiscoveryFailed &&\n headers &&\n Object.keys(headers).length > 0\n ) {\n failConnection(\n \"Authentication failed (HTTP 401). Server does not support OAuth. \" +\n \"Check your Authorization header value is correct.\"\n );\n return \"failed\";\n }\n\n // If OAuth discovery failed without custom headers, the server likely requires\n // authentication but doesn't support OAuth discovery\n // This handles cases where the server returns 401 but the error message shows \"404\"\n // from the OAuth endpoint attempts\n if (\n oauthDiscoveryFailed &&\n (!headers || Object.keys(headers).length === 0)\n ) {\n failConnection(\n \"Authentication required (HTTP 401). Server does not support OAuth. \" +\n \"Add an Authorization header in the Custom Headers section \" +\n \"(e.g., Authorization: Bearer YOUR_API_KEY).\"\n );\n return \"failed\";\n }\n\n // Handle 401 errors\n if (is401Error) {\n // If OAuth discovery failed, the server doesn't support OAuth\n // Show a clear message about this\n if (oauthDiscoveryFailed) {\n // No OAuth support and no custom headers - suggest adding API key\n failConnection(\n \"Authentication required (HTTP 401). Server does not support OAuth. \" +\n \"Add an Authorization header in the Custom Headers section \" +\n \"(e.g., Authorization: Bearer YOUR_API_KEY).\"\n );\n return \"failed\";\n }\n\n // OAuth discovery didn't fail, so OAuth might be available\n // Check if OAuth provider is configured\n if (authProviderRef.current) {\n // OAuth is configured\n addLog(\n \"info\",\n \"Authentication required. OAuth provider available.\"\n );\n\n // Check if we should trigger auth automatically or wait for user\n if (preventAutoAuth) {\n // Don't trigger auth flow automatically - let the user click \"Authenticate\"\n // This prevents unnecessary metadata discovery requests that may fail with CORS/404\n addLog(\n \"info\",\n \"Waiting for user to initiate authentication flow...\"\n );\n\n if (isMountedRef.current) {\n setState(\"pending_auth\");\n // Retrieve the stored auth URL if it was prepared during OAuth discovery\n const storedAuthUrl =\n authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (storedAuthUrl) {\n setAuthUrl(storedAuthUrl);\n addLog(\n \"info\",\n \"Retrieved stored auth URL for manual authentication\"\n );\n }\n }\n connectingRef.current = false;\n return \"auth_redirect\";\n } else {\n // preventAutoAuth is false - trigger auth flow automatically\n addLog(\n \"info\",\n \"Triggering automatic OAuth authentication flow...\"\n );\n\n try {\n // The SDK owns protected-resource discovery and parses the\n // original transport 401. Do not issue a duplicate probe.\n const authResult = await auth(authProviderRef.current, {\n serverUrl: url,\n fetchFn: authProviderRef.current.getProxyFetch?.(),\n });\n\n if (authResult === \"REDIRECT\") {\n // Step 2: Get the authorization response captured during\n // redirectToAuthorization, including RFC 9207 `iss` when\n // the provider exposes it.\n const flowProvider = authProviderRef.current as any;\n const authResponse =\n await flowProvider.getAuthorizationResponse?.();\n const authCode =\n authResponse?.code ??\n (await flowProvider.getAuthorizationCode?.());\n if (typeof authCode !== \"string\") {\n throw new Error(\n \"Authorization code not captured by headless provider\"\n );\n }\n\n // Step 3: Complete the OAuth flow by exchanging code for tokens\n await auth(authProviderRef.current, {\n serverUrl: url,\n authorizationCode: authCode,\n ...(authResponse?.iss !== undefined\n ? { iss: authResponse.iss }\n : {}),\n fetchFn: authProviderRef.current.getProxyFetch?.(),\n });\n }\n\n addLog(\"info\", \"OAuth flow completed, reconnecting...\");\n // Reconnect after successful auth\n return await tryConnectWithTransport(transportTypeParam);\n } catch (authError) {\n const authErrorMessage =\n authError instanceof Error\n ? authError.message\n : String(authError);\n failConnection(\n `Automatic OAuth authentication failed: ${authErrorMessage}`,\n authError instanceof Error\n ? authError\n : new Error(String(authError))\n );\n return \"failed\";\n }\n }\n }\n\n // Check if custom headers were provided (invalid credentials)\n if (headers && Object.keys(headers).length > 0) {\n failConnection(\n \"Authentication failed: Server returned 401 Unauthorized. \" +\n \"Check your Authorization header value is correct.\"\n );\n return \"failed\";\n }\n\n // No OAuth and no custom headers - suggest adding them\n failConnection(\n \"Authentication required: Server returned 401 Unauthorized. \" +\n \"Add an Authorization header in the Custom Headers section \" +\n \"(e.g., Authorization: Bearer YOUR_API_KEY).\"\n );\n return \"failed\";\n }\n\n // Handle other errors\n const isRetryingWithProxy = failConnection(\n errorMessage,\n error instanceof Error ? error : new Error(String(error))\n );\n // If failConnection triggered automatic proxy fallback, return a special\n // status so the caller does not treat this as a hard connection failure\n return isRetryingWithProxy ? \"auth_redirect\" : \"failed\";\n }\n };\n\n let finalStatus: \"success\" | \"auth_redirect\" | \"failed\" | \"fallback\" =\n \"failed\";\n\n addLog(\"debug\", \"Connecting via streamable HTTP\");\n finalStatus = await tryConnectWithTransport(\"http\");\n\n // Reset connecting flag for all terminal states and auth_redirect\n // auth_redirect needs to reset the flag so the auth callback can reconnect\n if (\n finalStatus === \"success\" ||\n finalStatus === \"failed\" ||\n finalStatus === \"auth_redirect\"\n ) {\n connectingRef.current = false;\n }\n\n addLog(\"debug\", `Connection sequence finished with status: ${finalStatus}`);\n }, [\n addLog,\n failConnection,\n disconnect,\n url,\n storageKeyPrefix,\n callbackUrl,\n oauthClientConfig.name,\n oauthClientConfig.version,\n oauthClientConfig.uri,\n oauthClientConfig.logo_uri,\n staticClientInfo,\n oauthClientMetadataUrl,\n oauthScope,\n headers,\n transportType,\n preventAutoAuth,\n detectMixedAuth,\n useRedirectFlow,\n onPopupWindow,\n enabled,\n timeout,\n mergedClientInfo,\n effectiveClientOptions,\n protocolNegotiation,\n // IMPORTANT: Include proxy-related dependencies so connect() uses updated values after fallback\n gatewayUrl,\n oauthProxyUrlOption,\n allHeaders,\n effectiveOAuthUrl,\n // Stable reverse-request proxies (empty-deps useCallbacks). Listed for\n // correctness; their identities never change, so they do not reconnect.\n stableOnSampling,\n stableOnElicitation,\n stableOnNotification,\n ]);\n\n /**\n * Effect: Update function refs to prevent stale closures\n * Used by retry and OAuth callback handlers\n */\n useEffect(() => {\n connectRef.current = connect;\n failConnectionRef.current = failConnection;\n }, [connect, failConnection]);\n\n /**\n * Retry connection after failure\n * Only works if current state is 'failed'\n * Note: Uses connectRef to avoid circular dependency with connect\n */\n const retry = useCallback(() => {\n if (stateRef.current === \"failed\") {\n addLog(\"info\", \"Retry requested...\");\n // Use connectRef to avoid circular dependency\n // connectRef is kept updated via useEffect\n connectRef.current?.();\n } else {\n addLog(\n \"warn\",\n `Retry called but state is not 'failed' (state: ${stateRef.current}). Ignoring.`\n );\n }\n }, [addLog]);\n\n /**\n * Trigger manual OAuth authentication flow\n *\n * Opens OAuth popup for user authorization. Use when state is 'pending_auth'\n * or to manually retry authentication.\n *\n * @example\n * ```typescript\n * if (mcp.state === 'pending_auth') {\n * mcp.authenticate() // Opens OAuth popup\n * }\n * ```\n */\n const authenticate = useCallback(async () => {\n addLog(\"info\", \"Manual authentication requested...\");\n const currentState = stateRef.current;\n const isOptionalMixedAuthentication =\n currentState === \"ready\" && authorizationRef.current?.mode === \"mixed\";\n\n if (currentState === \"failed\") {\n addLog(\"info\", \"Attempting to reconnect and authenticate via retry...\");\n retry();\n } else if (\n currentState === \"pending_auth\" ||\n (currentState === \"ready\" &&\n authorizationRef.current?.mode === \"mixed\" &&\n !authorizationRef.current.authenticated)\n ) {\n addLog(\"info\", \"Proceeding with authentication...\");\n\n try {\n assert(\n authProviderRef.current,\n \"Auth Provider not available for manual auth\"\n );\n assert(url, \"Server URL is required for authentication\");\n\n if (providedAuthProvider) {\n addLog(\n \"info\",\n \"Using provided authProvider for manual authentication\"\n );\n const parsedUrl = new URL(url);\n const baseUrl =\n parsedUrl.origin + parsedUrl.pathname.replace(/\\/+$/, \"\");\n await auth(authProviderRef.current, {\n serverUrl: baseUrl,\n fetchFn: authProviderRef.current.getProxyFetch?.(),\n });\n connectRef.current?.();\n return;\n }\n\n // Clear OAuth storage to ensure fresh authentication flow.\n // This is an explicit, user-initiated \"authenticate\" action (not a\n // lifecycle event), so wiping stale tokens/verifier here is correct.\n const clearedCount = authProviderRef.current.clearStorage?.() ?? 0;\n addLog(\n \"info\",\n `Cleared ${clearedCount} OAuth storage item(s) for fresh authentication`\n );\n\n // Update state to authenticating before redirect\n setState(\"authenticating\");\n\n // Capture the popup handle and OAuth `state` as the provider opens the\n // popup, so the opener (this window) can own the flow's lifecycle via\n // runAuthPopup() instead of waiting indefinitely for a push message.\n let capturedPopup: globalThis.Window | null = null;\n let capturedState: string | null = null;\n const captureOnPopupWindow = (\n popupUrl: string,\n features: string,\n popupWin: globalThis.Window | null\n ) => {\n capturedPopup = popupWin;\n try {\n capturedState = new URL(popupUrl).searchParams.get(\"state\");\n } catch {\n /* non-fatal: fall back to provider's last auth URL below */\n }\n onPopupWindow?.(popupUrl, features, popupWin);\n };\n\n // Recreate the auth provider WITHOUT preventAutoAuth.\n // proxyOAuthRequests is always true: the scoped OAuth proxy fetch is\n // the sole browser-CORS mechanism (the gateway no longer fronts OAuth\n // metadata — it broke RFC 8414 §3.3 issuer validation for strict\n // clients). It is a no-op when no OAuth proxy URL is configured.\n const { provider: freshAuthProvider, oauthProxyUrl } =\n createBrowserOAuthProvider({\n effectiveOAuthUrl,\n storageKeyPrefix,\n oauthClientConfig,\n callbackUrl,\n preventAutoAuth: false,\n useRedirectFlow,\n gatewayUrl,\n oauthProxyUrl: oauthProxyUrlOption,\n onPopupWindow: captureOnPopupWindow,\n proxyOAuthRequests: true,\n staticClientInfo,\n clientMetadataUrl: oauthClientMetadataUrl,\n scope: oauthScope,\n });\n\n if (oauthProxyUrl) {\n addLog(\"info\", \"Scoped OAuth proxy fetch enabled for manual auth\");\n }\n\n // Replace the auth provider\n authProviderRef.current = freshAuthProvider;\n\n addLog(\"info\", \"Triggering fresh OAuth authorization...\");\n\n // Generate a fresh authorization URL and open the popup/redirect.\n // The provider redirects/popups automatically (preventAutoAuth: false).\n const parsedUrl = new URL(url);\n const baseUrl =\n parsedUrl.origin + parsedUrl.pathname.replace(/\\/+$/, \"\");\n const authResult = await auth(freshAuthProvider, {\n serverUrl: baseUrl,\n fetchFn: freshAuthProvider.getProxyFetch?.(),\n });\n\n if (authResult === \"AUTHORIZED\") {\n addLog(\"info\", \"OAuth flow completed (tokens obtained)\");\n connectingRef.current = false;\n connectRef.current?.();\n return;\n }\n\n if (authResult !== \"REDIRECT\") {\n throw new Error(`Unexpected OAuth auth() result: ${authResult}`);\n }\n\n addLog(\"info\", \"OAuth authorization redirect initiated\");\n\n // Update authUrl with the new URL from the fresh provider\n // This is critical for the fallback link when popup is blocked\n const newAuthUrl = freshAuthProvider.getLastAttemptedAuthUrl?.();\n if (newAuthUrl) {\n setAuthUrl(newAuthUrl);\n addLog(\"info\", \"Updated auth URL for fallback:\", newAuthUrl);\n if (!capturedState) {\n try {\n capturedState = new URL(newAuthUrl).searchParams.get(\"state\");\n } catch {\n /* leave null; runAuthPopup accepts state-less results */\n }\n }\n }\n\n // Redirect flow navigates the whole page away — nothing to await here.\n if (useRedirectFlow) {\n return;\n }\n\n // Opener-owned popup flow: own the lifecycle so we can never get stuck\n // in \"authenticating\". Settles on result message / popup close / token\n // storage write / timeout (see runAuthPopup).\n const tokensKey = freshAuthProvider.getKey?.(\"tokens\");\n if (!tokensKey) {\n // Without a tokens key we can't run the supervised flow; fall back to\n // the always-on listener and leave state as authenticating.\n addLog(\n \"warn\",\n \"Could not derive tokens storage key; relying on callback listener.\"\n );\n return;\n }\n\n popupFlowActiveRef.current = true;\n let result;\n try {\n result = await runAuthPopup({\n popup: capturedPopup,\n state: capturedState,\n tokensKey,\n });\n } finally {\n popupFlowActiveRef.current = false;\n }\n\n if (!isMountedRef.current) return;\n\n switch (result.kind) {\n case \"success\":\n addLog(\n \"info\",\n \"Authentication succeeded; reconnecting to MCP server...\"\n );\n connectingRef.current = false;\n connectRef.current?.();\n break;\n case \"cancelled\":\n addLog(\n \"warn\",\n isOptionalMixedAuthentication\n ? \"Authentication popup was closed before completing. Public tools remain available.\"\n : \"Authentication popup was closed before completing. Returning to pending_auth.\"\n );\n setState(isOptionalMixedAuthentication ? \"ready\" : \"pending_auth\");\n break;\n case \"timeout\":\n addLog(\n \"warn\",\n isOptionalMixedAuthentication\n ? \"Authentication timed out waiting for the popup. Public tools remain available.\"\n : \"Authentication timed out waiting for the popup. Returning to pending_auth.\"\n );\n setState(isOptionalMixedAuthentication ? \"ready\" : \"pending_auth\");\n break;\n case \"error\":\n failConnection(`Authentication failed: ${result.error}`);\n break;\n default:\n // Exhaustive over AuthPopupResult[\"kind\"]; nothing to do.\n break;\n }\n } catch (authError) {\n if (!isMountedRef.current) return;\n const error =\n authError instanceof Error ? authError : new Error(String(authError));\n failConnection(`Manual authentication failed: ${error.message}`, error);\n }\n } else if (currentState === \"authenticating\") {\n addLog(\n \"warn\",\n \"Already attempting authentication. Check for blocked popups or wait for timeout.\"\n );\n const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (manualUrl && !authUrl) {\n setAuthUrl(manualUrl);\n addLog(\"info\", \"Manual authentication URL retrieved:\", manualUrl);\n }\n } else {\n addLog(\n \"info\",\n `Client not in a state requiring manual authentication trigger (state: ${currentState}). If needed, try disconnecting and reconnecting.`\n );\n }\n }, [\n addLog,\n retry,\n failConnection,\n authUrl,\n url,\n useRedirectFlow,\n onPopupWindow,\n storageKeyPrefix,\n oauthClientConfig.name,\n oauthClientConfig.uri,\n oauthClientConfig.logo_uri,\n staticClientInfo,\n oauthClientMetadataUrl,\n oauthScope,\n callbackUrl,\n mergedClientInfo,\n providedAuthProvider,\n ]);\n\n /**\n * Clear OAuth tokens from localStorage and disconnect\n *\n * Useful for logging out or resetting authentication state.\n *\n * @example\n * ```typescript\n * mcp.clearStorage() // Removes tokens and disconnects\n * ```\n */\n const clearStorage = useCallback(() => {\n if (authProviderRef.current?.clearStorage) {\n const count = authProviderRef.current.clearStorage();\n addLog(\"info\", `Cleared ${count} item(s) from localStorage for ${url}.`);\n setAuthUrl(undefined);\n disconnect();\n } else {\n addLog(\"warn\", \"Auth provider not initialized, cannot clear storage.\");\n }\n }, [url, addLog, disconnect]);\n\n // ===== Effects =====\n\n /**\n * Effect: Listen for OAuth callback messages from popup window\n *\n * Subscribes to two transports for the same `mcp_auth_callback` payload:\n * - `window.message` (postMessage from `window.opener`): the happy path\n * when the popup retained its opener reference.\n * - `BroadcastChannel(\"mcp_auth_callback\")`: same-origin fallback used by\n * the popup callback when `window.opener` has been severed by COOP,\n * cross-origin intermediate redirects, or browser tab grouping.\n * Without this, a popup that completes auth but lost its opener leaves\n * the parent stuck in `authenticating` forever.\n *\n * The popup only emits over one transport per callback, so the two\n * listeners don't double-fire on a single auth completion.\n */\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const handleCallbackPayload = (\n payload: McpAuthCallbackMessage | undefined,\n source: \"postMessage\" | \"BroadcastChannel\"\n ) => {\n // Defer to runAuthPopup while a manual authenticate() flow owns the\n // result, so a single completion doesn't trigger two reconnects.\n if (popupFlowActiveRef.current) {\n addLog(\n \"debug\",\n `Ignoring auth callback via ${source}; manual popup flow owns this result.`\n );\n return;\n }\n\n // Scope the result to this server. The callback page stamps the payload\n // with the originating server's URL hash; ignore results for other\n // servers so unrelated useMcp instances don't all reconnect at once.\n // Payloads without a hash (older callback pages) are accepted.\n const ourHash = authProviderRef.current?.serverUrlHash;\n if (\n payload?.serverUrlHash &&\n ourHash &&\n payload.serverUrlHash !== ourHash\n ) {\n addLog(\n \"debug\",\n `Ignoring auth callback via ${source} for a different server.`\n );\n return;\n }\n\n addLog(\"info\", `Received auth callback via ${source}.`, payload);\n if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);\n authTimeoutRef.current = null;\n\n if (payload?.success) {\n addLog(\n \"info\",\n \"Authentication successful via popup. Reconnecting client...\"\n );\n\n // Check if already connecting\n if (connectingRef.current) {\n addLog(\n \"debug\",\n \"Connection attempt already in progress, resetting flag to allow reconnection.\"\n );\n }\n\n // Reset the connecting flag and reconnect since auth just succeeded\n connectingRef.current = false;\n\n // Small delay to ensure state is clean before reconnecting\n setTimeout(() => {\n if (isMountedRef.current) {\n addLog(\n \"debug\",\n \"Initiating reconnection after successful auth callback.\"\n );\n connectRef.current?.();\n }\n }, 100);\n } else {\n // Don't clobber a connection that already became ready (or moved on):\n // a late/duplicate failure message must not knock a healthy client\n // back to \"failed\".\n if (\n stateRef.current !== \"authenticating\" &&\n stateRef.current !== \"pending_auth\"\n ) {\n addLog(\n \"debug\",\n `Ignoring stale auth failure callback (state=${stateRef.current}).`\n );\n return;\n }\n failConnectionRef.current?.(\n `Authentication failed in callback: ${payload?.error || \"Unknown reason.\"}`\n );\n }\n };\n\n const messageHandler = (event: globalThis.MessageEvent) => {\n if (event.origin !== window.location.origin) return;\n if (event.data?.type !== MCP_AUTH_CALLBACK_MESSAGE_TYPE) return;\n handleCallbackPayload(event.data, \"postMessage\");\n };\n window.addEventListener(\"message\", messageHandler);\n addLog(\"debug\", \"Auth callback message listener added.\");\n\n let broadcastChannel: BroadcastChannel | null = null;\n const broadcastHandler = (event: MessageEvent) => {\n if (event.data?.type !== MCP_AUTH_CALLBACK_MESSAGE_TYPE) return;\n handleCallbackPayload(event.data, \"BroadcastChannel\");\n };\n if (typeof BroadcastChannel !== \"undefined\") {\n try {\n broadcastChannel = new BroadcastChannel(MCP_AUTH_BROADCAST_CHANNEL);\n broadcastChannel.addEventListener(\"message\", broadcastHandler);\n addLog(\"debug\", \"Auth callback BroadcastChannel listener added.\");\n } catch (e) {\n addLog(\n \"warn\",\n \"Failed to open auth callback BroadcastChannel; lost-opener popups will not reach this client.\",\n e as Error\n );\n broadcastChannel = null;\n }\n }\n\n return () => {\n window.removeEventListener(\"message\", messageHandler);\n addLog(\"debug\", \"Auth callback message listener removed.\");\n if (broadcastChannel) {\n try {\n broadcastChannel.removeEventListener(\"message\", broadcastHandler);\n broadcastChannel.close();\n } catch {\n /* ignore */\n }\n addLog(\"debug\", \"Auth callback BroadcastChannel listener removed.\");\n }\n if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);\n };\n }, [addLog]);\n\n /**\n * Effect: Main connection lifecycle\n *\n * Runs on mount and when key connection parameters change.\n * - Initializes OAuth provider\n * - Initiates connection\n * - Cleans up on unmount or when URL changes\n */\n useEffect(() => {\n isMountedRef.current = true;\n\n // Skip connection if disabled or no URL provided\n if (!enabled || !url) {\n addLog(\n \"debug\",\n enabled\n ? \"No server URL provided, skipping connection.\"\n : \"Connection disabled via enabled flag.\"\n );\n setState(\"discovering\");\n return () => {\n isMountedRef.current = false;\n };\n }\n\n addLog(\"debug\", \"useMcp mounted, initiating connection.\");\n connectAttemptRef.current = 0;\n if (providedAuthProvider) {\n authProviderRef.current = providedAuthProvider as UseMcpAuthProvider;\n addLog(\"debug\", \"Using externally provided authProvider\");\n } else if (\n !authProviderRef.current ||\n authProviderRef.current.serverUrl !== effectiveOAuthUrl\n ) {\n const { provider, oauthProxyUrl } = createBrowserOAuthProvider({\n effectiveOAuthUrl,\n storageKeyPrefix,\n oauthClientConfig,\n callbackUrl,\n preventAutoAuth,\n useRedirectFlow,\n gatewayUrl,\n oauthProxyUrl: oauthProxyUrlOption,\n onPopupWindow,\n proxyOAuthRequests: true,\n staticClientInfo,\n clientMetadataUrl: oauthClientMetadataUrl,\n scope: oauthScope,\n });\n authProviderRef.current = provider;\n if (oauthProxyUrl) {\n addLog(\"debug\", `OAuth proxy URL in effect: ${oauthProxyUrl}`);\n }\n addLog(\n \"debug\",\n `BrowserOAuthClientProvider initialized/updated with URL: ${effectiveOAuthUrl}, proxy: ${oauthProxyUrl ? \"enabled\" : \"disabled\"}, gateway: ${gatewayUrl ? \"enabled\" : \"disabled\"}`\n );\n }\n connect();\n return () => {\n isMountedRef.current = false;\n addLog(\"debug\", \"useMcp unmounting, disconnecting.\");\n\n // NOTE: We intentionally do NOT clear OAuth storage on unmount, even\n // mid-flow. Wrapper remounts (provider revision changes, route\n // churn, StrictMode double-mounting) would otherwise destroy the\n // in-flight authorization state record + PKCE verifier and strand a\n // popup that completes after the remount. Stale state records carry a\n // 10-minute TTL (enforced in callback.ts) and the PKCE verifier is\n // overwritten by `saveCodeVerifier()` on the next auth start, so leaving\n // them in place is safe. Tokens that land after a remount are picked up\n // by the state-keyed callback listener / storage event and the wrapper\n // reconnects cleanly. Explicit logout still clears storage via\n // `clearStorage()` / `removeServer(id, { clearCredentials: true })`.\n\n disconnect(true);\n };\n }, [\n url,\n enabled,\n storageKeyPrefix,\n callbackUrl,\n oauthClientConfig.name,\n oauthClientConfig.version,\n oauthClientConfig.uri,\n oauthClientConfig.logo_uri,\n staticClientInfo,\n oauthClientMetadataUrl,\n oauthScope,\n useRedirectFlow,\n mergedClientInfo,\n effectiveOAuthUrl, // Triggers reconnection when proxy fallback changes OAuth URL\n proxyConfig, // Triggers reconnection when proxy config (including headers) changes\n autoProxyFallbackConfig.proxyAddress,\n providedAuthProvider,\n ]);\n\n /**\n * Effect: Auto-retry on failure\n *\n * If autoRetry is enabled and connection fails, automatically retries\n * after the specified delay.\n * Uses a ref to prevent duplicate scheduling which can cause render loops.\n */\n const retryRef = useRef(retry);\n const addLogRef = useRef(addLog);\n\n useEffect(() => {\n retryRef.current = retry;\n addLogRef.current = addLog;\n }, [retry, addLog]);\n\n useEffect(() => {\n let retryTimeoutId: number | null = null;\n\n if (state === \"failed\" && autoRetry && connectAttemptRef.current > 0) {\n // Prevent duplicate scheduling - only schedule if not already scheduled\n if (!retryScheduledRef.current) {\n retryScheduledRef.current = true;\n const delay =\n typeof autoRetry === \"number\" ? autoRetry : DEFAULT_RETRY_DELAY;\n addLogRef.current(\n \"info\",\n `Connection failed, auto-retrying in ${delay}ms...`\n );\n retryTimeoutId = setTimeout(() => {\n retryScheduledRef.current = false;\n if (isMountedRef.current && stateRef.current === \"failed\") {\n retryRef.current();\n }\n }, delay) as any;\n }\n } else if (state !== \"failed\") {\n // Reset the ref when not in failed state\n retryScheduledRef.current = false;\n }\n\n return () => {\n if (retryTimeoutId) {\n clearTimeout(retryTimeoutId);\n retryScheduledRef.current = false;\n }\n };\n }, [state, autoRetry]);\n\n /**\n * Ensure the server icon is loaded and available\n * Waits for the background icon loading to complete\n *\n * @returns Promise that resolves with the base64 icon or null\n */\n const ensureIconLoaded = useCallback(async (): Promise<string | null> => {\n if (stateRef.current !== \"ready\") {\n addLog(\"warn\", \"Cannot ensure icon loaded - not connected\");\n return null;\n }\n\n // If icon is already available, return it immediately\n if (serverInfo?.icon) {\n return serverInfo.icon;\n }\n\n // If icon loading is in progress, wait for it\n if (iconLoadingPromiseRef.current) {\n addLog(\"debug\", \"Waiting for icon to finish loading...\");\n const icon = await iconLoadingPromiseRef.current;\n return icon;\n }\n\n // No icon loading in progress and no icon available\n addLog(\"debug\", \"No icon available and no loading in progress\");\n return null;\n }, [serverInfo, addLog]);\n\n return {\n state,\n name: serverInfo?.name || url || \"\",\n tools,\n resources,\n resourceTemplates,\n prompts,\n skills,\n serverInfo,\n capabilities,\n protocolEra,\n protocolVersion,\n instructions,\n extensions,\n error,\n log,\n authUrl,\n authTokens,\n authorization,\n client: clientRef.current,\n ...connectionOperations,\n retry,\n disconnect,\n authenticate,\n clearStorage,\n ensureIconLoaded,\n };\n}\n","// popup-runner.ts\n//\n// Opener-owned OAuth popup runner. Models the pattern used by mature browser\n// OAuth libraries (auth0-spa-js `runPopup`, oidc-client-ts `AbstractChildWindow`,\n// msal-browser popup clients): the window that OPENED the popup owns a promise\n// that settles on exactly one of four terminal outcomes, so the caller can never\n// be left waiting forever.\n//\n// A flow settles on the first of:\n// 1. An `mcp_auth_callback` result message (postMessage from the popup's\n// `window.opener`, or a same-origin `BroadcastChannel` when the opener was\n// severed by COOP / cross-origin redirects / tab grouping), matched to this\n// flow by its OAuth `state` parameter.\n// 2. The popup being closed (`popup.closed` poll). Before declaring the flow\n// cancelled we check whether tokens already landed in storage — the popup\n// may have completed the exchange and closed before its message dispatched.\n// 3. A `storage` event for this flow's tokens key. This is the most robust\n// signal: the popup always persists tokens to localStorage before notifying,\n// and `storage` events fire cross-window even when message channels are\n// severed or partitioned (the MSAL \"redirect bridge partition\" gotcha).\n// 4. A timeout. Same tokens check as the close path before declaring timeout.\n\n/** Channel name shared by the popup callback notifier and every listener. */\nexport const MCP_AUTH_BROADCAST_CHANNEL = \"mcp_auth_callback\";\n\n/** Result message type posted by the OAuth callback page. */\nexport const MCP_AUTH_CALLBACK_MESSAGE_TYPE = \"mcp_auth_callback\";\n\n/**\n * Payload shape posted by the OAuth callback page over `postMessage` /\n * `BroadcastChannel`. `state` and `serverUrlHash` are used to scope a result\n * to the flow / server that initiated it; both are optional for backward\n * compatibility with callback pages built against older versions.\n */\nexport interface McpAuthCallbackMessage {\n type?: string;\n success?: boolean;\n error?: string;\n /** OAuth `state` parameter of the originating authorization request. */\n state?: string;\n /** Hash of the server URL the flow authenticated against. */\n serverUrlHash?: string;\n}\n\n/** Terminal outcome of an opener-owned popup flow. */\ntype AuthPopupResult =\n | { kind: \"success\" }\n | { kind: \"error\"; error: string }\n | { kind: \"cancelled\" }\n | { kind: \"timeout\" };\n\ninterface RunAuthPopupOptions {\n /**\n * The popup window handle returned by `window.open`. May be `null` when the\n * popup was blocked or opened out-of-band (e.g. a manual fallback link); the\n * runner then relies on the message / storage / timeout signals only.\n */\n popup: globalThis.Window | null;\n /** OAuth `state` parameter for this flow. Used to ignore unrelated results. */\n state: string | null;\n /** localStorage key under which the flow's tokens are persisted on success. */\n tokensKey: string;\n /** Overall flow timeout. Default 5 minutes. */\n timeoutMs?: number;\n /** Interval for the `popup.closed` poll. Default 1s (matches auth0-spa-js). */\n closePollMs?: number;\n /**\n * How long to keep waiting for a result after the popup reports closed\n * without tokens, before settling `cancelled`. COOP browsing-context-group\n * swaps (popup navigating cross-origin) make `popup.closed` report `true`\n * while the real window is still open mid-flow, so a closed signal is only\n * a soft hint — message/storage listeners stay alive during this grace\n * window and can still settle `success`. Default 20s.\n */\n closeGraceMs?: number;\n /**\n * Origin to accept `postMessage` results from. Defaults to the current\n * window origin. BroadcastChannel results are same-origin by definition.\n */\n expectedOrigin?: string;\n}\n\nfunction hasStoredTokens(tokensKey: string): boolean {\n try {\n return (\n typeof localStorage !== \"undefined\" && !!localStorage.getItem(tokensKey)\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Run an opener-owned OAuth popup flow and resolve once it reaches a terminal\n * outcome. Never rejects — all failure modes map to an {@link AuthPopupResult}.\n */\nexport function runAuthPopup({\n popup,\n state,\n tokensKey,\n timeoutMs = 5 * 60_000,\n closePollMs = 1000,\n closeGraceMs = 20_000,\n expectedOrigin = typeof window !== \"undefined\" ? window.location.origin : \"\",\n}: RunAuthPopupOptions): Promise<AuthPopupResult> {\n return new Promise<AuthPopupResult>((resolve) => {\n let settled = false;\n let closeTimer: ReturnType<typeof setInterval> | null = null;\n let timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n let graceTimer: ReturnType<typeof setTimeout> | null = null;\n let broadcastChannel: BroadcastChannel | null = null;\n\n const cleanup = () => {\n if (closeTimer) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n if (timeoutTimer) {\n clearTimeout(timeoutTimer);\n timeoutTimer = null;\n }\n if (graceTimer) {\n clearTimeout(graceTimer);\n graceTimer = null;\n }\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"message\", messageHandler);\n window.removeEventListener(\"storage\", storageHandler);\n }\n if (broadcastChannel) {\n try {\n broadcastChannel.removeEventListener(\"message\", broadcastHandler);\n broadcastChannel.close();\n } catch {\n /* ignore */\n }\n broadcastChannel = null;\n }\n };\n\n const settle = (result: AuthPopupResult) => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(result);\n };\n\n // Shared handler for postMessage + BroadcastChannel result payloads.\n const handlePayload = (payload: McpAuthCallbackMessage | undefined) => {\n if (!payload || payload.type !== MCP_AUTH_CALLBACK_MESSAGE_TYPE) return;\n // State-keyed: ignore results from a different concurrent flow. Payloads\n // without a `state` (older callback pages) are accepted for back-compat.\n if (payload.state && state && payload.state !== state) return;\n if (payload.success) {\n settle({ kind: \"success\" });\n } else {\n settle({\n kind: \"error\",\n error: payload.error ?? \"Authentication failed in callback.\",\n });\n }\n };\n\n const messageHandler = (event: globalThis.MessageEvent) => {\n if (expectedOrigin && event.origin !== expectedOrigin) return;\n handlePayload(event.data as McpAuthCallbackMessage | undefined);\n };\n\n const broadcastHandler = (event: globalThis.MessageEvent) => {\n handlePayload(event.data as McpAuthCallbackMessage | undefined);\n };\n\n const storageHandler = (event: globalThis.StorageEvent) => {\n if (event.key !== tokensKey) return;\n // A non-null new value means the popup just persisted fresh tokens.\n if (event.newValue) settle({ kind: \"success\" });\n };\n\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"message\", messageHandler);\n window.addEventListener(\"storage\", storageHandler);\n }\n\n if (typeof BroadcastChannel !== \"undefined\") {\n try {\n broadcastChannel = new BroadcastChannel(MCP_AUTH_BROADCAST_CHANNEL);\n broadcastChannel.addEventListener(\"message\", broadcastHandler);\n } catch {\n broadcastChannel = null;\n }\n }\n\n // Poll for popup closure. The user may close it without completing, or it\n // may complete and close before its result message is delivered.\n if (popup) {\n closeTimer = setInterval(() => {\n if (settled) return;\n let closed = false;\n try {\n closed = popup.closed;\n } catch {\n // Cross-origin access to `.closed` can throw under some engines;\n // treat as not-closed and keep waiting for other signals.\n closed = false;\n }\n if (!closed) return;\n if (closeTimer) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n if (hasStoredTokens(tokensKey)) {\n settle({ kind: \"success\" });\n return;\n }\n // Soft-close grace window: `popup.closed` is unreliable under COOP —\n // a cross-origin navigation swaps the browsing context group and the\n // original WindowProxy reports closed while the real window is still\n // open mid-consent (observed in the field: closed at ~3s, tokens\n // landing ~7s later). Keep the message/storage listeners alive and\n // only settle `cancelled` if nothing arrives within the grace window.\n graceTimer = setTimeout(() => {\n settle(\n hasStoredTokens(tokensKey)\n ? { kind: \"success\" }\n : { kind: \"cancelled\" }\n );\n }, closeGraceMs);\n }, closePollMs);\n }\n\n timeoutTimer = setTimeout(() => {\n settle(\n hasStoredTokens(tokensKey) ? { kind: \"success\" } : { kind: \"timeout\" }\n );\n }, timeoutMs);\n });\n}\n","import {\n Client,\n discoverOAuthProtectedResourceMetadata,\n SdkError,\n SdkHttpError,\n StreamableHTTPClientTransport,\n UnauthorizedError,\n type ClientOptions,\n type OAuthClientProvider,\n type VersionNegotiationMode,\n} from \"@modelcontextprotocol/client\";\nimport { completeOAuthFlow, isOAuthInteractionRequired } from \"../auth/flow.js\";\nimport type { MCPAuthorizationInfo } from \"../core/session.js\";\nimport { DialectJsonSchemaValidator } from \"../utils/json-schema-validator.js\";\nimport { logger } from \"../utils/logging.js\";\nimport type { ConnectorInitOptions } from \"./base.js\";\nimport { BaseConnector } from \"./base.js\";\n\nconst MIXED_AUTH_DISCOVERY_TIMEOUT_MS = 2_000;\n\n/**\n * Detect a 401 anywhere in an error / cause chain. Under\n * `versionNegotiation: \"auto\"` a connect-time 401 can surface wrapped as\n * `SdkError(EraNegotiationFailed)` with the `UnauthorizedError` at\n * `error.data.cause` (rather than a bare `SdkHttpError`), so we walk the chain.\n */\nfunction detectUnauthorized(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n if (err instanceof UnauthorizedError) return true;\n if (err instanceof SdkHttpError && err.status === 401) return true;\n if (err instanceof Error) {\n if (err.cause) {\n if (detectUnauthorized(err.cause, depth + 1)) return true;\n }\n const data = err instanceof SdkError ? (err.data as any) : undefined;\n if (data?.cause && detectUnauthorized(data.cause, depth + 1)) return true;\n }\n return false;\n}\n\n/** Client identity advertised to an MCP server during connection setup. */\nexport type ClientInfo = {\n /** Stable programmatic client name. */\n name: string;\n /** Optional human-readable client title. */\n title?: string;\n /** Client version string. */\n version: string;\n /** Human-readable client description. */\n description?: string;\n /** Icons representing the client. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Public website describing the client. */\n websiteUrl?: string;\n};\n\n/** HTTP-specific connector options. */\ninterface HttpConnectorOptions extends ConnectorInitOptions {\n /** Bearer token added to the `Authorization` header. */\n authToken?: string;\n /** Fetch implementation used by transport requests. */\n fetch?: typeof fetch;\n /** Additional transport request headers. */\n headers?: Record<string, string>;\n /** Connection timeout in milliseconds. Defaults to `10000`. */\n timeout?: number;\n /** Client identity advertised to the server. */\n clientInfo?: ClientInfo;\n /**\n * Protocol version negotiation mode passed to the SDK `Client`.\n * - `\"auto\"` (mcp-use HTTP default): probe with `server/discover`, falling\n * back to the 2025 handshake against legacy servers.\n * - `\"legacy\"`: classic 2025 `initialize` handshake, no probe. This matches\n * the official SDK's default when used directly.\n * - In auto mode, the probe performs OAuth discovery on auth-required\n * servers and can fail on servers whose\n * authorization-server issuer differs from the server URL (RFC 8414 §3.3),\n * which would otherwise mask the normal 401 → auth flow.\n * - `{ pin: \"2026-07-28\" }`: modern era only, no fallback.\n */\n protocolNegotiation?: VersionNegotiationMode;\n /** Gateway endpoint through which MCP transport requests are routed. */\n gatewayUrl?: string;\n /** Server identifier forwarded to the gateway for observability. */\n serverId?: string;\n /** Retry settings for streamable HTTP reconnection. */\n reconnectionOptions?: {\n /** Maximum delay between reconnection attempts in milliseconds. */\n maxReconnectionDelay?: number;\n /** Delay before the first reconnection attempt in milliseconds. */\n initialReconnectionDelay?: number;\n /** Multiplier applied after each failed attempt. */\n reconnectionDelayGrowFactor?: number;\n /** Maximum number of reconnection attempts. */\n maxRetries?: number;\n };\n /** Detect RFC 9728 metadata after anonymous connection. Defaults to true. */\n detectMixedAuth?: boolean;\n}\n\ntype StreamableHttpFailure = {\n fallbackReason: string;\n is401Error: boolean;\n httpStatusCode?: number;\n};\n\nfunction isOAuthClientProvider(\n provider: ConnectorInitOptions[\"authProvider\"]\n): provider is OAuthClientProvider {\n return Boolean(\n provider &&\n \"redirectToAuthorization\" in provider &&\n typeof provider.redirectToAuthorization === \"function\" &&\n \"tokens\" in provider &&\n typeof provider.tokens === \"function\"\n );\n}\n\nfunction createMcpProxyFetch(\n logicalServerUrl: string,\n proxyUrl: string,\n baseFetch: typeof fetch,\n serverId?: string\n): typeof fetch {\n const logical = new URL(logicalServerUrl);\n const proxy = proxyUrl.replace(/\\/$/, \"\");\n\n return async (input, init) => {\n const request = new Request(input, init);\n const requestUrl = new URL(request.url);\n const isMcpTransportRequest =\n requestUrl.origin === logical.origin &&\n requestUrl.pathname === logical.pathname;\n\n // OAuth discovery/token requests deliberately keep their own URLs so a\n // separately injected OAuth BFF fetch can handle them.\n if (!isMcpTransportRequest) {\n return baseFetch(request);\n }\n\n const headers = new Headers(request.headers);\n headers.set(\"X-Target-URL\", request.url);\n if (serverId) headers.set(\"X-Server-Id\", serverId);\n\n const body =\n request.method === \"GET\" || request.method === \"HEAD\"\n ? undefined\n : await request.clone().arrayBuffer();\n\n return baseFetch(\n new Request(proxy, {\n method: request.method,\n headers,\n body,\n signal: request.signal,\n redirect: \"manual\",\n })\n );\n };\n}\n\nfunction createDeadlineFetch(\n baseFetch: typeof fetch,\n deadlineSignal: AbortSignal\n): typeof fetch {\n return async (input, init) => {\n const requestSignal = init?.signal;\n if (!requestSignal) {\n return baseFetch(input, { ...init, signal: deadlineSignal });\n }\n\n const controller = new AbortController();\n const abortFromRequest = () => controller.abort(requestSignal.reason);\n const abortFromDeadline = () => controller.abort(deadlineSignal.reason);\n\n if (requestSignal.aborted) abortFromRequest();\n else\n requestSignal.addEventListener(\"abort\", abortFromRequest, { once: true });\n\n if (deadlineSignal.aborted) abortFromDeadline();\n else\n deadlineSignal.addEventListener(\"abort\", abortFromDeadline, {\n once: true,\n });\n\n try {\n return await baseFetch(input, { ...init, signal: controller.signal });\n } finally {\n requestSignal.removeEventListener(\"abort\", abortFromRequest);\n deadlineSignal.removeEventListener(\"abort\", abortFromDeadline);\n }\n };\n}\n\n/**\n * Connects to an MCP server using streamable HTTP.\n *\n * The connector negotiates modern and legacy protocol eras by default and can\n * route transport requests through an HTTP gateway.\n */\nexport class HttpConnector extends BaseConnector {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly timeout: number;\n private readonly customFetch?: typeof fetch;\n private readonly clientInfo: ClientInfo;\n private readonly protocolNegotiation: VersionNegotiationMode;\n private readonly gatewayUrl?: string;\n private readonly serverId?: string;\n private readonly reconnectionOptions?: HttpConnectorOptions[\"reconnectionOptions\"];\n private readonly detectMixedAuth: boolean;\n private transportType: \"streamable-http\" | null = null;\n private streamableTransport: StreamableHTTPClientTransport | null = null;\n private hadAccessTokenAtConnect = false;\n private pendingOAuthCompletion: Promise<void> | null = null;\n private authorizationDiscovery: Promise<\n MCPAuthorizationInfo | undefined\n > | null = null;\n\n /**\n * Creates an HTTP connector.\n *\n * @param baseUrl - MCP endpoint URL.\n * @param opts - Authentication, transport, SDK, and reconnection options.\n */\n constructor(baseUrl: string, opts: HttpConnectorOptions = {}) {\n super(opts);\n\n const originalUrl = baseUrl.replace(/\\/$/, \"\");\n this.baseUrl = originalUrl;\n this.headers = { ...(opts.headers ?? {}) };\n this.gatewayUrl = opts.gatewayUrl;\n this.serverId = opts.serverId;\n\n // Add auth token if provided\n if (opts.authToken) {\n this.headers.Authorization = `Bearer ${opts.authToken}`;\n }\n\n this.timeout = opts.timeout ?? 10000; // Default 10 seconds\n const baseFetch = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.customFetch = this.gatewayUrl\n ? createMcpProxyFetch(\n originalUrl,\n this.gatewayUrl,\n baseFetch,\n this.serverId\n )\n : opts.fetch;\n this.clientInfo = opts.clientInfo ?? {\n name: \"http-connector\",\n version: \"1.0.0\",\n };\n // Negotiate the most capable protocol available. The SDK safely falls back\n // to the 2025 sessionful era for v1 servers while using v2's sessionless\n // server/discover flow when it is available.\n this.protocolNegotiation = opts.protocolNegotiation ?? \"auto\";\n this.reconnectionOptions = opts.reconnectionOptions;\n this.detectMixedAuth = opts.detectMixedAuth ?? true;\n }\n\n private get oauthProvider(): OAuthClientProvider | undefined {\n return isOAuthClientProvider(this.opts.authProvider)\n ? this.opts.authProvider\n : undefined;\n }\n\n private async completeInteractiveAuthorization(): Promise<void> {\n const provider = this.oauthProvider;\n if (!provider) {\n throw new Error(\"No OAuth client provider is configured\");\n }\n if (!this.pendingOAuthCompletion) {\n this.pendingOAuthCompletion = completeOAuthFlow(provider, this.baseUrl, {\n fetchFn: this.customFetch,\n finishAuthorization: async (code, iss) => {\n const transport = this.streamableTransport;\n if (!transport) {\n throw new Error(\"OAuth transport is no longer connected\");\n }\n await transport.finishAuth(code, iss);\n },\n })\n .then(() => {\n this.authorizationCache = {\n ...(this.authorizationCache ?? { mode: \"mixed\" }),\n authenticated: true,\n };\n })\n .finally(() => {\n this.pendingOAuthCompletion = null;\n });\n }\n await this.pendingOAuthCompletion;\n }\n\n protected override async executeRequest<T>(\n operation: () => Promise<T>\n ): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n const provider = this.oauthProvider as\n | (OAuthClientProvider & { preventAutoAuth?: boolean })\n | undefined;\n if (\n !provider ||\n provider.preventAutoAuth === true ||\n !isOAuthInteractionRequired(error)\n ) {\n throw error;\n }\n await this.completeInteractiveAuthorization();\n return operation();\n }\n }\n\n /** Authenticate an already-connected server without requiring a 401 first. */\n override async authenticate(): Promise<void> {\n if (!this.connected || !this.streamableTransport) {\n throw new Error(\"MCP client is not connected\");\n }\n await this.completeInteractiveAuthorization();\n }\n\n override async discoverAuthorization(): Promise<\n MCPAuthorizationInfo | undefined\n > {\n if (\n !this.detectMixedAuth ||\n !this.oauthProvider ||\n this.hadAccessTokenAtConnect\n ) {\n return this.authorizationCache;\n }\n\n if (this.authorizationDiscovery) return this.authorizationDiscovery;\n\n this.authorizationDiscovery = this.discoverMixedAuthorization().then(\n (authorization) => {\n // A missing or temporarily unavailable RFC 9728 endpoint must not be\n // cached for the lifetime of an otherwise healthy MCP connection.\n if (!authorization) this.authorizationDiscovery = null;\n return authorization;\n }\n );\n return this.authorizationDiscovery;\n }\n\n private async discoverMixedAuthorization(): Promise<\n MCPAuthorizationInfo | undefined\n > {\n const controller = new AbortController();\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const discoveryTimeout = new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n const error = new Error(\n `Mixed-auth metadata discovery timed out after ${MIXED_AUTH_DISCOVERY_TIMEOUT_MS}ms`\n );\n controller.abort(error);\n reject(error);\n }, MIXED_AUTH_DISCOVERY_TIMEOUT_MS);\n });\n const baseFetch = this.customFetch ?? globalThis.fetch.bind(globalThis);\n\n try {\n const metadata = await Promise.race([\n discoverOAuthProtectedResourceMetadata(\n this.baseUrl,\n { protocolVersion: this.negotiatedProtocolVersion },\n createDeadlineFetch(baseFetch, controller.signal)\n ),\n discoveryTimeout,\n ]);\n this.authorizationCache = {\n mode: \"mixed\",\n authenticated: false,\n ...(metadata.resource ? { resource: metadata.resource } : {}),\n ...(metadata.scopes_supported\n ? { scopesSupported: [...metadata.scopes_supported] }\n : {}),\n };\n logger.info(\n \"OAuth protected-resource metadata found after anonymous connection; server uses mixed auth\"\n );\n } catch (error) {\n // RFC 9728 metadata is optional for anonymous servers. Discovery is a\n // best-effort classification and must never turn a valid MCP connection\n // into a failure.\n logger.debug(\"Mixed-auth metadata was not discovered:\", error);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n return this.authorizationCache;\n }\n\n private buildClientOptions(): ClientOptions {\n return {\n ...(this.opts.clientOptions || {}),\n jsonSchemaValidator:\n this.opts.clientOptions?.jsonSchemaValidator ??\n new DialectJsonSchemaValidator(),\n versionNegotiation: {\n // Allow a caller-supplied versionNegotiation in clientOptions to win.\n mode: this.protocolNegotiation,\n ...(this.opts.clientOptions?.versionNegotiation ?? {}),\n },\n listChanged: {\n tools: {\n autoRefresh: true,\n onChanged: (error, tools) =>\n void this.handleListChanged(\n \"notifications/tools/list_changed\",\n error,\n tools\n ),\n },\n resources: {\n autoRefresh: false,\n onChanged: (error) =>\n void this.handleListChanged(\n \"notifications/resources/list_changed\",\n error\n ),\n },\n prompts: {\n autoRefresh: false,\n onChanged: (error) =>\n void this.handleListChanged(\n \"notifications/prompts/list_changed\",\n error\n ),\n },\n ...(this.opts.clientOptions?.listChanged ?? {}),\n },\n capabilities: {\n ...(this.opts.clientOptions?.capabilities || {}),\n roots: { listChanged: true },\n ...(this.opts.onSampling ? { sampling: {} } : {}),\n ...(this.opts.onElicitation\n ? { elicitation: { form: {}, url: {} } }\n : {}),\n },\n };\n }\n\n // In v2 HTTP transport errors are thrown as SdkHttpError (subclass of\n // SdkError) with a numeric `.status` accessor, replacing v1's\n // StreamableHTTPError (which carried the status on `.code`).\n private unwrapStreamableError(err: unknown): SdkHttpError | null {\n if (err instanceof SdkHttpError) {\n return err;\n }\n if (err instanceof Error && err.cause instanceof SdkHttpError) {\n return err.cause;\n }\n return null;\n }\n\n private classifyStreamableHttpFailure(err: unknown): StreamableHttpFailure {\n let fallbackReason = \"Unknown error\";\n let is401Error = false;\n let httpStatusCode: number | undefined;\n\n const streamableErr = this.unwrapStreamableError(err);\n if (streamableErr) {\n const status = streamableErr.status;\n is401Error = status === 401;\n httpStatusCode = status;\n\n if (\n status === 400 &&\n streamableErr.message.includes(\"Missing session ID\")\n ) {\n fallbackReason = \"Server requires session ID\";\n logger.warn(`⚠️ ${fallbackReason}`);\n } else if (status === 404 || status === 405) {\n fallbackReason = `Server returned ${status} - server likely doesn't support streamable HTTP`;\n logger.debug(fallbackReason);\n } else {\n fallbackReason = `Server returned ${status}: ${streamableErr.message}`;\n logger.debug(fallbackReason);\n }\n\n return { fallbackReason, is401Error, httpStatusCode };\n }\n\n if (err instanceof Error) {\n const errorStr = err.toString();\n const errorMsg = err.message || \"\";\n is401Error =\n detectUnauthorized(err) ||\n errorStr.includes(\"401\") ||\n errorMsg.includes(\"Unauthorized\");\n\n if (\n errorStr.includes(\"Missing session ID\") ||\n errorStr.includes(\"Bad Request: Missing session ID\") ||\n errorMsg.includes(\"FastMCP session ID error\")\n ) {\n fallbackReason = \"Server requires session ID\";\n logger.warn(`⚠️ ${fallbackReason}`);\n } else if (\n errorStr.includes(\"405 Method Not Allowed\") ||\n errorStr.includes(\"404 Not Found\")\n ) {\n fallbackReason = \"Server doesn't support streamable HTTP (405/404)\";\n logger.debug(fallbackReason);\n } else {\n fallbackReason = `Streamable HTTP failed: ${err.message}`;\n logger.debug(fallbackReason);\n }\n }\n\n return { fallbackReason, is401Error, httpStatusCode };\n }\n\n /**\n * Establishes a streamable HTTP connection to the MCP server.\n *\n * @returns A promise that resolves after protocol negotiation completes.\n * @throws An error with `code: 401` when authentication is required.\n */\n async connect(): Promise<void> {\n if (this.connected) {\n logger.debug(\"Already connected to MCP implementation\");\n return;\n }\n\n const baseUrl = this.baseUrl;\n logger.debug(`Connecting to MCP implementation via HTTP: ${baseUrl}`);\n\n const oauthProvider = this.oauthProvider;\n if (oauthProvider) {\n try {\n this.hadAccessTokenAtConnect = Boolean(\n (await oauthProvider.tokens())?.access_token\n );\n } catch {\n this.hadAccessTokenAtConnect = false;\n }\n }\n\n try {\n await this.connectWithStreamableHttp(baseUrl);\n logger.debug(\"✅ Successfully connected via streamable HTTP\");\n } catch (err: unknown) {\n logger.debug(\"Streamable HTTP connect failed\", err);\n const { fallbackReason, is401Error, httpStatusCode } =\n this.classifyStreamableHttpFailure(err);\n\n await this.cleanupResources();\n\n if (is401Error) {\n logger.info(\"Authentication required\");\n const authError = new Error(\"Authentication required\") as any;\n authError.code = 401;\n throw authError;\n }\n\n const finalError = new Error(\n `Could not connect via streamable HTTP: ${fallbackReason}`\n );\n if (httpStatusCode !== undefined) {\n Object.defineProperty(finalError, \"code\", {\n value: httpStatusCode,\n writable: false,\n enumerable: true,\n configurable: true,\n });\n }\n throw finalError;\n }\n }\n\n /**\n * Tee an SSE response so v2 MRTR progress can be correlated even when the\n * upstream SDK does not carry the original callback to retry request IDs.\n */\n private observeSseProgress(response: Response): Response {\n if (\n !response.body ||\n !response.headers.get(\"content-type\")?.includes(\"text/event-stream\")\n ) {\n return response;\n }\n const [body, observed] = response.body.tee();\n void (async () => {\n const reader = observed.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const events = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = events.pop() ?? \"\";\n for (const event of events) {\n for (const line of event.split(/\\r?\\n/)) {\n if (!line.startsWith(\"data:\")) continue;\n try {\n const message = JSON.parse(line.slice(5).trim()) as {\n method?: string;\n params?: unknown;\n };\n if (message.method === \"notifications/progress\") {\n this.forwardRoundProgress(message.params);\n }\n } catch {\n // Ignore malformed/non-JSON SSE data; the SDK remains authoritative.\n }\n }\n }\n }\n } catch (error) {\n if (!(error instanceof DOMException && error.name === \"AbortError\")) {\n logger.debug(\"Progress observer stream ended:\", error);\n }\n } finally {\n reader.releaseLock();\n }\n })();\n return new Response(body, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n\n private async connectWithStreamableHttp(baseUrl: string): Promise<void> {\n try {\n logger.debug(\"[HttpConnector] Connecting with Streamable HTTP\", {\n baseUrl,\n originalUrl: this.baseUrl,\n gatewayUrl: this.gatewayUrl || \"none\",\n authProviderUrl:\n this.opts.authProvider &&\n \"serverUrl\" in this.opts.authProvider &&\n typeof this.opts.authProvider.serverUrl === \"string\"\n ? this.opts.authProvider.serverUrl\n : \"none\",\n headers: this.headers,\n });\n\n const baseFetch = this.customFetch ?? globalThis.fetch.bind(globalThis);\n const observedFetch: typeof fetch = async (input, init) => {\n const response = await baseFetch(input, init);\n const requestHeaders = new Headers(\n input instanceof Request ? input.headers : undefined\n );\n new Headers(init?.headers).forEach((value, key) => {\n requestHeaders.set(key, value);\n });\n // subscriptions/listen owns its SSE reader and acknowledgement state.\n // Re-wrapping that response breaks the SDK's per-request stream hooks;\n // the progress observer is only for ordinary request/response calls.\n return requestHeaders.get(\"mcp-method\") === \"subscriptions/listen\"\n ? response\n : this.observeSseProgress(response);\n };\n\n // Create StreamableHTTPClientTransport directly\n // The official SDK's StreamableHTTPClientTransport automatically handles session IDs\n // when client.connect() is called - it sends initialize, gets session ID from response header,\n // and opens the SSE stream with that session ID\n const streamableTransport = new StreamableHTTPClientTransport(\n new URL(baseUrl),\n {\n authProvider: this.opts.authProvider, // ← Pass OAuth provider to SDK\n fetch: observedFetch,\n requestInit: {\n headers: this.headers,\n },\n reconnectionOptions: {\n maxReconnectionDelay: 30000,\n initialReconnectionDelay: 1000,\n reconnectionDelayGrowFactor: 1.5,\n maxRetries: 2,\n ...this.reconnectionOptions,\n },\n // Don't pass sessionId - let the SDK generate it automatically during connect()\n }\n );\n\n // Store transport for cleanup (we'll create ConnectionManager later if needed for reconnection)\n let transport: StreamableHTTPClientTransport = streamableTransport;\n\n // Wrap transport if wrapper is provided\n if (this.opts.wrapTransport) {\n const serverId = this.baseUrl; // Use URL as server ID for now\n transport = this.opts.wrapTransport(\n transport,\n serverId\n ) as StreamableHTTPClientTransport;\n }\n\n // Create and connect the client\n // This performs both initialize AND initialized notification\n // Always advertise roots capability - server may query roots/list even if client has no roots\n const clientOptions = this.buildClientOptions();\n logger.debug(\n `Creating Client with capabilities:`,\n JSON.stringify(clientOptions.capabilities, null, 2)\n );\n this.client = new Client(this.clientInfo, clientOptions);\n\n // Register inbound handlers BEFORE connect() so they are available for the\n // entire connection lifetime (including reverse RPC during/after initialize).\n this.setupRootsHandler();\n this.setupSamplingHandler();\n this.setupElicitationHandler();\n this.setupNotificationHandler();\n logger.debug(\n \"Roots/sampling/elicitation/notification handlers registered before connect\"\n );\n\n try {\n // The SDK's StreamableHTTPClientTransport should automatically:\n // 1. Send POST initialize request\n // 2. Extract mcp-session-id from response header\n // 3. Open GET SSE stream with that session ID in header\n //\n // Keep the connection timeout outside the SDK request options so it\n // cannot leak onto streams opened during connection setup.\n let connectTimeout: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n this.client.connect(transport),\n new Promise<never>((_, reject) => {\n connectTimeout = setTimeout(\n () =>\n reject(\n new Error(`MCP connection timed out after ${this.timeout}ms`)\n ),\n this.timeout\n );\n }),\n ]).finally(() => {\n if (connectTimeout !== undefined) clearTimeout(connectTimeout);\n });\n\n // The official SDK opens the optional v1 standalone GET stream in the\n // background after initialization. Do not gate ordinary request/response\n // readiness on that long-lived stream: proxies may buffer its headers,\n // while tools/list and other client operations are already usable.\n // Inbound request and notification handlers are registered above before\n // connect(), so the stream can attach later without racing handler setup.\n\n // Streamable HTTP servers may optionally assign a session ID.\n const sessionId = streamableTransport.sessionId;\n if (sessionId) {\n logger.debug(`Session ID obtained: ${sessionId}`);\n }\n } catch (connectErr) {\n // Check if the error is due to missing session ID during connection handshake\n if (connectErr instanceof Error) {\n const errMsg = connectErr.message || connectErr.toString();\n if (\n errMsg.includes(\"Missing session ID\") ||\n errMsg.includes(\"Bad Request: Missing session ID\") ||\n errMsg.includes(\"Mcp-Session-Id header is required\")\n ) {\n // Wrap it in a more specific error so the outer catch can detect it\n const wrappedError = new Error(\n `Session ID error: ${errMsg}. The SDK should automatically extract session ID from initialize response.`\n );\n wrappedError.cause = connectErr;\n throw wrappedError;\n }\n }\n throw connectErr;\n }\n\n // Store the transport for later cleanup\n this.streamableTransport = streamableTransport;\n // Create a minimal connection manager wrapper for cleanup purposes.\n // Note: terminateSession() is invoked from cleanupResources() *before*\n // the SDK's client.close() aborts the transport's abort controller.\n // Calling terminateSession() here would race the abort and surface a\n // spurious AbortError on every clean shutdown.\n this.connectionManager = {\n stop: async () => {\n if (this.streamableTransport) {\n try {\n await this.streamableTransport.close();\n } catch (e) {\n logger.warn(`Error closing Streamable HTTP transport: ${e}`);\n } finally {\n this.streamableTransport = null;\n }\n }\n },\n } as any;\n\n this.connected = true;\n this.transportType = \"streamable-http\";\n // Inbound request handlers (roots/sampling/elicitation) were registered before connect()\n logger.debug(\n `Successfully connected to MCP implementation via streamable HTTP: ${baseUrl}`\n );\n\n // Track connector initialization\n this.trackConnectorInit({\n serverUrl: this.baseUrl,\n publicIdentifier: `${this.baseUrl} (streamable-http)`,\n });\n } catch (err) {\n // Clean up partial resources before throwing\n await this.cleanupResources();\n throw err;\n }\n }\n\n /**\n * Returns fields that identify the endpoint and negotiated transport.\n *\n * @returns HTTP connector identity metadata.\n */\n get publicIdentifier(): Record<string, string> {\n return {\n type: \"http\",\n url: this.baseUrl,\n transport: this.transportType || \"unknown\",\n protocolEra: this.protocolEra ?? \"unknown\",\n };\n }\n\n /**\n * Returns the active transport type.\n *\n * @returns `\"streamable-http\"` after connection, otherwise `null`.\n */\n getTransportType(): \"streamable-http\" | null {\n return this.transportType;\n }\n\n // Send the streamable-HTTP DELETE *before* super.cleanupResources() invokes\n // client.close(). The SDK's transport.close() aborts the shared abort\n // controller, and terminateSession()'s DELETE fetch reuses that signal —\n // running it after close() rejects immediately with AbortError.\n protected async cleanupResources(): Promise<void> {\n // Only legacy (2025-era) connections carry an Mcp-Session-Id worth\n // terminating. Modern (2026-07-28) connections are stateless per-request,\n // so there is no session DELETE to issue.\n if (this.streamableTransport && this.protocolEra !== \"modern\") {\n let terminationTimeout: ReturnType<typeof setTimeout> | undefined;\n try {\n const terminated = await Promise.race([\n this.streamableTransport.terminateSession().then(() => true),\n new Promise<false>(\n (resolve) =>\n (terminationTimeout = setTimeout(\n () => resolve(false),\n Math.min(this.timeout, 5000)\n ))\n ),\n ]);\n if (!terminated) {\n logger.debug(\n \"Timed out terminating legacy HTTP session; closing transport\"\n );\n }\n } catch (e) {\n logger.debug(`Error terminating Streamable HTTP session: ${e}`);\n } finally {\n if (terminationTimeout) clearTimeout(terminationTimeout);\n }\n }\n await super.cleanupResources();\n this.authorizationDiscovery = null;\n }\n}\n","import {\n auth,\n InsufficientScopeError,\n UnauthorizedError,\n type OAuthClientProvider,\n} from \"@modelcontextprotocol/client\";\nimport type { NodeOAuthAuthorizationResponse } from \"./node.js\";\nimport { runAuthPopup } from \"./popup.js\";\n\nconst DEFAULT_AUTH_TIMEOUT_MS = 5 * 60_000;\n\n/** Provider extras used by the Node loopback and browser popup flows. */\ntype FlowProvider = OAuthClientProvider & {\n serverUrlHash?: string;\n hasPendingFlow?: boolean;\n getAuthorizationResponse?: () => Promise<NodeOAuthAuthorizationResponse>;\n getAuthorizationCode?: () => Promise<string>;\n getProxyFetch?: (baseFetch?: typeof fetch) => typeof fetch | undefined;\n getKey?: (keySuffix: string) => string;\n getLastAttemptedAuthUrl?: () => string | null;\n markFlowComplete?: () => void;\n preventAutoAuth?: boolean;\n startAuthorization?: () => void;\n useRedirectFlow?: boolean;\n};\n\n/** Host callback used to complete the official transport's pending OAuth flow. */\ntype FinishOAuthAuthorization = (code: string, iss?: string) => Promise<void>;\n\n/**\n * True if the error (or a wrapped cause) is an HTTP 401 / UnauthorizedError\n * that should trigger the OAuth completion dance.\n */\nexport function isUnauthorized(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n if (err instanceof UnauthorizedError) return true;\n if (err instanceof Error) {\n const code = (err as { code?: unknown }).code;\n if (code === 401) return true;\n if (err.name === \"UnauthorizedError\") return true;\n const message = err.message ?? \"\";\n if (message.includes(\"401\") || message.includes(\"Unauthorized\")) {\n return true;\n }\n if (err.cause && isUnauthorized(err.cause, depth + 1)) return true;\n const data = (err as { data?: { cause?: unknown } }).data;\n if (data?.cause && isUnauthorized(data.cause, depth + 1)) return true;\n }\n return false;\n}\n\n/**\n * True when the official SDK has started an interactive OAuth flow that the\n * host must finish before retrying the logical MCP operation.\n */\nexport function isOAuthInteractionRequired(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n if (\n err instanceof InsufficientScopeError ||\n err instanceof UnauthorizedError\n ) {\n return true;\n }\n if (err instanceof Error) {\n if (\n err.name === \"InsufficientScopeError\" ||\n err.name === \"UnauthorizedError\"\n ) {\n return true;\n }\n if (err.cause && isOAuthInteractionRequired(err.cause, depth + 1)) {\n return true;\n }\n const data = (err as { data?: { cause?: unknown } }).data;\n if (data?.cause && isOAuthInteractionRequired(data.cause, depth + 1)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Complete an in-progress or required OAuth authorization for `provider`.\n *\n * - Node loopback providers expose `getAuthorizationCode()`; we await the\n * code and finish the token exchange.\n * - Browser providers open a popup/redirect; we wait for the callback page\n * (`onMcpAuthorization`) to exchange the code and signal success over\n * `BroadcastChannel` / `postMessage`.\n *\n * Safe to call when the SDK transport already invoked `auth()` on a 401\n * (Node: `hasPendingFlow`; we skip a duplicate `auth()` in that case).\n */\nexport async function completeOAuthFlow(\n provider: OAuthClientProvider,\n serverUrl: string,\n options: {\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n finishAuthorization?: FinishOAuthAuthorization;\n } = {}\n): Promise<void> {\n const flowProvider = provider as FlowProvider;\n const timeoutMs = options.timeoutMs ?? DEFAULT_AUTH_TIMEOUT_MS;\n const fetchFn =\n options.fetchFn ?? flowProvider.getProxyFetch?.() ?? undefined;\n\n if (!flowProvider.hasPendingFlow) {\n const result = await auth(provider, { serverUrl, fetchFn });\n if (result === \"AUTHORIZED\") return;\n if (result !== \"REDIRECT\") {\n throw new Error(`Unexpected OAuth auth() result: ${result}`);\n }\n }\n\n // With preventAutoAuth, redirectToAuthorization() deliberately only stores\n // the SDK-prepared URL. An explicit authenticate() call is the user gesture\n // that should launch that already-prepared request.\n if (\n flowProvider.preventAutoAuth === true &&\n typeof flowProvider.startAuthorization === \"function\"\n ) {\n flowProvider.startAuthorization();\n }\n\n if (\n typeof flowProvider.getAuthorizationResponse === \"function\" ||\n typeof flowProvider.getAuthorizationCode === \"function\"\n ) {\n const response =\n typeof flowProvider.getAuthorizationResponse === \"function\"\n ? await flowProvider.getAuthorizationResponse()\n : { code: await flowProvider.getAuthorizationCode!() };\n if (options.finishAuthorization) {\n await options.finishAuthorization(response.code, response.iss);\n } else {\n // Connect-time authorization may no longer have its failed transport.\n // Keep the official top-level helper as the fallback for that case.\n await auth(provider, {\n serverUrl,\n authorizationCode: response.code,\n ...(response.iss !== undefined ? { iss: response.iss } : {}),\n fetchFn,\n });\n }\n return;\n }\n\n await waitForBrowserAuthComplete(flowProvider, timeoutMs);\n}\n\nasync function waitForBrowserAuthComplete(\n provider: FlowProvider,\n timeoutMs: number\n): Promise<void> {\n if (typeof window === \"undefined\") {\n throw new Error(\n \"OAuth redirect requires a browser environment or a provider with getAuthorizationCode()\"\n );\n }\n\n if (provider.useRedirectFlow) {\n // Do not return to the caller and retry the MCP connection before the\n // full-page navigation replaces this JavaScript context.\n await new Promise<void>(() => {});\n return;\n }\n\n const tokensKey = provider.getKey?.(\"tokens\");\n if (!tokensKey) {\n throw new Error(\n \"Browser OAuth provider must expose getKey() for token storage\"\n );\n }\n\n let state: string | null = null;\n const authUrl = provider.getLastAttemptedAuthUrl?.();\n if (authUrl) {\n try {\n state = new URL(authUrl).searchParams.get(\"state\");\n } catch {\n // state-less fallback is supported by runAuthPopup\n }\n }\n\n try {\n const result = await runAuthPopup({\n popup: null,\n state,\n tokensKey,\n timeoutMs,\n });\n\n switch (result.kind) {\n case \"success\":\n return;\n case \"cancelled\":\n throw new Error(\"OAuth authentication was cancelled.\");\n case \"timeout\":\n throw new Error(\n `OAuth callback not received within ${timeoutMs}ms. Ensure /oauth/callback calls onMcpAuthorization().`\n );\n case \"error\":\n throw new Error(result.error);\n default:\n throw new Error(\"Unexpected OAuth popup result\");\n }\n } finally {\n provider.markFlowComplete?.();\n }\n}\n","import type {\n JsonSchemaType,\n jsonSchemaValidator,\n} from \"@modelcontextprotocol/client\";\nimport {\n CfWorkerJsonSchemaValidator,\n type CfWorkerSchemaDraft,\n} from \"@modelcontextprotocol/client/validators/cf-worker\";\n\nconst DRAFT_04_URI = \"http://json-schema.org/draft-04/schema\";\nconst DRAFT_07_URIS = new Set([\n \"http://json-schema.org/draft-07/schema\",\n \"https://json-schema.org/draft-07/schema\",\n]);\nconst DRAFT_2019_09_URIS = new Set([\n \"https://json-schema.org/draft/2019-09/schema\",\n \"http://json-schema.org/draft/2019-09/schema\",\n]);\nconst DRAFT_2020_12_URIS = new Set([\n \"https://json-schema.org/draft/2020-12/schema\",\n \"http://json-schema.org/draft/2020-12/schema\",\n]);\n\nfunction resolveDraft(schema: JsonSchemaType): CfWorkerSchemaDraft | undefined {\n if (!(\"$schema\" in schema) || typeof schema.$schema !== \"string\") {\n return \"2020-12\";\n }\n\n const normalized = schema.$schema.replace(/#$/, \"\");\n\n if (normalized === DRAFT_04_URI) return \"4\";\n if (DRAFT_07_URIS.has(normalized)) return \"7\";\n if (DRAFT_2019_09_URIS.has(normalized)) return \"2019-09\";\n if (DRAFT_2020_12_URIS.has(normalized)) return \"2020-12\";\n\n return undefined;\n}\n\n/**\n * JSON Schema validator that maps common `$schema` dialect URIs to the\n * matching `@cfworker/json-schema` draft. The v2 SDK default rejects any\n * schema not declaring JSON Schema 2020-12 as an \"unsupported dialect\", which\n * breaks `tools/call` against v1-era servers that emit draft-04/-07/2019-09\n * `$schema` on tool `outputSchema` (mcp-use#1839). Unknown `$schema` URIs\n * still fail fast via the SDK's strict default validator.\n */\nexport class DialectJsonSchemaValidator implements jsonSchemaValidator {\n getValidator<T>(schema: JsonSchemaType) {\n const draft = resolveDraft(schema);\n const delegate =\n draft !== undefined\n ? new CfWorkerJsonSchemaValidator({ draft })\n : new CfWorkerJsonSchemaValidator();\n return delegate.getValidator<T>(schema);\n }\n}\n","import type {\n CallToolResult,\n Client,\n ClientOptions,\n CompleteRequestParams,\n CompleteResult,\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n AuthProvider,\n JSONRPCMessage,\n Notification,\n OAuthClientProvider,\n ProtocolEra,\n RequestOptions,\n Root,\n Tool,\n} from \"@modelcontextprotocol/client\";\nimport { logger } from \"../utils/logging.js\";\nimport { isOAuthInteractionRequired } from \"../auth/flow.js\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\n\n/**\n * Accept-anything Standard Schema used for raw passthrough requests whose\n * method string is arbitrary (possibly non-spec). v2's `Protocol.request()`\n * requires a result schema for non-spec methods; this preserves the v1\n * \"return whatever the server sent\" behavior without importing Zod here.\n */\nconst passthroughResultSchema = {\n \"~standard\": {\n version: 1 as const,\n vendor: \"mcp-use\",\n validate: (value: unknown) => ({ value }),\n },\n};\n\nimport type { ConnectionManager } from \"./connection-manager.js\";\nimport type { ConnectorInitEventData } from \"../telemetry/events.js\";\nimport { trackConnectorTelemetry } from \"../telemetry/connector-telemetry.js\";\nimport type { MCPAuthorizationInfo, MCPServerInfo } from \"../core/session.js\";\n\n/**\n * Handles a notification received from an MCP server.\n *\n * @param notification - Notification envelope supplied by the server.\n */\nexport type NotificationHandler = (\n notification: Notification\n) => void | Promise<void>;\n\n/** Shared initialization options for all connector transports. */\nexport interface ConnectorInitOptions {\n /**\n * Options forwarded to the underlying MCP `Client` instance.\n *\n * By default, all connectors (HTTP and stdio) use `DialectJsonSchemaValidator`\n * to support common `$schema` dialects (draft-04, draft-07, 2019-09, 2020-12)\n * for cross-version compatibility with v1-era servers. Override with\n * `clientOptions.jsonSchemaValidator` if stricter validation is needed.\n */\n clientOptions?: ClientOptions;\n /**\n * Arbitrary request options (timeouts, cancellation, etc.) used by helper\n * methods when they issue SDK requests. Can be overridden per‑call.\n */\n defaultRequestOptions?: RequestOptions;\n /**\n * OAuth client provider for automatic authentication\n */\n authProvider?: AuthProvider | OAuthClientProvider;\n /**\n * Optional callback to wrap the transport before passing it to the Client.\n * Useful for logging, monitoring, or other transport-level interceptors.\n */\n wrapTransport?: (transport: any, serverId: string) => any;\n /**\n * Initial roots to provide to the server.\n * Roots allow the server to know which directories/files the client has access to.\n */\n roots?: Root[];\n /**\n * Optional callback function to handle sampling requests from servers.\n * When provided, the client will declare sampling capability and handle\n * `sampling/createMessage` requests by calling this callback.\n *\n * @deprecated Sampling is deprecated by the 2026 protocol. Retained for v1\n * push requests and v2 multi-round-trip compatibility.\n */\n onSampling?: (\n params: SamplingCreateMessageParams\n ) => Promise<SamplingCreateMessageResult>;\n /**\n * Optional callback function to handle elicitation requests from servers.\n * When provided, the client will declare elicitation capability and handle\n * `elicitation/create` requests by calling this callback.\n *\n * Elicitation allows servers to request additional information from users:\n * - Form mode: Collect structured data with JSON schema validation\n * - URL mode: Direct users to external URLs for sensitive interactions\n */\n onElicitation?: (\n params: ElicitRequestFormParams | ElicitRequestURLParams\n ) => Promise<ElicitResult>;\n /**\n * Optional callback for server notifications.\n * When provided, registered as initial notification handler.\n */\n onNotification?: NotificationHandler;\n /**\n * Reconnection options for streamable HTTP transport.\n * Controls retry behavior of the underlying `StreamableHTTPClientTransport`.\n */\n reconnectionOptions?: {\n /** Maximum delay between reconnection attempts in milliseconds. */\n maxReconnectionDelay?: number;\n /** Delay before the first reconnection attempt in milliseconds. */\n initialReconnectionDelay?: number;\n /** Multiplier applied to the delay after each failed attempt. */\n reconnectionDelayGrowFactor?: number;\n /** Maximum number of reconnection attempts. */\n maxRetries?: number;\n };\n}\n\n/**\n * Implements protocol operations shared by MCP transport connectors.\n *\n * Subclasses provide transport-specific connection setup and a public\n * identifier. Call {@link BaseConnector.connect}, then\n * {@link BaseConnector.initialize}, before invoking protocol operations.\n */\nexport abstract class BaseConnector {\n protected client: Client | null = null;\n protected connectionManager: ConnectionManager<any> | null = null;\n protected toolsCache: Tool[] | null = null;\n protected capabilitiesCache: Record<string, unknown> | null = null;\n protected serverInfoCache: MCPServerInfo | null = null;\n protected authorizationCache: MCPAuthorizationInfo | undefined;\n protected connected = false;\n protected readonly opts: ConnectorInitOptions;\n protected notificationHandlers: NotificationHandler[] = [];\n protected rootsCache: Root[] = [];\n private activeProgressHandlers = new Set<\n NonNullable<RequestOptions[\"onprogress\"]>\n >();\n\n /**\n * Creates a connector with shared SDK and callback options.\n *\n * @param opts - Connector initialization options.\n */\n constructor(opts: ConnectorInitOptions = {}) {\n this.opts = opts;\n // Initialize roots from options\n if (opts.roots) {\n this.rootsCache = [...opts.roots];\n }\n // Register initial notification handler if provided\n if (opts.onNotification) {\n this.notificationHandlers.push(opts.onNotification);\n }\n }\n\n /**\n * Track connector initialization event\n * Should be called by subclasses after successful connection\n */\n protected trackConnectorInit(\n data: Omit<ConnectorInitEventData, \"connectorType\">\n ): void {\n const connectorType = this.constructor.name;\n trackConnectorTelemetry({ connectorType, ...data });\n }\n\n /**\n * Register a handler for server notifications\n *\n * @param handler - Function to call when a notification is received\n *\n * @example\n * ```typescript\n * connector.onNotification((notification) => {\n * console.log(`Received: ${notification.method}`, notification.params);\n * });\n * ```\n */\n onNotification(handler: NotificationHandler): void {\n this.notificationHandlers.push(handler);\n // Wire up to SDK client if already connected\n if (this.client) {\n this.setupNotificationHandler();\n }\n }\n\n /** Forward a normalized notification to every registered consumer. */\n protected async forwardNotification(\n notification: Notification\n ): Promise<void> {\n for (const handler of this.notificationHandlers) {\n try {\n await handler(notification);\n } catch (err) {\n logger.error(\"Error in notification handler:\", err);\n }\n }\n }\n\n /** Handle SDK list-change callbacks identically on v1 and v2 connections. */\n protected async handleListChanged(\n method:\n | \"notifications/tools/list_changed\"\n | \"notifications/resources/list_changed\"\n | \"notifications/prompts/list_changed\",\n error: Error | null,\n tools?: Tool[] | null\n ): Promise<void> {\n if (error) {\n logger.warn(`[Auto] ${method} refresh failed:`, error);\n return;\n }\n if (method === \"notifications/tools/list_changed\" && tools) {\n this.toolsCache = [...tools];\n }\n await this.forwardNotification({ method } as Notification);\n }\n\n /**\n * Internal: wire notification handlers to the SDK client\n * Includes automatic handling for list_changed notifications per MCP spec\n */\n protected setupNotificationHandler(): void {\n if (!this.client) return;\n\n // Use fallbackNotificationHandler to catch all notifications\n this.client.fallbackNotificationHandler = async (\n notification: Notification\n ) => {\n // Auto-handle list_changed notifications per MCP spec\n // Clients SHOULD re-fetch the list when receiving these notifications\n switch (notification.method) {\n case \"notifications/tools/list_changed\":\n await this.refreshToolsCache();\n break;\n case \"notifications/resources/list_changed\":\n await this.onResourcesListChanged();\n break;\n case \"notifications/prompts/list_changed\":\n await this.onPromptsListChanged();\n break;\n default:\n break;\n }\n\n await this.forwardNotification(notification);\n };\n\n // The SDK registers specific handlers for progress and cancelled notifications\n // that bypass fallbackNotificationHandler entirely. Override them to also\n // forward to user-registered handlers so they appear in notification UIs.\n const client = this.client as any;\n const handlersMap = client._notificationHandlers as Map<\n string,\n (notification: Notification) => Promise<void>\n >;\n\n for (const method of [\n \"notifications/progress\",\n \"notifications/cancelled\",\n ]) {\n const originalHandler = handlersMap.get(method);\n if (originalHandler) {\n handlersMap.set(method, async (notification: Notification) => {\n await originalHandler(notification);\n await this.forwardNotification(notification);\n });\n }\n }\n }\n\n /**\n * Forward v2 MRTR progress whose retry request IDs are not associated with\n * the original call callback by the current SDK beta.\n *\n * ponytail: fallback is enabled only when exactly one progress-aware call is\n * active; remove it when the upstream SDK propagates handlers to MRTR rounds.\n */\n protected setupRoundProgressForwarding(): void {\n if (!this.client) return;\n const sdkClient = this.client as unknown as {\n _onnotification: (message: JSONRPCMessage) => void | Promise<void>;\n _progressHandlers?: Map<unknown, unknown>;\n };\n const original = sdkClient._onnotification.bind(this.client);\n sdkClient._onnotification = async (message: JSONRPCMessage) => {\n if (\n message &&\n typeof message === \"object\" &&\n (message as { method?: unknown }).method === \"notifications/progress\"\n ) {\n this.forwardRoundProgress((message as { params?: unknown }).params);\n }\n await original?.(message);\n };\n }\n\n /** Forward progress parsed from a transport stream to the active call. */\n protected forwardRoundProgress(params: unknown): void {\n if (this.activeProgressHandlers.size === 1) {\n const [handler] = this.activeProgressHandlers;\n handler?.(\n params as Parameters<NonNullable<RequestOptions[\"onprogress\"]>>[0]\n );\n }\n }\n\n /**\n * Auto-refresh tools cache when server sends tools/list_changed notification\n */\n protected async refreshToolsCache(): Promise<void> {\n if (!this.client) return;\n try {\n logger.debug(\n \"[Auto] Refreshing tools cache due to list_changed notification\"\n );\n const result = await this.client.listTools();\n this.toolsCache = (result.tools ?? []) as Tool[];\n logger.debug(\n `[Auto] Refreshed tools cache: ${this.toolsCache.length} tools`\n );\n } catch (err) {\n logger.warn(\"[Auto] Failed to refresh tools cache:\", err);\n }\n }\n\n /**\n * Called when server sends resources/list_changed notification\n * Resources aren't cached by default, but we log for user awareness\n */\n protected async onResourcesListChanged(): Promise<void> {\n logger.debug(\n \"[Auto] Resources list changed - clients should re-fetch if needed\"\n );\n }\n\n /**\n * Called when server sends prompts/list_changed notification\n * Prompts aren't cached by default, but we log for user awareness\n */\n protected async onPromptsListChanged(): Promise<void> {\n logger.debug(\n \"[Auto] Prompts list changed - clients should re-fetch if needed\"\n );\n }\n\n /**\n * Set roots and notify the server.\n * Roots represent directories or files that the client has access to.\n *\n * @param roots - Array of Root objects with `uri` (must start with \"file://\") and optional `name`\n *\n * @deprecated Roots are retained only for v1 compatibility.\n *\n * @example\n * ```typescript\n * await connector.setRoots([\n * { uri: \"file:///home/user/project\", name: \"My Project\" },\n * { uri: \"file:///home/user/data\" }\n * ]);\n * ```\n */\n async setRoots(roots: Root[]): Promise<void> {\n this.rootsCache = [...roots];\n if (this.client) {\n logger.debug(\n `Sending roots/list_changed notification with ${roots.length} root(s)`\n );\n await this.client.sendRootsListChanged();\n }\n }\n\n /**\n * Returns the roots currently advertised to the server.\n *\n * @returns A copy of the configured roots.\n */\n getRoots(): Root[] {\n return [...this.rootsCache];\n }\n\n /**\n * Internal: set up roots/list request handler.\n * Must be registered after Client construction and before connect() so the\n * handler is available during initialize / reverse RPC for the full session.\n */\n protected setupRootsHandler(): void {\n if (!this.client) return;\n\n // Handle roots/list requests from the server\n this.client.setRequestHandler(\"roots/list\", async () => {\n logger.debug(\n `Server requested roots list, returning ${this.rootsCache.length} root(s)`\n );\n return { roots: this.rootsCache };\n });\n }\n\n /**\n * Internal: set up sampling/createMessage request handler.\n * Must be registered after Client construction and before connect().\n */\n protected setupSamplingHandler(): void {\n if (!this.client) {\n logger.debug(\"setupSamplingHandler: No client available\");\n return;\n }\n const samplingCallback = this.opts.onSampling;\n if (!samplingCallback) {\n logger.debug(\"setupSamplingHandler: No sampling callback provided\");\n return;\n }\n\n logger.debug(\"setupSamplingHandler: Setting up sampling request handler\");\n // Handle sampling/createMessage requests from the server\n this.client.setRequestHandler(\"sampling/createMessage\", async (request) => {\n logger.debug(\"Server requested sampling, forwarding to callback\");\n return await samplingCallback(request.params);\n });\n logger.debug(\n \"setupSamplingHandler: Sampling handler registered successfully\"\n );\n }\n\n /**\n * Internal: set up elicitation/create request handler.\n * Must be registered after Client construction and before connect().\n */\n protected setupElicitationHandler(): void {\n if (!this.client) {\n logger.debug(\"setupElicitationHandler: No client available\");\n return;\n }\n const elicitationCallback = this.opts.onElicitation;\n if (!elicitationCallback) {\n logger.debug(\"setupElicitationHandler: No elicitation callback provided\");\n return;\n }\n\n logger.debug(\n \"setupElicitationHandler: Setting up elicitation request handler\"\n );\n // Handle elicitation/create requests from the server\n this.client.setRequestHandler(\"elicitation/create\", async (request) => {\n logger.debug(\"Server requested elicitation, forwarding to callback\");\n return await elicitationCallback(\n request.params as ElicitRequestFormParams | ElicitRequestURLParams\n );\n });\n logger.debug(\n \"setupElicitationHandler: Elicitation handler registered successfully\"\n );\n }\n\n /**\n * Establishes the transport connection and creates the SDK client.\n *\n * @returns A promise that resolves when the connector is connected.\n */\n abstract connect(): Promise<void>;\n\n /**\n * Returns transport-specific fields suitable for logs and telemetry.\n *\n * @returns A record identifying the connector without exposing credentials.\n */\n abstract get publicIdentifier(): Record<string, string>;\n\n /**\n * Run one logical MCP operation. HTTP connectors override this host seam to\n * finish an SDK-started interactive OAuth flow and retry exactly once.\n */\n protected async executeRequest<T>(operation: () => Promise<T>): Promise<T> {\n return operation();\n }\n\n /** OAuth state discovered for the active connection, when available. */\n get authorization(): MCPAuthorizationInfo | undefined {\n return this.authorizationCache;\n }\n\n /**\n * Discover optional authorization metadata without delaying connection\n * readiness. HTTP connectors override this with RFC 9728 discovery.\n */\n async discoverAuthorization(): Promise<MCPAuthorizationInfo | undefined> {\n return this.authorization;\n }\n\n /** Start optional OAuth for a connected mixed-auth server. */\n async authenticate(): Promise<void> {\n throw new Error(\"This connector does not support interactive OAuth\");\n }\n\n /**\n * Disconnects the SDK client and releases transport resources.\n *\n * @returns A promise that resolves after cleanup completes.\n */\n async disconnect(): Promise<void> {\n if (!this.connected) {\n logger.debug(\"Not connected to MCP implementation\");\n return;\n }\n\n logger.debug(\"Disconnecting from MCP implementation\");\n await this.cleanupResources();\n this.connected = false;\n logger.debug(\"Disconnected from MCP implementation\");\n }\n\n /** Whether an SDK client currently exists for this connector. */\n get isClientConnected(): boolean {\n return this.client != null;\n }\n\n /**\n * Initialise the MCP session **after** `connect()` has succeeded.\n *\n * In the SDK, `Client.connect(transport)` automatically performs the\n * protocol‑level `initialize` handshake, so we only need to cache the list of\n * tools and expose some server info.\n *\n * @param defaultRequestOptions - Options used while fetching the initial tool list.\n * @returns The capabilities advertised by the server.\n * @throws When {@link BaseConnector.connect} has not completed.\n */\n async initialize(\n defaultRequestOptions: RequestOptions = this.opts.defaultRequestOptions ??\n {}\n ): Promise<ReturnType<Client[\"getServerCapabilities\"]>> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(\"Caching server capabilities & tools\");\n\n // Cache server capabilities for callers who need them.\n const capabilities = this.client.getServerCapabilities();\n this.capabilitiesCache = (capabilities as Record<string, unknown>) || null;\n\n // The SDK normalizes identity from legacy initialize responses and modern\n // result metadata. Modern servers may remain anonymous.\n const serverInfo = this.client.getServerVersion();\n this.serverInfoCache = serverInfo\n ? {\n name: serverInfo.name,\n version: serverInfo.version,\n title: serverInfo.title,\n description: serverInfo.description,\n websiteUrl: serverInfo.websiteUrl,\n icons: serverInfo.icons,\n }\n : null;\n\n // Fetch and cache tools\n // Gracefully handle servers that don't implement tools/list or have no tools\n try {\n const listToolsRes = await this.executeRequest(() =>\n this.client!.listTools(undefined, defaultRequestOptions)\n );\n this.toolsCache = (listToolsRes.tools ?? []) as Tool[];\n logger.debug(`Fetched ${this.toolsCache.length} tools from server`);\n } catch (err: unknown) {\n if (isOAuthInteractionRequired(err)) throw err;\n const error = err as Error & { code?: number };\n // If tools/list is not implemented or fails, assume no tools\n // This commonly happens with blank servers that have no tools registered\n if (error.code === -32601) {\n logger.debug(\"Server does not implement tools/list, assuming no tools\");\n } else {\n logger.debug(\"Failed to list tools, assuming empty:\", error.message);\n }\n this.toolsCache = [];\n }\n\n logger.debug(\"Server capabilities:\", capabilities);\n logger.debug(\"Server info:\", serverInfo);\n return capabilities;\n }\n\n /**\n * Returns the tool list cached during initialization.\n *\n * @throws When {@link BaseConnector.initialize} has not completed.\n */\n get tools(): Tool[] {\n if (!this.toolsCache) {\n throw new Error(\"MCP client is not initialized; call initialize() first\");\n }\n return this.toolsCache;\n }\n\n /** Capabilities cached during initialization, or an empty object. */\n get serverCapabilities(): Record<string, unknown> {\n return this.capabilitiesCache || {};\n }\n\n /** Server identity cached during initialization, or `null`. */\n get serverInfo(): MCPServerInfo | null {\n return this.serverInfoCache;\n }\n\n /** Instructions supplied by the connected server, if any. */\n get instructions(): string | undefined {\n return this.client?.getInstructions?.();\n }\n\n /**\n * The negotiated protocol era for the active connection.\n * - `\"legacy\"` — 2025-era server, sessionful `initialize` handshake.\n * - `\"modern\"` — 2026-era server, stateless per-request.\n * `undefined` before the connection has negotiated.\n */\n get protocolEra(): ProtocolEra | undefined {\n return this.client?.getProtocolEra?.();\n }\n\n /** The protocol version string negotiated for the active connection. */\n get negotiatedProtocolVersion(): string | undefined {\n return this.client?.getNegotiatedProtocolVersion?.();\n }\n\n /**\n * Calls a tool on the connected server.\n *\n * @param name - Tool name.\n * @param args - Tool arguments.\n * @param options - Per-request timeout, cancellation, and progress options.\n * @returns The tool result returned by the server.\n * @throws When the connector is not connected or the tool call fails.\n */\n async callTool(\n name: string,\n args: Record<string, any>,\n options?: RequestOptions\n ): Promise<CallToolResult> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n // If resetTimeoutOnProgress is enabled but no onprogress callback is provided,\n // add a no-op callback to trigger the SDK to add progressToken to the request.\n // The SDK only adds progressToken when onprogress is present, which is required\n // for the server to send progress notifications that reset the timeout.\n const enhancedOptions = options ? { ...options } : undefined;\n if (\n enhancedOptions?.resetTimeoutOnProgress &&\n !enhancedOptions.onprogress\n ) {\n // Add no-op progress callback to trigger progressToken addition\n enhancedOptions.onprogress = () => {\n // No-op: progress notifications are handled by the SDK's timeout reset logic\n };\n logger.debug(\n `[BaseConnector] Added onprogress callback for tool '${name}' to enable progressToken`\n );\n }\n\n logger.debug(`Calling tool '${name}' with args`, args);\n const progressHandler = enhancedOptions?.onprogress;\n if (progressHandler) this.activeProgressHandlers.add(progressHandler);\n try {\n const res = await this.executeRequest(() =>\n this.client!.callTool({ name, arguments: args }, enhancedOptions)\n );\n logger.debug(`Tool '${name}' returned`, res);\n return res as CallToolResult;\n } finally {\n if (progressHandler) this.activeProgressHandlers.delete(progressHandler);\n }\n }\n\n /**\n * List all available tools from the MCP server.\n * This method fetches fresh tools from the server, unlike the `tools` getter which returns cached tools.\n *\n * @param options - Optional request options\n * @returns Array of available tools\n */\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n logger.debug(\"[listTools] Fetching fresh tools from server...\");\n const result = await this.executeRequest(() =>\n this.client!.listTools(undefined, options)\n );\n // Create a new array to ensure React detects the change (avoid reference equality issues)\n const tools = result.tools ? [...result.tools] : [];\n logger.debug(\n `[listTools] Returned ${tools.length} tools:`,\n tools.map((t) => t.name)\n );\n return tools;\n }\n\n /**\n * List resources from the server with optional pagination\n *\n * @param cursor - Optional cursor for pagination\n * @param options - Request options\n * @returns Resource list with optional nextCursor for pagination\n */\n async listResources(cursor?: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(\"Listing resources\", cursor ? `with cursor: ${cursor}` : \"\");\n return await this.executeRequest(() =>\n this.client!.listResources({ cursor }, options)\n );\n }\n\n /**\n * List all resources from the server, automatically handling pagination\n *\n * @param options - Request options\n * @returns Complete list of all resources\n */\n async listAllResources(options?: RequestOptions): Promise<{\n /** Resources returned across all result pages. */\n resources: any[];\n }> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n // Check if server advertises resources capability\n if (!this.capabilitiesCache?.resources) {\n logger.debug(\"Server does not advertise resources capability, skipping\");\n return { resources: [] };\n }\n\n try {\n logger.debug(\"Listing all resources (with auto-pagination)\");\n return await this.executeRequest(async () => {\n const allResources: any[] = [];\n let cursor: string | undefined = undefined;\n\n do {\n const result: { resources?: any[]; nextCursor?: string } =\n await this.client!.listResources({ cursor }, options);\n allResources.push(...(result.resources || []));\n cursor = result.nextCursor;\n } while (cursor);\n\n return { resources: allResources };\n });\n } catch (err: unknown) {\n const error = err as Error & { code?: number };\n // Gracefully handle if server advertises but doesn't actually support it\n if (error.code === -32601) {\n logger.debug(\"Server advertised resources but method not found\");\n return { resources: [] };\n }\n throw err;\n }\n }\n\n /**\n * List resource templates from the server\n *\n * @param options - Request options\n * @returns List of available resource templates\n */\n async listResourceTemplates(options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(\"Listing resource templates\");\n return await this.executeRequest(() =>\n this.client!.listResourceTemplates(undefined, options)\n );\n }\n\n /**\n * Request completion suggestions for a prompt or resource template argument\n *\n * @param params - Completion request parameters\n * @param options - Request options\n * @returns Completion suggestions from the server\n */\n async complete(\n params: CompleteRequestParams,\n options?: RequestOptions\n ): Promise<CompleteResult> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n logger.debug(\"[complete] Requesting completions for:\", params.ref);\n const result = await this.executeRequest(() =>\n this.client!.complete(params, options)\n );\n logger.debug(\n `[complete] Received ${result.completion.values.length} suggestions`\n );\n return result;\n }\n\n /**\n * Reads a resource by URI.\n *\n * @param uri - Resource URI to read.\n * @param options - Per-request options.\n * @returns The resource contents returned by the server.\n */\n async readResource(uri: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Reading resource ${uri}`);\n const res = await this.executeRequest(() =>\n this.client!.readResource({ uri }, options)\n );\n return res;\n }\n\n /**\n * Subscribe to resource updates\n *\n * @param uri - URI of the resource to subscribe to\n * @param options - Request options\n */\n async subscribeToResource(uri: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Subscribing to resource: ${uri}`);\n return await this.executeRequest(() =>\n this.client!.subscribeResource({ uri }, options)\n );\n }\n\n /**\n * Unsubscribe from resource updates\n *\n * @param uri - URI of the resource to unsubscribe from\n * @param options - Request options\n */\n async unsubscribeFromResource(uri: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Unsubscribing from resource: ${uri}`);\n return await this.executeRequest(() =>\n this.client!.unsubscribeResource({ uri }, options)\n );\n }\n\n /**\n * Lists prompts exposed by the server.\n *\n * @returns The prompt list, or an empty list when prompts are unsupported.\n */\n async listPrompts() {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n // Check if server advertises prompts capability\n if (!this.capabilitiesCache?.prompts) {\n logger.debug(\"Server does not advertise prompts capability, skipping\");\n return { prompts: [] };\n }\n\n try {\n logger.debug(\"Listing prompts\");\n return await this.executeRequest(() => this.client!.listPrompts());\n } catch (err: unknown) {\n const error = err as Error & { code?: number };\n // Gracefully handle if server advertises but doesn't actually support it\n if (error.code === -32601) {\n logger.debug(\"Server advertised prompts but method not found\");\n return { prompts: [] };\n }\n throw err;\n }\n }\n\n /**\n * Gets a prompt with the supplied arguments.\n *\n * @param name - Prompt name.\n * @param args - Prompt arguments.\n * @param options - Per-request timeout, cancellation, and progress options.\n * @returns The rendered prompt returned by the server.\n */\n async getPrompt(\n name: string,\n args: Record<string, any>,\n options?: RequestOptions\n ) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Getting prompt ${name}`);\n return await this.executeRequest(() =>\n this.client!.getPrompt({ name, arguments: args }, options)\n );\n }\n\n /**\n * Sends a raw, potentially non-standard request through the SDK client.\n *\n * @param method - JSON-RPC method name.\n * @param params - Request parameters. Defaults to an empty object.\n * @param options - Per-request options.\n * @returns The unvalidated result returned by the server.\n */\n async request(\n method: string,\n params: Record<string, any> | null = null,\n options?: RequestOptions\n ) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Sending raw request '${method}' with params`, params);\n // v2 requires a result schema for non-spec methods; a passthrough schema\n // preserves the v1 behavior of returning the raw server result for any\n // method string.\n return await this.executeRequest(() =>\n this.client!.request(\n { method, params: params ?? {} },\n passthroughResultSchema,\n options\n )\n );\n }\n\n /**\n * Helper to tear down the client & connection manager safely.\n */\n protected async cleanupResources(): Promise<void> {\n const issues: string[] = [];\n\n if (this.client) {\n try {\n if (typeof this.client.close === \"function\") {\n await this.client.close();\n }\n } catch (e) {\n const msg = `Error closing client: ${e}`;\n logger.warn(msg);\n issues.push(msg);\n } finally {\n this.client = null;\n }\n }\n\n if (this.connectionManager) {\n try {\n await this.connectionManager.stop();\n } catch (e) {\n const msg = `Error stopping connection manager: ${e}`;\n logger.warn(msg);\n issues.push(msg);\n } finally {\n this.connectionManager = null;\n }\n }\n\n this.toolsCache = null;\n this.authorizationCache = undefined;\n if (issues.length) {\n logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);\n }\n }\n}\n","import type { ConnectorInitEventData } from \"./events.js\";\n\ntype ConnectorTracker = (data: ConnectorInitEventData) => Promise<void> | void;\n\nlet tracker: ConnectorTracker | undefined;\n\n/** @internal Configures the runtime-specific connector telemetry sink. */\nexport function setConnectorTelemetryTracker(\n nextTracker: ConnectorTracker | undefined\n): void {\n tracker = nextTracker;\n}\n\n/** @internal Sends connector telemetry when the active runtime configured it. */\nexport function trackConnectorTelemetry(data: ConnectorInitEventData): void {\n void tracker?.(data);\n}\n","declare const __MCP_USE_PACKAGE_VERSION__: string;\n\n/** Installed `@mcp-use/client` package version. */\nexport const VERSION = __MCP_USE_PACKAGE_VERSION__;\n\n/**\n * Returns the installed `@mcp-use/client` package version.\n *\n * @returns Package version string.\n */\nexport function getPackageVersion(): string {\n return VERSION;\n}\n","import type {\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n Notification,\n AuthProvider,\n OAuthClientInformation,\n OAuthClientProvider,\n Root,\n RequestTypeMap,\n RequestOptions,\n ResultTypeMap,\n ClientOptions,\n VersionNegotiationMode,\n} from \"@modelcontextprotocol/client\";\nimport type { BaseConnector, ConnectorInitOptions } from \"../transport/base.js\";\nimport type { ClientInfo } from \"../transport/http.js\";\nimport { HttpConnector } from \"../transport/http.js\";\nimport type { StdioStderrMode } from \"../transport/stdio.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\n\n/** Parameters accepted by the MCP `sampling/createMessage` request. */\nexport type SamplingCreateMessageParams =\n RequestTypeMap[\"sampling/createMessage\"][\"params\"];\n\n/** Result returned for the MCP `sampling/createMessage` request. */\nexport type SamplingCreateMessageResult =\n ResultTypeMap[\"sampling/createMessage\"];\n\n/**\n * Handles a sampling request initiated by an MCP server.\n *\n * @param params - Sampling request parameters supplied by the server.\n * @returns The model-generated sampling result.\n */\nexport type OnSamplingCallback = (\n params: SamplingCreateMessageParams\n) => Promise<SamplingCreateMessageResult>;\n\n/**\n * Handles a form or URL elicitation request initiated by an MCP server.\n *\n * @param params - Elicitation request parameters supplied by the server.\n * @returns The user's elicitation decision and optional content.\n */\nexport type OnElicitationCallback = (\n params: ElicitRequestFormParams | ElicitRequestURLParams\n) => Promise<ElicitResult>;\n\n/**\n * Handles a notification sent by an MCP server.\n *\n * @param notification - The notification envelope supplied by the server.\n */\nexport type OnNotificationCallback = (\n notification: Notification\n) => void | Promise<void>;\n\n/**\n * Callback options shared by per-server config and global defaults.\n */\nexport interface CallbackConfig {\n /**\n * Callback for sampling input.\n *\n * @deprecated Sampling is deprecated by the 2026 protocol. Retained for v1\n * push requests and the v2 `input_required` compatibility window.\n */\n onSampling?: OnSamplingCallback;\n /** Callback for elicitation requests from servers. */\n onElicitation?: OnElicitationCallback;\n /** Callback for notifications from servers. */\n onNotification?: OnNotificationCallback;\n}\n\n/**\n * Resolves callback handlers, preferring per-server values over global values.\n *\n * @param perServer - Callback overrides for one server.\n * @param globalDefaults - Fallback callbacks shared by all servers.\n * @returns The effective callbacks for the server.\n */\nexport function resolveCallbacks(\n perServer: CallbackConfig | undefined,\n globalDefaults: CallbackConfig | undefined\n): {\n /** Effective sampling callback. */\n onSampling?: OnSamplingCallback;\n /** Effective elicitation callback. */\n onElicitation?: OnElicitationCallback;\n /** Effective notification callback. */\n onNotification?: OnNotificationCallback;\n} {\n const pickSampling = perServer?.onSampling ?? globalDefaults?.onSampling;\n const pickElicitation =\n perServer?.onElicitation ?? globalDefaults?.onElicitation;\n const pickNotification =\n perServer?.onNotification ?? globalDefaults?.onNotification;\n\n return {\n onSampling: pickSampling,\n onElicitation: pickElicitation,\n onNotification: pickNotification,\n };\n}\n\n/**\n * Base server configuration with common optional fields\n */\n/** Options shared by HTTP and stdio server configurations. */\ninterface BaseServerConfig extends CallbackConfig {\n /** Client identity advertised to the server. */\n clientInfo?: ClientInfo;\n /** Initial roots advertised to the server. */\n roots?: Root[];\n /** Options forwarded to the official MCP SDK Client. */\n clientOptions?: ClientOptions;\n /** Default timeout/cancellation options for requests. */\n defaultRequestOptions?: RequestOptions;\n}\n\n/**\n * Configures a local MCP server launched over standard input and output.\n */\nexport interface StdioServerConfig extends BaseServerConfig {\n /** Executable used to start the server. */\n command: string;\n /** Arguments passed to {@link StdioServerConfig.command}. */\n args: string[];\n /** Environment variables merged with the current process environment. */\n env?: Record<string, string>;\n /** Working directory used to launch the server process. */\n cwd?: string;\n /**\n * How the server process's standard error is handled. Defaults to `\"pipe\"`,\n * which forwards it to the connector's `errlog`. Use `\"inherit\"` to give the\n * child the parent's stderr file descriptor instead, preserving TTY\n * detection and colorization, or `\"ignore\"` to discard it.\n */\n stderr?: StdioStderrMode;\n /**\n * Protocol version negotiation mode. Defaults to `\"legacy\"` for stdio (the\n * SDK advises against probing for spawn-per-invocation tools). See\n * {@link StdioConnector}.\n */\n protocolNegotiation?: VersionNegotiationMode;\n}\n\n/**\n * Options forwarded to the platform `createOAuthProvider` when the client\n * auto-provisions OAuth for an HTTP server. Platform-specific fields\n * (e.g. Node `openBrowser`, browser `oauthProxyUrl`) are accepted and ignored\n * by the other runtime.\n */\nexport interface AutoOAuthOptions {\n /** Prefix used for persisted OAuth session keys. */\n storageKeyPrefix?: string;\n /** OAuth client display name. */\n clientName?: string;\n /** Public URL describing the OAuth client. */\n clientUri?: string;\n /** Public URL for the OAuth client logo. */\n logoUri?: string;\n /** OAuth redirect URI. The platform provider supplies a default when omitted. */\n callbackUrl?: string;\n /** URL of an OAuth Client ID Metadata Document. */\n clientMetadataUrl?: string;\n /** Space-delimited OAuth scopes to request. */\n scope?: string;\n /** Pre-registered public client id (skips DCR). */\n staticClientInfo?: OAuthClientInformation;\n /** Preferred Node loopback port. Defaults to `33418`. */\n preferredPort?: number;\n /** Number of Node loopback ports to try. Defaults to `10`. */\n portRange?: number;\n /** Node loopback callback timeout in milliseconds. Defaults to five minutes. */\n authTimeoutMs?: number;\n /** Node: override browser launch (CLI prints the URL instead). */\n openBrowser?: (url: string) => void | Promise<void>;\n /** Browser: wait for explicit authenticate() instead of auto popup. */\n preventAutoAuth?: boolean;\n /** Browser: full-page redirect instead of popup. */\n useRedirectFlow?: boolean;\n /** Browser: same-origin OAuth BFF base URL. */\n oauthProxyUrl?: string;\n /** Whether browser OAuth HTTP uses `oauthProxyUrl`. Defaults to `true` when the URL is set. */\n proxyOAuthRequests?: boolean;\n}\n\n/**\n * Configures a remote MCP server accessed with streamable HTTP.\n */\nexport interface HttpServerConfig extends BaseServerConfig {\n /** MCP endpoint URL. */\n url: string;\n /** Headers included with MCP transport requests. */\n headers?: Record<string, string>;\n /** Fetch implementation used by the HTTP transport. */\n fetch?: typeof fetch;\n /** Bearer token added as the `Authorization` header. */\n authToken?: string;\n /** Connection timeout in milliseconds. */\n timeout?: number;\n /** OAuth provider used when the server requires authorization. */\n authProvider?: AuthProvider | OAuthClientProvider;\n /**\n * Auto-OAuth options for HTTP servers.\n * - omit / `{}`: client creates the platform provider on connect\n * - `false`: disable auto-OAuth (e.g. CLI `--no-oauth`)\n * - object: forwarded to `createOAuthProvider`\n *\n * Ignored when `authProvider` or `authToken` is set, or when `headers`\n * already includes `Authorization`.\n */\n oauth?: AutoOAuthOptions | false;\n /**\n * Detect mixed-auth servers after an anonymous connection by using the\n * official SDK's RFC 9728 protected-resource metadata discovery.\n * @defaultValue true\n */\n detectMixedAuth?: boolean;\n /**\n * Protocol version negotiation mode. Defaults to `\"auto\"` to negotiate both\n * v1 and v2 MCP servers. See {@link HttpConnector}.\n */\n protocolNegotiation?: VersionNegotiationMode;\n}\n\n/**\n * Tests whether the client should create an OAuth provider for an HTTP server.\n *\n * @param serverConfig - Server configuration to inspect.\n * @returns `true` for an HTTP configuration without explicit authorization.\n */\nexport function shouldAutoProvisionOAuth(\n serverConfig: ServerConfig\n): serverConfig is HttpServerConfig {\n if (!(\"url\" in serverConfig) || typeof serverConfig.url !== \"string\") {\n return false;\n }\n if (serverConfig.authProvider) return false;\n if (serverConfig.authToken) return false;\n if (serverConfig.oauth === false) return false;\n const headers = serverConfig.headers;\n if (headers) {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === \"authorization\") return false;\n }\n }\n return true;\n}\n\n/**\n * Configuration for either a local stdio server or a remote HTTP server.\n */\nexport type ServerConfig = StdioServerConfig | HttpServerConfig;\n\n/**\n * Top-level MCP client configuration.\n *\n * Callback and client identity values act as defaults for individual servers.\n */\nexport interface MCPClientConfigShape extends CallbackConfig {\n /** Default client identity for all servers; overridable per server. */\n clientInfo?: ClientInfo;\n /** Server configurations keyed by the name used in client methods. */\n mcpServers?: Record<string, ServerConfig>;\n}\n\n/**\n * Default clientInfo for mcp-use\n */\nfunction getDefaultClientInfo(): ClientInfo {\n return {\n name: \"mcp-use\",\n title: \"mcp-use\",\n version: getPackageVersion(),\n description:\n \"mcp-use is a complete TypeScript framework for building and using MCP\",\n icons: [\n {\n src: \"https://mcp-use.com/logo.png\",\n },\n ],\n websiteUrl: \"https://mcp-use.com\",\n };\n}\n\n/**\n * Normalizes a client identity and fills optional metadata with package defaults.\n *\n * @param input - Candidate client identity.\n * @returns The supplied identity merged with defaults, or the complete default\n * identity when `input` does not contain both `name` and `version`.\n */\nexport function normalizeClientInfo(input: unknown): ClientInfo {\n const fallback = getDefaultClientInfo();\n if (!input || typeof input !== \"object\") return fallback;\n const ci = input as Partial<ClientInfo>;\n // Require name + version (SDK/client contract)\n if (!ci.name || !ci.version) return fallback;\n return { ...fallback, ...ci };\n}\n\n/**\n * Expands the `capabilities.views` shorthand into the MCP Apps extension.\n *\n * @param clientOptions - SDK client options to normalize.\n * @returns Normalized options, or `undefined` when no options were supplied.\n */\nexport function resolveClientOptions(\n clientOptions: ClientOptions | undefined\n): ClientOptions | undefined {\n const capabilities = clientOptions?.capabilities as\n | Record<string, unknown>\n | undefined;\n if (!capabilities || capabilities.views !== true) return clientOptions;\n\n const { views: _views, ...capsWithoutViews } = capabilities;\n const extensions =\n capsWithoutViews.extensions &&\n typeof capsWithoutViews.extensions === \"object\" &&\n !Array.isArray(capsWithoutViews.extensions)\n ? { ...(capsWithoutViews.extensions as Record<string, unknown>) }\n : {};\n\n return {\n ...clientOptions,\n capabilities: {\n ...capsWithoutViews,\n extensions: {\n ...extensions,\n \"io.modelcontextprotocol/ui\": {\n mimeTypes: [\"text/html;profile=mcp-app\"],\n },\n },\n },\n };\n}\n\n/**\n * Creates an HTTP connector from a runtime-neutral server configuration.\n *\n * @param serverConfig - Server configuration to convert.\n * @param connectorOptions - Connector options that override derived values.\n * @returns An HTTP connector for the configured endpoint.\n * @throws When `serverConfig` is a stdio configuration or has no recognized transport.\n */\nexport function createConnectorFromConfig(\n serverConfig: ServerConfig,\n connectorOptions?: Partial<ConnectorInitOptions>\n): BaseConnector {\n // Normalize clientInfo to ensure required fields are present\n const clientInfo = normalizeClientInfo(serverConfig.clientInfo);\n\n if (\"command\" in serverConfig && \"args\" in serverConfig) {\n throw new Error(\n \"Stdio connector is not supported in this environment. \" +\n \"Stdio connections require Node.js and are only available in the Node.js MCPClient.\"\n );\n }\n\n if (\"url\" in serverConfig) {\n return new HttpConnector(serverConfig.url, {\n headers: serverConfig.headers,\n fetch: serverConfig.fetch,\n authToken: serverConfig.authToken,\n authProvider: serverConfig.authProvider,\n detectMixedAuth: serverConfig.detectMixedAuth,\n protocolNegotiation: serverConfig.protocolNegotiation,\n timeout: serverConfig.timeout,\n roots: serverConfig.roots,\n clientOptions: resolveClientOptions(serverConfig.clientOptions),\n defaultRequestOptions: serverConfig.defaultRequestOptions,\n clientInfo,\n ...connectorOptions,\n });\n }\n\n throw new Error(\"Cannot determine connector type from config\");\n}\n","// browser-provider.ts\nimport {\n extractWWWAuthenticateParams,\n type OAuthClientInformation,\n type OAuthClientInformationContext,\n type OAuthClientMetadata,\n type OAuthClientProvider,\n type OAuthDiscoveryState,\n type OAuthTokens,\n} from \"@modelcontextprotocol/client\";\nimport { LocalStorageKVStore } from \"./storage.js\";\nimport { OAuthSessionStore } from \"./session-store.js\";\n\n/**\n * Serialize request body for proxying\n */\nasync function serializeBody(body: BodyInit): Promise<any> {\n if (typeof body === \"string\") return body;\n if (body instanceof URLSearchParams || body instanceof FormData) {\n return Object.fromEntries(body.entries());\n }\n if (body instanceof Blob) return await body.text();\n return body;\n}\n\nfunction trimTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 47) {\n end--;\n }\n return value.slice(0, end);\n}\n\n/** Options for the browser implementation of the SDK `OAuthClientProvider`. */\nexport interface BrowserOAuthOptions {\n /** Prefix used for persisted OAuth keys. */\n storageKeyPrefix?: string;\n /** Human-readable OAuth client name. */\n clientName?: string;\n /** Public website describing the OAuth client. */\n clientUri?: string;\n /** Public OAuth client logo URL. */\n logoUri?: string;\n /** OAuth redirect URI. */\n callbackUrl?: string;\n /** Whether initial connection waits for an explicit authentication action. */\n preventAutoAuth?: boolean;\n /** Whether authorization uses a full-page redirect instead of a popup. */\n useRedirectFlow?: boolean;\n /** Same-origin proxy endpoint for OAuth HTTP requests. */\n oauthProxyUrl?: string;\n /** MCP proxy URL the transport connected to, used to re-anchor discovery. */\n connectionUrl?: string;\n /** HTTPS URL serving this public client's metadata document for CIMD. */\n clientMetadataUrl?: string;\n /**\n * When true (default), OAuth requests (.well-known metadata, token,\n * registration, revocation, and introspection) are routed through\n * `oauthProxyUrl` to bypass CORS.\n * The routing is applied only to the scoped fetch returned by\n * {@link BrowserOAuthClientProvider.getProxyFetch}; it never mutates the\n * global `fetch`. Set to false to connect directly even when an OAuth proxy\n * URL is available (e.g. when the MCP gateway already proxies OAuth).\n */\n proxyOAuthRequests?: boolean;\n /**\n * Pre-registered OAuth client information. When set, the SDK skips\n * Dynamic Client Registration and uses this client_id directly.\n * Required for proxy-mode auth servers (e.g. Slack, WorkOS proxy)\n * that strip `registration_endpoint` from metadata.\n */\n staticClientInfo?: OAuthClientInformation;\n /** OAuth scope string forwarded to the SDK via clientMetadata.scope. */\n scope?: string;\n /** Called immediately before the provider opens an authorization popup. */\n onPopupWindow?: (\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void;\n}\n\n/**\n * Browser-compatible OAuth client provider for MCP using localStorage.\n */\nexport class BrowserOAuthClientProvider implements OAuthClientProvider {\n /** Protected MCP server URL associated with this provider. */\n readonly serverUrl: string;\n /** Pre-registered public client information, when configured. */\n readonly staticClientInfo?: OAuthClientInformation;\n private session: OAuthSessionStore;\n private readonly storage: LocalStorageKVStore;\n\n // Browser-only state\n /** Whether initial connection waits for explicit authentication. */\n readonly preventAutoAuth?: boolean;\n private useRedirectFlow?: boolean;\n private oauthProxyUrl?: string;\n private connectionUrl?: string;\n private proxyOAuthRequests: boolean;\n private lastAttemptedAuthUrl: string | null = null;\n private authorizationPending = false;\n /** Latest protected-resource metadata URL advertised by an MCP 401. */\n private challengedResourceMetadataUrl: string | undefined;\n /** Callback invoked immediately before an authorization popup opens. */\n readonly onPopupWindow:\n | ((\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void)\n | undefined;\n\n constructor(serverUrl: string, options: BrowserOAuthOptions = {}) {\n if (options.staticClientInfo?.client_secret) {\n throw new Error(\n \"Browser OAuth clients must be public clients; staticClientInfo.client_secret is not allowed.\"\n );\n }\n this.serverUrl = serverUrl;\n this.storage = new LocalStorageKVStore();\n this.session = new OAuthSessionStore(\n serverUrl,\n { ...options, allowClientSecret: false },\n this.storage\n );\n this.preventAutoAuth = options.preventAutoAuth;\n this.useRedirectFlow = options.useRedirectFlow;\n this.oauthProxyUrl = options.oauthProxyUrl;\n this.connectionUrl = options.connectionUrl;\n this.proxyOAuthRequests = options.proxyOAuthRequests ?? true;\n this.staticClientInfo = options.staticClientInfo;\n this.onPopupWindow = options.onPopupWindow;\n }\n\n // --- Identity / key fields exposed for callback handling ---\n\n /** Prefix used for persisted OAuth keys. */\n get storageKeyPrefix(): string {\n return this.session.storageKeyPrefix;\n }\n\n /** Stable hash used to namespace storage for this server. */\n get serverUrlHash(): string {\n return this.session.serverUrlHash;\n }\n\n /** Human-readable OAuth client name. */\n get clientName(): string {\n return this.session.clientName;\n }\n\n /** Public website describing the OAuth client. */\n get clientUri(): string {\n return this.session.clientUri;\n }\n\n /** Public OAuth client logo URL. */\n get logoUri(): string {\n return this.session.logoUri;\n }\n\n /** OAuth redirect URI. */\n get callbackUrl(): string {\n return this.session.callbackUrl;\n }\n\n /** Space-delimited OAuth scopes requested by the client. */\n get scope(): string | undefined {\n return this.session.scope;\n }\n\n get clientMetadataUrl(): string | undefined {\n return this.session.clientMetadataUrl;\n }\n\n /**\n * Returns a provider-scoped storage key.\n *\n * @param keySuffix - Suffix identifying the stored value.\n * @returns Namespaced storage key.\n */\n getKey(keySuffix: string): string {\n return this.session.getKey(keySuffix);\n }\n\n /** Whether an authorization flow is awaiting completion. */\n get hasPendingFlow(): boolean {\n return this.authorizationPending;\n }\n\n /** Marks the current authorization flow as complete. */\n markFlowComplete(): void {\n this.authorizationPending = false;\n }\n\n /**\n * Re-anchor an SDK-derived OAuth discovery URL from the MCP connection\n * (proxy) origin onto the actual MCP server.\n *\n * When MCP traffic is tunneled through a gateway/inspector proxy, the SDK\n * transport derives `/.well-known/*` URLs from the URL it connected to (the\n * proxy) whenever no `resource_metadata` hint is available — the SSE\n * transport's EventSource cannot read `WWW-Authenticate`, and token refresh\n * runs without a 401 response at hand. The proxy origin serves no OAuth\n * metadata, so discovery would fail and the server would be misclassified\n * as \"does not support OAuth\". Rewriting reproduces what a direct\n * connection would have requested: the same well-known document, anchored\n * on the server origin, with the RFC 8414 §3.1 / RFC 9728 §3.1 path\n * insertion using the server's path instead of the proxy's.\n */\n private reanchorWellKnownUrl(url: string): string {\n if (!this.connectionUrl) return url;\n try {\n const requested = new URL(url);\n const connection = new URL(this.connectionUrl);\n if (requested.origin !== connection.origin) return url;\n if (!requested.pathname.startsWith(\"/.well-known/\")) return url;\n\n const target = new URL(this.serverUrl);\n const rest = requested.pathname.slice(\"/.well-known/\".length);\n const [doc, ...suffixParts] = rest.split(\"/\");\n if (!doc) return url;\n\n const suffix = suffixParts.length ? `/${suffixParts.join(\"/\")}` : \"\";\n const connectionPath = trimTrailingSlashes(connection.pathname);\n const targetPath = trimTrailingSlashes(target.pathname);\n // Path-insertion form: swap the proxy's inserted path for the server's.\n // Root form (no suffix) stays root. Unrelated suffixes are preserved.\n const newSuffix =\n suffix && suffix === connectionPath ? targetPath : suffix;\n\n return `${target.origin}/.well-known/${doc}${newSuffix}${requested.search}`;\n } catch {\n return url;\n }\n }\n\n private rememberResourceMetadataChallenge(response: Response): boolean {\n if (response.status !== 401) return false;\n const { resourceMetadataUrl } = extractWWWAuthenticateParams(response);\n if (!resourceMetadataUrl) return false;\n this.challengedResourceMetadataUrl = resourceMetadataUrl.toString();\n return true;\n }\n\n /**\n * Returns a `fetch` function, scoped to this provider, that routes OAuth\n * metadata and non-browser OAuth endpoint requests through the configured\n * `oauthProxyUrl` to bypass CORS. Authorization endpoints are navigated by\n * the browser and all unrelated requests pass through unchanged.\n *\n * Unlike patching the global `fetch`, the returned function only affects the\n * transport/auth calls it is explicitly handed to (via the SDK transport's\n * `fetch` option or `auth({ fetchFn })`). Connecting one server \"Via Proxy\"\n * therefore never alters fetch behavior for other servers, other\n * connections, or the rest of the page.\n *\n * OAuth metadata is always fetched with `cache: \"no-store\"`, including in\n * direct mode. Authorization servers commonly vary CORS headers by Origin;\n * bypassing the browser HTTP cache prevents a revalidated response cached\n * for another localhost origin from poisoning discovery. When OAuth proxying\n * is disabled or no `oauthProxyUrl` is configured, all requests still go\n * directly to their original URLs.\n *\n * @param baseFetch - The fetch used for non-OAuth requests and for the\n * underlying proxy calls. Defaults to the global `fetch`.\n */\n getProxyFetch(baseFetch?: typeof fetch): typeof fetch | undefined {\n const base: typeof fetch = baseFetch ?? globalThis.fetch.bind(globalThis);\n const oauthProxyUrl =\n this.proxyOAuthRequests && this.oauthProxyUrl\n ? this.oauthProxyUrl\n : undefined;\n const discoveredEndpoints = new Set<string>();\n let restoredDiscovery = false;\n\n // Create scoped fetch\n return async (\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> => {\n const requestedUrl =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n // The SDK derives discovery URLs from the transport URL. Re-anchor URLs\n // derived from an MCP proxy onto the actual MCP server before routing.\n const url = this.reanchorWellKnownUrl(requestedUrl);\n\n let pathname: string;\n try {\n pathname = new URL(url).pathname;\n } catch {\n return await base(input, init);\n }\n const isMetadata = pathname.includes(\"/.well-known/\");\n\n // Metadata responses can carry Origin-specific CORS headers. Never let\n // the browser reuse or revalidate a response cached for another origin.\n // This is scoped to discovery; MCP traffic and OAuth endpoint POSTs keep\n // their caller-provided cache behavior.\n if (!oauthProxyUrl) {\n const response = await base(\n isMetadata ? url : input,\n isMetadata ? { ...init, cache: \"no-store\" } : init\n );\n if (!isMetadata) this.rememberResourceMetadataChallenge(response);\n return response;\n }\n\n if (!restoredDiscovery) {\n restoredDiscovery = true;\n const metadata = (await this.discoveryState())\n ?.authorizationServerMetadata as Record<string, unknown> | undefined;\n for (const key of [\n \"registration_endpoint\",\n \"token_endpoint\",\n \"revocation_endpoint\",\n \"introspection_endpoint\",\n ]) {\n if (typeof metadata?.[key] === \"string\") {\n discoveredEndpoints.add(metadata[key]);\n }\n }\n }\n const isProxiedEndpoint =\n discoveredEndpoints.has(url) ||\n /\\/(?:register|registration|token|revoke|revocation|introspect|introspection)\\/?$/.test(\n pathname\n );\n\n if (!isMetadata && !isProxiedEndpoint) {\n const response = await base(input, init);\n if (this.rememberResourceMetadataChallenge(response)) {\n // Endpoints restored before the MCP request may belong to discovery\n // that the fresh challenge has just made stale. Fresh metadata will\n // repopulate this routing set as the SDK rediscovers it.\n discoveredEndpoints.clear();\n }\n return response;\n }\n\n // Don't intercept requests already going to our OAuth proxy (avoid circular proxying)\n // Check if the URL is pointing to our OAuth proxy endpoint\n try {\n const urlObj = new URL(url);\n const proxyUrlObj = new URL(oauthProxyUrl);\n // If the request is going to the same origin and path as our OAuth proxy, don't intercept\n if (\n urlObj.origin === proxyUrlObj.origin &&\n (urlObj.pathname.startsWith(proxyUrlObj.pathname) ||\n url.includes(\"/inspector/api/oauth\"))\n ) {\n return await base(input, init);\n }\n } catch {\n // If URL parsing fails, continue with interception (better safe than sorry)\n }\n\n const proxyEndpoint = isMetadata\n ? `${oauthProxyUrl}/metadata?serverUrl=${encodeURIComponent(\n this.serverUrl\n )}&url=${encodeURIComponent(url)}`\n : `${oauthProxyUrl}/proxy`;\n\n if (isMetadata) {\n const response = await base(proxyEndpoint, {\n ...init,\n method: \"GET\",\n cache: \"no-store\",\n });\n try {\n const metadata = (await response.clone().json()) as Record<\n string,\n unknown\n >;\n for (const key of [\n \"registration_endpoint\",\n \"token_endpoint\",\n \"revocation_endpoint\",\n \"introspection_endpoint\",\n ]) {\n if (typeof metadata[key] === \"string\") {\n discoveredEndpoints.add(metadata[key]);\n }\n }\n } catch {\n // The SDK owns metadata validation and will reject malformed responses.\n }\n return response;\n }\n\n const inputRequest = input instanceof Request ? input : undefined;\n const method = init?.method ?? inputRequest?.method ?? \"POST\";\n const requestHeaders = init?.headers ?? inputRequest?.headers;\n let body: unknown;\n if (init?.body !== undefined && init.body !== null) {\n body = await serializeBody(init.body);\n } else if (inputRequest?.body && method !== \"GET\" && method !== \"HEAD\") {\n body = await inputRequest.clone().text();\n }\n const response = await base(proxyEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n serverUrl: this.serverUrl,\n url,\n method,\n headers: requestHeaders\n ? Object.fromEntries(new Headers(requestHeaders as HeadersInit))\n : {},\n body,\n }),\n });\n const data = (await response.json()) as {\n status?: unknown;\n statusText?: unknown;\n headers?: unknown;\n body?: unknown;\n };\n if (!response.ok || typeof data.status !== \"number\") {\n return new Response(JSON.stringify(data), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n return new Response(JSON.stringify(data.body), {\n status: data.status,\n statusText:\n typeof data.statusText === \"string\" ? data.statusText : undefined,\n headers: new Headers(\n data.headers && typeof data.headers === \"object\"\n ? (data.headers as HeadersInit)\n : undefined\n ),\n });\n };\n }\n\n // --- SDK Interface Methods (delegated) ---\n\n get redirectUrl(): string {\n return this.session.redirectUrl;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return this.session.clientMetadata;\n }\n\n tokens(\n ctx?: OAuthClientInformationContext\n ): Promise<OAuthTokens | undefined> {\n return this.session.tokens(ctx);\n }\n\n saveTokens(\n tokens: OAuthTokens,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n this.lastAttemptedAuthUrl = null;\n this.authorizationPending = false;\n return this.session.saveTokens(tokens, ctx);\n }\n\n /**\n * Returns the configured or dynamically registered OAuth client information.\n *\n * @param ctx - Optional registration context.\n * @returns OAuth client information, or `undefined` when not registered.\n */\n async clientInformation(\n ctx?: OAuthClientInformationContext\n ): Promise<OAuthClientInformation | undefined> {\n // Pre-registered client info (proxy-mode servers like Slack/WorkOS proxy\n // strip registration_endpoint, so DCR is not an option). When set, this\n // bypasses any stored DCR result so a stale localStorage entry can't\n // shadow the configured client_id.\n if (this.staticClientInfo) return this.staticClientInfo;\n return this.session.clientInformation(ctx);\n }\n\n /**\n * Persists public OAuth client registration information.\n *\n * Static client configuration takes precedence, and browser providers discard\n * any client secret returned for a public client.\n *\n * @param clientInformation - Registration information to save.\n * @param ctx - Optional registration context.\n */\n async saveClientInformation(\n clientInformation: OAuthClientInformation,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n // When a pre-registered client_id is configured, never persist DCR results\n // — the static client_id is the source of truth.\n if (this.staticClientInfo) return;\n\n // Browser clients always register as public clients\n // (`token_endpoint_auth_method: \"none\"`). Some authorization servers,\n // including Auth0 DCR, still include a generated client_secret in the\n // registration response even though the public client must not use or\n // retain it. Persist only the public portion of the response. Keep the\n // session store's secret rejection intact as a defense-in-depth guard for\n // every other browser persistence path.\n const { client_secret: discardedClientSecret, ...publicClientInformation } =\n clientInformation;\n if (discardedClientSecret) {\n console.info(\n `[${this.storageKeyPrefix}] Discarded client_secret returned for a public browser OAuth client.`\n );\n }\n return this.session.saveClientInformation(\n publicClientInformation as OAuthClientInformation,\n ctx\n );\n }\n\n codeVerifier(): Promise<string> {\n return this.session.codeVerifier();\n }\n\n saveCodeVerifier(codeVerifier: string): Promise<void> {\n return this.session.saveCodeVerifier(codeVerifier);\n }\n\n invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"\n ): Promise<void> {\n return this.session.invalidateCredentials(scope);\n }\n\n /**\n * Persist OAuth discovery state (SEP-2352). Delegated to the session store;\n * implementing this silences the SDK's per-callback warning and enables the\n * authorization-server mix-up defense on the callback leg.\n */\n saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n return this.session.saveDiscoveryState(state);\n }\n\n /** Return previously saved OAuth discovery state, or `undefined`. */\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n const state = await this.session.discoveryState();\n const challengedUrl = this.challengedResourceMetadataUrl;\n this.challengedResourceMetadataUrl = undefined;\n\n if (challengedUrl && state) {\n // A fresh MCP challenge is authoritative. RFC 9728 section 5.2 says it\n // can indicate that protected-resource metadata has changed even when\n // the metadata URL itself is unchanged. Always rediscover after such a\n // challenge instead of trusting a complete-but-stale persisted document.\n // Let the SDK rediscover from the challenge while preserving issuer-keyed\n // tokens and client registrations until normal issuer validation decides\n // whether either credential is reusable.\n await this.session.invalidateCredentials(\"discovery\");\n return undefined;\n }\n\n return state;\n }\n\n /**\n * Return the token endpoint from the SDK's persisted discovery state.\n * Returns `null` before a successful authorization discovery.\n */\n getTokenEndpoint(): Promise<string | null> {\n return this.session.getTokenEndpoint();\n }\n\n /** Return the protected-resource URL selected during OAuth discovery. */\n getResource(): Promise<string | null> {\n return this.session.getResource();\n }\n\n /**\n * Return the stored public OAuth client ID. Browser providers do not retain\n * client secrets.\n */\n async getClientCredentials(): Promise<{\n /** Public OAuth client identifier. */\n client_id: string;\n } | null> {\n const info = await this.clientInformation();\n return info?.client_id ? { client_id: info.client_id } : null;\n }\n\n /**\n * Generates and persists `StoredState` for an authorization request,\n * and returns the sanitized URL with the `state` param appended. Does NOT\n * open a popup or redirect —\n * use `redirectToAuthorization` for that.\n */\n async prepareAuthorizationUrl(authorizationUrl: URL): Promise<string> {\n const prepared = await this.session.storeAuthorizationState(\n authorizationUrl,\n {\n extraProviderOptions: {\n oauthProxyUrl: this.oauthProxyUrl,\n ...(this.clientMetadataUrl\n ? { clientMetadataUrl: this.clientMetadataUrl }\n : {}),\n ...(this.staticClientInfo\n ? { staticClientInfo: this.staticClientInfo }\n : {}),\n ...(this.scope ? { scope: this.scope } : {}),\n },\n flowType: this.useRedirectFlow ? \"redirect\" : \"popup\",\n returnUrl:\n typeof window !== \"undefined\" ? window.location.href : undefined,\n }\n );\n this.lastAttemptedAuthUrl = prepared;\n this.authorizationPending = true;\n return prepared;\n }\n\n /**\n * Redirects the user agent to the authorization URL, storing necessary state.\n * @param authorizationUrl - The fully constructed authorization URL from the SDK.\n */\n async redirectToAuthorization(authorizationUrl: URL): Promise<void> {\n await this.prepareAuthorizationUrl(authorizationUrl);\n\n // If auto-auth is prevented, just store the URL but don't redirect/popup\n if (this.preventAutoAuth) {\n console.info(\n `[${this.storageKeyPrefix}] Auto-auth prevented. Authorization URL stored for manual trigger.`\n );\n return;\n }\n\n this.startAuthorization();\n }\n\n /**\n * Open the authorization URL prepared by the official SDK.\n *\n * This is the explicit-user-action counterpart to `preventAutoAuth`: the\n * provider still lets the SDK own discovery and PKCE state, while a host can\n * launch the stored authorization request later from an Authenticate button.\n */\n startAuthorization(): void {\n const authorizationUrl = this.lastAttemptedAuthUrl;\n if (!authorizationUrl) {\n throw new Error(\"No prepared OAuth authorization is available\");\n }\n\n // Use redirect flow if enabled (avoids popup blockers)\n if (this.useRedirectFlow) {\n console.info(\n `[${this.storageKeyPrefix}] Redirecting to authorization URL (full-page redirect).`\n );\n window.location.href = authorizationUrl;\n return;\n }\n\n // Otherwise, use popup flow (legacy behavior)\n const popupFeatures =\n \"width=600,height=700,resizable=yes,scrollbars=yes,status=yes\";\n try {\n const popup = window.open(\n authorizationUrl,\n `mcp_auth_${this.serverUrlHash}`,\n popupFeatures\n );\n\n if (this.onPopupWindow) {\n this.onPopupWindow(authorizationUrl, popupFeatures, popup);\n }\n\n if (!popup || popup.closed || typeof popup.closed === \"undefined\") {\n console.warn(\n `[${this.storageKeyPrefix}] Popup likely blocked by browser. Manual navigation might be required using the stored URL.`\n );\n } else {\n popup.focus();\n console.info(\n `[${this.storageKeyPrefix}] Redirecting to authorization URL in popup.`\n );\n }\n } catch (e) {\n console.error(\n `[${this.storageKeyPrefix}] Error opening popup window:`,\n e\n );\n }\n }\n\n /**\n * Retrieves the last URL passed to `redirectToAuthorization`. Useful for manual fallback.\n */\n getLastAttemptedAuthUrl(): string | null {\n return this.lastAttemptedAuthUrl;\n }\n\n /**\n * Removes OAuth state stored for this server.\n *\n * @returns The number of storage entries removed.\n */\n clearStorage(): number {\n this.lastAttemptedAuthUrl = null;\n this.authorizationPending = false;\n const prefixPattern = `${this.storageKeyPrefix}_${this.serverUrlHash}_`;\n const keysToRemove: string[] = [];\n let count = 0;\n\n for (const key of this.storage.keys()) {\n if (key.startsWith(prefixPattern)) {\n keysToRemove.push(key);\n }\n }\n\n const uniqueKeysToRemove = [...new Set(keysToRemove)];\n uniqueKeysToRemove.forEach((key) => {\n this.storage.remove(key);\n count++;\n });\n return count;\n }\n}\n\n/**\n * Creates the browser OAuth provider used by the root client entry.\n */\nexport async function createOAuthProvider(\n serverUrl: string,\n options: BrowserOAuthOptions = {}\n): Promise<OAuthClientProvider> {\n return new BrowserOAuthClientProvider(serverUrl, options);\n}\n\nexport type { BrowserOAuthOptions as OAuthProviderOptions };\n","/**\n * Minimal key/value storage abstraction used by OAuthSessionStore.\n *\n * Browser-safe module — Node filesystem KV lives in `storage-file.ts`.\n *\n * @internal\n */\nexport interface KVStore {\n get(key: string): Promise<string | null> | string | null;\n set(key: string, value: string): Promise<void> | void;\n remove(key: string): Promise<void> | void;\n keys(): Promise<string[]> | string[];\n}\n\ntype EncryptedEnvelope = {\n v: 1;\n alg: \"A256GCM\";\n iv: string;\n ciphertext: string;\n};\n\nconst AUTH_CRYPTO_DATABASE = \"mcp-use-oauth-crypto\";\nconst AUTH_CRYPTO_STORE = \"keys\";\nconst AUTH_CRYPTO_KEY = \"aes-gcm-v1\";\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n\n/**\n * Encrypted `KVStore` backed by `globalThis.localStorage`.\n *\n * Values use AES-256-GCM with a non-extractable origin key held by IndexedDB.\n * Legacy plaintext values are encrypted on first read. When durable browser\n * cryptography is unavailable, the store removes plaintext and falls back to\n * memory for the lifetime of this instance.\n *\n * @internal\n */\nexport class LocalStorageKVStore implements KVStore {\n private readonly fallback = new Map<string, string>();\n private keyPromise: Promise<CryptoKey> | undefined;\n private durable = true;\n\n async get(key: string): Promise<string | null> {\n if (!this.durable) return this.fallback.get(key) ?? null;\n\n let stored: string | null;\n try {\n stored = localStorage.getItem(key);\n } catch {\n this.durable = false;\n return this.fallback.get(key) ?? null;\n }\n if (stored === null) return null;\n\n const envelope = parseEncryptedEnvelope(stored);\n if (!envelope) {\n await this.set(key, stored);\n return stored;\n }\n\n try {\n const cryptoKey = await this.getCryptoKey();\n const plaintext = await globalThis.crypto.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: decodeBase64(envelope.iv),\n additionalData: textEncoder.encode(key),\n },\n cryptoKey,\n decodeBase64(envelope.ciphertext)\n );\n return textDecoder.decode(plaintext);\n } catch {\n await this.remove(key);\n return null;\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n if (!this.durable) {\n this.fallback.set(key, value);\n return;\n }\n\n try {\n const cryptoKey = await this.getCryptoKey();\n const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = await globalThis.crypto.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv,\n additionalData: textEncoder.encode(key),\n },\n cryptoKey,\n textEncoder.encode(value)\n );\n const envelope: EncryptedEnvelope = {\n v: 1,\n alg: \"A256GCM\",\n iv: encodeBase64(iv),\n ciphertext: encodeBase64(new Uint8Array(ciphertext)),\n };\n localStorage.setItem(key, JSON.stringify(envelope));\n this.fallback.delete(key);\n } catch {\n this.durable = false;\n try {\n localStorage.removeItem(key);\n } catch {\n // Storage may be disabled entirely.\n }\n this.fallback.set(key, value);\n }\n }\n\n remove(key: string): void {\n this.fallback.delete(key);\n try {\n localStorage.removeItem(key);\n } catch {\n this.durable = false;\n }\n }\n\n keys(): string[] {\n const out = new Set(this.fallback.keys());\n if (this.durable) {\n try {\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key) out.add(key);\n }\n } catch {\n this.durable = false;\n }\n }\n return [...out];\n }\n\n private getCryptoKey(): Promise<CryptoKey> {\n this.keyPromise ??= getOrCreateCryptoKey();\n return this.keyPromise;\n }\n}\n\nfunction parseEncryptedEnvelope(value: string): EncryptedEnvelope | undefined {\n try {\n const parsed: unknown = JSON.parse(value);\n if (\n !parsed ||\n typeof parsed !== \"object\" ||\n !(\"v\" in parsed) ||\n parsed.v !== 1 ||\n !(\"alg\" in parsed) ||\n parsed.alg !== \"A256GCM\" ||\n !(\"iv\" in parsed) ||\n typeof parsed.iv !== \"string\" ||\n !(\"ciphertext\" in parsed) ||\n typeof parsed.ciphertext !== \"string\"\n ) {\n return undefined;\n }\n return parsed as EncryptedEnvelope;\n } catch {\n return undefined;\n }\n}\n\nasync function getOrCreateCryptoKey(): Promise<CryptoKey> {\n if (!globalThis.crypto?.subtle || typeof indexedDB === \"undefined\") {\n throw new Error(\"Durable browser cryptography is unavailable\");\n }\n\n const candidate = await globalThis.crypto.subtle.generateKey(\n { name: \"AES-GCM\", length: 256 },\n false,\n [\"encrypt\", \"decrypt\"]\n );\n const database = await openCryptoDatabase();\n try {\n return await new Promise<CryptoKey>((resolve, reject) => {\n const transaction = database.transaction(AUTH_CRYPTO_STORE, \"readwrite\");\n const store = transaction.objectStore(AUTH_CRYPTO_STORE);\n const request = store.get(AUTH_CRYPTO_KEY);\n let selected: CryptoKey | undefined;\n\n request.onsuccess = () => {\n selected = request.result as CryptoKey | undefined;\n if (!selected) {\n selected = candidate;\n store.put(candidate, AUTH_CRYPTO_KEY);\n }\n };\n request.onerror = () => reject(request.error);\n transaction.oncomplete = () => {\n if (selected) resolve(selected);\n else reject(new Error(\"OAuth encryption key was not initialized\"));\n };\n transaction.onerror = () => reject(transaction.error);\n transaction.onabort = () => reject(transaction.error);\n });\n } finally {\n database.close();\n }\n}\n\nfunction openCryptoDatabase(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(AUTH_CRYPTO_DATABASE, 1);\n request.onupgradeneeded = () => {\n const database = request.result;\n if (!database.objectStoreNames.contains(AUTH_CRYPTO_STORE)) {\n database.createObjectStore(AUTH_CRYPTO_STORE);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n request.onblocked = () =>\n reject(new Error(\"OAuth encryption database is blocked\"));\n });\n}\n\nfunction encodeBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nfunction decodeBase64(value: string): Uint8Array<ArrayBuffer> {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index++) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n","import type {\n OAuthClientInformation,\n OAuthClientInformationContext,\n OAuthClientMetadata,\n OAuthDiscoveryState,\n StoredOAuthTokens,\n} from \"@modelcontextprotocol/client\";\nimport { validateClientMetadataUrl } from \"@modelcontextprotocol/client\";\nimport { sanitizeUrl } from \"./url.js\";\nimport type { KVStore } from \"./storage.js\";\n\n/**\n * Internal type for storing OAuth state during the OAuth flow.\n * @internal\n */\nexport interface StoredState {\n expiry: number;\n serverUrlHash: string;\n providerOptions: {\n serverUrl: string;\n storageKeyPrefix: string;\n clientName: string;\n clientUri: string;\n callbackUrl: string;\n oauthProxyUrl?: string;\n clientMetadataUrl?: string;\n staticClientInfo?: OAuthClientInformation;\n scope?: string;\n };\n flowType?: \"popup\" | \"redirect\";\n returnUrl?: string;\n}\n\n/**\n * Common options for OAuthSessionStore.\n *\n * @internal\n */\nexport interface OAuthSessionStoreOptions {\n /** Prefix used for persisted OAuth keys. */\n storageKeyPrefix?: string;\n /** Human-readable OAuth client name. */\n clientName?: string;\n /** Public website describing the OAuth client. */\n clientUri?: string;\n /** Public OAuth client logo URL. */\n logoUri?: string;\n /** OAuth redirect URI. */\n callbackUrl?: string;\n /** OAuth Client ID Metadata Document URL. */\n clientMetadataUrl?: string;\n /** Whether this platform may persist confidential-client credentials. */\n allowClientSecret?: boolean;\n /** OAuth scope string forwarded to the SDK via clientMetadata.scope. */\n scope?: string;\n}\n\n/**\n * Options passed by the platform provider when persisting an authorization\n * request prior to redirecting the user agent.\n *\n * @internal\n */\ninterface StoreAuthorizationStateOptions {\n /**\n * Platform-specific provider options that should round-trip through the\n * stored state so the callback handler can rebuild the provider.\n */\n extraProviderOptions?: Record<string, unknown>;\n flowType?: \"popup\" | \"redirect\";\n returnUrl?: string;\n}\n\n/**\n * Platform-neutral helper that owns OAuth session persistence and refresh\n * logic. Used by `BrowserOAuthClientProvider` and `NodeOAuthClientProvider`\n * — each platform provider implements `OAuthClientProvider` directly and\n * delegates the generic methods here.\n *\n * @internal\n */\nexport class OAuthSessionStore {\n readonly serverUrl: string;\n readonly storageKeyPrefix: string;\n readonly serverUrlHash: string;\n readonly clientName: string;\n readonly clientUri: string;\n readonly logoUri: string;\n readonly callbackUrl: string;\n readonly clientMetadataUrl?: string;\n readonly scope?: string;\n\n private store: KVStore;\n private allowClientSecret: boolean;\n\n constructor(\n serverUrl: string,\n options: OAuthSessionStoreOptions,\n store: KVStore\n ) {\n validateClientMetadataUrl(options.clientMetadataUrl);\n this.serverUrl = serverUrl;\n this.storageKeyPrefix = options.storageKeyPrefix || \"mcp:auth\";\n this.serverUrlHash = OAuthSessionStore.hashString(serverUrl);\n this.clientName = options.clientName || \"mcp-use\";\n this.clientUri =\n options.clientUri ||\n (typeof window !== \"undefined\"\n ? window.location.origin\n : \"https://mcp-use.com\");\n this.logoUri = options.logoUri || \"https://mcp-use.com/logo.png\";\n this.callbackUrl = sanitizeUrl(\n options.callbackUrl ||\n (typeof window !== \"undefined\"\n ? new URL(\"/oauth/callback\", window.location.origin).toString()\n : \"/oauth/callback\")\n );\n this.clientMetadataUrl = options.clientMetadataUrl;\n this.scope = options.scope;\n this.store = store;\n this.allowClientSecret = options.allowClientSecret ?? true;\n }\n\n getKey(keySuffix: string): string {\n return `${this.storageKeyPrefix}_${this.serverUrlHash}_${keySuffix}`;\n }\n\n static hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n }\n\n // --- SDK Interface Methods (delegated) ---\n\n get redirectUrl(): string {\n return this.callbackUrl;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n redirect_uris: [this.redirectUrl],\n token_endpoint_auth_method: \"none\",\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n client_name: this.clientName,\n client_uri: this.clientUri,\n logo_uri: this.logoUri,\n ...(this.scope ? { scope: this.scope } : {}),\n };\n }\n\n private credentialKey(\n kind: \"client_info\" | \"tokens\",\n ctx?: OAuthClientInformationContext\n ): string {\n return ctx\n ? this.getKey(`${kind}_${encodeURIComponent(ctx.issuer)}`)\n : this.getKey(kind);\n }\n\n private async readCredential<T extends { issuer?: string }>(\n kind: \"client_info\" | \"tokens\",\n ctx?: OAuthClientInformationContext\n ): Promise<{ key: string; value: T } | undefined> {\n const key = this.credentialKey(kind, ctx);\n const data = await this.store.get(key);\n if (!data && ctx) {\n const legacyKey = this.credentialKey(kind);\n const legacyData = await this.store.get(legacyKey);\n if (legacyData) {\n try {\n const legacyValue = JSON.parse(legacyData) as T;\n if (!legacyValue.issuer || legacyValue.issuer === ctx.issuer) {\n const migratedValue = {\n ...legacyValue,\n issuer: ctx.issuer,\n };\n const migratedData = JSON.stringify(migratedValue);\n await this.store.set(key, migratedData);\n await this.store.set(legacyKey, migratedData);\n return { key, value: migratedValue };\n }\n } catch {\n await this.store.remove(legacyKey);\n }\n }\n return undefined;\n }\n if (!data) return undefined;\n try {\n return { key, value: JSON.parse(data) as T };\n } catch (e) {\n console.warn(\n `[${this.storageKeyPrefix}] Failed to parse ${kind.replace(\"_\", \" \")}:`,\n e\n );\n await this.store.remove(key);\n return undefined;\n }\n }\n\n async tokens(\n ctx?: OAuthClientInformationContext\n ): Promise<StoredOAuthTokens | undefined> {\n return (await this.readCredential<StoredOAuthTokens>(\"tokens\", ctx))?.value;\n }\n\n async saveTokens(\n tokens: StoredOAuthTokens,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n // Persist tokens BEFORE clearing the verifier / last_auth_url so a failed\n // write can't strand the auth flow with no way to recover.\n const serialized = JSON.stringify(tokens);\n await this.store.set(this.credentialKey(\"tokens\", ctx), serialized);\n // The no-context SDK read is the transport's latest bearer token lookup.\n if (ctx) await this.store.set(this.credentialKey(\"tokens\"), serialized);\n await this.store.remove(this.getKey(\"code_verifier\"));\n await this.store.remove(this.getKey(\"last_auth_url\"));\n await this.store.remove(this.getKey(\"last_auth_callback_url\"));\n }\n\n async clientInformation(\n ctx?: OAuthClientInformationContext\n ): Promise<OAuthClientInformation | undefined> {\n if (!this.allowClientSecret) {\n const registeredRedirectUri = await this.store.get(\n this.getKey(\"client_info_redirect_uri\")\n );\n if (registeredRedirectUri !== this.redirectUrl) {\n await this.invalidateCredentials(\"registration\");\n console.info(\n `[${this.storageKeyPrefix}] Re-registering browser OAuth client after its Inspector callback changed or could not be verified.`\n );\n return undefined;\n }\n }\n\n const stored = await this.readCredential<\n OAuthClientInformation & {\n issuer?: string;\n redirect_uris?: string[];\n client_secret?: string;\n }\n >(\"client_info\", ctx);\n if (!stored) return undefined;\n const { key, value: clientInfo } = stored;\n try {\n if (!this.allowClientSecret && clientInfo.client_secret) {\n await this.invalidateCredentials(\"registration\");\n console.warn(\n `[${this.storageKeyPrefix}] Recovered stale browser OAuth credentials containing a client_secret.`\n );\n return undefined;\n }\n const storedRedirectUris = Array.isArray(clientInfo.redirect_uris)\n ? clientInfo.redirect_uris\n : [];\n // Node clients can retain registrations from servers that omit\n // redirect_uris. Browser clients cannot: the same origin may serve both\n // embedded and standalone Inspectors at different callback paths.\n const hasMatchingRedirect =\n (storedRedirectUris.length === 0 && this.allowClientSecret) ||\n storedRedirectUris.includes(this.redirectUrl);\n\n if (!hasMatchingRedirect) {\n console.info(\n `[${this.storageKeyPrefix}] Recovering cached OAuth credentials after a redirect URI change.`\n );\n await this.invalidateCredentials(\"registration\");\n return undefined;\n }\n\n return clientInfo;\n } catch {\n await this.store.remove(key);\n return undefined;\n }\n }\n\n async saveClientInformation(\n clientInformation: OAuthClientInformation,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n const info = clientInformation as OAuthClientInformation & {\n client_secret?: string;\n };\n if (!this.allowClientSecret && info.client_secret) {\n await this.store.remove(this.credentialKey(\"client_info\", ctx));\n if (ctx) await this.store.remove(this.credentialKey(\"client_info\"));\n throw new Error(\n \"Browser OAuth clients must be public clients; client_secret persistence is not allowed.\"\n );\n }\n const persistedClientInformation =\n !this.allowClientSecret &&\n (!(\"redirect_uris\" in clientInformation) ||\n !Array.isArray(\n (clientInformation as { redirect_uris?: unknown }).redirect_uris\n ) ||\n (clientInformation as { redirect_uris: unknown[] }).redirect_uris\n .length === 0)\n ? { ...clientInformation, redirect_uris: [this.redirectUrl] }\n : clientInformation;\n const serialized = JSON.stringify(persistedClientInformation);\n await this.store.set(this.credentialKey(\"client_info\", ctx), serialized);\n if (ctx) {\n await this.store.set(this.credentialKey(\"client_info\"), serialized);\n }\n if (!this.allowClientSecret) {\n await this.store.set(\n this.getKey(\"client_info_redirect_uri\"),\n this.redirectUrl\n );\n }\n }\n\n async saveCodeVerifier(codeVerifier: string): Promise<void> {\n await this.store.set(this.getKey(\"code_verifier\"), codeVerifier);\n }\n\n async codeVerifier(): Promise<string> {\n const key = this.getKey(\"code_verifier\");\n const verifier = await this.store.get(key);\n if (!verifier) {\n throw new Error(\n `[${this.storageKeyPrefix}] Code verifier not found in storage for key ${key}. Auth flow likely corrupted or timed out.`\n );\n }\n return verifier;\n }\n\n async invalidateCredentials(\n scope:\n | \"all\"\n | \"registration\"\n | \"client\"\n | \"tokens\"\n | \"verifier\"\n | \"discovery\"\n ): Promise<void> {\n const removeCredentialKeys = async (\n kind: \"client_info\" | \"tokens\"\n ): Promise<void> => {\n const prefix = `${this.getKey(kind)}_`;\n for (const key of await this.store.keys()) {\n if (key === this.getKey(kind) || key.startsWith(prefix)) {\n await this.store.remove(key);\n }\n }\n };\n\n switch (scope) {\n case \"registration\":\n // The SDK saves freshly discovered issuer metadata before it asks for\n // client information. Preserve that callback-leg binding while\n // replacing stale browser registration and authorization artifacts.\n await removeCredentialKeys(\"tokens\");\n await removeCredentialKeys(\"client_info\");\n await this.store.remove(this.getKey(\"code_verifier\"));\n await this.store.remove(this.getKey(\"last_auth_url\"));\n await this.store.remove(this.getKey(\"last_auth_callback_url\"));\n await this.store.remove(this.getKey(\"client_info_redirect_uri\"));\n await this.store.remove(this.getKey(\"token_endpoint\"));\n break;\n case \"all\":\n await removeCredentialKeys(\"tokens\");\n await removeCredentialKeys(\"client_info\");\n await this.store.remove(this.getKey(\"code_verifier\"));\n await this.store.remove(this.getKey(\"last_auth_url\"));\n await this.store.remove(this.getKey(\"last_auth_callback_url\"));\n await this.store.remove(this.getKey(\"client_info_redirect_uri\"));\n await this.store.remove(this.getKey(\"discovery_state\"));\n await this.store.remove(this.getKey(\"token_endpoint\"));\n break;\n case \"client\":\n await removeCredentialKeys(\"client_info\");\n break;\n case \"tokens\":\n await removeCredentialKeys(\"tokens\");\n break;\n case \"verifier\":\n await this.store.remove(this.getKey(\"code_verifier\"));\n break;\n case \"discovery\":\n await this.store.remove(this.getKey(\"discovery_state\"));\n break;\n default:\n break;\n }\n }\n\n /**\n * Persist the OAuth discovery state (authorization-server metadata resolved\n * during the auth flow). Stored with the same durability as the code\n * verifier so the callback leg can verify it is exchanging the code at the\n * same authorization server the redirect targeted (SEP-2352 mix-up defense).\n */\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this.store.set(this.getKey(\"discovery_state\"), JSON.stringify(state));\n }\n\n /** Return the previously saved discovery state, or `undefined`. */\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n const data = await this.store.get(this.getKey(\"discovery_state\"));\n if (!data) return undefined;\n try {\n return JSON.parse(data) as OAuthDiscoveryState;\n } catch {\n await this.store.remove(this.getKey(\"discovery_state\"));\n return undefined;\n }\n }\n\n // --- Helper / non-SDK methods ---\n\n /**\n * Generates and persists `StoredState` for an authorization request,\n * appends the `state` query param to the URL, and persists the sanitized\n * URL to `last_auth_url` so it can be replayed on popup-blocker fallback.\n *\n * @returns The sanitized authorization URL string with the `state` param appended.\n */\n async storeAuthorizationState(\n authorizationUrl: URL,\n opts: StoreAuthorizationStateOptions = {}\n ): Promise<string> {\n const state = globalThis.crypto.randomUUID();\n const stateKey = `${this.storageKeyPrefix}_${this.serverUrlHash}_state_${state}`;\n\n const stateData: StoredState = {\n serverUrlHash: this.serverUrlHash,\n expiry: Date.now() + 1000 * 60 * 10, // State expires in 10 minutes\n providerOptions: {\n serverUrl: this.serverUrl,\n storageKeyPrefix: this.storageKeyPrefix,\n clientName: this.clientName,\n clientUri: this.clientUri,\n callbackUrl: this.callbackUrl,\n ...(this.clientMetadataUrl\n ? { clientMetadataUrl: this.clientMetadataUrl }\n : {}),\n ...(opts.extraProviderOptions ?? {}),\n },\n flowType: opts.flowType,\n returnUrl: opts.returnUrl,\n };\n\n authorizationUrl.searchParams.set(\"state\", state);\n const sanitizedAuthUrl = sanitizeUrl(authorizationUrl.toString());\n\n // Persist the state record BEFORE the last_auth_url so a partial failure\n // can't leave behind an auth URL whose state has no backing record.\n await this.store.set(stateKey, JSON.stringify(stateData));\n await this.store.set(\n this.getKey(\"last_auth_callback_url\"),\n this.redirectUrl\n );\n await this.store.set(this.getKey(\"last_auth_url\"), sanitizedAuthUrl);\n\n return sanitizedAuthUrl;\n }\n\n /**\n * Return the token endpoint from SDK-managed discovery state. The SDK\n * persists this state during `auth()`, avoiding a second discovery flow.\n */\n async getTokenEndpoint(): Promise<string | null> {\n return (\n (await this.discoveryState())?.authorizationServerMetadata\n ?.token_endpoint ?? null\n );\n }\n\n /**\n * Return the protected-resource URL selected during OAuth discovery.\n * Consumers can persist it and reuse it for server-side refresh exchanges.\n */\n async getResource(): Promise<string | null> {\n const resource = (await this.discoveryState())?.resourceMetadata?.resource;\n return typeof resource === \"string\" ? resource : null;\n }\n}\n","/**\n * URL sanitization utility\n *\n * Sanitizes URLs to prevent security issues by:\n * - Restricting to http/https protocols only\n * - Encoding URL components properly\n * - Validating hostnames\n */\n\n/**\n * Sanitizes a URL string by encoding all components and validating the protocol.\n *\n * @param raw - The raw URL string to sanitize\n * @returns The sanitized URL as a string\n * @throws Error if the URL is invalid or uses an unsupported protocol\n */\nexport function sanitizeUrl(raw: string): string {\n const abort = () => {\n throw new Error(`Invalid url to pass to open(): ${raw}`);\n };\n\n let url!: URL;\n\n try {\n url = new URL(raw);\n } catch (_) {\n abort();\n }\n\n // Don't allow any other scheme than http(s)\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") abort();\n\n // Hostnames can't be updated, but let's reject if they contain anything suspicious\n if (url.hostname !== encodeURIComponent(url.hostname)) abort();\n\n // Forcibly sanitise all the pieces of the URL\n if (url.username) url.username = encodeURIComponent(url.username);\n if (url.password) url.password = encodeURIComponent(url.password);\n url.pathname =\n url.pathname.slice(0, 1) +\n encodeURIComponent(url.pathname.slice(1)).replace(/%2f/gi, \"/\");\n url.search =\n url.search.slice(0, 1) +\n Array.from(url.searchParams.entries()).map(sanitizeParam).join(\"&\");\n url.hash = url.hash.slice(0, 1) + encodeURIComponent(url.hash.slice(1));\n\n return url.href;\n}\n\n/**\n * Helper function to sanitize URL search parameters\n */\nfunction sanitizeParam([k, v]: [string, string]): string {\n return `${encodeURIComponent(k)}${v.length > 0 ? `=${encodeURIComponent(v)}` : \"\"}`;\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/client\";\nimport type { AutoOAuthOptions, CallbackConfig } from \"./config.js\";\nimport { normalizeClientInfo, resolveCallbacks } from \"./config.js\";\nimport type { BaseConnector } from \"../transport/base.js\";\nimport { HttpConnector } from \"../transport/http.js\";\nimport {\n createOAuthProvider,\n type BrowserOAuthOptions,\n} from \"../auth/browser.js\";\nimport { logger } from \"../utils/logging.js\";\nimport { Tel } from \"../telemetry/telemetry-browser.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\nimport { BaseMCPClient } from \"./base.js\";\n\n/**\n * Manages MCP server connections in browsers and other Web API runtimes.\n *\n * The browser client supports HTTP servers and the connection-management\n * operations inherited from its runtime-neutral base client. It does not spawn local\n * processes or read configuration files.\n */\nfunction trackBrowserClientInit(config: Record<string, any>): void {\n const servers = Object.keys(config.mcpServers ?? {});\n Tel.getInstance()\n .trackMCPClientInit({\n codeMode: false,\n sandbox: false,\n allCallbacks: false,\n verify: false,\n servers,\n numServers: servers.length,\n isBrowser: true,\n })\n .catch((e: unknown) =>\n logger.debug(`Failed to track BrowserMCPClient init: ${e}`)\n );\n}\n\nexport class BrowserMCPClient extends BaseMCPClient {\n /**\n * Returns the installed `@mcp-use/client` package version.\n *\n * @returns The package version string.\n */\n public static getPackageVersion(): string {\n return getPackageVersion();\n }\n\n /**\n * Creates a browser MCP client.\n *\n * @param config - Client configuration containing an optional `mcpServers` map.\n */\n constructor(config?: Record<string, any>) {\n super(config);\n trackBrowserClientInit(this.config);\n }\n\n /**\n * Creates a browser client from an inline configuration object.\n *\n * @param cfg - Client configuration containing an optional `mcpServers` map.\n * @returns A browser client initialized with `cfg`.\n */\n public static fromDict(cfg: Record<string, any>): BrowserMCPClient {\n return new BrowserMCPClient(cfg);\n }\n\n protected async createDefaultOAuthProvider(\n serverUrl: string,\n options: AutoOAuthOptions = {}\n ): Promise<OAuthClientProvider> {\n return createOAuthProvider(serverUrl, options as BrowserOAuthOptions);\n }\n\n /**\n * Create a connector from server configuration (Browser version)\n * Supports HTTP connector only\n */\n protected createConnectorFromConfig(\n serverConfig: Record<string, any>\n ): BaseConnector {\n const {\n url,\n headers,\n fetch: configuredFetch,\n authToken,\n authProvider,\n detectMixedAuth,\n wrapTransport,\n clientOptions,\n protocolNegotiation,\n timeout,\n gatewayUrl,\n serverId,\n reconnectionOptions,\n } = serverConfig;\n\n if (!url) {\n throw new Error(\"Server URL is required\");\n }\n\n // Resolve callbacks: per-server overrides global (from config root)\n const globalDefaults = this.config as CallbackConfig;\n const resolved = resolveCallbacks(\n serverConfig as CallbackConfig,\n globalDefaults\n );\n\n // Root clientInfo as fallback when server config omits it\n const clientInfo = normalizeClientInfo(\n serverConfig.clientInfo ?? this.config.clientInfo\n );\n\n // Prepare connector options\n const connectorOptions = {\n headers,\n fetch: configuredFetch ?? globalThis.fetch.bind(globalThis),\n authToken,\n authProvider,\n detectMixedAuth,\n wrapTransport,\n clientOptions,\n onSampling: resolved.onSampling,\n onElicitation: resolved.onElicitation,\n onNotification: resolved.onNotification,\n protocolNegotiation,\n timeout,\n clientInfo,\n gatewayUrl,\n serverId,\n reconnectionOptions,\n };\n\n logger.debug(\n `[BrowserMCPClient] Connector options prepared (clientOptions: ${clientOptions ? \"provided\" : \"none\"})`\n );\n\n return new HttpConnector(url, connectorOptions);\n }\n}\n","/**\n * Cross-compatible telemetry: PostHog via fetch, Web Crypto, feature-detected\n * opt-out. Optional {@link TelemetryStorage} (fs from node entry, localStorage\n * when available) for durable user ids.\n */\nimport { logger } from \"../utils/logging.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\nimport type {\n BaseTelemetryEvent,\n ConnectorInitEventData,\n MCPAgentExecutionEventData,\n MCPClientInitEventData,\n} from \"./events.js\";\nimport {\n ClientAddServerEvent,\n ClientRemoveServerEvent,\n ConnectorInitEvent,\n MCPAgentExecutionEvent,\n MCPClientInitEvent,\n} from \"./events.js\";\nimport { capturePostHog } from \"./tel-fetch.js\";\n\nfunction generateUUID(): string {\n return globalThis.crypto.randomUUID();\n}\n\nfunction secureRandomString(): string {\n const array = new Uint8Array(8);\n globalThis.crypto.getRandomValues(array);\n return Array.from(array, (v) => v.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport type TelemetryStorage = {\n getUserId(): string | null;\n setUserId(id: string): void;\n};\n\ntype RuntimeEnvironment =\n | \"browser\"\n | \"node\"\n | \"cloudflare-workers\"\n | \"edge\"\n | \"deno\"\n | \"bun\"\n | \"unknown\";\n\ntype StorageCapability = \"persistent\" | \"session-only\";\n\nconst USER_ID_STORAGE_KEY = \"mcp_use_user_id\";\nconst PROJECT_API_KEY = \"phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI\";\nconst HOST = \"https://eu.i.posthog.com\";\n\n/** Install before first `getInstance()` — node entry wires fs storage here. */\nlet configuredStorage: TelemetryStorage | null = null;\n\nexport function configureTelemetryStorage(storage: TelemetryStorage): void {\n configuredStorage = storage;\n}\n\nfunction isLocalStorageFunctional(): boolean {\n return (\n typeof localStorage !== \"undefined\" &&\n typeof localStorage.getItem === \"function\" &&\n typeof localStorage.setItem === \"function\" &&\n typeof localStorage.removeItem === \"function\"\n );\n}\n\nfunction createLocalStorageBackend(): TelemetryStorage | null {\n if (!isLocalStorageFunctional()) return null;\n try {\n localStorage.setItem(\"__mcp_use_test__\", \"1\");\n localStorage.removeItem(\"__mcp_use_test__\");\n } catch {\n return null;\n }\n return {\n getUserId() {\n try {\n return localStorage.getItem(USER_ID_STORAGE_KEY);\n } catch {\n return null;\n }\n },\n setUserId(id: string) {\n try {\n localStorage.setItem(USER_ID_STORAGE_KEY, id);\n } catch {\n // ignore\n }\n },\n };\n}\n\nfunction detectRuntimeEnvironment(): RuntimeEnvironment {\n try {\n if (typeof (globalThis as { Bun?: unknown }).Bun !== \"undefined\") {\n return \"bun\";\n }\n if (typeof (globalThis as { Deno?: unknown }).Deno !== \"undefined\") {\n return \"deno\";\n }\n if (\n typeof navigator !== \"undefined\" &&\n navigator.userAgent?.includes(\"Cloudflare-Workers\")\n ) {\n return \"cloudflare-workers\";\n }\n if (\n typeof (globalThis as { EdgeRuntime?: unknown }).EdgeRuntime !==\n \"undefined\"\n ) {\n return \"edge\";\n }\n if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n return \"browser\";\n }\n if (\n typeof process !== \"undefined\" &&\n typeof process.versions?.node !== \"undefined\"\n ) {\n return \"node\";\n }\n return \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction readSourceHint(): string | undefined {\n if (typeof process !== \"undefined\" && process.env?.MCP_USE_TELEMETRY_SOURCE) {\n return process.env.MCP_USE_TELEMETRY_SOURCE;\n }\n try {\n if (isLocalStorageFunctional()) {\n return localStorage.getItem(\"MCP_USE_TELEMETRY_SOURCE\") ?? undefined;\n }\n } catch {\n // ignore\n }\n return undefined;\n}\n\nfunction isTelemetryDisabled(): boolean {\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as { __MCP_USE_ANONYMIZED_TELEMETRY__?: boolean })\n .__MCP_USE_ANONYMIZED_TELEMETRY__ === false\n ) {\n return true;\n }\n if (\n typeof process !== \"undefined\" &&\n process.env?.MCP_USE_ANONYMIZED_TELEMETRY?.toLowerCase() === \"false\"\n ) {\n return true;\n }\n try {\n if (\n isLocalStorageFunctional() &&\n localStorage.getItem(\"MCP_USE_ANONYMIZED_TELEMETRY\") === \"false\"\n ) {\n return true;\n }\n } catch {\n // ignore\n }\n return false;\n}\n\nfunction sessionId(): string {\n try {\n return `session-${generateUUID()}`;\n } catch {\n return `session-${Date.now()}-${secureRandomString()}`;\n }\n}\n\n/**\n * Shared telemetry singleton for node and browser.\n *\n * Usage: `Tel.getInstance().trackMCPClientInit(...)`\n */\nexport class Telemetry {\n private static instance: Telemetry | null = null;\n\n private readonly UNKNOWN_USER_ID = \"UNKNOWN_USER_ID\";\n\n private _currUserId: string | null = null;\n private _telemetryEnabled = false;\n private _pending = new Set<Promise<void>>();\n private _runtimeEnvironment: RuntimeEnvironment;\n private _storageCapability: StorageCapability;\n private _storage: TelemetryStorage | null;\n private _source: string;\n private _productVersion?: string;\n\n private constructor() {\n this._runtimeEnvironment = detectRuntimeEnvironment();\n this._storage = configuredStorage ?? createLocalStorageBackend() ?? null;\n this._storageCapability = this._storage ? \"persistent\" : \"session-only\";\n this._source = readSourceHint() || this._runtimeEnvironment;\n\n const disabled = isTelemetryDisabled();\n const canSupport = this._runtimeEnvironment !== \"unknown\";\n\n if (disabled) {\n this._telemetryEnabled = false;\n logger.debug(\"Telemetry disabled via opt-out\");\n } else if (!canSupport) {\n this._telemetryEnabled = false;\n logger.debug(\n `Telemetry disabled - unknown environment: ${this._runtimeEnvironment}`\n );\n } else {\n logger.debug(\n \"Anonymized telemetry enabled. Set MCP_USE_ANONYMIZED_TELEMETRY=false to disable.\"\n );\n this._telemetryEnabled = true;\n }\n }\n\n get runtimeEnvironment(): RuntimeEnvironment {\n return this._runtimeEnvironment;\n }\n\n get storageCapability(): StorageCapability {\n return this._storageCapability;\n }\n\n static getInstance(): Telemetry {\n if (!Telemetry.instance) {\n Telemetry.instance = new Telemetry();\n }\n return Telemetry.instance;\n }\n\n setSource(source: string): void {\n this._source = source;\n try {\n if (isLocalStorageFunctional()) {\n localStorage.setItem(\"MCP_USE_TELEMETRY_SOURCE\", source);\n }\n } catch {\n // ignore\n }\n logger.debug(`Telemetry source set to: ${source}`);\n }\n\n getSource(): string {\n return this._source;\n }\n\n setProductVersion(version: string): void {\n this._productVersion = version;\n }\n\n get isEnabled(): boolean {\n return this._telemetryEnabled;\n }\n\n get userId(): string {\n if (this._currUserId) return this._currUserId;\n\n try {\n if (this._storage) {\n const existing = this._storage.getUserId();\n if (existing) {\n this._currUserId = existing;\n return existing;\n }\n const id = generateUUID();\n this._storage.setUserId(id);\n this._currUserId = id;\n return id;\n }\n this._currUserId = sessionId();\n } catch {\n this._currUserId = this.UNKNOWN_USER_ID;\n }\n return this._currUserId;\n }\n\n async capture(event: BaseTelemetryEvent): Promise<void> {\n if (!this._telemetryEnabled) return;\n\n const currentUserId = this.userId;\n const properties: Record<string, unknown> = {\n ...event.properties,\n mcp_use_version: this._productVersion ?? getPackageVersion(),\n language: \"typescript\",\n source: this._source,\n runtime: this._runtimeEnvironment,\n };\n\n const p = capturePostHog({\n host: HOST,\n apiKey: PROJECT_API_KEY,\n event: event.name,\n distinctId: currentUserId,\n properties,\n });\n this._pending.add(p);\n void p.finally(() => this._pending.delete(p));\n }\n\n async trackAgentExecution(data: MCPAgentExecutionEventData): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new MCPAgentExecutionEvent(data));\n }\n\n async trackMCPClientInit(data: MCPClientInitEventData): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new MCPClientInitEvent(data));\n }\n\n async trackConnectorInit(data: ConnectorInitEventData): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new ConnectorInitEvent(data));\n }\n\n async trackClientAddServer(\n serverName: string,\n serverConfig: Record<string, any>\n ): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new ClientAddServerEvent({ serverName, serverConfig }));\n }\n\n async trackClientRemoveServer(serverName: string): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new ClientRemoveServerEvent({ serverName }));\n }\n\n async trackUseMcpConnection(data: {\n url: string;\n transportType: string;\n success: boolean;\n errorType?: string | null;\n connectionTimeMs?: number | null;\n hasOAuth: boolean;\n hasSampling: boolean;\n hasElicitation: boolean;\n }): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture({\n name: \"usemcp_connection\",\n properties: {\n url_domain: new URL(data.url).hostname,\n transport_type: data.transportType,\n success: data.success,\n error_type: data.errorType ?? null,\n connection_time_ms: data.connectionTimeMs ?? null,\n has_oauth: data.hasOAuth,\n has_sampling: data.hasSampling,\n has_elicitation: data.hasElicitation,\n },\n });\n }\n\n async trackUseMcpToolCall(data: {\n toolName: string;\n success: boolean;\n errorType?: string | null;\n executionTimeMs?: number | null;\n }): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture({\n name: \"usemcp_tool_call\",\n properties: {\n tool_name: data.toolName,\n success: data.success,\n error_type: data.errorType ?? null,\n execution_time_ms: data.executionTimeMs ?? null,\n },\n });\n }\n\n async trackUseMcpResourceRead(data: {\n resourceUri: string;\n success: boolean;\n errorType?: string | null;\n }): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture({\n name: \"usemcp_resource_read\",\n properties: {\n resource_uri_scheme: data.resourceUri.split(\":\")[0],\n success: data.success,\n error_type: data.errorType ?? null,\n },\n });\n }\n\n identify(userId: string, properties?: Record<string, unknown>): void {\n this._currUserId = userId;\n this._storage?.setUserId(userId);\n if (this._telemetryEnabled) {\n void capturePostHog({\n host: HOST,\n apiKey: PROJECT_API_KEY,\n event: \"$identify\",\n distinctId: userId,\n properties: { $set: properties ?? {} },\n });\n }\n }\n\n reset(): void {\n this._currUserId = null;\n }\n\n flush(): void {\n void Promise.allSettled([...this._pending]);\n }\n\n async shutdown(): Promise<void> {\n try {\n await Promise.allSettled([...this._pending]);\n logger.debug(\"Telemetry fetch captures flushed\");\n } catch (e) {\n logger.debug(`Error flushing telemetry captures: ${e}`);\n }\n }\n}\n\n/**\n * Backward-compatible name for {@link Telemetry}.\n *\n * @alias\n */\nexport const Tel = Telemetry;\n\nexport function setTelemetrySource(source: string): void {\n Tel.getInstance().setSource(source);\n}\n\nexport function setProductVersion(version: string): void {\n Tel.getInstance().setProductVersion(version);\n}\n","export abstract class BaseTelemetryEvent {\n abstract get name(): string;\n abstract get properties(): Record<string, any>;\n}\n\n// ============================================================================\n// MCPAgentExecutionEvent\n// ============================================================================\n\nexport interface MCPAgentExecutionEventData {\n // Execution method and context\n executionMethod: string; // \"run\" or \"astream\"\n query: string; // The actual user query\n success: boolean;\n\n // Agent configuration\n modelProvider: string;\n modelName: string;\n serverCount: number;\n serverIdentifiers: Array<Record<string, string>>;\n totalToolsAvailable: number;\n toolsAvailableNames: string[];\n maxStepsConfigured: number;\n memoryEnabled: boolean;\n useServerManager: boolean;\n\n // Execution PARAMETERS\n maxStepsUsed: number | null;\n manageConnector: boolean;\n externalHistoryUsed: boolean;\n\n // Execution results\n stepsTaken?: number | null;\n toolsUsedCount?: number | null;\n toolsUsedNames?: string[] | null;\n response?: string | null; // The actual response\n executionTimeMs?: number | null;\n errorType?: string | null;\n\n // Context\n conversationHistoryLength?: number | null;\n}\n\nexport class MCPAgentExecutionEvent extends BaseTelemetryEvent {\n constructor(private data: MCPAgentExecutionEventData) {\n super();\n }\n\n get name(): string {\n return \"mcp_agent_execution\";\n }\n\n get properties(): Record<string, any> {\n return {\n // Core execution info\n execution_method: this.data.executionMethod,\n query_length: this.data.query.length,\n success: this.data.success,\n // Agent configuration\n model_provider: this.data.modelProvider,\n model_name: this.data.modelName,\n server_count: this.data.serverCount,\n total_tools_available: this.data.totalToolsAvailable,\n max_steps_configured: this.data.maxStepsConfigured,\n memory_enabled: this.data.memoryEnabled,\n use_server_manager: this.data.useServerManager,\n // Execution parameters (always include, even if null)\n max_steps_used: this.data.maxStepsUsed,\n manage_connector: this.data.manageConnector,\n external_history_used: this.data.externalHistoryUsed,\n // Execution results (always include, even if null)\n steps_taken: this.data.stepsTaken ?? null,\n tools_used_count: this.data.toolsUsedCount ?? null,\n response_length: this.data.response ? this.data.response.length : null,\n execution_time_ms: this.data.executionTimeMs ?? null,\n error_type: this.data.errorType ?? null,\n conversation_history_length: this.data.conversationHistoryLength ?? null,\n };\n }\n}\n\n// ============================================================================\n// MCPClientInitEvent\n// ============================================================================\n\nexport interface MCPClientInitEventData {\n codeMode: boolean;\n sandbox: boolean;\n allCallbacks: boolean;\n verify: boolean;\n servers: string[];\n numServers: number;\n isBrowser: boolean; // true for BrowserMCPClient, false for Node.js MCPClient\n}\n\nexport class MCPClientInitEvent extends BaseTelemetryEvent {\n constructor(private data: MCPClientInitEventData) {\n super();\n }\n\n get name(): string {\n return \"mcpclient_init\";\n }\n\n get properties(): Record<string, any> {\n return {\n code_mode: this.data.codeMode,\n sandbox: this.data.sandbox,\n all_callbacks: this.data.allCallbacks,\n verify: this.data.verify,\n servers: this.data.servers,\n num_servers: this.data.numServers,\n is_browser: this.data.isBrowser,\n };\n }\n}\n\n// ============================================================================\n// ConnectorInitEvent\n// ============================================================================\n\nexport interface ConnectorInitEventData {\n connectorType: string;\n serverCommand?: string | null;\n serverArgs?: string[] | null;\n serverUrl?: string | null;\n publicIdentifier?: string | null;\n}\n\nexport class ConnectorInitEvent extends BaseTelemetryEvent {\n constructor(private data: ConnectorInitEventData) {\n super();\n }\n\n get name(): string {\n return \"connector_init\";\n }\n\n get properties(): Record<string, any> {\n return {\n connector_type: this.data.connectorType,\n server_command: this.data.serverCommand ?? null,\n server_args: this.data.serverArgs ?? null,\n server_url: this.data.serverUrl ?? null,\n public_identifier: this.data.publicIdentifier ?? null,\n };\n }\n}\n\n// ============================================================================\n// ClientAddServerEvent\n// ============================================================================\n\n/**\n * Raw input data for tracking server addition.\n * The event class will extract the necessary properties.\n */\ninterface ClientAddServerEventInput {\n serverName: string;\n serverConfig: Record<string, any>;\n}\n\nexport class ClientAddServerEvent extends BaseTelemetryEvent {\n constructor(private data: ClientAddServerEventInput) {\n super();\n }\n\n get name(): string {\n return \"client_add_server\";\n }\n\n get properties(): Record<string, any> {\n const { serverName, serverConfig } = this.data;\n const url = serverConfig.url;\n\n return {\n server_name: serverName,\n server_url_domain: url ? this._extractHostname(url) : null,\n transport: serverConfig.transport ?? null,\n has_auth: !!(serverConfig.authToken || serverConfig.authProvider),\n };\n }\n\n private _extractHostname(url: string): string | null {\n try {\n return new URL(url).hostname;\n } catch {\n return null;\n }\n }\n}\n\n// ============================================================================\n// ClientRemoveServerEvent\n// ============================================================================\n\n/**\n * Raw input data for tracking server removal.\n */\ninterface ClientRemoveServerEventInput {\n serverName: string;\n}\n\nexport class ClientRemoveServerEvent extends BaseTelemetryEvent {\n constructor(private data: ClientRemoveServerEventInput) {\n super();\n }\n\n get name(): string {\n return \"client_remove_server\";\n }\n\n get properties(): Record<string, any> {\n return {\n server_name: this.data.serverName,\n };\n }\n}\n","/**\n * Fire-and-forget telemetry HTTP request. Never surfaces network/HTTP failures\n * to the host app — telemetry must not log or throw into user code.\n */\nexport async function telFetch(url: string, init?: RequestInit): Promise<void> {\n try {\n await fetch(url, init);\n } catch {\n // Telemetry must never break or log into the host app.\n }\n}\n\nexport const POSTHOG_HOST = \"https://eu.i.posthog.com\";\nexport const POSTHOG_API_KEY =\n \"phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI\";\n\nconst CONTENT_PROPERTY =\n /(^|_)(arguments?|args|body|command|headers?|location|message|query|response|secret|subject|token|uri|url|user_agent)(_|$)/i;\nconst IDENTIFYING_PROPERTY =\n /(^|_)(server_identifiers?|server_names?|servers|tool_names?|tools_(available|used)_names)(_|$)/i;\nconst AGGREGATE_PROPERTY =\n /(_count|_length|_duration(?:_ms)?|_time_ms|(^|_)num_[a-z0-9_]+)$/i;\n\nfunction normalizePropertyKey(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replace(/[^a-z0-9_$]+/gi, \"_\")\n .toLowerCase();\n}\n\nfunction sanitizeValue(value: unknown, seen: WeakSet<object>): unknown {\n if (Array.isArray(value)) {\n if (seen.has(value)) {\n throw new TypeError(\"Cyclic telemetry properties are not supported\");\n }\n seen.add(value);\n const sanitized = value.map((item) => sanitizeValue(item, seen));\n seen.delete(value);\n return sanitized;\n }\n\n if (\n value !== null &&\n typeof value === \"object\" &&\n (Object.getPrototypeOf(value) === Object.prototype ||\n Object.getPrototypeOf(value) === null)\n ) {\n if (seen.has(value)) {\n throw new TypeError(\"Cyclic telemetry properties are not supported\");\n }\n seen.add(value);\n const sanitized = sanitizeProperties(\n value as Record<string, unknown>,\n seen\n );\n seen.delete(value);\n return sanitized;\n }\n\n return value;\n}\n\nfunction sanitizeProperties(\n properties: Record<string, unknown>,\n seen = new WeakSet<object>()\n): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(properties)) {\n const normalizedKey = normalizePropertyKey(key);\n if (AGGREGATE_PROPERTY.test(normalizedKey)) {\n if (value === null || typeof value === \"number\") {\n sanitized[key] = value;\n }\n continue;\n }\n if (\n IDENTIFYING_PROPERTY.test(normalizedKey) ||\n CONTENT_PROPERTY.test(normalizedKey)\n ) {\n continue;\n }\n sanitized[key] = sanitizeValue(value, seen);\n }\n return sanitized;\n}\n\n/**\n * Send a single event to PostHog's public capture endpoint using `fetch` only\n * (no `posthog-js` / `posthog-node` SDK dependency). Errors are swallowed.\n */\nexport async function capturePostHog(params: {\n host?: string;\n apiKey?: string;\n event: string;\n distinctId: string;\n properties: Record<string, unknown>;\n}): Promise<void> {\n try {\n const host = params.host ?? POSTHOG_HOST;\n const apiKey = params.apiKey ?? POSTHOG_API_KEY;\n const body = JSON.stringify({\n api_key: apiKey,\n event: params.event,\n distinct_id: params.distinctId,\n properties: sanitizeProperties(params.properties),\n timestamp: new Date().toISOString(),\n });\n await telFetch(`${host}/i/v0/e/`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n keepalive: true,\n body,\n });\n } catch {\n // Invalid telemetry data must never surface into host application code.\n }\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/client\";\nimport type { BaseConnector } from \"../transport/base.js\";\nimport type {\n AutoOAuthOptions,\n HttpServerConfig,\n MCPClientConfigShape,\n ServerConfig,\n} from \"./config.js\";\nimport { shouldAutoProvisionOAuth } from \"./config.js\";\nimport { completeOAuthFlow, isUnauthorized } from \"../auth/flow.js\";\nimport { logger } from \"../utils/logging.js\";\nimport { MCPSession } from \"./session.js\";\nimport type { MCPConnection } from \"./session.js\";\nimport {\n trackClientAddServer,\n trackClientRemoveServer,\n} from \"../telemetry/client-telemetry.js\";\n\nfunction isOAuthClientProvider(\n provider: unknown\n): provider is OAuthClientProvider {\n return (\n !!provider &&\n typeof provider === \"object\" &&\n \"redirectUrl\" in provider &&\n \"clientMetadata\" in provider\n );\n}\n\n/**\n * Base MCPClient class with shared functionality across all environments.\n *\n * This abstract class provides the core client logic for managing MCP servers,\n * sessions, and configurations. It works in both Node.js and browser environments\n * by delegating platform-specific operations to concrete implementations.\n *\n * Platform-specific implementations such as the Node.js `MCPClient` should\n * extend this class and override the abstract {@link createConnectorFromConfig}\n * method to provide environment-specific connector creation.\n *\n * @example\n * ```typescript\n * // Typically used through concrete implementations\n * import { MCPClient } from \"@mcp-use/client\";\n *\n * const client = new MCPClient({\n * mcpServers: {\n * 'my-server': {\n * command: 'node',\n * args: ['server.js']\n * }\n * }\n * });\n * ```\n *\n * @see {@link MCPSession} for session management\n */\nexport abstract class BaseMCPClient {\n /**\n * Internal configuration object containing MCP server definitions.\n */\n protected config: MCPClientConfigShape = {};\n\n /**\n * Map of server names to their active sessions.\n */\n protected sessions: Record<string, MCPSession> = {};\n\n /**\n * List of server names that have active sessions.\n * This array is kept in sync with the sessions map and can be used\n * to iterate over active connections.\n *\n * @example\n * ```typescript\n * console.log(`Active servers: ${client.activeSessions.join(', ')}`);\n * ```\n */\n public activeSessions: string[] = [];\n\n /**\n * Creates a new BaseMCPClient instance.\n *\n * @param config - Optional configuration object with MCP server definitions\n *\n * @example\n * ```typescript\n * const client = new MCPClient({\n * mcpServers: {\n * 'example': {\n * command: 'node',\n * args: ['server.js']\n * }\n * }\n * });\n * ```\n */\n constructor(config?: MCPClientConfigShape) {\n if (config) {\n this.config = config;\n }\n }\n\n /**\n * Creates a client instance from a configuration dictionary.\n *\n * This static factory method must be implemented by concrete subclasses\n * to provide proper type information and platform-specific initialization.\n *\n * @param _cfg - Configuration dictionary\n * @returns Client instance\n * @throws If called on the base class instead of a concrete implementation\n *\n * @example\n * ```typescript\n * const client = MCPClient.fromDict({\n * mcpServers: {\n * 'my-server': { command: 'node', args: ['server.js'] }\n * }\n * });\n * ```\n */\n public static fromDict(_cfg: MCPClientConfigShape): BaseMCPClient {\n // This will be overridden by concrete implementations\n throw new Error(\"fromDict must be implemented by concrete class\");\n }\n\n /**\n * Adds a new MCP server configuration to the client.\n *\n * This method adds or updates a server configuration dynamically without\n * needing to restart the client. The server can then be used to create\n * new sessions.\n *\n * @param name - Unique name for the server\n * @param serverConfig - Server configuration object (connector type, command, args, etc.)\n *\n * @example\n * ```typescript\n * client.addServer('new-server', {\n * command: 'python',\n * args: ['server.py']\n * });\n *\n * // Now you can create a session\n * const session = await client.createSession('new-server');\n * ```\n *\n * @see {@link removeServer} for removing servers\n * @see {@link getServerConfig} for retrieving configurations\n */\n public addServer(name: string, serverConfig: ServerConfig): void {\n this.config.mcpServers = this.config.mcpServers || {};\n this.config.mcpServers[name] = serverConfig;\n trackClientAddServer(name, serverConfig);\n }\n\n /**\n * Removes an MCP server configuration from the client.\n *\n * This method removes a server configuration and cleans up any active\n * sessions associated with that server. If there's an active session,\n * it will be removed from the active sessions list.\n *\n * @param name - Name of the server to remove\n *\n * @example\n * ```typescript\n * // Remove a server configuration\n * await client.removeServer('old-server');\n *\n * // The server name will no longer appear in getServerNames()\n * console.log(client.getServerNames()); // 'old-server' is gone\n * ```\n *\n * @see {@link addServer} for adding servers\n * @see {@link closeSession} for properly closing sessions before removal\n */\n public async removeServer(name: string): Promise<void> {\n if (!this.config.mcpServers?.[name]) return;\n\n await this.closeSession(name);\n delete this.config.mcpServers[name];\n trackClientRemoveServer(name);\n }\n\n /**\n * Gets the names of all configured MCP servers.\n *\n * @returns Array of server names defined in the configuration\n *\n * @example\n * ```typescript\n * const serverNames = client.getServerNames();\n * console.log(`Configured servers: ${serverNames.join(', ')}`);\n *\n * // Create sessions for all servers\n * for (const name of serverNames) {\n * await client.createSession(name);\n * }\n * ```\n *\n * @see {@link activeSessions} for servers with active sessions\n */\n public getServerNames(): string[] {\n return Object.keys(this.config.mcpServers ?? {});\n }\n\n /**\n * Gets the configuration for a specific MCP server.\n *\n * @param name - Name of the server\n * @returns Server configuration object, or undefined if not found\n *\n * @example\n * ```typescript\n * const config = client.getServerConfig('my-server');\n * if (config) {\n * console.log(`Command: ${config.command}`);\n * console.log(`Args: ${config.args.join(' ')}`);\n * }\n * ```\n *\n * @see {@link getConfig} for retrieving the entire configuration\n */\n public getServerConfig(name: string): ServerConfig | undefined {\n return this.config.mcpServers?.[name];\n }\n\n /**\n * Gets the complete client configuration.\n *\n * @returns Complete configuration object including all server definitions\n *\n * @example\n * ```typescript\n * const config = client.getConfig();\n * console.log(`Total servers: ${Object.keys(config.mcpServers).length}`);\n * ```\n *\n * @see {@link getServerConfig} for retrieving individual server configurations\n */\n public getConfig(): MCPClientConfigShape {\n return this.config ?? {};\n }\n\n /**\n * Creates a connector from server configuration.\n *\n * This abstract method must be implemented by platform-specific subclasses\n * to create the appropriate connector type (Stdio, HTTP, WebSocket, etc.)\n * based on the server configuration and runtime environment.\n *\n * @param serverConfig - Server configuration object\n * @returns Platform-specific connector instance\n */\n protected abstract createConnectorFromConfig(\n serverConfig: ServerConfig\n ): BaseConnector | Promise<BaseConnector>;\n\n /**\n * Platform OAuth provider used when an HTTP server has no bearer token /\n * `authProvider`. Node and browser entries implement this via their\n * `createOAuthProvider` export.\n */\n protected abstract createDefaultOAuthProvider(\n serverUrl: string,\n options?: AutoOAuthOptions\n ): Promise<OAuthClientProvider>;\n\n /**\n * Creates a new session for connecting to an MCP server.\n *\n * @deprecated Use {@link connect}; modern MCP servers are sessionless.\n *\n * This method initializes a connection to the specified server using the\n * configuration provided during client construction. Sessions manage the\n * lifecycle of connections and provide methods for calling tools, listing\n * resources, and more.\n *\n * If a session already exists for the server, it will be replaced with a new one.\n *\n * @param serverName - The name of the server as defined in the client configuration\n * @param autoInitialize - Whether to automatically initialize the session (default: true)\n * @returns A promise that resolves to the created MCPSession instance\n * @throws If the server is not found in the configuration\n *\n * @example\n * ```typescript\n * // Create and initialize a session\n * const session = await client.createSession('my-server');\n * const tools = await session.listTools();\n *\n * // Create without auto-initialization\n * const session = await client.createSession('my-server', false);\n * await session.connect();\n * await session.initialize();\n * ```\n *\n * @see {@link MCPSession} for session management methods\n * @see {@link closeSession} for closing sessions\n * @see {@link getSession} for retrieving existing sessions\n */\n public async createSession(\n serverName: string,\n autoInitialize = true\n ): Promise<MCPSession> {\n const servers = this.config.mcpServers ?? {};\n\n if (Object.keys(servers).length === 0) {\n logger.warn(\"No MCP servers defined in config\");\n }\n\n if (!servers[serverName]) {\n throw new Error(`Server '${serverName}' not found in config`);\n }\n\n let serverConfig: ServerConfig = { ...servers[serverName] };\n let oauthProvider: OAuthClientProvider | undefined;\n\n if (shouldAutoProvisionOAuth(serverConfig)) {\n const oauthOptions =\n serverConfig.oauth === false ? undefined : (serverConfig.oauth ?? {});\n oauthProvider = await this.createDefaultOAuthProvider(\n serverConfig.url,\n oauthOptions\n );\n serverConfig = {\n ...serverConfig,\n authProvider: oauthProvider,\n };\n } else if (\n \"authProvider\" in serverConfig &&\n serverConfig.authProvider &&\n isOAuthClientProvider(serverConfig.authProvider)\n ) {\n oauthProvider = serverConfig.authProvider;\n }\n\n const openSession = async (): Promise<MCPSession> => {\n const connector = await Promise.resolve(\n this.createConnectorFromConfig(serverConfig)\n );\n const session = new MCPSession(connector);\n if (autoInitialize) {\n await session.initialize();\n }\n return session;\n };\n\n let session: MCPSession;\n try {\n session = await openSession();\n } catch (err) {\n const httpConfig = serverConfig as HttpServerConfig;\n if (\n !autoInitialize ||\n !oauthProvider ||\n !(\"url\" in httpConfig) ||\n !isUnauthorized(err)\n ) {\n throw err;\n }\n if (\n (\n oauthProvider as OAuthClientProvider & {\n preventAutoAuth?: boolean;\n }\n ).preventAutoAuth\n ) {\n throw err;\n }\n logger.info(\n `[MCPClient] Unauthorized connecting to '${serverName}'; completing OAuth…`\n );\n await completeOAuthFlow(oauthProvider, httpConfig.url);\n session = await openSession();\n }\n\n this.sessions[serverName] = session;\n if (!this.activeSessions.includes(serverName)) {\n this.activeSessions.push(serverName);\n }\n return session;\n }\n\n /**\n * Connect to a configured MCP server and return a ready, protocol-neutral\n * connection.\n *\n * The returned connection represents either a legacy sessionful server or a\n * modern sessionless server uniformly. Inspect {@link MCPConnection.info} for\n * the negotiated protocol version and normalized server metadata.\n *\n * @param serverName - The configured server name.\n */\n public async connect(serverName: string): Promise<MCPConnection> {\n return this.createSession(serverName);\n }\n\n /**\n * Creates sessions for all configured MCP servers.\n *\n * This is a convenience method that iterates through all servers in the\n * configuration and creates a session for each one. Sessions are created\n * sequentially to avoid overwhelming the system.\n *\n * @param autoInitialize - Whether to automatically initialize each session (default: true)\n * @returns A promise that resolves to a map of server names to sessions\n *\n * @example\n * ```typescript\n * // Create sessions for all configured servers\n * const sessions = await client.createAllSessions();\n * console.log(`Created ${Object.keys(sessions).length} sessions`);\n *\n * // List tools from all servers\n * for (const [name, session] of Object.entries(sessions)) {\n * const tools = await session.listTools();\n * console.log(`${name}: ${tools.length} tools`);\n * }\n * ```\n *\n * @see {@link createSession} for creating individual sessions\n * @see {@link closeAllSessions} for closing all sessions\n */\n public async createAllSessions(\n autoInitialize = true\n ): Promise<Record<string, MCPSession>> {\n const servers = this.config.mcpServers ?? {};\n\n if (Object.keys(servers).length === 0) {\n logger.warn(\"No MCP servers defined in config\");\n }\n\n for (const name of Object.keys(servers)) {\n await this.createSession(name, autoInitialize);\n }\n\n return this.sessions;\n }\n\n /**\n * Connect to every configured server sequentially.\n *\n * Each result uses the same {@link MCPConnection} API regardless of whether\n * the negotiated protocol is legacy/sessionful or modern/sessionless.\n */\n public async connectAll(): Promise<Record<string, MCPConnection>> {\n return this.createAllSessions();\n }\n\n /**\n * Retrieves an existing session by server name.\n *\n * This method returns null if no session exists, making it safe for\n * checking session existence without throwing errors.\n *\n * @param serverName - Name of the server\n * @returns The session instance or null if not found\n *\n * @example\n * ```typescript\n * const session = client.getSession('my-server');\n * if (session) {\n * const tools = await session.listTools();\n * } else {\n * console.log('Session not found, creating...');\n * await client.createSession('my-server');\n * }\n * ```\n *\n * @see {@link requireSession} for getting a session that throws if not found\n * @see {@link createSession} for creating sessions\n */\n public getSession(serverName: string): MCPSession | null {\n const session = this.sessions[serverName];\n if (!session) {\n return null;\n }\n return session;\n }\n\n /**\n * Retrieves an existing session by server name, throwing if not found.\n *\n * This method is useful when you need to ensure a session exists before\n * proceeding. It throws a descriptive error if the session is not found.\n *\n * @param serverName - Name of the server\n * @returns The session instance\n * @throws If the session is not found\n *\n * @example\n * ```typescript\n * try {\n * const session = client.requireSession('my-server');\n * const tools = await session.listTools();\n * } catch (error) {\n * console.error('Session not found:', error.message);\n * }\n * ```\n *\n * @see {@link getSession} for a null-returning alternative\n * @see {@link createSession} for creating sessions\n */\n public requireSession(serverName: string): MCPSession {\n const session = this.sessions[serverName];\n if (!session) {\n throw new Error(\n `Session '${serverName}' not found. Available sessions: ${this.activeSessions.join(\", \") || \"none\"}`\n );\n }\n return session;\n }\n\n /**\n * Gets all active sessions as a map of server names to sessions.\n *\n * @returns Map of server names to their active sessions\n *\n * @example\n * ```typescript\n * const sessions = client.getAllActiveSessions();\n *\n * // Iterate over all active sessions\n * for (const [name, session] of Object.entries(sessions)) {\n * console.log(`Server: ${name}`);\n * const tools = await session.listTools();\n * console.log(` Tools: ${tools.length}`);\n * }\n * ```\n *\n * @see {@link activeSessions} for just the list of server names\n * @see {@link getSession} for retrieving individual sessions\n */\n public getAllActiveSessions(): Record<string, MCPSession> {\n return Object.fromEntries(\n this.activeSessions.map((n) => [n, this.sessions[n]])\n );\n }\n\n /**\n * Closes a session and cleans up its resources.\n *\n * This method gracefully disconnects from the server and removes the\n * session from the active sessions list. It's safe to call even if\n * the session doesn't exist.\n *\n * @param serverName - Name of the server whose session should be closed\n *\n * @example\n * ```typescript\n * // Close a specific session\n * await client.closeSession('my-server');\n *\n * // Verify it's closed\n * console.log(client.activeSessions.includes('my-server')); // false\n * ```\n *\n * @see {@link closeAllSessions} for closing all sessions at once\n * @see {@link createSession} for creating new sessions\n */\n public async closeSession(serverName: string): Promise<void> {\n const session = this.sessions[serverName];\n if (!session) {\n logger.warn(\n `No session exists for server ${serverName}, nothing to close`\n );\n return;\n }\n try {\n logger.debug(`Closing session for server ${serverName}`);\n await session.disconnect();\n } catch (e) {\n logger.error(`Error closing session for server '${serverName}': ${e}`);\n } finally {\n // Only remove the slot if it still references the session we captured.\n // A parallel createSession() (e.g. URL/env change in useMcp) may have\n // written a new session here while we were awaiting `session.disconnect()`;\n // wiping that would leave consumers with `getSession() === null` and\n // surface as \"No active session found\".\n if (this.sessions[serverName] === session) {\n delete this.sessions[serverName];\n this.activeSessions = this.activeSessions.filter(\n (n) => n !== serverName\n );\n }\n }\n }\n\n /**\n * Closes all active sessions and cleans up their resources.\n *\n * This method iterates through all sessions and attempts to close each one\n * gracefully. If any session fails to close, the error is logged but the\n * method continues to close remaining sessions.\n *\n * This is particularly useful for cleanup on application shutdown.\n *\n * @example\n * ```typescript\n * // Clean shutdown\n * try {\n * await client.closeAllSessions();\n * console.log('All sessions closed successfully');\n * } catch (error) {\n * console.error('Error during cleanup:', error);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Use in application shutdown handler\n * process.on('SIGINT', async () => {\n * console.log('Shutting down...');\n * await client.closeAllSessions();\n * process.exit(0);\n * });\n * ```\n *\n * @see {@link closeSession} for closing individual sessions\n * @see {@link createAllSessions} for creating sessions\n */\n public async closeAllSessions(): Promise<void> {\n const serverNames = Object.keys(this.sessions);\n const errors: string[] = [];\n for (const serverName of serverNames) {\n try {\n logger.debug(`Closing session for server ${serverName}`);\n await this.closeSession(serverName);\n } catch (e: any) {\n const errorMsg = `Failed to close session for server '${serverName}': ${e}`;\n logger.error(errorMsg);\n errors.push(errorMsg);\n }\n }\n if (errors.length) {\n logger.error(\n `Encountered ${errors.length} errors while closing sessions`\n );\n } else {\n logger.debug(\"All sessions closed successfully\");\n }\n }\n\n /** Close every active MCP connection. */\n public async close(): Promise<void> {\n await this.closeAllSessions();\n }\n}\n","import type {\n CallToolResult,\n CompleteRequestParams,\n CompleteResult,\n MetaObject,\n Notification,\n ProtocolEra,\n RequestOptions,\n Root,\n Tool,\n} from \"@modelcontextprotocol/client\";\nimport type { BaseConnector, NotificationHandler } from \"../transport/base.js\";\n\n/** Negotiated protocol era: `\"legacy\"` or `\"modern\"`. */\nexport type MCPProtocolEra = ProtocolEra;\n\n/** OAuth availability inferred after an anonymous MCP connection succeeds. */\nexport interface MCPAuthorizationInfo {\n /** Mixed auth means public MCP operations succeeded while OAuth is available. */\n mode: \"mixed\";\n /** Whether this client currently has OAuth access tokens. */\n authenticated: boolean;\n /** Canonical protected-resource identifier from RFC 9728 metadata. */\n resource?: string;\n /** Scopes advertised by the protected resource, when provided. */\n scopesSupported?: string[];\n}\n\n/**\n * Server information normalized across legacy sessionful and modern sessionless\n * MCP protocols.\n */\nexport interface MCPServerInfo {\n /** Stable server name. */\n name: string;\n /** Server version reported during initialization. */\n version?: string;\n /** Optional human-readable server title. */\n title?: string;\n /** Optional human-readable server description. */\n description?: string;\n /** Public website describing the server. */\n websiteUrl?: string;\n /** Icons advertised by the server. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n}\n\n/**\n * Connection metadata available after the MCP SDK has negotiated a protocol.\n *\n * `extensions` retains protocol-specific extensions without requiring\n * callers to branch on the negotiated era.\n */\nexport interface MCPConnectionInfo {\n /** Negotiated protocol era. */\n protocolEra: MCPProtocolEra;\n /** Negotiated MCP protocol version. */\n protocolVersion: string;\n /** Server identity reported during negotiation, when provided. */\n server?: MCPServerInfo;\n /** Capabilities advertised by the server. */\n capabilities: Record<string, unknown>;\n /** Instructions advertised by the server. */\n instructions?: string;\n /** Protocol extension metadata advertised by the server. */\n extensions: Record<string, unknown>;\n /** Optional OAuth state discovered without forcing authentication. */\n authorization?: MCPAuthorizationInfo;\n}\n\n/**\n * A ready connection to an MCP server.\n *\n * The connection has the same public API for legacy, sessionful MCP servers\n * and modern, sessionless MCP servers. The underlying SDK owns the lifecycle\n * distinction and protocol negotiation.\n *\n * Sessions handle:\n * - Connection lifecycle (connect, disconnect, initialize)\n * - Tool invocation\n * - Resource access\n * - Prompt retrieval\n * - Notification handling\n * - Root directory management\n *\n * Sessions are typically created by `MCPClient.createSession()` rather than\n * being instantiated directly.\n *\n * @example\n * ```typescript\n * // Create via client\n * const client = new MCPClient('./config.json');\n * const session = await client.createSession('my-server');\n *\n * // Use the session\n * const tools = await session.listTools();\n * const result = await session.callTool('my-tool', { arg: 'value' });\n * ```\n *\n * @example\n * ```typescript\n * // Manual creation (advanced)\n * import { StdioConnector } from \"@mcp-use/client\";\n *\n * const connector = new StdioConnector({\n * command: 'node',\n * args: ['server.js']\n * });\n * const session = new MCPSession(connector);\n * await session.initialize();\n * ```\n *\n * @see {@link BaseConnector} for connector implementations\n */\nexport class MCPConnection {\n /**\n * The underlying connector managing the transport layer.\n * This is the Stdio, HTTP, or WebSocket connector handling actual communication.\n */\n readonly connector: BaseConnector;\n\n /**\n * Whether to automatically connect when initializing.\n * @internal\n */\n private autoConnect: boolean;\n\n /**\n * Creates a new MCP session.\n *\n * @param connector - The connector to use for communication (Stdio, HTTP, WebSocket)\n * @param autoConnect - Whether to automatically connect during initialization (default: true)\n *\n * @example\n * ```typescript\n * const connector = new HttpConnector({ url: 'http://localhost:3000/mcp' });\n * const session = new MCPSession(connector);\n * await session.initialize(); // Auto-connects and initializes\n * ```\n *\n * @example\n * ```typescript\n * // Manual connection control\n * const session = new MCPSession(connector, false);\n * await session.connect();\n * await session.initialize();\n * ```\n */\n constructor(connector: BaseConnector, autoConnect = true) {\n this.connector = connector;\n this.autoConnect = autoConnect;\n }\n\n /**\n * Establishes the connection to the MCP server.\n *\n * This method starts the underlying transport (spawns process for Stdio,\n * opens WebSocket, etc.) but does not perform the MCP initialization\n * handshake. Call {@link initialize} after connecting.\n *\n * @returns Promise that resolves when connected\n *\n * @example\n * ```typescript\n * await session.connect();\n * await session.initialize();\n * ```\n *\n * @see {@link initialize} for performing the MCP handshake\n * @see {@link disconnect} for closing the connection\n */\n async connect(): Promise<void> {\n await this.connector.connect();\n }\n\n /**\n * Closes the connection to the MCP server.\n *\n * This method gracefully shuts down the transport and cleans up resources.\n * After disconnecting, the session cannot be used until reconnected.\n *\n * @returns Promise that resolves when disconnected\n *\n * @example\n * ```typescript\n * await session.disconnect();\n * console.log('Session closed');\n * ```\n *\n * @see {@link connect} for establishing connections\n */\n async disconnect(): Promise<void> {\n await this.connector.disconnect();\n }\n\n /**\n * Initializes the MCP session with the server.\n *\n * This method performs the MCP initialization handshake, exchanging\n * capabilities and metadata with the server. If `autoConnect` is true\n * and the session is not yet connected, it will connect first.\n *\n * After initialization, you can list and call tools, read resources, etc.\n *\n * @returns Promise that resolves when initialized\n *\n * @example\n * ```typescript\n * const session = await client.createSession('my-server', false);\n * await session.connect();\n * await session.initialize();\n * // Now ready to use\n * const tools = await session.listTools();\n * ```\n *\n * @see {@link connect} for establishing the connection first\n */\n async initialize(): Promise<void> {\n if (!this.isConnected && this.autoConnect) {\n await this.connect();\n }\n await this.connector.initialize();\n }\n\n /**\n * Checks if the session is currently connected to the server.\n *\n * @returns True if connected, false otherwise\n *\n * @example\n * ```typescript\n * if (session.isConnected) {\n * const tools = await session.listTools();\n * }\n * ```\n */\n get isConnected(): boolean {\n return this.connector && this.connector.isClientConnected;\n }\n\n /**\n * Register an event handler for session events\n *\n * @param event - The event type to listen for\n * @param handler - The handler function to call when the event occurs\n *\n * @example\n * ```typescript\n * session.on(\"notification\", async (notification) => {\n * console.log(`Received: ${notification.method}`, notification.params);\n *\n * if (notification.method === \"notifications/tools/list_changed\") {\n * // Refresh tools list\n * }\n * });\n * ```\n */\n on(event: \"notification\", handler: NotificationHandler): void {\n if (event === \"notification\") {\n this.connector.onNotification(handler);\n }\n }\n\n /**\n * Set roots and notify the server.\n * Roots represent directories or files that the client has access to.\n *\n * @param roots - Array of Root objects with `uri` (must start with \"file://\") and optional `name`\n *\n * @deprecated Roots are a v1 compatibility feature and are not part of the\n * sessionless v2 protocol.\n *\n * @example\n * ```typescript\n * await session.setRoots([\n * { uri: \"file:///home/user/project\", name: \"My Project\" },\n * { uri: \"file:///home/user/data\" }\n * ]);\n * ```\n */\n async setRoots(roots: Root[]): Promise<void> {\n return this.connector.setRoots(roots);\n }\n\n /**\n * Gets the current roots advertised to the server.\n *\n * Roots represent directories or files that the client has provided access to.\n * The server may use this information to scope its operations.\n *\n * @returns Array of Root objects\n *\n * @example\n * ```typescript\n * const roots = session.getRoots();\n * console.log(`Current roots: ${roots.map(r => r.uri).join(', ')}`);\n * ```\n *\n * @see {@link setRoots} for updating roots\n */\n getRoots(): Root[] {\n return this.connector.getRoots();\n }\n\n /**\n * Get the cached list of tools from the server.\n *\n * @returns Array of available tools\n *\n * @example\n * ```typescript\n * const tools = session.tools;\n * console.log(`Available tools: ${tools.map(t => t.name).join(\", \")}`);\n * ```\n */\n get tools(): Tool[] {\n return this.connector.tools;\n }\n\n /**\n * List all available tools from the MCP server.\n * This method fetches fresh tools from the server, unlike the `tools` getter which returns cached tools.\n *\n * @param options - Optional request options\n * @returns Array of available tools\n *\n * @example\n * ```typescript\n * const tools = await session.listTools();\n * console.log(`Available tools: ${tools.map(t => t.name).join(\", \")}`);\n * ```\n */\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n return this.connector.listTools(options);\n }\n\n /**\n * Get the server capabilities advertised during initialization.\n *\n * @returns Server capabilities object\n */\n get serverCapabilities(): Record<string, unknown> {\n return this.connector.serverCapabilities;\n }\n\n /**\n * Get the server information (name and version).\n *\n * @returns Server info object or null if not available\n */\n get serverInfo(): MCPServerInfo | null {\n return this.connector.serverInfo;\n }\n\n /** OAuth state discovered for this connection, when available. */\n get authorization(): MCPAuthorizationInfo | undefined {\n return this.connector.authorization;\n }\n\n /** Discover optional OAuth metadata without delaying MCP readiness. */\n async discoverAuthorization(): Promise<MCPAuthorizationInfo | undefined> {\n return this.connector.discoverAuthorization();\n }\n\n /** Authenticate an already-connected mixed-auth server. */\n async authenticate(): Promise<void> {\n await this.connector.authenticate();\n }\n\n /**\n * The negotiated protocol era for this session's connection:\n * `\"legacy\"` (2025-era) or `\"modern\"` (2026-07-28-era).\n * `undefined` before the connection has negotiated.\n */\n get protocolEra(): MCPProtocolEra | undefined {\n return this.connector.protocolEra;\n }\n\n /** The negotiated protocol version string for this session's connection. */\n get negotiatedProtocolVersion(): string | undefined {\n return this.connector.negotiatedProtocolVersion;\n }\n\n /**\n * Normalized server metadata for this ready connection.\n *\n * @throws When called before protocol negotiation completes.\n */\n get info(): MCPConnectionInfo {\n const protocolEra = this.protocolEra;\n const protocolVersion = this.negotiatedProtocolVersion;\n const server = this.serverInfo;\n\n if (!protocolEra || !protocolVersion) {\n throw new Error(\"MCP connection is not initialized\");\n }\n\n const capabilities = this.serverCapabilities;\n const extensions =\n capabilities.extensions &&\n typeof capabilities.extensions === \"object\" &&\n !Array.isArray(capabilities.extensions)\n ? (capabilities.extensions as Record<string, unknown>)\n : {};\n\n return {\n protocolEra,\n protocolVersion,\n ...(server ? { server } : {}),\n capabilities,\n instructions: this.connector.instructions,\n extensions,\n ...(this.authorization ? { authorization: this.authorization } : {}),\n };\n }\n\n /**\n * Whether the server advertised a named MCP capability.\n *\n * @param capability - A top-level capability name such as `\"tools\"` or\n * `\"resources\"`.\n */\n supports(capability: string): boolean {\n return capability in this.serverCapabilities;\n }\n\n /**\n * Call a tool on the server.\n *\n * @param name - Name of the tool to call\n * @param args - Arguments to pass to the tool (defaults to empty object)\n * @param options - Optional request options (timeout, progress handlers, etc.)\n * @returns Result from the tool execution\n *\n * @example\n * ```typescript\n * const result = await session.callTool(\"add\", { a: 5, b: 3 });\n * console.log(`Result: ${result.content[0].text}`);\n * ```\n */\n async callTool(\n name: string,\n args: Record<string, any> = {},\n options?: RequestOptions\n ): Promise<CallToolResult> {\n return this.connector.callTool(name, args, options);\n }\n\n /**\n * List resources from the server with optional pagination.\n *\n * @param cursor - Optional cursor for pagination\n * @param options - Request options\n * @returns Resource list with optional nextCursor for pagination\n *\n * @example\n * ```typescript\n * const result = await session.listResources();\n * console.log(`Found ${result.resources.length} resources`);\n * ```\n */\n async listResources(cursor?: string, options?: RequestOptions) {\n return this.connector.listResources(cursor, options);\n }\n\n /**\n * List all resources from the server, automatically handling pagination.\n *\n * @param options - Request options\n * @returns Complete list of all resources\n *\n * @example\n * ```typescript\n * const result = await session.listAllResources();\n * console.log(`Total resources: ${result.resources.length}`);\n * ```\n */\n async listAllResources(options?: RequestOptions) {\n return this.connector.listAllResources(options);\n }\n\n /**\n * List resource templates from the server.\n *\n * @param options - Request options\n * @returns List of available resource templates\n *\n * @example\n * ```typescript\n * const result = await session.listResourceTemplates();\n * console.log(`Available templates: ${result.resourceTemplates.length}`);\n * ```\n */\n async listResourceTemplates(options?: RequestOptions) {\n return this.connector.listResourceTemplates(options);\n }\n\n /**\n * Request completion suggestions for a prompt or resource template argument.\n *\n * @param params - Completion request parameters\n * @param options - Request options\n * @returns Completion suggestions from the server\n *\n * @example\n * ```typescript\n * // Complete a prompt argument\n * const result = await session.complete({\n * ref: { type: \"ref/prompt\", name: \"my-prompt\" },\n * argument: { name: \"language\", value: \"py\" }\n * });\n * console.log(result.completion.values); // [\"python\"]\n * ```\n */\n async complete(\n params: CompleteRequestParams,\n options?: RequestOptions\n ): Promise<CompleteResult> {\n return this.connector.complete(params, options);\n }\n\n /**\n * Read a resource by URI.\n *\n * @param uri - URI of the resource to read\n * @param options - Request options\n * @returns Resource content\n *\n * @example\n * ```typescript\n * const resource = await session.readResource(\"file:///path/to/file.txt\");\n * console.log(resource.contents);\n * ```\n */\n async readResource(uri: string, options?: RequestOptions) {\n return this.connector.readResource(uri, options);\n }\n\n /**\n * Subscribe to resource updates.\n *\n * @param uri - URI of the resource to subscribe to\n * @param options - Request options\n *\n * @example\n * ```typescript\n * await session.subscribeToResource(\"file:///path/to/file.txt\");\n * // Now you'll receive notifications when this resource changes\n * ```\n */\n async subscribeToResource(uri: string, options?: RequestOptions) {\n return this.connector.subscribeToResource(uri, options);\n }\n\n /**\n * Unsubscribe from resource updates.\n *\n * @param uri - URI of the resource to unsubscribe from\n * @param options - Request options\n *\n * @example\n * ```typescript\n * await session.unsubscribeFromResource(\"file:///path/to/file.txt\");\n * ```\n */\n async unsubscribeFromResource(uri: string, options?: RequestOptions) {\n return this.connector.unsubscribeFromResource(uri, options);\n }\n\n /**\n * List available prompts from the server.\n *\n * @returns List of available prompts\n *\n * @example\n * ```typescript\n * const result = await session.listPrompts();\n * console.log(`Available prompts: ${result.prompts.length}`);\n * ```\n */\n async listPrompts() {\n return this.connector.listPrompts();\n }\n\n /**\n * Get a specific prompt with arguments.\n *\n * @param name - Name of the prompt to get\n * @param args - Arguments for the prompt\n * @param options - Per-request timeout, cancellation, and progress options\n * @returns Prompt result\n *\n * @example\n * ```typescript\n * const prompt = await session.getPrompt(\"greeting\", { name: \"Alice\" });\n * console.log(prompt.messages);\n * ```\n */\n async getPrompt(\n name: string,\n args: Record<string, any>,\n options?: RequestOptions\n ) {\n return this.connector.getPrompt(name, args, options);\n }\n\n /**\n * Send a raw request through the client.\n *\n * @param method - MCP method name\n * @param params - Request parameters\n * @param options - Request options\n * @returns Response from the server\n *\n * @example\n * ```typescript\n * const result = await session.request(\"custom/method\", { key: \"value\" });\n * ```\n */\n async request(\n method: string,\n params: Record<string, any> | null = null,\n options?: RequestOptions\n ) {\n return this.connector.request(method, params, options);\n }\n\n /** List one page of skills advertised through the experimental extension. */\n async listSkills(cursor?: string, options?: RequestOptions) {\n return (await this.request(\n \"skills/list\",\n cursor === undefined ? {} : { cursor },\n options\n )) as import(\"./skills.js\").SkillsListResult;\n }\n\n /** List the complete skill catalog, following pagination defensively. */\n async listAllSkills(options?: RequestOptions) {\n const skills: import(\"./skills.js\").Skill[] = [];\n const seenCursors = new Set<string>();\n let cursor: string | undefined;\n do {\n const page = await this.listSkills(cursor, options);\n skills.push(...(Array.isArray(page.skills) ? page.skills : []));\n cursor = page.nextCursor;\n if (cursor !== undefined) {\n if (seenCursors.has(cursor)) {\n throw new Error(\"skills/list returned a repeated pagination cursor\");\n }\n seenCursors.add(cursor);\n }\n } while (cursor !== undefined);\n return { skills };\n }\n\n /** Get one skill by its canonical `SKILL.md` URI. */\n async getSkill(uri: string, options?: RequestOptions) {\n return (await this.request(\n \"skills/get\",\n { uri },\n options\n )) as import(\"./skills.js\").SkillGetResult;\n }\n\n /** Read one non-recursive skill directory. */\n async readResourceDirectory(\n uri: string,\n cursor?: string,\n options?: RequestOptions\n ) {\n return (await this.request(\n \"resources/directory/read\",\n cursor === undefined ? { uri } : { uri, cursor },\n options\n )) as import(\"./skills.js\").SkillDirectoryReadResult;\n }\n}\n\n/** @deprecated Use {@link MCPConnection}. */\nexport { MCPConnection as MCPSession };\n\n// Re-export types for convenience\nexport type { CallToolResult, MetaObject, Notification, Root, Tool };\nexport type {\n Skill,\n SkillDirectoryEntry,\n SkillDirectoryReadResult,\n SkillGetResult,\n SkillResource,\n SkillsListResult,\n} from \"./skills.js\";\nexport { SKILLS_EXTENSION_ID } from \"./skills.js\";\n","import type { ServerConfig } from \"../core/config.js\";\n\ninterface ClientTelemetryTracker {\n addServer(name: string, config: ServerConfig): Promise<void> | void;\n removeServer(name: string): Promise<void> | void;\n}\n\nlet tracker: ClientTelemetryTracker | undefined;\n\n/** @internal Configures the runtime-specific client telemetry sink. */\nexport function setClientTelemetryTracker(\n nextTracker: ClientTelemetryTracker | undefined\n): void {\n tracker = nextTracker;\n}\n\n/** @internal Records that a configured server was added. */\nexport function trackClientAddServer(name: string, config: ServerConfig): void {\n void tracker?.addServer(name, config);\n}\n\n/** @internal Records that a configured server was removed. */\nexport function trackClientRemoveServer(name: string): void {\n void tracker?.removeServer(name);\n}\n","const FAVICON_API = \"https://favicon.tools.mcp-use.com\";\n\nconst IPV4_RE = /^\\d{1,3}(\\.\\d{1,3}){3}$/;\n\nfunction parseHostname(serverUrl: string): string | null {\n try {\n const raw = serverUrl.includes(\"://\") ? serverUrl : `https://${serverUrl}`;\n return new URL(raw).hostname;\n } catch {\n return null;\n }\n}\n\nfunction isLocalHost(hostname: string): boolean {\n const h = hostname.toLowerCase();\n if (h === \"localhost\" || h.endsWith(\".localhost\")) return true;\n if (h === \"host.docker.internal\" || h === \"0.0.0.0\") return true;\n if (!IPV4_RE.test(h)) return false;\n\n if (h === \"127.0.0.1\" || h.startsWith(\"127.\")) return true;\n if (h.startsWith(\"10.\")) return true;\n if (h.startsWith(\"192.168.\")) return true;\n\n const m = /^172\\.(\\d+)\\./.exec(h);\n if (m) {\n const second = Number.parseInt(m[1]!, 10);\n if (second >= 16 && second <= 31) return true;\n }\n\n return false;\n}\n\nfunction subdomainLevels(hostname: string): string[] {\n const parts = hostname.split(\".\");\n return Array.from({ length: parts.length - 1 }, (_, i) =>\n parts.slice(i).join(\".\")\n );\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\n/**\n * Detect and retrieve an MCP server's favicon as a base64 data URL.\n * Skips local/private hosts; walks subdomain levels until a non-default favicon is found.\n */\nexport async function detectFavicon(serverUrl: string): Promise<string | null> {\n try {\n const hostname = parseHostname(serverUrl);\n if (!hostname || isLocalHost(hostname)) return null;\n\n for (const domain of subdomainLevels(hostname)) {\n try {\n const res = await fetch(`${FAVICON_API}/${domain}?response=json`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) continue;\n\n const data = (await res.json()) as { url: string; source: string };\n if (data.source === \"default\") continue;\n\n const imageUrl = data.url.replace(/^http:\\/\\//, \"https://\");\n const img = await fetch(imageUrl, {\n signal: AbortSignal.timeout(2000),\n });\n if (!img.ok) continue;\n\n return await blobToDataUrl(await img.blob());\n } catch {\n continue;\n }\n }\n\n return null;\n } catch (error) {\n console.warn(\"[favicon] Error detecting favicon:\", error);\n return null;\n }\n}\n","import { BrowserOAuthClientProvider } from \"../auth/browser.js\";\nimport type { OAuthClientInformation } from \"@modelcontextprotocol/client\";\nimport type { MCPServerInfo } from \"../core/session.js\";\nimport { detectFavicon } from \"../utils/favicon.js\";\n\nexport const USE_MCP_SERVER_NAME = \"inspector-server\";\n\n/** Asserts that a condition is true, throwing an error if not. */\nexport function assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\ntype ServerInfoWithIcon = MCPServerInfo & { icon?: string };\ntype AddLog = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n ...args: unknown[]\n) => void;\n\n/** Resolve a server-provided icon, then fall back to domain favicon discovery. */\nexport async function loadServerIcon(params: {\n serverInfo: MCPServerInfo;\n url?: string;\n isMounted: () => boolean;\n setServerInfo: (\n update: (previous?: ServerInfoWithIcon) => ServerInfoWithIcon | undefined\n ) => void;\n addLog: AddLog;\n}): Promise<string | null> {\n try {\n const iconUrl = params.serverInfo.icons?.[0]?.src;\n if (iconUrl) {\n params.addLog(\"info\", \"Server provided icon:\", iconUrl);\n const response = await fetch(iconUrl);\n const blob = await response.blob();\n const base64 = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n\n if (params.isMounted()) {\n params.setServerInfo((previous) =>\n previous ? { ...previous, icon: base64 } : undefined\n );\n params.addLog(\"debug\", \"Server icon converted to base64\");\n }\n return base64;\n }\n\n if (params.url) {\n const favicon = await detectFavicon(params.url);\n if (!params.isMounted()) {\n params.addLog(\n \"debug\",\n \"Connection aborted after favicon detection - component unmounted\"\n );\n return null;\n }\n if (favicon) {\n params.setServerInfo((previous) =>\n previous ? { ...previous, icon: favicon } : undefined\n );\n params.addLog(\"debug\", \"Favicon detected and added to serverInfo\");\n return favicon;\n }\n }\n\n return null;\n } catch (error) {\n params.addLog(\"debug\", \"Icon loading failed (non-critical):\", error);\n return null;\n }\n}\n\n/** Human-readable reason when MCP operations run before the client is usable. */\nexport function formatMcpNotReadyReason(\n state: string,\n hasClient: boolean\n): string {\n return !hasClient ? `client disconnected (state=${state})` : `state=${state}`;\n}\n\ntype OAuthClientConfig = {\n name?: string;\n version?: string;\n uri?: string;\n logo_uri?: string;\n};\n\nexport function deriveOAuthClientConfigFromClientInfo(clientInfo: {\n name: string;\n title?: string;\n version: string;\n description?: string;\n icons?: Array<{\n src: string;\n mimeType?: string;\n sizes?: string[];\n }>;\n websiteUrl?: string;\n}): OAuthClientConfig {\n return {\n name: clientInfo.name,\n version: clientInfo.version,\n uri: clientInfo.websiteUrl,\n logo_uri: clientInfo.icons?.[0]?.src,\n };\n}\n\nexport function isOAuthDiscoveryFailure(error: Error | unknown): boolean {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const msg = errorMessage.toLowerCase();\n\n return (\n msg.includes(\"oauth discovery failed\") ||\n msg.includes(\"oauth-authorization-server\") ||\n msg.includes(\"not valid json\") ||\n (msg.includes(\"404\") &&\n (msg.includes(\"openid-configuration\") ||\n msg.includes(\"oauth-protected-resources\") ||\n msg.includes(\"oauth-authorization-url\") ||\n msg.includes(\"register\"))) ||\n (msg.includes(\"invalid oauth error response\") && msg.includes(\"not found\"))\n );\n}\n\n/**\n * Derive the companion OAuth proxy endpoint from an MCP proxy endpoint.\n *\n * The Inspector proxy convention is `/proxy` for MCP traffic and `/oauth` for\n * OAuth metadata/token requests. An explicit OAuth URL always takes priority.\n */\nexport function deriveOAuthProxyUrl(\n gatewayUrl: string | undefined,\n explicitOAuthProxyUrl: string | undefined\n): string | undefined {\n if (explicitOAuthProxyUrl) return explicitOAuthProxyUrl;\n if (!gatewayUrl) return undefined;\n\n try {\n const url = new URL(gatewayUrl);\n url.pathname = url.pathname.replace(/\\/proxy\\/?$/, \"/oauth\");\n return url.toString();\n } catch {\n return undefined;\n }\n}\n\nexport function createBrowserOAuthProvider(params: {\n effectiveOAuthUrl: string;\n storageKeyPrefix: string;\n oauthClientConfig: OAuthClientConfig;\n callbackUrl: string;\n preventAutoAuth: boolean;\n useRedirectFlow: boolean;\n /** MCP proxy URL used to derive the companion OAuth proxy when needed. */\n gatewayUrl?: string;\n /**\n * Explicit OAuth proxy base URL. Takes precedence over the URL derived from\n * `gatewayUrl`. Lets consumers proxy OAuth traffic (CORS bypass) while\n * keeping MCP traffic direct.\n */\n oauthProxyUrl?: string;\n onPopupWindow?: (\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void;\n /**\n * Whether the provider should route OAuth requests through the derived\n * OAuth proxy (to bypass CORS). The provider exposes this via its scoped\n * `getProxyFetch()` — it never patches the global `fetch`.\n */\n proxyOAuthRequests: boolean;\n staticClientInfo?: OAuthClientInformation;\n clientMetadataUrl?: string;\n scope?: string;\n}): {\n provider: BrowserOAuthClientProvider;\n oauthProxyUrl?: string;\n} {\n const oauthProxyUrl = deriveOAuthProxyUrl(\n params.gatewayUrl,\n params.oauthProxyUrl\n );\n const provider = new BrowserOAuthClientProvider(params.effectiveOAuthUrl, {\n storageKeyPrefix: params.storageKeyPrefix,\n clientName: params.oauthClientConfig.name,\n clientUri: params.oauthClientConfig.uri,\n logoUri:\n params.oauthClientConfig.logo_uri || \"https://mcp-use.com/logo.png\",\n callbackUrl: params.callbackUrl,\n preventAutoAuth: params.preventAutoAuth,\n useRedirectFlow: params.useRedirectFlow,\n oauthProxyUrl,\n connectionUrl: params.gatewayUrl,\n onPopupWindow: params.onPopupWindow,\n proxyOAuthRequests: params.proxyOAuthRequests,\n staticClientInfo: params.staticClientInfo,\n clientMetadataUrl: params.clientMetadataUrl,\n scope: params.scope,\n });\n\n return { provider, oauthProxyUrl };\n}\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport function startConnectionHealthMonitoring(params: {\n gatewayUrl?: string;\n url?: string;\n allHeaders?: Record<string, string>;\n getAuthHeaders?: () => Promise<Record<string, string>>;\n isMountedRef: { current: boolean };\n stateRef: { current: string };\n autoReconnectRef: { current: boolean | number | Record<string, unknown> };\n setState: (state: \"discovering\") => void;\n addLog: (level: LogLevel, message: string, ...args: unknown[]) => void;\n connect: () => void;\n defaultReconnectDelay: number;\n healthCheckIntervalMs?: number;\n healthCheckTimeoutMs?: number;\n}): () => void {\n let healthCheckInterval: ReturnType<typeof setInterval> | null = null;\n let lastSuccessfulCheck = Date.now();\n // ponytail: many MCP servers only accept POST; one 405/404 disables HEAD polling.\n let headProbeUnsupported = false;\n const healthCheckIntervalMs = params.healthCheckIntervalMs ?? 10000;\n const healthCheckTimeoutMs = params.healthCheckTimeoutMs ?? 30000;\n\n const checkConnectionHealth = async () => {\n if (headProbeUnsupported) {\n return;\n }\n if (!params.isMountedRef.current || params.stateRef.current !== \"ready\") {\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n return;\n }\n\n try {\n const healthCheckUrl = params.gatewayUrl || params.url;\n if (!healthCheckUrl) {\n return;\n }\n\n const authHeaders = params.getAuthHeaders\n ? await params.getAuthHeaders()\n : {};\n const healthCheckHeaders = {\n ...params.allHeaders,\n ...authHeaders,\n ...(params.gatewayUrl && params.url\n ? { \"X-Target-URL\": params.url }\n : {}),\n };\n const response = await fetch(healthCheckUrl, {\n method: \"HEAD\",\n headers: healthCheckHeaders,\n signal: AbortSignal.timeout(5000),\n });\n\n if (response.status === 405 || response.status === 404) {\n headProbeUnsupported = true;\n lastSuccessfulCheck = Date.now();\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n return;\n }\n\n if (response.ok || response.status < 500) {\n lastSuccessfulCheck = Date.now();\n } else {\n throw new Error(`Server returned ${response.status}`);\n }\n } catch {\n const timeSinceLastSuccess = Date.now() - lastSuccessfulCheck;\n if (timeSinceLastSuccess > healthCheckTimeoutMs) {\n params.addLog(\n \"warn\",\n `Connection appears to be broken (no response for ${Math.round(timeSinceLastSuccess / 1000)}s), attempting to reconnect...`\n );\n\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n\n if (params.autoReconnectRef.current && params.isMountedRef.current) {\n params.setState(\"discovering\");\n params.addLog(\"info\", \"Auto-reconnecting to MCP server...\");\n\n setTimeout(\n () => {\n if (\n params.isMountedRef.current &&\n params.stateRef.current === \"discovering\"\n ) {\n params.connect();\n }\n },\n typeof params.autoReconnectRef.current === \"number\"\n ? params.autoReconnectRef.current\n : params.defaultReconnectDelay\n );\n }\n }\n }\n };\n\n healthCheckInterval = setInterval(\n checkConnectionHealth,\n healthCheckIntervalMs\n );\n return () => {\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n };\n}\n","import type {\n CompleteRequestParams,\n CompleteResult,\n Prompt,\n Resource,\n ResourceTemplateType as ResourceTemplate,\n Tool,\n} from \"@modelcontextprotocol/client\";\nimport {\n useCallback,\n type Dispatch,\n type RefObject,\n type SetStateAction,\n} from \"react\";\nimport type { MCPConnection } from \"../core/session.js\";\nimport { isOAuthInteractionRequired } from \"../auth/flow.js\";\nimport { Tel } from \"../telemetry/telemetry-browser.js\";\nimport { formatMcpNotReadyReason } from \"./useMcp-helpers.js\";\nimport type { UseMcpResult } from \"./types.js\";\n\ntype AddLog = (\n level: UseMcpResult[\"log\"][number][\"level\"],\n message: string,\n ...args: unknown[]\n) => void;\n\ntype Params = {\n stateRef: RefObject<UseMcpResult[\"state\"]>;\n connectionRef: RefObject<MCPConnection | null>;\n hasClient: () => boolean;\n isMounted: () => boolean;\n setTools: Dispatch<SetStateAction<Tool[]>>;\n setResources: Dispatch<SetStateAction<Resource[]>>;\n setResourceTemplates: Dispatch<SetStateAction<ResourceTemplate[]>>;\n setPrompts: Dispatch<SetStateAction<Prompt[]>>;\n setSkills: Dispatch<SetStateAction<import(\"../core/skills.js\").Skill[]>>;\n addLog: AddLog;\n onAuthorizationRequired: (error: unknown) => void;\n};\n\nfunction requireConnection(params: Params, operation: string): MCPConnection {\n const connection = params.connectionRef.current;\n if (\n params.stateRef.current !== \"ready\" ||\n !params.hasClient() ||\n !connection\n ) {\n throw new Error(\n `MCP client is not ready (${formatMcpNotReadyReason(\n params.stateRef.current,\n params.hasClient()\n )}). Cannot ${operation}.`\n );\n }\n return connection;\n}\n\nasync function executeWithAuthorizationSignal<T>(\n params: Params,\n operation: () => Promise<T>\n): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n if (isOAuthInteractionRequired(error)) {\n params.onAuthorizationRequired(error);\n }\n throw error;\n }\n}\n\nexport function useMcpOperations(params: Params) {\n const callTool = useCallback<UseMcpResult[\"callTool\"]>(\n async (name, args, options) => {\n const connection = requireConnection(params, `call tool \"${name}\"`);\n params.addLog(\"info\", `Calling tool: ${name}`, args);\n const startedAt = Date.now();\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.callTool(name, args || {}, options)\n );\n params.addLog(\"info\", `Tool \"${name}\" call successful:`, result);\n Tel.getInstance()\n .trackUseMcpToolCall({\n toolName: name,\n success: true,\n executionTimeMs: Date.now() - startedAt,\n })\n .catch(() => {});\n return result;\n } catch (error) {\n params.addLog(\"error\", `Tool \"${name}\" call failed:`, error);\n Tel.getInstance()\n .trackUseMcpToolCall({\n toolName: name,\n success: false,\n errorType: error instanceof Error ? error.name : \"UnknownError\",\n executionTimeMs: Date.now() - startedAt,\n })\n .catch(() => {});\n throw error;\n }\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const listResources = useCallback(async () => {\n const connection = requireConnection(params, \"list resources\");\n params.addLog(\"info\", \"Listing resources\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listAllResources()\n );\n params.setResources(result.resources || []);\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const readResource = useCallback(\n async (uri: string) => {\n const connection = requireConnection(params, \"read resource\");\n params.addLog(\"info\", `Reading resource: ${uri}`);\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.readResource(uri)\n );\n Tel.getInstance()\n .trackUseMcpResourceRead({ resourceUri: uri, success: true })\n .catch(() => {});\n return result;\n } catch (error) {\n Tel.getInstance()\n .trackUseMcpResourceRead({\n resourceUri: uri,\n success: false,\n errorType: error instanceof Error ? error.name : \"UnknownError\",\n })\n .catch(() => {});\n throw error;\n }\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const listSkills = useCallback(async () => {\n const connection = requireConnection(params, \"list skills\");\n params.addLog(\"info\", \"Listing skills\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listAllSkills()\n );\n params.setSkills(result.skills);\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const getSkill = useCallback(\n async (uri: string) => {\n const connection = requireConnection(params, \"get skill\");\n params.addLog(\"info\", `Getting skill: ${uri}`);\n return executeWithAuthorizationSignal(params, () =>\n connection.getSkill(uri)\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const readResourceDirectory = useCallback(\n async (uri: string, cursor?: string) => {\n const connection = requireConnection(params, \"read resource directory\");\n params.addLog(\"info\", `Reading resource directory: ${uri}`);\n return executeWithAuthorizationSignal(params, () =>\n connection.readResourceDirectory(uri, cursor)\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const listPrompts = useCallback(async () => {\n const connection = requireConnection(params, \"list prompts\");\n params.addLog(\"info\", \"Listing prompts\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listPrompts()\n );\n params.setPrompts(result.prompts || []);\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshTools = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n params.setTools(\n (await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listTools()\n )) || []\n );\n } catch (error) {\n params.addLog(\"error\", \"Failed to refresh tools:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshResources = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listAllResources()\n );\n params.setResources(result.resources || []);\n } catch (error) {\n params.addLog(\"warn\", \"Failed to refresh resources:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshPrompts = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listPrompts()\n );\n params.setPrompts(result.prompts || []);\n } catch (error) {\n params.addLog(\"warn\", \"Failed to refresh prompts:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshSkills = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listAllSkills()\n );\n params.setSkills(result.skills);\n } catch (error) {\n // A development reload may remove the final skills directory, in which\n // case the replacement server intentionally no longer exposes the\n // extension. Clear the prior snapshot without treating that transition\n // as a connection failure.\n params.setSkills([]);\n params.addLog(\"debug\", \"Skills are unavailable after refresh:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshResourceTemplates = useCallback(async () => {\n const connection = requireConnection(params, \"refresh resource templates\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listResourceTemplates()\n );\n if (params.isMounted()) {\n params.setResourceTemplates(result.resourceTemplates || []);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshAll = useCallback(\n () =>\n Promise.all([\n refreshTools(),\n refreshResources(),\n refreshResourceTemplates(),\n refreshPrompts(),\n ]).then(() => undefined),\n [refreshTools, refreshResources, refreshResourceTemplates, refreshPrompts]\n );\n\n const getPrompt = useCallback(\n async (name: string, args?: Record<string, unknown>) => {\n const connection = requireConnection(params, \"get prompt\");\n return executeWithAuthorizationSignal(params, () =>\n connection.getPrompt(name, args || {})\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const complete = useCallback(\n async (request: CompleteRequestParams): Promise<CompleteResult> => {\n const connection = requireConnection(params, \"request completion\");\n return executeWithAuthorizationSignal(params, () =>\n connection.complete(request)\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n return {\n callTool,\n listResources,\n readResource,\n listSkills,\n getSkill,\n readResourceDirectory,\n listPrompts,\n refreshTools,\n refreshResources,\n refreshPrompts,\n refreshSkills,\n refreshResourceTemplates,\n refreshAll,\n getPrompt,\n complete,\n };\n}\n","/**\n * Resolve an OAuth token's absolute expiry. JWT `exp` is authoritative when\n * available; `expires_in` is only a fallback for opaque tokens.\n */\nexport function getOAuthTokenExpiry(tokens: {\n access_token?: string;\n expires_in?: unknown;\n}): number | undefined {\n try {\n const payload = JSON.parse(atob(tokens.access_token?.split(\".\")[1] ?? \"\"));\n if (typeof payload.exp === \"number\") return payload.exp * 1000;\n } catch {\n // Opaque tokens do not contain a JWT expiry claim.\n }\n return typeof tokens.expires_in === \"number\"\n ? Date.now() + tokens.expires_in * 1000\n : undefined;\n}\n","import { StreamableHTTPClientTransport } from \"@modelcontextprotocol/client\";\nimport { BrowserOAuthClientProvider } from \"./browser.js\";\nimport {\n MCP_AUTH_BROADCAST_CHANNEL,\n MCP_AUTH_CALLBACK_MESSAGE_TYPE,\n type McpAuthCallbackMessage,\n} from \"./popup.js\";\nimport type { StoredState } from \"./session-store.js\";\nimport { LocalStorageKVStore } from \"./storage.js\";\n\ninterface AuthCallbackMeta {\n state?: string | null;\n serverUrlHash?: string | null;\n}\n\nlet inFlightCallback: Promise<void> | null = null;\n\nfunction isMcpAuthPopupWindow(): boolean {\n return typeof window !== \"undefined\" && window.name.startsWith(\"mcp_auth_\");\n}\n\nfunction buildCallbackPayload(\n success: boolean,\n error: string | undefined,\n meta: AuthCallbackMeta\n): McpAuthCallbackMessage {\n return {\n type: MCP_AUTH_CALLBACK_MESSAGE_TYPE,\n success,\n ...(success ? {} : { error: error ?? \"Unknown error\" }),\n ...(meta.state ? { state: meta.state } : {}),\n ...(meta.serverUrlHash ? { serverUrlHash: meta.serverUrlHash } : {}),\n };\n}\n\nfunction broadcastCallback(payload: McpAuthCallbackMessage): void {\n if (typeof BroadcastChannel === \"undefined\") return;\n\n let channel: BroadcastChannel | undefined;\n try {\n channel = new BroadcastChannel(MCP_AUTH_BROADCAST_CHANNEL);\n channel.postMessage(payload);\n } catch (error) {\n console.warn(\"[mcp-callback] Failed to broadcast callback result:\", error);\n } finally {\n if (channel) {\n setTimeout(() => {\n try {\n channel?.close();\n } catch {\n // Best-effort signaling only.\n }\n }, 0);\n }\n }\n}\n\nfunction renderResult(\n title: string,\n message: string,\n error: boolean,\n returnUrl?: string\n): void {\n if (typeof document === \"undefined\") return;\n\n document.body.innerHTML = \"\";\n const container = document.createElement(\"div\");\n container.style.fontFamily = \"sans-serif\";\n container.style.padding = \"20px\";\n\n const heading = document.createElement(\"h1\");\n heading.textContent = title;\n container.appendChild(heading);\n\n const text = document.createElement(\"p\");\n text.textContent = message;\n if (error) {\n text.style.color = \"red\";\n text.style.backgroundColor = \"#ffebeb\";\n text.style.border = \"1px solid red\";\n text.style.padding = \"10px\";\n text.style.borderRadius = \"4px\";\n }\n container.appendChild(text);\n\n const close = document.createElement(\"a\");\n close.href = \"#\";\n close.textContent = \"Close this window\";\n close.onclick = (event) => {\n event.preventDefault();\n window.close();\n return false;\n };\n container.appendChild(close);\n\n if (returnUrl) {\n const separator = document.createTextNode(\" or \");\n const back = document.createElement(\"a\");\n back.href = returnUrl;\n back.textContent = \"return to the app\";\n container.append(separator, back);\n }\n\n document.body.appendChild(container);\n}\n\nasync function findStoredState(state: string): Promise<{\n key: string;\n value: StoredState;\n store: LocalStorageKVStore;\n}> {\n const store = new LocalStorageKVStore();\n const legacySuffix = `:state_${state}`;\n const scopedSuffix = `_state_${state}`;\n const key = (await store.keys()).find(\n (candidate) =>\n candidate.endsWith(legacySuffix) || candidate.endsWith(scopedSuffix)\n );\n const serialized = key ? await store.get(key) : null;\n if (!key || !serialized) {\n throw new Error(`Invalid or expired OAuth state \"${state}\".`);\n }\n\n let value: StoredState;\n try {\n value = JSON.parse(serialized) as StoredState;\n } catch {\n await store.remove(key);\n throw new Error(\"Failed to parse stored OAuth state.\");\n }\n\n return { key, value, store };\n}\n\nfunction redirectWithError(returnUrl: string, message: string): void {\n const url = new URL(returnUrl);\n url.searchParams.set(\"auth_error\", \"oauth_callback_failed\");\n url.searchParams.set(\"auth_error_description\", message);\n window.location.href = url.toString();\n}\n\nfunction signalResult(\n success: boolean,\n error: string | undefined,\n storedState: StoredState | null,\n meta: AuthCallbackMeta\n): void {\n const payload = buildCallbackPayload(success, error, meta);\n const returnUrl = storedState?.returnUrl;\n const popup = storedState?.flowType === \"popup\" || isMcpAuthPopupWindow();\n\n if (storedState?.flowType === \"redirect\" && returnUrl) {\n if (success) window.location.href = returnUrl;\n else redirectWithError(returnUrl, error ?? \"Authentication failed.\");\n return;\n }\n\n if (window.opener && !window.opener.closed) {\n window.opener.postMessage(payload, window.location.origin);\n window.close();\n return;\n }\n\n if (popup) {\n broadcastCallback(payload);\n renderResult(\n success ? \"Authentication Successful!\" : \"Authentication Error\",\n success\n ? \"You're authenticated. You can close this window and return to the app.\"\n : (error ?? \"Authentication failed.\"),\n !success,\n returnUrl\n );\n try {\n window.close();\n } catch {\n // The browser may forbid closing after a COOP browsing-context swap.\n }\n return;\n }\n\n if (returnUrl) {\n if (success) window.location.href = returnUrl;\n else redirectWithError(returnUrl, error ?? \"Authentication failed.\");\n return;\n }\n\n if (!success) {\n renderResult(\n \"Authentication Error\",\n error ?? \"Authentication failed.\",\n true\n );\n return;\n }\n\n window.location.href = \"/\";\n}\n\n/**\n * Completes the browser OAuth callback once per page load.\n *\n * This host validates the CSRF state and restores the browser provider. The MCP\n * SDK transport owns callback parameter parsing, issuer validation, OAuth error\n * handling, and the authorization-code exchange.\n */\nexport function onMcpAuthorization(): Promise<void> {\n if (!inFlightCallback) inFlightCallback = completeAuthorization();\n return inFlightCallback;\n}\n\nasync function completeAuthorization(): Promise<void> {\n const callbackParams = new URLSearchParams(window.location.search);\n const state = callbackParams.get(\"state\");\n let stateKey: string | null = null;\n let stateStore: LocalStorageKVStore | null = null;\n let storedState: StoredState | null = null;\n let provider: BrowserOAuthClientProvider | null = null;\n\n try {\n if (!state) {\n throw new Error(\"OAuth callback is missing the state parameter.\");\n }\n\n const stored = await findStoredState(state);\n stateKey = stored.key;\n stateStore = stored.store;\n storedState = stored.value;\n\n if (!storedState.expiry || storedState.expiry < Date.now()) {\n await stateStore.remove(stateKey);\n throw new Error(\n \"OAuth state has expired. Please start authentication again.\"\n );\n }\n\n if (!storedState.providerOptions) {\n throw new Error(\"Stored OAuth state is missing provider options.\");\n }\n\n const { serverUrl, ...providerOptions } = storedState.providerOptions;\n provider = new BrowserOAuthClientProvider(serverUrl, providerOptions);\n\n const transport = new StreamableHTTPClientTransport(new URL(serverUrl), {\n authProvider: provider,\n fetch: provider.getProxyFetch(),\n });\n\n await transport.finishAuth(callbackParams);\n await stateStore.remove(stateKey);\n signalResult(true, undefined, storedState, {\n state,\n serverUrlHash: storedState.serverUrlHash,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(\"[mcp-callback] OAuth callback failed:\", error);\n\n if (stateKey && stateStore) await stateStore.remove(stateKey);\n if (provider) {\n await (stateStore ?? new LocalStorageKVStore()).remove(\n provider.getKey(\"last_auth_url\")\n );\n }\n\n signalResult(false, message, storedState, {\n state,\n serverUrlHash: storedState?.serverUrlHash,\n });\n }\n}\n","/**\n * React entry point for the MCP connection console.\n *\n * Provides the `useMcp` hook, the multi-server `McpClientProvider`, and the\n * supporting storage / logging utilities for connecting to MCP servers from a\n * React app. MCP Apps host rendering lives in {@link ViewRenderer}.\n */\n\nexport type {\n UseMcpOptions,\n UseMcpResult,\n ReconnectionOptions,\n McpServer,\n McpServerConfig,\n /** @deprecated Use McpServerConfig */\n McpServerOptions,\n PersistedMcpServerConfig,\n McpNotification,\n PendingSamplingRequest,\n PendingElicitationRequest,\n} from \"./types.js\";\nexport type {\n Skill,\n SkillDirectoryEntry,\n SkillDirectoryReadResult,\n SkillGetResult,\n SkillResource,\n SkillsListResult,\n} from \"../core/skills.js\";\nexport { SKILLS_EXTENSION_ID } from \"../core/skills.js\";\nexport { pickPersistedServerConfig, toPersistedServerConfig } from \"./types.js\";\nexport { useMcp } from \"./useMcp.js\";\nexport { detectFavicon } from \"../utils/favicon.js\";\n\n// Re-export auth callback handler for the OAuth flow\nexport { onMcpAuthorization } from \"../auth/callback.js\";\nexport { isOAuthInteractionRequired } from \"../auth/flow.js\";\n\n// Re-export browser telemetry (browser-specific implementation)\nexport {\n Tel,\n Telemetry,\n setTelemetrySource,\n} from \"../telemetry/telemetry-browser.js\";\n\n// Protocol types re-exported so consumers need only @mcp-use/client/react.\nexport type {\n CallToolResult,\n ContentBlock,\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n GetPromptResult,\n JSONRPCMessage,\n Prompt,\n ReadResourceResult,\n Resource,\n ResourceTemplateType,\n Tool,\n Transport,\n} from \"@modelcontextprotocol/client\";\nexport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\n/** JSON-RPC envelope for `sampling/createMessage`. */\nexport type SamplingCreateMessageRequest = {\n /** JSON-RPC method name. */\n method: \"sampling/createMessage\";\n /** Sampling request parameters. */\n params: SamplingCreateMessageParams;\n};\n/** @deprecated Use {@link SamplingCreateMessageRequest}. */\nexport type { SamplingCreateMessageRequest as CreateMessageRequest };\n/** @deprecated Use {@link SamplingCreateMessageResult}. */\nexport type { SamplingCreateMessageResult as CreateMessageResult };\nexport { specTypeSchemas } from \"@modelcontextprotocol/client\";\n\n// Multi-server client provider and hooks\nexport {\n McpClientProvider,\n useMcpClient,\n useMcpServer,\n} from \"./McpClientProvider.js\";\nexport type {\n McpClientContextType,\n McpClientProviderProps,\n} from \"./McpClientProvider.js\";\n\n// Storage providers\nexport {\n LocalStorageProvider,\n MemoryStorageProvider,\n type CachedServerMetadata,\n type StorageProvider,\n} from \"./storage.js\";\n\n// RPC logger utilities\nexport {\n getRpcLogs,\n getAllRpcLogs,\n subscribeToRpcLogs,\n clearRpcLogs,\n type RpcLogEntry,\n} from \"./rpc-logger.js\";\n\n// MCP Apps host renderer\nexport {\n ViewRenderer,\n resolveViewResource,\n getViewResourceUri,\n isViewResource,\n isViewTool,\n isToolVisibleToModel,\n parseCustomProps,\n buildSandboxProxyBlobHtml,\n buildViewSandboxBlobUrl,\n buildViewSandboxUrl,\n type ViewRendererProps,\n type ViewConnection,\n type ViewDisplayMode,\n type ViewCspMode,\n type ViewRendererSource,\n type ResolvedViewResource,\n type ViewCspViolation,\n type ViewLifecycleEvent,\n type ViewLifecycleStatus,\n type ViewAppToolConnection,\n type McpUiDownloadFileRequest,\n type McpUiDownloadFileResult,\n type McpUiHostCapabilities,\n type McpUiHostContext,\n type McpUiResourceCsp,\n type McpUiResourcePermissions,\n type McpUiSupportedContentBlockModalities,\n} from \"./view/ViewRenderer.js\";\n","import type { ElicitResult, Transport } from \"@modelcontextprotocol/client\";\nimport type { SamplingCreateMessageResult } from \"../core/config.js\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { Logger } from \"../utils/logging.js\";\nimport type { StorageProvider } from \"./storage.js\";\nimport type {\n McpServer,\n McpServerConfig,\n PendingElicitationRequest,\n PendingSamplingRequest,\n PersistedMcpServerConfig,\n} from \"./types.js\";\nimport { pickLiveServerConfig, toPersistedServerConfig } from \"./types.js\";\nimport { useMcp } from \"./useMcp.js\";\nimport { useMcpServerQueues } from \"./useMcpServerQueues.js\";\n\n// Module-level logger for McpClientProvider & friends\nconst providerLogger = Logger.get(\"McpClientProvider\");\n\n// ===== Types =====\n\n/**\n * Context value for multi-server management\n */\nexport interface McpClientContextType {\n /** Managed servers and their current reactive state. */\n servers: McpServer[];\n /** Idempotent — safe to call multiple times with the same id; duplicates are silently ignored. */\n addServer: (id: string, config: McpServerConfig) => void;\n /**\n * Remove a server from the provider.\n *\n * By default this only tears down the live connection and leaves persisted\n * OAuth credentials (tokens / client_info / PKCE verifier) intact, so routine\n * remove+add churn (config refetches, deployment-status flips, env-scoped\n * wrappers sharing a URL hash) does not silently log the user out.\n *\n * Pass `{ clearCredentials: true }` for an explicit logout / \"forget this\n * server\" action to also wipe the persisted OAuth storage.\n */\n removeServer: (\n id: string,\n opts?: { clearCredentials?: boolean }\n ) => Promise<void>;\n /** Updates cached presentation metadata for a managed server. */\n updateServerMetadata: (\n id: string,\n metadata: { name: string }\n ) => Promise<void>;\n /** Merges configuration changes into a managed server. */\n updateServer: (\n id: string,\n options: Partial<McpServerConfig>\n ) => Promise<void>;\n /** Returns a managed server by ID. */\n getServer: (id: string) => McpServer | undefined;\n /** Whether storage has finished loading (true if no storage provider) */\n storageLoaded: boolean;\n}\n\n// ===== Context =====\n\nconst McpClientContext = createContext<McpClientContextType | null>(null);\n\n// ===== Constants =====\n\nfunction sameSerializedValue(left: unknown, right: unknown): boolean {\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\n/**\n * Compares the serializable provider-facing state for one MCP connection.\n *\n * The wrapper and provider both use this comparison so metadata-only updates\n * (including negotiated v1/v2 details) cannot be dropped at either boundary.\n */\nfunction isSameMcpServer(left: McpServer, right: McpServer): boolean {\n return (\n left.id === right.id &&\n sameSerializedValue(\n pickLiveServerConfig(left),\n pickLiveServerConfig(right)\n ) &&\n left.name === right.name &&\n left.state === right.state &&\n left.error === right.error &&\n left.authUrl === right.authUrl &&\n sameSerializedValue(left.authTokens, right.authTokens) &&\n sameSerializedValue(left.authorization, right.authorization) &&\n left.protocolEra === right.protocolEra &&\n left.protocolVersion === right.protocolVersion &&\n sameSerializedValue(left.serverInfo, right.serverInfo) &&\n sameSerializedValue(left.capabilities, right.capabilities) &&\n left.instructions === right.instructions &&\n sameSerializedValue(left.extensions, right.extensions) &&\n sameSerializedValue(left.tools, right.tools) &&\n sameSerializedValue(left.resources, right.resources) &&\n sameSerializedValue(left.resourceTemplates, right.resourceTemplates) &&\n sameSerializedValue(left.prompts, right.prompts) &&\n sameSerializedValue(left.skills, right.skills) &&\n sameSerializedValue(left.notifications, right.notifications) &&\n left.unreadNotificationCount === right.unreadNotificationCount &&\n sameSerializedValue(\n left.pendingSamplingRequests,\n right.pendingSamplingRequests\n ) &&\n sameSerializedValue(\n left.pendingElicitationRequests,\n right.pendingElicitationRequests\n ) &&\n left.client === right.client\n );\n}\n\ninterface ServerConfig {\n id: string;\n options: McpServerConfig;\n}\n\ninterface McpServerWrapperProps {\n id: string;\n options: McpServerConfig;\n defaultCallbackUrl?: string;\n defaultOAuthProxyUrl?: string;\n defaultProxyConfig?: {\n proxyAddress?: string;\n headers?: Record<string, string>;\n };\n defaultAutoProxyFallback?:\n | boolean\n | {\n enabled?: boolean;\n proxyAddress?: string;\n };\n /** Default connection config merged under each server (per-server wins). */\n defaultServerConfig?: Partial<McpServerConfig>;\n clientInfo?: {\n name: string;\n title?: string;\n version: string;\n description?: string;\n icons?: Array<{\n src: string;\n mimeType?: string;\n sizes?: string[];\n }>;\n websiteUrl?: string;\n /**\n * Default capabilities advertised to all servers managed by this provider.\n * Per-server `clientOptions.capabilities` are merged on top, with per-server\n * values taking precedence. Stripped from the MCP `clientInfo` wire field.\n */\n capabilities?: Record<string, unknown>;\n };\n cachedMetadata?: import(\"./storage.js\").CachedServerMetadata;\n onUpdate: (server: McpServer) => void;\n onUpdateConfig: (\n id: string,\n config: Partial<McpServerConfig>\n ) => Promise<void>;\n onUpdateDisplayName: (id: string, displayName: string) => Promise<void>;\n onReconnect: (id: string) => Promise<void>;\n rpcWrapTransport?: (transport: Transport, serverId: string) => Transport;\n onGlobalSamplingRequest?: (\n request: PendingSamplingRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: SamplingCreateMessageResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n onGlobalElicitationRequest?: (\n request: PendingElicitationRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: ElicitResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n}\n\n/**\n * Wraps a single MCP connection (useMcp) and manages per-server notifications,\n * pending sampling and elicitation requests, and exposes state updates to a parent.\n *\n * This internal component wires the MCP hook callbacks to local queues/handlers,\n * applies optional transport wrappers (e.g., RPC logging), maintains notification\n * history with unread tracking, and calls `onUpdate` with an enriched `McpServer`\n * view when meaningful server state changes occur.\n *\n * @param id - Unique identifier for the server instance\n * @param options - Configuration passed to the underlying MCP hook; callbacks for sampling, elicitation, and notifications are handled by this wrapper and therefore excluded from the forwarded options\n * @param onUpdate - Callback invoked with the current `McpServer` representation when the server's meaningful state changes\n * @param rpcWrapTransport - Optional transport wrapper (typically for RPC logging) that will be composed with the user's `wrapTransport` if provided\n * @param onGlobalSamplingRequest - Optional global handler invoked whenever a sampling request is enqueued; receives the request, server id/name, and approve/reject handlers\n * @param onGlobalElicitationRequest - Optional global handler invoked whenever an elicitation request is enqueued; receives the request, server id/name, and approve/reject handlers\n */\nfunction McpServerWrapper({\n id,\n options,\n defaultCallbackUrl,\n defaultOAuthProxyUrl,\n defaultProxyConfig,\n defaultAutoProxyFallback,\n clientInfo: providerClientInfo,\n cachedMetadata,\n onUpdate,\n onUpdateConfig,\n onUpdateDisplayName,\n onReconnect,\n rpcWrapTransport,\n onGlobalSamplingRequest,\n onGlobalElicitationRequest,\n}: McpServerWrapperProps) {\n // Extract callback options (these don't need to be passed to useMcp)\n const {\n displayName,\n onSamplingRequest,\n onElicitationRequest,\n onNotificationReceived,\n wrapTransport: optionsWrapTransport,\n } = options;\n\n // Memoize the options passed to useMcp to prevent render loops\n // The spread operator creates new objects every render, which causes\n // useMcp's callbacks (connect, retry) to be recreated, triggering the\n // autoRetry effect repeatedly\n const mcpOptions = useMemo(() => {\n const {\n displayName: _displayName,\n onSamplingRequest: _onSamplingRequest,\n onElicitationRequest: _onElicitationRequest,\n onNotificationReceived: _onNotificationReceived,\n wrapTransport: _wrapTransport,\n ...rest\n } = options;\n\n // Merge defaults from provider with server-specific options\n // Server-specific options take precedence over defaults\n return {\n ...rest,\n // Use server-specific callbackUrl if provided, otherwise use provider default\n callbackUrl: rest.callbackUrl || defaultCallbackUrl,\n oauthProxyUrl: rest.oauthProxyUrl || defaultOAuthProxyUrl,\n // Use server-specific proxyConfig if provided, otherwise use default\n proxyConfig: rest.proxyConfig || defaultProxyConfig,\n // Use server-specific autoProxyFallback if provided, otherwise use default\n autoProxyFallback:\n rest.autoProxyFallback !== undefined\n ? rest.autoProxyFallback\n : defaultAutoProxyFallback,\n // Merge provider clientInfo with server-specific clientInfo\n // Server-specific takes precedence\n clientInfo: rest.clientInfo\n ? providerClientInfo\n ? { ...providerClientInfo, ...rest.clientInfo }\n : rest.clientInfo\n : providerClientInfo,\n // Pass cached metadata as initial server info if available\n _initialServerInfo: cachedMetadata,\n serverId: id,\n };\n }, [\n options,\n defaultCallbackUrl,\n defaultOAuthProxyUrl,\n defaultProxyConfig,\n defaultAutoProxyFallback,\n providerClientInfo,\n cachedMetadata,\n ]);\n\n // Merge user's wrapTransport with RPC logging wrapper\n const combinedWrapTransport = useMemo(() => {\n if (!rpcWrapTransport && !optionsWrapTransport) return undefined;\n\n return (transport: Transport) => {\n let wrapped = transport;\n\n // Apply RPC logging first if enabled\n if (rpcWrapTransport) {\n wrapped = rpcWrapTransport(wrapped, id);\n }\n\n // Then apply user's wrapper if provided\n if (optionsWrapTransport) {\n wrapped = optionsWrapTransport(wrapped, id);\n }\n\n return wrapped;\n };\n }, [rpcWrapTransport, optionsWrapTransport, id]);\n\n const queues = useMcpServerQueues({\n serverId: id,\n serverName: displayName || id,\n onNotificationReceived,\n onSamplingRequest,\n onElicitationRequest,\n onGlobalSamplingRequest,\n onGlobalElicitationRequest,\n });\n\n // Use the core useMcp hook with our callbacks\n const mcp = useMcp({\n ...mcpOptions,\n onNotification: queues.onNotification,\n onSampling: queues.onSampling,\n onElicitation: queues.onElicitation,\n wrapTransport: combinedWrapTransport,\n });\n\n useEffect(() => {\n if (mcp.state !== \"ready\") {\n queues.rejectAll(\"MCP server connection is no longer active\");\n }\n }, [mcp.state, queues.rejectAll]);\n\n const updateConfig = useCallback(\n (config: Partial<McpServerConfig>) => onUpdateConfig(id, config),\n [id, onUpdateConfig]\n );\n\n const setHeaders = useCallback(\n (headers: Record<string, string> | undefined) => {\n const proxyAddress = options.proxyConfig?.proxyAddress?.trim();\n if (options.connectionMode === \"proxy\" && proxyAddress) {\n return onUpdateConfig(id, {\n proxyConfig: {\n ...options.proxyConfig,\n proxyAddress,\n ...(headers ? { headers } : {}),\n },\n headers: undefined,\n });\n }\n return onUpdateConfig(id, { headers });\n },\n [id, options.connectionMode, options.proxyConfig, onUpdateConfig]\n );\n\n const setDisplayName = useCallback(\n (displayName: string) => onUpdateDisplayName(id, displayName),\n [id, onUpdateDisplayName]\n );\n\n const reconnect = useCallback(() => onReconnect(id), [id, onReconnect]);\n\n // Update parent when state changes\n const onUpdateRef = useRef(onUpdate);\n const prevServerRef = useRef<McpServer | null>(null);\n\n useEffect(() => {\n onUpdateRef.current = onUpdate;\n }, [onUpdate]);\n\n useEffect(() => {\n const server: McpServer = {\n ...pickLiveServerConfig(options),\n ...mcp,\n id,\n displayName: displayName || options.displayName || id,\n notifications: queues.notifications,\n unreadNotificationCount: queues.unreadNotificationCount,\n markNotificationRead: queues.markNotificationRead,\n markAllNotificationsRead: queues.markAllNotificationsRead,\n clearNotifications: queues.clearNotifications,\n pendingSamplingRequests: queues.pendingSamplingRequests,\n approveSampling: queues.approveSampling,\n rejectSampling: queues.rejectSampling,\n pendingElicitationRequests: queues.pendingElicitationRequests,\n approveElicitation: queues.approveElicitation,\n rejectElicitation: queues.rejectElicitation,\n updateConfig,\n setHeaders,\n setDisplayName,\n reconnect,\n };\n\n // Only update if something actually changed\n const prevServer = prevServerRef.current;\n if (!prevServer || !isSameMcpServer(prevServer, server)) {\n prevServerRef.current = server;\n onUpdateRef.current(server);\n } else {\n providerLogger.debug(\n `[McpServerWrapper ${id}] No meaningful changes detected, skipping onUpdate`\n );\n }\n }, [\n id,\n displayName,\n options,\n options.url,\n // Primitive values that indicate meaningful state changes\n mcp.state,\n mcp.error,\n mcp.authUrl,\n mcp.tools,\n mcp.resources,\n mcp.resourceTemplates,\n mcp.prompts,\n mcp.skills,\n mcp.serverInfo,\n mcp.capabilities,\n mcp.protocolEra,\n mcp.protocolVersion,\n mcp.instructions,\n mcp.extensions,\n mcp.authTokens,\n mcp.authorization,\n // Functions excluded - they're stable via useCallback in useMcp\n // mcp.log excluded - log changes shouldn't trigger provider updates\n // mcp.client excluded - client reference stability handled by manual check\n queues,\n updateConfig,\n setHeaders,\n setDisplayName,\n reconnect,\n ]);\n\n return null;\n}\n\n// ===== Provider =====\n\n/**\n * Props for McpClientProvider\n */\nexport interface McpClientProviderProps {\n /** React subtree that can access the MCP client context. */\n children: ReactNode;\n\n /**\n * Initial servers configuration (like Python MCPClient.from_dict)\n * Servers defined here will be auto-connected on mount\n */\n mcpServers?: Record<string, McpServerConfig>;\n\n /**\n * Default OAuth callback URL for all servers.\n * Can be overridden per-server via the callbackUrl option in addServer().\n * Useful when the app is mounted at a sub-path (e.g. /inspector) so the\n * OAuth redirect lands on the correct route without requiring a server-side\n * redirect shim.\n */\n defaultCallbackUrl?: string;\n\n /** Default same-origin OAuth BFF URL for browser OAuth requests. */\n defaultOAuthProxyUrl?: string;\n\n /**\n * Default proxy configuration for all servers\n * Can be overridden per-server in addServer() options\n */\n defaultProxyConfig?: {\n /** Default MCP proxy endpoint. */\n proxyAddress?: string;\n /** Default headers sent to the MCP proxy. */\n headers?: Record<string, string>;\n };\n\n /**\n * Enable automatic proxy fallback for all servers by default\n * When enabled, if a direct connection fails with FastMCP or CORS errors,\n * automatically retries using proxy configuration\n * @defaultValue false\n */\n defaultAutoProxyFallback?:\n | boolean\n | {\n /** Whether automatic proxy fallback is enabled. */\n enabled?: boolean;\n /** Proxy endpoint used after direct connection fails. */\n proxyAddress?: string;\n };\n\n /**\n * Default connection options merged under each server's options (per-server wins).\n * Useful for app-wide auth UX such as `preventAutoAuth` or `useRedirectFlow`.\n */\n defaultServerConfig?: Partial<McpServerConfig>;\n\n /**\n * Client info for all servers (used for OAuth registration and server capabilities).\n * Can be overridden per-server in addServer() options.\n *\n * The optional `capabilities` field sets default MCP capabilities advertised to\n * every server managed by this provider (e.g. MCP Apps / SEP-1865 extensions).\n * It is merged with per-server `clientOptions.capabilities` (per-server takes\n * precedence) and is stripped from the actual MCP `clientInfo` wire field.\n */\n clientInfo?: {\n /** Client name displayed on OAuth consent pages (required) */\n name: string;\n /** Client title/display name */\n title?: string;\n /** Client version (required) */\n version: string;\n /** Client description */\n description?: string;\n /** Client icons (first icon used as logo_uri for OAuth) */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Client website URL (used as client_uri for OAuth) */\n websiteUrl?: string;\n /**\n * Default capabilities advertised to all servers managed by this provider.\n * Per-server `clientOptions.capabilities` are merged on top, with per-server\n * values taking precedence. Stripped from the MCP `clientInfo` wire field.\n *\n * @example\n * ```tsx\n * capabilities: {\n * views: true,\n * // or explicitly:\n * extensions: {\n * \"io.modelcontextprotocol/ui\": { mimeTypes: [\"text/html;profile=mcp-app\"] },\n * },\n * }\n * ```\n */\n capabilities?: Record<string, unknown>;\n };\n\n /**\n * Storage provider for persisting server configurations\n * When provided, automatically loads servers on mount and saves on changes\n */\n storageProvider?: StorageProvider;\n\n /**\n * Enable RPC logging for debugging (browser only)\n * Logs all MCP protocol messages to console\n */\n enableRpcLogging?: boolean;\n\n /**\n * Callback when a server is added\n */\n onServerAdded?: (id: string, server: McpServer) => void;\n\n /**\n * Callback when a server is removed\n */\n onServerRemoved?: (id: string) => void;\n\n /**\n * Callback when a server's state changes\n */\n onServerStateChange?: (id: string, state: McpServer[\"state\"]) => void;\n\n /**\n * Callback when a sampling request is received from any server\n * @param request - The sampling request details\n * @param serverId - The ID of the server that sent the request\n * @param serverName - The name of the server\n * @param approve - Function to approve the request\n * @param reject - Function to reject the request\n */\n onSamplingRequest?: (\n request: PendingSamplingRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: SamplingCreateMessageResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n\n /**\n * Callback when an elicitation request is received from any server\n * @param request - The elicitation request details\n * @param serverId - The ID of the server that sent the request\n * @param serverName - The name of the server\n * @param approve - Function to approve the request\n * @param reject - Function to reject the request\n */\n onElicitationRequest?: (\n request: PendingElicitationRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: ElicitResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n}\n\n/**\n * Provider for managing multiple MCP server connections\n *\n * Provides a context for adding/removing servers and accessing their state.\n * Each server maintains its own connection, notification history, and\n * pending sampling/elicitation requests.\n *\n * Supports:\n * - Initial server configuration via `mcpServers` prop\n * - Persistence via pluggable `storageProvider`\n * - RPC logging for debugging\n * - Lifecycle callbacks for state changes\n *\n * @example\n * ```tsx\n * // With initial servers\n * <McpClientProvider\n * mcpServers={{\n * linear: { url: \"https://mcp.linear.app/sse\" },\n * github: { url: \"https://mcp.github.com/mcp\" }\n * }}\n * >\n * <MyApp />\n * </McpClientProvider>\n *\n * // With persistence\n * <McpClientProvider\n * storageProvider={new LocalStorageProvider(\"my-servers\")}\n * enableRpcLogging={true}\n * >\n * <MyApp />\n * </McpClientProvider>\n * ```\n */\nexport function McpClientProvider({\n children,\n mcpServers,\n defaultCallbackUrl,\n defaultOAuthProxyUrl,\n defaultProxyConfig,\n defaultAutoProxyFallback = false,\n defaultServerConfig,\n clientInfo,\n storageProvider,\n enableRpcLogging = false,\n onServerAdded,\n onServerRemoved,\n onServerStateChange,\n onSamplingRequest,\n onElicitationRequest,\n}: McpClientProviderProps) {\n const [serverConfigs, setServerConfigs] = useState<ServerConfig[]>([]);\n const [servers, setServers] = useState<McpServer[]>([]);\n const [serverRevisions, setServerRevisions] = useState<\n Record<string, number>\n >({});\n const [storageLoaded, setStorageLoaded] = useState(false);\n const didLoadInitialServers = useRef(false);\n\n // Mirror of `servers` for synchronous access from event handlers\n // (specifically `removeServer` / `updateServer`). Reading the latest\n // servers from a ref lets us run the wrapper teardown side effects\n // (`disconnect()` / `clearStorage()`) OUTSIDE the `setServers` updater\n // function. Those wrapper callbacks fire synchronous setStates on the\n // wrapper itself (`setLog` via `addLog`, `setAuthUrl`); when invoked\n // inside an updater they land during the provider's render phase, which\n // React reports as\n // \"Cannot update a component (`McpServerWrapper`) while rendering a\n // different component (`McpClientProvider`)\".\n // Reading from the ref keeps the callback identities stable too — we\n // don't have to add `servers` to their dependency arrays, which would\n // re-create the callbacks on every connection-state tick and trigger\n // downstream effects in consumers.\n const serversRef = useRef<McpServer[]>([]);\n useEffect(() => {\n serversRef.current = servers;\n }, [servers]);\n\n // Store cached server metadata\n const cachedMetadataRef = useRef<\n Record<string, import(\"./storage.js\").CachedServerMetadata>\n >({});\n\n // Load RPC transport wrapper if enabled\n const [rpcWrapTransport, setRpcWrapTransport] = useState<\n ((transport: any, serverId: string) => any) | undefined\n >(undefined);\n const [rpcLoggingReady, setRpcLoggingReady] = useState(false);\n\n useEffect(() => {\n if (!enableRpcLogging || typeof window === \"undefined\") {\n setRpcWrapTransport(undefined);\n setRpcLoggingReady(true); // RPC logging not needed, mark as ready\n return;\n }\n\n // Load the RPC logger dynamically\n import(\"./rpc-logger.js\")\n .then((module) => {\n providerLogger.debug(\"[McpClientProvider] RPC logger loaded\");\n setRpcWrapTransport(() => module.wrapTransportForLogging);\n setRpcLoggingReady(true); // RPC logging loaded, mark as ready\n })\n .catch((err) => {\n providerLogger.error(\n \"[McpClientProvider] Failed to load RPC logger:\",\n err\n );\n setRpcWrapTransport(undefined);\n setRpcLoggingReady(true); // Failed to load, but still mark as ready to unblock\n });\n }, [enableRpcLogging]);\n\n // Load servers from storage on mount\n // Wait for RPC logging to be ready before loading servers\n useEffect(() => {\n if (!rpcLoggingReady) {\n providerLogger.debug(\n \"[McpClientProvider] Waiting for RPC logging to be ready before loading servers\"\n );\n return;\n }\n if (didLoadInitialServers.current) return;\n didLoadInitialServers.current = true;\n\n const loadServers = async () => {\n providerLogger.debug(\n \"[McpClientProvider] Loading servers, storageProvider:\",\n !!storageProvider,\n \"mcpServers:\",\n mcpServers\n );\n\n if (!storageProvider) {\n // No storage provider - just load from mcpServers prop if provided\n if (mcpServers) {\n const configs = Object.entries(mcpServers).map(([id, options]) => ({\n id,\n options,\n }));\n providerLogger.debug(\n \"[McpClientProvider] Loaded from mcpServers prop:\",\n configs.length\n );\n setServerConfigs(configs);\n }\n setStorageLoaded(true);\n return;\n }\n\n // Has storage provider - load from storage and merge with mcpServers\n try {\n const storedServers = await Promise.resolve(\n storageProvider.getServers()\n );\n\n providerLogger.debug(\n \"[McpClientProvider] Loaded from storage:\",\n Object.keys(storedServers).length\n );\n\n // Load cached metadata if supported by storage provider\n if (storageProvider.getServerMetadata) {\n try {\n const serverIds = Object.keys(storedServers);\n const metadataPromises = serverIds.map(async (id) => {\n const metadata = await Promise.resolve(\n storageProvider.getServerMetadata!(id)\n );\n return [id, metadata] as const;\n });\n const metadataEntries = await Promise.all(metadataPromises);\n cachedMetadataRef.current = Object.fromEntries(\n metadataEntries.filter(\n (\n entry\n ): entry is [\n string,\n import(\"./storage.js\").CachedServerMetadata,\n ] => entry[1] !== undefined\n )\n );\n providerLogger.debug(\n \"[McpClientProvider] Loaded cached metadata for\",\n Object.keys(cachedMetadataRef.current).length,\n \"servers\"\n );\n } catch (metadataError) {\n providerLogger.warn(\n \"[McpClientProvider] Failed to load cached metadata:\",\n metadataError\n );\n }\n }\n\n // Merge with initial mcpServers (mcpServers takes precedence)\n const mergedServers = { ...storedServers, ...mcpServers };\n\n // Convert to ServerConfig array\n const configs = Object.entries(mergedServers).map(([id, options]) => ({\n id,\n options,\n }));\n\n providerLogger.debug(\n \"[McpClientProvider] Total servers after merge:\",\n configs.length\n );\n setServerConfigs(configs);\n setStorageLoaded(true);\n } catch (error) {\n providerLogger.error(\n \"[McpClientProvider] Failed to load from storage:\",\n error\n );\n // Fall back to mcpServers only\n if (mcpServers) {\n const configs = Object.entries(mcpServers).map(([id, options]) => ({\n id,\n options,\n }));\n setServerConfigs(configs);\n }\n setStorageLoaded(true);\n }\n };\n\n loadServers();\n }, [storageProvider, mcpServers, rpcLoggingReady]);\n\n // Save servers to storage when they change\n useEffect(() => {\n if (!storageProvider || !storageLoaded) return;\n\n const saveServers = async () => {\n try {\n const serversToSave = serverConfigs.reduce(\n (acc, config) => {\n acc[config.id] = toPersistedServerConfig(config.options);\n return acc;\n },\n {} as Record<string, PersistedMcpServerConfig>\n );\n\n await Promise.resolve(storageProvider.setServers(serversToSave));\n } catch (error) {\n providerLogger.error(\n \"[McpClientProvider] Failed to save to storage:\",\n error\n );\n }\n };\n\n saveServers();\n }, [serverConfigs, storageProvider, storageLoaded]);\n\n const handleServerUpdate = useCallback(\n (updatedServer: McpServer) => {\n providerLogger.debug(\n `[McpClientProvider] handleServerUpdate called for server ${updatedServer.id}`,\n {\n toolCount: updatedServer.tools.length,\n state: updatedServer.state,\n }\n );\n\n const callbacksToRun: Array<() => void> = [];\n\n setServers((prev) => {\n const index = prev.findIndex((s) => s.id === updatedServer.id);\n const isNewServer = index === -1;\n\n if (isNewServer) {\n providerLogger.debug(\n `[McpClientProvider] Adding new server ${updatedServer.id} to state`\n );\n // Defer callbacks outside the state updater to avoid triggering\n // render-phase updates in user-provided handlers.\n callbacksToRun.push(() =>\n onServerAdded?.(updatedServer.id, updatedServer)\n );\n return [...prev, updatedServer];\n }\n\n // Check if actually changed to avoid loops\n const current = prev[index];\n const stateChanged = current.state !== updatedServer.state;\n const serverInfoChanged =\n current.serverInfo !== updatedServer.serverInfo;\n\n providerLogger.debug(\n `[McpClientProvider] Comparing server ${updatedServer.id}:`,\n {\n toolsChanged: current.tools !== updatedServer.tools,\n currentToolCount: current.tools.length,\n updatedToolCount: updatedServer.tools.length,\n stateChanged,\n }\n );\n\n if (isSameMcpServer(current, updatedServer)) {\n providerLogger.debug(\n `[McpClientProvider] No changes detected for server ${updatedServer.id}, skipping update`\n );\n return prev;\n }\n\n providerLogger.debug(\n `[McpClientProvider] Updating server ${updatedServer.id} in state`\n );\n\n // State changed - call callback\n if (stateChanged) {\n callbacksToRun.push(() =>\n onServerStateChange?.(updatedServer.id, updatedServer.state)\n );\n }\n\n // Server info changed - update cached metadata\n if (\n serverInfoChanged &&\n updatedServer.serverInfo &&\n storageProvider?.setServerMetadata\n ) {\n const metadata: import(\"./storage.js\").CachedServerMetadata = {\n name: updatedServer.serverInfo.name,\n version: updatedServer.serverInfo.version,\n title: updatedServer.serverInfo.title,\n websiteUrl: updatedServer.serverInfo.websiteUrl,\n icons: updatedServer.serverInfo.icons,\n icon: updatedServer.serverInfo.icon,\n };\n\n // Update cached metadata ref\n cachedMetadataRef.current[updatedServer.id] = metadata;\n\n // Save to storage asynchronously\n Promise.resolve(\n storageProvider.setServerMetadata(updatedServer.id, metadata)\n ).catch((err) => {\n providerLogger.error(\n \"[McpClientProvider] Failed to save server metadata:\",\n err\n );\n });\n }\n\n const newServers = [...prev];\n newServers[index] = updatedServer;\n return newServers;\n });\n\n if (callbacksToRun.length > 0) {\n queueMicrotask(() => {\n callbacksToRun.forEach((callback) => callback());\n });\n }\n },\n [onServerAdded, onServerStateChange, storageProvider]\n );\n\n const addServer = useCallback((id: string, options: McpServerConfig) => {\n setServerConfigs((prev) => {\n if (prev.find((s) => s.id === id)) return prev;\n providerLogger.debug(\n \"[McpClientProvider] Adding new server to configs:\",\n id\n );\n return [...prev, { id, options }];\n });\n }, []);\n\n const removeServer = useCallback(\n async (id: string, opts?: { clearCredentials?: boolean }) => {\n // Capture the wrapper from the latest state BEFORE scheduling state\n // updates. The wrapper teardown (`disconnect()` / `clearStorage()`)\n // synchronously fires setState on the wrapper itself; running it here\n // — in the event-handler context — keeps those updates out of the\n // `setServers` updater, which would otherwise execute during the\n // provider's render phase and trigger\n // \"Cannot update a component (`McpServerWrapper`) while rendering\n // a different component (`McpClientProvider`)\".\n const captured = serversRef.current.find((s) => s.id === id);\n\n setServers((prev) => prev.filter((s) => s.id !== id));\n setServerConfigs((prev) => prev.filter((s) => s.id !== id));\n setServerRevisions((prev) => {\n const { [id]: _removed, ...remaining } = prev;\n return remaining;\n });\n\n if (captured?.disconnect) await captured.disconnect();\n // Only wipe persisted OAuth credentials on an explicit logout/forget.\n // Routine removal (and the remove+add churn callers use) must preserve\n // tokens — wrappers sharing a URL hash would otherwise destroy each\n // other's freshly minted credentials.\n if (opts?.clearCredentials && captured?.clearStorage) {\n await captured.clearStorage();\n }\n\n if (enableRpcLogging) {\n const { clearRpcLogs } = await import(\"./rpc-logger.js\");\n clearRpcLogs(id);\n }\n onServerRemoved?.(id);\n },\n [enableRpcLogging, onServerRemoved]\n );\n\n const updateServer = useCallback(\n async (id: string, options: Partial<McpServerConfig>) => {\n const currentConfig = serverConfigs.find((s) => s.id === id);\n if (!currentConfig) {\n providerLogger.warn(\n `[McpClientProvider] Cannot update server \"${id}\" - not found`\n );\n return;\n }\n\n const updatedOptions: McpServerConfig = {\n ...currentConfig.options,\n ...options,\n };\n\n if (\n sameSerializedValue(\n pickLiveServerConfig(currentConfig.options),\n pickLiveServerConfig(updatedOptions)\n )\n ) {\n return;\n }\n\n const captured = serversRef.current.find((s) => s.id === id);\n\n // Complete teardown before remounting so an old transport cannot race\n // the replacement connection.\n await captured?.disconnect();\n\n setServers((prev) => prev.filter((s) => s.id !== id));\n setServerConfigs((prev) =>\n prev.map((server) =>\n server.id === id ? { id, options: updatedOptions } : server\n )\n );\n setServerRevisions((prev) => ({\n ...prev,\n [id]: (prev[id] ?? 0) + 1,\n }));\n },\n [serverConfigs]\n );\n\n const reconnectServer = useCallback(\n async (id: string) => {\n const currentConfig = serverConfigs.find((s) => s.id === id);\n if (!currentConfig) {\n providerLogger.warn(\n `[McpClientProvider] Cannot reconnect server \"${id}\" - not found`\n );\n return;\n }\n\n const captured = serversRef.current.find((s) => s.id === id);\n await captured?.disconnect();\n\n setServers((prev) => prev.filter((s) => s.id !== id));\n setServerRevisions((prev) => ({\n ...prev,\n [id]: (prev[id] ?? 0) + 1,\n }));\n },\n [serverConfigs]\n );\n\n const updateServerMetadata = useCallback(\n async (id: string, metadata: { name: string }) => {\n return new Promise<void>((resolve) => {\n const currentConfig = serverConfigs.find((s) => s.id === id);\n if (!currentConfig) {\n providerLogger.warn(\n `[McpClientProvider] Cannot update server metadata for \"${id}\" - not found`\n );\n resolve();\n return;\n }\n\n const updatedOptions: McpServerConfig = {\n ...currentConfig.options,\n displayName: metadata.name,\n };\n\n setServers((prev) =>\n prev.map((server) =>\n server.id === id\n ? { ...server, displayName: metadata.name }\n : server\n )\n );\n\n setServerConfigs((prev) => {\n const updated = prev.map((s) =>\n s.id === id ? { id, options: updatedOptions } : s\n );\n setTimeout(() => resolve(), 0);\n return updated;\n });\n });\n },\n [serverConfigs]\n );\n\n const getServer = useCallback(\n (id: string) => {\n return servers.find((s) => s.id === id);\n },\n [servers]\n );\n\n const contextValue = useMemo(\n () => ({\n servers,\n addServer,\n removeServer,\n updateServerMetadata,\n updateServer,\n getServer,\n storageLoaded,\n }),\n [\n servers,\n addServer,\n removeServer,\n updateServerMetadata,\n updateServer,\n getServer,\n storageLoaded,\n ]\n );\n\n // Strip `capabilities` from clientInfo — it is a provider-level default for\n // MCP capabilities, not a standard MCP clientInfo wire field.\n const { capabilities: defaultCapabilities, ...clientInfoWithoutCaps } =\n clientInfo || {};\n const clientInfoForWrapper = useMemo(\n () =>\n Object.keys(clientInfoWithoutCaps).length\n ? (clientInfoWithoutCaps as typeof clientInfo)\n : undefined,\n [clientInfo]\n );\n\n // Merge defaultCapabilities into each server's clientOptions.capabilities.\n // Memoized so the merged options objects are stable references across renders —\n // a new object on every render would cause McpServerWrapper to reconnect.\n const mergedServerConfigs = useMemo(\n () =>\n serverConfigs.map((config) => {\n let options: McpServerConfig = defaultServerConfig\n ? { ...defaultServerConfig, ...config.options }\n : config.options;\n\n if (defaultCapabilities) {\n options = {\n ...options,\n clientOptions: {\n ...options.clientOptions,\n capabilities: {\n ...defaultCapabilities,\n ...options.clientOptions?.capabilities,\n },\n },\n };\n }\n\n return { id: config.id, options };\n }),\n [serverConfigs, defaultCapabilities, defaultServerConfig]\n );\n\n // ponytail: OAuth callback must not auto-connect saved servers — a 401 on that\n // page runs SDK auth() and overwrites the in-flight PKCE verifier before finishAuth.\n const skipServerConnections =\n typeof window !== \"undefined\" &&\n /\\/oauth\\/callback\\/?$/.test(window.location.pathname);\n\n return (\n <McpClientContext.Provider value={contextValue}>\n {children}\n {!skipServerConnections &&\n mergedServerConfigs.map((config) => (\n <McpServerWrapper\n key={`${config.id}-v${serverRevisions[config.id] ?? 0}`}\n id={config.id}\n options={config.options}\n defaultCallbackUrl={defaultCallbackUrl}\n defaultOAuthProxyUrl={defaultOAuthProxyUrl}\n defaultProxyConfig={defaultProxyConfig}\n defaultAutoProxyFallback={defaultAutoProxyFallback}\n clientInfo={clientInfoForWrapper}\n cachedMetadata={cachedMetadataRef.current[config.id]}\n onUpdate={handleServerUpdate}\n onUpdateConfig={updateServer}\n onUpdateDisplayName={(id, displayName) =>\n updateServerMetadata(id, { name: displayName })\n }\n onReconnect={reconnectServer}\n rpcWrapTransport={rpcWrapTransport}\n onGlobalSamplingRequest={onSamplingRequest}\n onGlobalElicitationRequest={onElicitationRequest}\n />\n ))}\n </McpClientContext.Provider>\n );\n}\n\n// ===== Hooks =====\n\n/**\n * Hook to access the MCP client context\n *\n * Provides access to all servers and management functions.\n * Must be used within a McpClientProvider.\n *\n * @example\n * ```tsx\n * const {\n * servers,\n * addServer,\n * removeServer,\n * updateServer,\n * updateServerMetadata,\n * } = useMcpClient();\n *\n * // Add a server\n * addServer(\"linear\", { url: \"https://mcp.linear.app/sse\" });\n *\n * // Update a server's configured display name without reconnecting\n * await updateServerMetadata(\"linear\", { name: \"Linear Production\" });\n *\n * // Update connection-affecting configuration and reconnect\n * await updateServer(\"linear\", { headers: { Authorization: \"Bearer ...\" } });\n * // Or from a connected server handle:\n * await servers[0].setHeaders({ Authorization: \"Bearer ...\" });\n *\n * // Rename without reconnecting\n * await servers[0].setDisplayName(\"Linear Production\");\n *\n * // Access servers\n * servers.forEach(server => {\n * console.log(server.id, server.state);\n * });\n * ```\n */\nexport function useMcpClient(): McpClientContextType {\n const context = useContext(McpClientContext);\n if (!context) {\n throw new Error(\"useMcpClient must be used within a McpClientProvider\");\n }\n return context;\n}\n\n/**\n * Retrieve the McpServer object for a given server id.\n *\n * @returns The `McpServer` for the provided `id`, or `undefined` if no matching server is registered.\n * @throws If called outside of a `McpClientProvider` (context not available).\n */\nexport function useMcpServer(id: string): McpServer | undefined {\n const { servers } = useMcpClient();\n return useMemo(\n () => servers.find((server) => server.id === id),\n [id, servers]\n );\n}\n","import type {\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n Notification,\n} from \"@modelcontextprotocol/client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\nimport type {\n McpNotification,\n PendingElicitationRequest,\n PendingSamplingRequest,\n} from \"./types.js\";\n\nconst MAX_NOTIFICATIONS = 500;\nconst REVERSE_REQUEST_TIMEOUT_MS = 5 * 60_000;\n\ntype PendingResolver<T> = {\n resolve: (value: T) => void;\n reject: (reason: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\n/** Per-server UI queues for notifications, sampling, and elicitation. */\nexport function useMcpServerQueues(params: {\n serverId: string;\n serverName: string;\n onNotificationReceived?: (notification: McpNotification) => void;\n onSamplingRequest?: (request: PendingSamplingRequest) => void;\n onElicitationRequest?: (request: PendingElicitationRequest) => void;\n onGlobalSamplingRequest?: (\n request: PendingSamplingRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: SamplingCreateMessageResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n onGlobalElicitationRequest?: (\n request: PendingElicitationRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: ElicitResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n}) {\n const [notifications, setNotifications] = useState<McpNotification[]>([]);\n const [pendingSamplingRequests, setPendingSamplingRequests] = useState<\n PendingSamplingRequest[]\n >([]);\n const [pendingElicitationRequests, setPendingElicitationRequests] = useState<\n PendingElicitationRequest[]\n >([]);\n const samplingCounter = useRef(0);\n const elicitationCounter = useRef(0);\n const samplingResolvers = useRef(\n new Map<string, PendingResolver<SamplingCreateMessageResult>>()\n );\n const elicitationResolvers = useRef(\n new Map<string, PendingResolver<ElicitResult>>()\n );\n\n const rejectAll = useCallback((reason: string) => {\n for (const resolver of samplingResolvers.current.values()) {\n clearTimeout(resolver.timeout);\n resolver.reject(new Error(reason));\n }\n samplingResolvers.current.clear();\n for (const resolver of elicitationResolvers.current.values()) {\n clearTimeout(resolver.timeout);\n resolver.reject(new Error(reason));\n }\n elicitationResolvers.current.clear();\n setPendingSamplingRequests([]);\n setPendingElicitationRequests([]);\n }, []);\n\n useEffect(\n () => () => rejectAll(\"MCP server connection was removed\"),\n [rejectAll]\n );\n\n const onNotification = useCallback(\n (notification: Notification) => {\n const entry: McpNotification = {\n id:\n globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`,\n method: notification.method,\n params: notification.params as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n read: false,\n };\n setNotifications((previous) =>\n [entry, ...previous].slice(0, MAX_NOTIFICATIONS)\n );\n params.onNotificationReceived?.(entry);\n },\n [params.onNotificationReceived]\n );\n\n const approveSampling = useCallback(\n (id: string, result: SamplingCreateMessageResult) => {\n const resolver = samplingResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n samplingResolvers.current.delete(id);\n setPendingSamplingRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.resolve(result);\n },\n []\n );\n\n const rejectSampling = useCallback((id: string, error?: string) => {\n const resolver = samplingResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n samplingResolvers.current.delete(id);\n setPendingSamplingRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.reject(new Error(error ?? \"User rejected sampling request\"));\n }, []);\n\n const onSampling = useCallback(\n (requestParams: SamplingCreateMessageParams) =>\n new Promise<SamplingCreateMessageResult>((resolve, reject) => {\n const id = `sampling-${samplingCounter.current++}`;\n const request: PendingSamplingRequest = {\n id,\n request: { method: \"sampling/createMessage\", params: requestParams },\n timestamp: Date.now(),\n serverName: params.serverName,\n };\n const timeout = setTimeout(\n () => rejectSampling(id, \"Sampling request timed out\"),\n REVERSE_REQUEST_TIMEOUT_MS\n );\n samplingResolvers.current.set(id, { resolve, reject, timeout });\n setPendingSamplingRequests((previous) => [...previous, request]);\n params.onSamplingRequest?.(request);\n params.onGlobalSamplingRequest?.(\n request,\n params.serverId,\n params.serverName,\n approveSampling,\n rejectSampling\n );\n }),\n [approveSampling, params, rejectSampling]\n );\n\n const approveElicitation = useCallback((id: string, result: ElicitResult) => {\n const resolver = elicitationResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n elicitationResolvers.current.delete(id);\n setPendingElicitationRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.resolve(result);\n }, []);\n\n const rejectElicitation = useCallback((id: string, error?: string) => {\n const resolver = elicitationResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n elicitationResolvers.current.delete(id);\n setPendingElicitationRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.reject(new Error(error ?? \"User rejected elicitation request\"));\n }, []);\n\n const onElicitation = useCallback(\n (requestParams: ElicitRequestFormParams | ElicitRequestURLParams) =>\n new Promise<ElicitResult>((resolve, reject) => {\n const id = `elicitation-${elicitationCounter.current++}`;\n const request: PendingElicitationRequest = {\n id,\n request: requestParams,\n timestamp: Date.now(),\n serverName: params.serverName,\n };\n const timeout = setTimeout(\n () => rejectElicitation(id, \"Elicitation request timed out\"),\n REVERSE_REQUEST_TIMEOUT_MS\n );\n elicitationResolvers.current.set(id, { resolve, reject, timeout });\n setPendingElicitationRequests((previous) => [...previous, request]);\n params.onElicitationRequest?.(request);\n params.onGlobalElicitationRequest?.(\n request,\n params.serverId,\n params.serverName,\n approveElicitation,\n rejectElicitation\n );\n }),\n [approveElicitation, params, rejectElicitation]\n );\n\n const markNotificationRead = useCallback((id: string) => {\n setNotifications((previous) =>\n previous.map((notification) =>\n notification.id === id ? { ...notification, read: true } : notification\n )\n );\n }, []);\n const markAllNotificationsRead = useCallback(\n () =>\n setNotifications((previous) =>\n previous.map((entry) => ({ ...entry, read: true }))\n ),\n []\n );\n const clearNotifications = useCallback(() => setNotifications([]), []);\n\n return {\n notifications,\n pendingSamplingRequests,\n pendingElicitationRequests,\n unreadNotificationCount: notifications.filter((entry) => !entry.read)\n .length,\n markNotificationRead,\n markAllNotificationsRead,\n clearNotifications,\n approveSampling,\n rejectSampling,\n approveElicitation,\n rejectElicitation,\n onNotification,\n onSampling,\n onElicitation,\n rejectAll,\n };\n}\n","import {\n toPersistedServerConfig,\n type McpServerConfig,\n type PersistedMcpServerConfig,\n} from \"./types.js\";\n\n/** Cached presentation metadata for a managed MCP server. */\nexport interface CachedServerMetadata {\n /** Programmatic server name. */\n name?: string;\n /** Server version. */\n version?: string;\n /** Human-readable server title. */\n title?: string;\n /** Public server website. */\n websiteUrl?: string;\n /** Icons advertised by the server. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n }>;\n /** Resolved icon data URL used by the UI. */\n icon?: string;\n /** Unix timestamp in milliseconds when the metadata was cached. */\n cachedAt?: number;\n}\n\n/**\n * Persists managed server configurations and optional presentation metadata.\n *\n * Implementations may be synchronous or asynchronous.\n */\nexport interface StorageProvider {\n /** Returns all saved server configurations keyed by server ID. */\n getServers():\n | Promise<Record<string, PersistedMcpServerConfig>>\n | Record<string, PersistedMcpServerConfig>;\n /** Replaces all saved server configurations. */\n setServers(\n servers: Record<string, PersistedMcpServerConfig>\n ): Promise<void> | void;\n /** Saves one server configuration. */\n setServer(id: string, config: PersistedMcpServerConfig): Promise<void> | void;\n /** Removes one saved server configuration. */\n removeServer(id: string): Promise<void> | void;\n /** Removes all saved configurations and metadata. */\n clear(): Promise<void> | void;\n /** Returns cached metadata for one server, when supported. */\n getServerMetadata?(\n id: string\n ):\n | Promise<CachedServerMetadata | undefined>\n | CachedServerMetadata\n | undefined;\n /** Saves cached metadata for one server, when supported. */\n setServerMetadata?(\n id: string,\n metadata: CachedServerMetadata\n ): Promise<void> | void;\n /** Removes cached metadata for one server, when supported. */\n removeServerMetadata?(id: string): Promise<void> | void;\n}\n\n/** Stores managed server configurations in browser `localStorage`. */\nexport class LocalStorageProvider implements StorageProvider {\n private metadataKey: string;\n\n /**\n * Creates a browser storage provider.\n *\n * @param storageKey - Key used for configurations. Metadata uses the same key\n * with a `-metadata` suffix. Defaults to `\"mcp-client-servers\"`.\n */\n constructor(private storageKey: string = \"mcp-client-servers\") {\n this.metadataKey = `${storageKey}-metadata`;\n }\n\n /** Returns sanitized server configurations from `localStorage`. */\n getServers(): Record<string, PersistedMcpServerConfig> {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (!stored) return {};\n const parsed: unknown = JSON.parse(stored);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n const sanitized = Object.fromEntries(\n Object.entries(parsed).flatMap(([id, config]) =>\n config && typeof config === \"object\" && !Array.isArray(config)\n ? [\n [\n id,\n toPersistedServerConfig(config as McpServerConfig),\n ] as const,\n ]\n : []\n )\n );\n const serialized = JSON.stringify(sanitized);\n if (serialized !== stored) {\n try {\n localStorage.setItem(this.storageKey, serialized);\n } catch {\n console.error(\n \"[LocalStorageProvider] Failed to persist sanitized servers.\"\n );\n }\n }\n return sanitized;\n } catch {\n console.error(\"[LocalStorageProvider] Failed to load servers.\");\n return {};\n }\n }\n\n /** Replaces all saved server configurations. */\n setServers(servers: Record<string, PersistedMcpServerConfig>): void {\n try {\n const sanitized = Object.fromEntries(\n Object.entries(servers).map(([id, config]) => [\n id,\n toPersistedServerConfig(config),\n ])\n );\n localStorage.setItem(this.storageKey, JSON.stringify(sanitized));\n } catch {\n console.error(\"[LocalStorageProvider] Failed to save servers.\");\n }\n }\n\n /** Saves one server configuration. */\n setServer(id: string, config: PersistedMcpServerConfig): void {\n const servers = this.getServers();\n servers[id] = config;\n this.setServers(servers);\n }\n\n /** Removes one server and its cached metadata. */\n removeServer(id: string): void {\n const servers = this.getServers();\n delete servers[id];\n this.setServers(servers);\n this.removeServerMetadata(id);\n }\n\n /** Removes all saved configurations and metadata. */\n clear(): void {\n try {\n localStorage.removeItem(this.storageKey);\n localStorage.removeItem(this.metadataKey);\n } catch {\n console.error(\"[LocalStorageProvider] Failed to clear.\");\n }\n }\n\n private getAllMetadata(): Record<string, CachedServerMetadata> {\n try {\n const stored = localStorage.getItem(this.metadataKey);\n return stored ? JSON.parse(stored) : {};\n } catch {\n console.error(\"[LocalStorageProvider] Failed to load metadata.\");\n return {};\n }\n }\n\n private setAllMetadata(metadata: Record<string, CachedServerMetadata>): void {\n try {\n localStorage.setItem(this.metadataKey, JSON.stringify(metadata));\n } catch {\n console.error(\"[LocalStorageProvider] Failed to save metadata.\");\n }\n }\n\n /** Returns cached presentation metadata for a server. */\n getServerMetadata(id: string): CachedServerMetadata | undefined {\n return this.getAllMetadata()[id];\n }\n\n /** Saves presentation metadata and stamps the current cache time. */\n setServerMetadata(id: string, metadata: CachedServerMetadata): void {\n const allMetadata = this.getAllMetadata();\n allMetadata[id] = { ...metadata, cachedAt: Date.now() };\n this.setAllMetadata(allMetadata);\n }\n\n /** Removes cached presentation metadata for a server. */\n removeServerMetadata(id: string): void {\n const allMetadata = this.getAllMetadata();\n delete allMetadata[id];\n this.setAllMetadata(allMetadata);\n }\n}\n\n/** Stores managed server configurations in memory for tests or ephemeral UIs. */\nexport class MemoryStorageProvider implements StorageProvider {\n private storage: Record<string, PersistedMcpServerConfig> = {};\n private metadata: Record<string, CachedServerMetadata> = {};\n\n /** Returns a shallow copy of all stored server configurations. */\n getServers(): Record<string, PersistedMcpServerConfig> {\n return { ...this.storage };\n }\n\n /** Replaces all stored server configurations. */\n setServers(servers: Record<string, PersistedMcpServerConfig>): void {\n this.storage = Object.fromEntries(\n Object.entries(servers).map(([id, config]) => [\n id,\n toPersistedServerConfig(config),\n ])\n );\n }\n\n /** Stores one server configuration. */\n setServer(id: string, config: PersistedMcpServerConfig): void {\n this.storage[id] = toPersistedServerConfig(config);\n }\n\n /** Removes one server and its cached metadata. */\n removeServer(id: string): void {\n delete this.storage[id];\n this.removeServerMetadata(id);\n }\n\n /** Removes all configurations and metadata. */\n clear(): void {\n this.storage = {};\n this.metadata = {};\n }\n\n /** Returns cached presentation metadata for a server. */\n getServerMetadata(id: string): CachedServerMetadata | undefined {\n return this.metadata[id];\n }\n\n /** Saves presentation metadata and stamps the current cache time. */\n setServerMetadata(id: string, metadata: CachedServerMetadata): void {\n this.metadata[id] = { ...metadata, cachedAt: Date.now() };\n }\n\n /** Removes cached presentation metadata for a server. */\n removeServerMetadata(id: string): void {\n delete this.metadata[id];\n }\n}\n","export {\n AppBridge,\n PostMessageTransport,\n buildAllowAttribute,\n RESOURCE_MIME_TYPE,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\n\nexport type {\n McpUiDownloadFileRequest,\n McpUiDownloadFileResult,\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiMessageRequest,\n McpUiOpenLinkRequest,\n McpUiRequestDisplayModeRequest,\n McpUiResourceCsp,\n McpUiResourcePermissions,\n McpUiSizeChangedNotification,\n McpUiSupportedContentBlockModalities,\n McpUiUpdateModelContextRequest,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\n","import {\n AppBridge,\n PostMessageTransport,\n buildAllowAttribute,\n type McpUiDownloadFileRequest,\n type McpUiHostCapabilities,\n type McpUiMessageRequest,\n type McpUiOpenLinkRequest,\n type McpUiRequestDisplayModeRequest,\n type McpUiSizeChangedNotification,\n type McpUiUpdateModelContextRequest,\n} from \"./ext-apps-bridge.js\";\nimport type {\n CallToolRequest,\n LoggingMessageNotificationParams,\n ReadResourceRequest,\n Tool,\n Transport,\n} from \"@modelcontextprotocol/client\";\nimport React, {\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { parseCustomProps } from \"./parse-custom-props.js\";\nimport { injectOpenAiFileApis } from \"./inject-openai-file-apis.js\";\nimport { installInitializedSync } from \"./initialized-sync.js\";\nimport { resolveViewResource } from \"./resolve-view-resource.js\";\nimport { buildViewSandboxBlobUrl } from \"./sandbox-blob-url.js\";\nimport type {\n ResolvedViewResource,\n ViewDisplayMode,\n ViewRendererProps,\n} from \"./types.js\";\nimport {\n useViewDisplayModeControls,\n VIEW_DIMENSIONS,\n} from \"./use-display-mode.js\";\nimport {\n assertAppCanCallTool,\n buildDefaultHostCapabilities,\n dispatchUiMessage,\n resolveRequestedDisplayMode,\n} from \"./view-host-policy.js\";\n\nconst DEFAULT_HOST_INFO = { name: \"mcp-use-client\", version: \"2.0.0\" } as const;\nconst DEFAULT_TOOL_CALL_TIMEOUT = 600_000;\nconst SANDBOX_PROXY_READY = \"ui/notifications/sandbox-proxy-ready\";\n\nfunction CloseIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\nfunction waitForSandboxProxyReady(iframe: HTMLIFrameElement): Promise<void> {\n return new Promise((resolve) => {\n const listener = (event: MessageEvent) => {\n if (\n event.source === iframe.contentWindow &&\n event.data?.method === SANDBOX_PROXY_READY\n ) {\n window.removeEventListener(\"message\", listener);\n resolve();\n }\n };\n window.addEventListener(\"message\", listener);\n });\n}\n\nfunction buildToolResultPayload(\n toolOutput: unknown,\n customProps?: Record<string, string>\n): Parameters<AppBridge[\"sendToolResult\"]>[0] | null {\n const structuredContent = parseCustomProps(customProps);\n if (Object.keys(structuredContent).length > 0) {\n return {\n ...(typeof toolOutput === \"object\" && toolOutput !== null\n ? toolOutput\n : {}),\n structuredContent,\n } as Parameters<AppBridge[\"sendToolResult\"]>[0];\n }\n if (toolOutput === undefined || toolOutput === null) return null;\n return toolOutput as Parameters<AppBridge[\"sendToolResult\"]>[0];\n}\n\nfunction ViewRendererBase({\n viewId,\n source,\n sandboxUrl,\n toolName = \"view\",\n toolInput,\n toolOutput,\n partialToolInput,\n customProps,\n cancelled,\n hostInfo = DEFAULT_HOST_INFO,\n hostContext,\n hostCapabilities,\n messageCapabilities,\n modelContextCapabilities,\n cspMode = \"widget-declared\",\n displayMode: displayModeProp,\n onDisplayModeChange,\n inlineMaxWidth = 768,\n chromeless,\n onMessage,\n onSamplingRequest,\n onDownloadFile,\n onAppToolsChanged,\n onModelContextUpdate,\n onLog,\n onReady,\n onLifecycleChange,\n onError,\n onCspViolation,\n onResourceResolved,\n wrapTransport,\n toolCallTimeout = DEFAULT_TOOL_CALL_TIMEOUT,\n mockOpenAiFileApis = false,\n onInlineHeightChange,\n fullscreenHeader,\n renderFullscreenClose,\n className,\n testId = \"mcp-app-frame\",\n invoking,\n invoked,\n}: ViewRendererProps) {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const bridgeRef = useRef<AppBridge | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const pendingBlobRevocationsRef = useRef(\n new Map<string, ReturnType<typeof setTimeout>>()\n );\n const connectionRef = useRef(\n source.kind === \"live\" ? source.connection : null\n );\n\n const [resolved, setResolved] = useState<ResolvedViewResource | null>(null);\n const [activeSandboxUrl, setActiveSandboxUrl] = useState<URL | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n const [initCount, setInitCount] = useState(0);\n const [inlineHeight, setInlineHeight] = useState<number>(\n VIEW_DIMENSIONS.DEFAULT_HEIGHT\n );\n const [internalDisplayMode, setInternalDisplayMode] =\n useState<ViewDisplayMode>(\"inline\");\n const displayMode = displayModeProp ?? internalDisplayMode;\n const hasMessageHandler = onMessage !== undefined;\n const hasModelContextHandler = onModelContextUpdate !== undefined;\n const hasLogHandler = onLog !== undefined;\n const hasSamplingHandler = onSamplingRequest !== undefined;\n const hasDownloadHandler = onDownloadFile !== undefined;\n const effectiveHostCapabilities = useMemo<McpUiHostCapabilities>(\n () => ({\n ...buildDefaultHostCapabilities({\n hasConnection: source.kind === \"live\",\n hasMessageHandler,\n hasModelContextHandler,\n hasLogHandler,\n hasSamplingHandler,\n hasDownloadHandler,\n messageCapabilities,\n modelContextCapabilities,\n }),\n ...hostCapabilities,\n }),\n [\n hostCapabilities,\n hasLogHandler,\n hasSamplingHandler,\n hasDownloadHandler,\n hasMessageHandler,\n hasModelContextHandler,\n messageCapabilities,\n modelContextCapabilities,\n source.kind,\n ]\n );\n\n // Guest hostContext must track the shell's displayMode even when the parent\n // only uses ViewRenderer's internal state (e.g. inspector chat).\n const effectiveHostContext = useMemo(() => {\n if (!hostContext) return hostContext;\n if (hostContext.displayMode === displayMode) return hostContext;\n return { ...hostContext, displayMode };\n }, [hostContext, displayMode]);\n\n const hostContextRef = useRef(effectiveHostContext);\n hostContextRef.current = effectiveHostContext;\n const onMessageRef = useRef(onMessage);\n onMessageRef.current = onMessage;\n const onSamplingRequestRef = useRef(onSamplingRequest);\n onSamplingRequestRef.current = onSamplingRequest;\n const onDownloadFileRef = useRef(onDownloadFile);\n onDownloadFileRef.current = onDownloadFile;\n const onAppToolsChangedRef = useRef(onAppToolsChanged);\n onAppToolsChangedRef.current = onAppToolsChanged;\n const toolInputRef = useRef(toolInput);\n toolInputRef.current = toolInput;\n const partialToolInputRef = useRef(partialToolInput);\n partialToolInputRef.current = partialToolInput;\n const toolOutputRef = useRef(toolOutput);\n toolOutputRef.current = toolOutput;\n const customPropsRef = useRef(customProps);\n customPropsRef.current = customProps;\n const onResourceResolvedRef = useRef(onResourceResolved);\n onResourceResolvedRef.current = onResourceResolved;\n const onModelContextUpdateRef = useRef(onModelContextUpdate);\n onModelContextUpdateRef.current = onModelContextUpdate;\n const onLogRef = useRef(onLog);\n onLogRef.current = onLog;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onCspViolationRef = useRef(onCspViolation);\n onCspViolationRef.current = onCspViolation;\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n const onLifecycleChangeRef = useRef(onLifecycleChange);\n onLifecycleChangeRef.current = onLifecycleChange;\n const onInlineHeightChangeRef = useRef(onInlineHeightChange);\n onInlineHeightChangeRef.current = onInlineHeightChange;\n const sandboxUrlRef = useRef(sandboxUrl);\n sandboxUrlRef.current = sandboxUrl;\n const cspModeRef = useRef(cspMode);\n cspModeRef.current = cspMode;\n const mockOpenAiFileApisRef = useRef(mockOpenAiFileApis);\n mockOpenAiFileApisRef.current = mockOpenAiFileApis;\n\n const resolveSandboxUrl = useCallback((next: ResolvedViewResource): URL => {\n const custom = sandboxUrlRef.current;\n if (custom) {\n return typeof custom === \"function\" ? custom(next) : custom;\n }\n return buildViewSandboxBlobUrl({\n cspMode: cspModeRef.current,\n permissions: next.permissions,\n widgetCsp: next.declaredCsp,\n });\n }, []);\n\n const setDisplayMode = useCallback(\n (mode: ViewDisplayMode) => {\n if (onDisplayModeChange) onDisplayModeChange(mode);\n else setInternalDisplayMode(mode);\n },\n [onDisplayModeChange]\n );\n\n const {\n handleDisplayModeChange,\n fullscreenShellClassName,\n pipShellClassName,\n isFullscreen,\n isPip,\n } = useViewDisplayModeControls({\n containerRef,\n displayMode,\n setDisplayMode,\n });\n\n const handleDisplayModeChangeRef = useRef(handleDisplayModeChange);\n handleDisplayModeChangeRef.current = handleDisplayModeChange;\n const displayModeRef = useRef(displayMode);\n displayModeRef.current = displayMode;\n\n const liveResourceUri =\n source.kind === \"live\" ? source.resourceUri : undefined;\n const preloadedHtml = source.kind === \"preloaded\" ? source.html : undefined;\n\n if (source.kind === \"live\") {\n connectionRef.current = source.connection;\n }\n\n // Resolve widget HTML from live connection or preloaded source\n useEffect(() => {\n let cancelledEffect = false;\n onLifecycleChangeRef.current?.({ status: \"resolving\" });\n\n const applyResolved = (next: ResolvedViewResource) => {\n setResolved(next);\n onLifecycleChangeRef.current?.({ status: \"sandbox-loading\" });\n const nextSandbox = resolveSandboxUrl(next);\n setActiveSandboxUrl((prev) =>\n prev?.href === nextSandbox.href ? prev : nextSandbox\n );\n onResourceResolvedRef.current?.(next);\n };\n\n if (source.kind === \"preloaded\") {\n const preloaded: ResolvedViewResource = {\n html: source.html,\n declaredCsp: source.csp,\n csp: cspMode === \"permissive\" ? undefined : source.csp,\n permissions: source.permissions,\n prefersBorder: source.prefersBorder ?? false,\n mimeType: \"text/html;profile=mcp-app\",\n mimeTypeValid: true,\n mimeTypeWarning: null,\n };\n applyResolved(preloaded);\n return;\n }\n\n const { connection, resourceUri } = source;\n connectionRef.current = connection;\n\n (async () => {\n try {\n const resourceResult = await connection.readResource(resourceUri);\n if (cancelledEffect) return;\n const listingResource = connection.resources?.find(\n (r) => r.uri === resourceUri\n ) as { _meta?: { ui?: unknown } } | undefined;\n const next = resolveViewResource({\n resourceResult,\n listingResource,\n cspMode,\n resourceUri,\n });\n if (!next.mimeTypeValid) {\n const message =\n next.mimeTypeWarning ||\n 'Invalid MIME type - SEP-1865 requires \"text/html;profile=mcp-app\"';\n setLoadError(message);\n onLifecycleChangeRef.current?.({ status: \"error\", error: message });\n return;\n }\n applyResolved(next);\n } catch (err) {\n if (cancelledEffect) return;\n setLoadError(\n err instanceof Error ? err.message : \"Failed to prepare view\"\n );\n onLifecycleChangeRef.current?.({\n status: \"error\",\n error: err instanceof Error ? err.message : \"Failed to prepare view\",\n });\n }\n })();\n\n return () => {\n cancelledEffect = true;\n };\n }, [source.kind, liveResourceUri, preloadedHtml, cspMode, resolveSandboxUrl]);\n\n // Delay revocation so React StrictMode's development-only effect cleanup can\n // be cancelled by the matching setup before the iframe navigation commits.\n useEffect(() => {\n const url = activeSandboxUrl;\n if (!url || url.protocol !== \"blob:\") return;\n\n const pending = pendingBlobRevocationsRef.current.get(url.href);\n if (pending) {\n clearTimeout(pending);\n pendingBlobRevocationsRef.current.delete(url.href);\n }\n\n return () => {\n const timer = setTimeout(() => {\n URL.revokeObjectURL(url.href);\n pendingBlobRevocationsRef.current.delete(url.href);\n }, 1_000);\n pendingBlobRevocationsRef.current.set(url.href, timer);\n };\n }, [activeSandboxUrl]);\n\n const isBlobSandbox = activeSandboxUrl?.protocol === \"blob:\";\n const sandboxOrigin =\n !activeSandboxUrl || isBlobSandbox\n ? null\n : (() => {\n try {\n return activeSandboxUrl.origin;\n } catch {\n return null;\n }\n })();\n\n // CSP violations + iframe console forwarding\n useEffect(() => {\n if (!sandboxOrigin && !isBlobSandbox) return;\n\n const handleMessage = (event: MessageEvent) => {\n const iframe = iframeRef.current;\n if (!iframe?.contentWindow) return;\n if (event.source !== iframe.contentWindow) return;\n if (\n !isBlobSandbox &&\n event.origin !== sandboxOrigin &&\n sandboxOrigin !== \"*\"\n ) {\n return;\n }\n\n if (event.data?.type === \"mcp-apps:csp-violation\") {\n onCspViolationRef.current?.({\n directive: event.data.directive,\n effectiveDirective: event.data.effectiveDirective,\n blockedUri: event.data.blockedUri,\n sourceFile: event.data.sourceFile,\n lineNumber: event.data.lineNumber,\n columnNumber: event.data.columnNumber,\n originalPolicy: event.data.originalPolicy,\n timestamp: event.data.timestamp || Date.now(),\n });\n return;\n }\n\n if (event.data?.type === \"iframe-console-log\") {\n // Console records share the iframe postMessage channel with MCP Apps\n // JSON-RPC. Consume them before PostMessageTransport sees them.\n event.stopImmediatePropagation();\n onLogRef.current?.({\n level: event.data.level ?? \"log\",\n data: event.data.args,\n });\n return;\n }\n };\n\n window.addEventListener(\"message\", handleMessage, true);\n return () => window.removeEventListener(\"message\", handleMessage, true);\n }, [sandboxOrigin, isBlobSandbox]);\n\n // Bridge lifecycle: sandbox → connect → resource-ready → initialized\n useEffect(() => {\n if (!resolved || !activeSandboxUrl) return;\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n let disposed = false;\n let bridge: AppBridge | null = null;\n\n const run = async () => {\n try {\n onLifecycleChangeRef.current?.({ status: \"connecting\" });\n iframe.setAttribute(\n \"sandbox\",\n \"allow-scripts allow-same-origin allow-forms\"\n );\n const allowAttribute = buildAllowAttribute(resolved.permissions);\n if (allowAttribute) {\n iframe.setAttribute(\"allow\", allowAttribute);\n }\n\n const readyPromise = waitForSandboxProxyReady(iframe);\n if (activeSandboxUrl.protocol === \"blob:\") {\n const response = await fetch(activeSandboxUrl.href);\n const sandboxHtml = await response.text();\n if (disposed) return;\n iframe.srcdoc = sandboxHtml;\n } else {\n iframe.src = activeSandboxUrl.href;\n }\n await readyPromise;\n if (disposed) return;\n\n const capabilities: McpUiHostCapabilities = {\n ...effectiveHostCapabilities,\n sandbox: {\n csp: cspMode === \"permissive\" ? undefined : resolved.csp,\n permissions: resolved.permissions,\n },\n };\n\n bridge = new AppBridge(null, hostInfo, capabilities, {\n hostContext: hostContextRef.current,\n });\n\n if (capabilities.message) {\n bridge.onmessage = async ({\n content,\n }: McpUiMessageRequest[\"params\"]) => {\n await dispatchUiMessage(onMessageRef.current, content);\n return {};\n };\n }\n\n if (capabilities.sampling) {\n bridge.oncreatesamplingmessage = async (params) => {\n const handler = onSamplingRequestRef.current;\n if (!handler) {\n throw new Error(\"This host surface does not support sampling\");\n }\n return handler(params);\n };\n }\n\n if (capabilities.downloadFile) {\n bridge.ondownloadfile = async (\n params: McpUiDownloadFileRequest[\"params\"]\n ) => {\n const handler = onDownloadFileRef.current;\n if (!handler) {\n throw new Error(\"This host surface does not support downloads\");\n }\n return handler(params);\n };\n }\n\n bridge.onopenlink = async ({ url }: McpUiOpenLinkRequest[\"params\"]) => {\n if (url) window.open(url, \"_blank\", \"noopener,noreferrer\");\n return {};\n };\n\n if (capabilities.serverTools) {\n bridge.oncalltool = (async ({\n name,\n arguments: args,\n }: CallToolRequest[\"params\"]) => {\n const conn = connectionRef.current;\n if (!conn) throw new Error(\"Server connection not available\");\n assertAppCanCallTool(conn.tools, name);\n try {\n return await conn.callTool(name, args || {}, {\n timeout: toolCallTimeout,\n resetTimeoutOnProgress: true,\n });\n } catch (error) {\n bridge?.sendToolCancelled({\n reason: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }) as typeof bridge.oncalltool;\n }\n\n if (capabilities.serverResources) {\n bridge.onreadresource = (async ({\n uri,\n }: ReadResourceRequest[\"params\"]) => {\n const conn = connectionRef.current;\n if (!conn) throw new Error(\"Server connection not available\");\n return (await conn.readResource(uri)) as object;\n }) as NonNullable<AppBridge[\"onreadresource\"]>;\n\n bridge.onlistresources = (async () => {\n const conn = connectionRef.current;\n if (!conn) throw new Error(\"Server connection not available\");\n return { resources: [...(conn.resources ?? [])] } as object;\n }) as NonNullable<AppBridge[\"onlistresources\"]>;\n }\n\n bridge.onrequestdisplaymode = async ({\n mode,\n }: McpUiRequestDisplayModeRequest[\"params\"]) => {\n const requested = (mode ?? \"inline\") as ViewDisplayMode;\n const effective = resolveRequestedDisplayMode({\n requested,\n current: displayModeRef.current,\n hostAvailable: hostContextRef.current?.availableDisplayModes,\n appAvailable: bridge?.getAppCapabilities()?.availableDisplayModes,\n });\n await handleDisplayModeChangeRef.current(effective);\n return { mode: effective };\n };\n\n if (capabilities.updateModelContext) {\n bridge.onupdatemodelcontext = async ({\n content,\n structuredContent,\n }: McpUiUpdateModelContextRequest[\"params\"]) => {\n if (!onModelContextUpdateRef.current) {\n throw new Error(\n \"This host surface does not support model context updates\"\n );\n }\n await onModelContextUpdateRef.current({\n content,\n structuredContent,\n });\n return {};\n };\n }\n\n if (capabilities.logging) {\n bridge.onloggingmessage = async ({\n level,\n data,\n }: LoggingMessageNotificationParams) => {\n onLogRef.current?.({ level, data });\n return {};\n };\n }\n\n bridge.onsizechange = async ({\n height,\n }: McpUiSizeChangedNotification[\"params\"]) => {\n if (displayModeRef.current !== \"inline\") return;\n if (height !== undefined) {\n setInlineHeight(height);\n onInlineHeightChangeRef.current?.(height);\n }\n };\n\n let publishedAppToolsSignature: string | null = null;\n const publishAppTools = async () => {\n const handler = onAppToolsChangedRef.current;\n if (!bridge || !handler) return;\n const appCapabilities = bridge.getAppCapabilities();\n if (!appCapabilities?.tools) {\n handler(null);\n return;\n }\n const result = await bridge.listTools({});\n if (disposed || !bridge) return;\n const signature = JSON.stringify(result.tools);\n if (signature === publishedAppToolsSignature) return;\n publishedAppToolsSignature = signature;\n const currentBridge = bridge;\n handler({\n tools: result.tools as Tool[],\n callTool: (name, args) =>\n currentBridge.callTool({\n name,\n arguments: args ?? {},\n }),\n });\n };\n\n bridge.setNotificationHandler(\n \"notifications/tools/list_changed\",\n async () => {\n await publishAppTools();\n }\n );\n\n const syncGuestToolState = async () => {\n if (!bridge || disposed) return;\n\n const currentPartialToolInput = partialToolInputRef.current;\n const hasCompletedToolResult =\n toolOutputRef.current !== undefined &&\n toolOutputRef.current !== null;\n if (currentPartialToolInput && !hasCompletedToolResult) {\n await bridge.sendToolInputPartial({\n arguments: currentPartialToolInput,\n });\n } else {\n const mergedArgs = {\n ...toolInputRef.current,\n ...parseCustomProps(customPropsRef.current),\n };\n await bridge.sendToolInput({ arguments: mergedArgs });\n }\n\n const toolResultPayload = buildToolResultPayload(\n toolOutputRef.current,\n customPropsRef.current\n );\n if (toolResultPayload) {\n await bridge.sendToolResult(toolResultPayload);\n }\n };\n\n const initPromise = installInitializedSync(\n bridge,\n syncGuestToolState,\n (error) => {\n if (disposed) return;\n const message =\n error instanceof Error\n ? error.message\n : \"Failed to synchronize view state\";\n onErrorRef.current?.(message);\n onLifecycleChangeRef.current?.({\n status: \"error\",\n error: message,\n });\n }\n );\n let transport: Transport = new PostMessageTransport(\n iframe.contentWindow!,\n iframe.contentWindow!\n );\n if (wrapTransport) {\n transport = wrapTransport(transport, viewId);\n }\n await bridge.connect(transport);\n if (disposed) return;\n\n await bridge.sendSandboxResourceReady({\n html: mockOpenAiFileApisRef.current\n ? injectOpenAiFileApis(resolved.html)\n : resolved.html,\n csp: resolved.csp,\n permissions: resolved.permissions,\n });\n await initPromise;\n if (disposed) return;\n\n bridgeRef.current = bridge;\n setInitCount((c) => c + 1);\n onLifecycleChangeRef.current?.({ status: \"initialized\" });\n\n await publishAppTools();\n\n onLifecycleChangeRef.current?.({ status: \"ready\" });\n } catch (err) {\n if (!disposed) {\n const message =\n err instanceof Error ? err.message : \"Failed to connect view\";\n setLoadError(message);\n onErrorRef.current?.(message);\n onLifecycleChangeRef.current?.({ status: \"error\", error: message });\n }\n }\n };\n\n void run();\n\n return () => {\n disposed = true;\n const toClose = bridge;\n bridgeRef.current = null;\n onAppToolsChangedRef.current?.(null);\n if (!toClose) return;\n onLifecycleChangeRef.current?.({ status: \"tearing-down\" });\n void (async () => {\n try {\n await Promise.race([\n toClose.teardownResource({}),\n new Promise((_, reject) =>\n setTimeout(() => reject(new Error(\"teardown timeout\")), 2000)\n ),\n ]);\n } catch {\n // proceed\n } finally {\n toClose.close().catch(() => {});\n onLifecycleChangeRef.current?.({ status: \"closed\" });\n }\n })();\n };\n }, [\n resolved,\n activeSandboxUrl,\n hostInfo,\n effectiveHostCapabilities,\n cspMode,\n viewId,\n wrapTransport,\n toolCallTimeout,\n mockOpenAiFileApis,\n ]);\n\n // Host context updates after init\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (!bridge || initCount === 0 || !effectiveHostContext) return;\n void bridge.setHostContext(effectiveHostContext);\n }, [effectiveHostContext, initCount]);\n\n // Partial tool input\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (\n !bridge ||\n initCount === 0 ||\n !partialToolInput ||\n (toolOutput !== undefined && toolOutput !== null)\n ) {\n return;\n }\n void bridge.sendToolInputPartial({ arguments: partialToolInput });\n }, [initCount, partialToolInput, toolOutput]);\n\n // Tool input + custom props\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (\n !bridge ||\n initCount === 0 ||\n (partialToolInput && (toolOutput === undefined || toolOutput === null))\n ) {\n return;\n }\n const mergedArgs = {\n ...toolInput,\n ...parseCustomProps(customProps),\n };\n void bridge.sendToolInput({ arguments: mergedArgs });\n }, [initCount, toolInput, partialToolInput, customProps, toolOutput]);\n\n // Tool output\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (!bridge || initCount === 0) return;\n const toolResultPayload = buildToolResultPayload(toolOutput, customProps);\n if (!toolResultPayload) return;\n void bridge.sendToolResult(toolResultPayload);\n }, [initCount, toolOutput, customProps]);\n\n // Cancellation\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (!bridge || initCount === 0 || !cancelled) return;\n void bridge.sendToolCancelled({ reason: \"Cancelled by user\" });\n }, [cancelled, initCount]);\n\n const readyFiredRef = useRef(false);\n useEffect(() => {\n if (readyFiredRef.current || initCount === 0) return;\n readyFiredRef.current = true;\n onReadyRef.current?.();\n }, [initCount]);\n\n const showHostBorder =\n resolved !== null && resolved.prefersBorder && displayMode !== \"fullscreen\";\n\n if (loadError) {\n return (\n <div className={className}>\n <div className=\"border border-red-200/50 dark:border-red-800/50 bg-red-50/30 dark:bg-red-950/20 rounded-lg p-4\">\n <p className=\"text-sm text-red-600 dark:text-red-400\">\n Failed to load view: {loadError}\n </p>\n </div>\n </div>\n );\n }\n\n if (!resolved) {\n return (\n <div className={className}>\n <div className=\"flex items-center justify-center w-full h-[200px]\">\n <span className=\"text-sm text-muted-foreground\">Loading view…</span>\n </div>\n </div>\n );\n }\n\n const containerClassName =\n fullscreenShellClassName ??\n pipShellClassName ??\n \"flex group flex-1 items-center justify-center\";\n\n const frameStyle: CSSProperties = {\n height: isFullscreen || isPip ? \"100%\" : `${inlineHeight}px`,\n width: \"100%\",\n maxWidth: displayMode === \"inline\" ? `${inlineMaxWidth}px` : \"100%\",\n transition: isFullscreen || isPip ? undefined : \"height 300ms ease-out\",\n };\n\n const viewShell = (\n <div\n ref={containerRef}\n className={\n isFullscreen\n ? `${containerClassName} flex flex-col`\n : containerClassName\n }\n style={\n isPip\n ? {\n height: VIEW_DIMENSIONS.DEFAULT_HEIGHT,\n maxWidth: VIEW_DIMENSIONS.PIP_MAX_WIDTH,\n zIndex: 100,\n }\n : isFullscreen\n ? { zIndex: 100 }\n : undefined\n }\n >\n {isFullscreen && (\n // ponytail: inspector Tailwind may not emit client arbitrary classes\n // (h-[50px], grid-cols-[auto_1fr_auto]) — use inline layout instead.\n <header\n className=\"grid shrink-0 items-center border-b border-zinc-200 bg-background px-3 dark:border-zinc-700\"\n style={{\n height: VIEW_DIMENSIONS.FULLSCREEN_HEADER_HEIGHT,\n gridTemplateColumns: \"auto 1fr auto\",\n }}\n >\n {renderFullscreenClose ? (\n renderFullscreenClose({\n onClick: () => void handleDisplayModeChange(\"inline\"),\n \"data-testid\": \"debugger-exit-fullscreen-button\",\n \"aria-label\": \"Exit fullscreen\",\n })\n ) : (\n <button\n type=\"button\"\n data-testid=\"debugger-exit-fullscreen-button\"\n aria-label=\"Exit fullscreen\"\n className=\"flex size-8 cursor-pointer items-center justify-center rounded-full border border-zinc-200 bg-background text-foreground shadow-sm hover:bg-muted dark:border-zinc-700\"\n onClick={() => void handleDisplayModeChange(\"inline\")}\n >\n <CloseIcon />\n </button>\n )}\n <div className=\"flex min-w-0 items-center justify-center gap-2 px-2\">\n {fullscreenHeader?.iconUrl ? (\n <img\n src={fullscreenHeader.iconUrl}\n alt=\"\"\n className=\"size-6 shrink-0 rounded-md object-contain\"\n />\n ) : null}\n <span className=\"truncate text-sm font-medium text-foreground\">\n {fullscreenHeader?.title ?? toolName}\n </span>\n </div>\n <div className=\"size-8 shrink-0\" aria-hidden />\n </header>\n )}\n {isPip &&\n (renderFullscreenClose ? (\n <div className=\"absolute right-3 top-3\" style={{ zIndex: 110 }}>\n {renderFullscreenClose({\n onClick: () => void handleDisplayModeChange(\"inline\"),\n \"data-testid\": \"debugger-exit-pip-button\",\n \"aria-label\": \"Exit picture-in-picture\",\n })}\n </div>\n ) : (\n <button\n type=\"button\"\n data-testid=\"debugger-exit-pip-button\"\n aria-label=\"Exit picture-in-picture\"\n className=\"absolute right-3 top-3 z-[110] flex size-8 cursor-pointer items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm backdrop-blur-sm hover:bg-background\"\n style={{ zIndex: 110 }}\n onClick={() => void handleDisplayModeChange(\"inline\")}\n >\n <CloseIcon />\n </button>\n ))}\n <div\n className={\n isFullscreen\n ? \"relative flex min-h-0 w-full flex-1 flex-col\"\n : isPip\n ? \"relative w-full h-full min-h-0 flex flex-1 flex-col\"\n : \"relative w-full flex flex-1 justify-center items-center\"\n }\n >\n {!isPip && !isFullscreen && (invoking || invoked) && (\n <div className=\"absolute -top-8 left-2 z-10 whitespace-nowrap pointer-events-none text-xs text-muted-foreground\">\n {invoking && !toolOutput ? invoking : invoked}\n </div>\n )}\n <div\n data-testid={testId}\n data-mcp-app-tool={toolName}\n className={\n displayMode === \"fullscreen\"\n ? \"w-full h-full overflow-hidden\"\n : \"w-full overflow-hidden\"\n }\n style={frameStyle}\n >\n <iframe\n ref={iframeRef}\n title={`MCP App: ${toolName}`}\n className={\n showHostBorder\n ? \"w-full h-full bg-transparent border border-border rounded-xl\"\n : \"w-full h-full bg-transparent border-0\"\n }\n />\n </div>\n </div>\n </div>\n );\n\n // ponytail: do not portal — moving the shell remounts the iframe and wipes\n // the guest. Chat history chrome hides via data-mcp-widget-fullscreen instead.\n return <div className={className}>{viewShell}</div>;\n}\n\nfunction viewRendererAreEqual(\n prev: ViewRendererProps,\n next: ViewRendererProps\n): boolean {\n if (prev.viewId !== next.viewId) return false;\n if (prev.source !== next.source) return false;\n if (prev.sandboxUrl !== next.sandboxUrl) return false;\n if (prev.displayMode !== next.displayMode) return false;\n if (prev.cancelled !== next.cancelled) return false;\n if (prev.toolInput !== next.toolInput) return false;\n if (prev.toolOutput !== next.toolOutput) return false;\n if (prev.partialToolInput !== next.partialToolInput) return false;\n if (prev.customProps !== next.customProps) return false;\n if (prev.hostContext !== next.hostContext) return false;\n if (prev.hostCapabilities !== next.hostCapabilities) return false;\n if (prev.messageCapabilities !== next.messageCapabilities) return false;\n if (prev.modelContextCapabilities !== next.modelContextCapabilities)\n return false;\n if (prev.onMessage !== next.onMessage) return false;\n if (prev.onSamplingRequest !== next.onSamplingRequest) return false;\n if (prev.onDownloadFile !== next.onDownloadFile) return false;\n if (prev.onAppToolsChanged !== next.onAppToolsChanged) return false;\n if (prev.onModelContextUpdate !== next.onModelContextUpdate) return false;\n if (prev.cspMode !== next.cspMode) return false;\n if (prev.mockOpenAiFileApis !== next.mockOpenAiFileApis) return false;\n if (prev.onInlineHeightChange !== next.onInlineHeightChange) return false;\n if (prev.fullscreenHeader !== next.fullscreenHeader) return false;\n if (prev.renderFullscreenClose !== next.renderFullscreenClose) return false;\n if (prev.className !== next.className) return false;\n if (prev.onReady !== next.onReady) return false;\n if (prev.onLifecycleChange !== next.onLifecycleChange) return false;\n return true;\n}\n\n/**\n * Renders an MCP App inside an isolated iframe and bridges host capabilities.\n *\n * The renderer resolves live MCP resources or accepts preloaded HTML, applies\n * the selected CSP policy, and forwards tool state and host callbacks through\n * the MCP Apps bridge.\n */\nexport const ViewRenderer = memo(ViewRendererBase, viewRendererAreEqual);\n\nexport type { ViewRendererProps } from \"./types.js\";\nexport { resolveViewResource } from \"./resolve-view-resource.js\";\nexport {\n getViewResourceUri,\n isViewResource,\n isViewTool,\n} from \"./view-detection.js\";\nexport { isToolVisibleToModel } from \"./view-host-policy.js\";\nexport { parseCustomProps } from \"./parse-custom-props.js\";\nexport {\n buildSandboxProxyBlobHtml,\n buildViewSandboxBlobUrl,\n buildViewSandboxUrl,\n} from \"./sandbox-blob-url.js\";\nexport type {\n ViewConnection,\n ViewDisplayMode,\n ViewCspMode,\n ViewRendererSource,\n ResolvedViewResource,\n ViewCspViolation,\n ViewLifecycleEvent,\n ViewLifecycleStatus,\n ViewAppToolConnection,\n} from \"./types.js\";\nexport type {\n McpUiDownloadFileRequest,\n McpUiDownloadFileResult,\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiResourceCsp,\n McpUiResourcePermissions,\n McpUiSupportedContentBlockModalities,\n} from \"./ext-apps-bridge.js\";\n","/**\n * Parses JSON object and array values from string-valued custom properties.\n *\n * Invalid JSON and scalar-looking strings are preserved unchanged.\n *\n * @param customProps - Properties supplied by a host integration.\n * @returns A new record containing parsed object and array values.\n */\nexport function parseCustomProps(\n customProps?: Record<string, string>\n): Record<string, unknown> {\n const parsed: Record<string, unknown> = {};\n if (!customProps) return parsed;\n for (const [k, v] of Object.entries(customProps)) {\n if (\n typeof v === \"string\" &&\n (v.trim().startsWith(\"[\") || v.trim().startsWith(\"{\"))\n ) {\n try {\n parsed[k] = JSON.parse(v);\n } catch {\n parsed[k] = v;\n }\n } else {\n parsed[k] = v;\n }\n }\n return parsed;\n}\n","import { LATEST_PROTOCOL_VERSION } from \"@modelcontextprotocol/ext-apps/app-bridge\";\n\nconst OPENAI_COMPATIBILITY_BRIDGE_SCRIPT = `<script>\n(function () {\n var files = new Map();\n var pendingRequests = new Map();\n var requestId = 0;\n var hostConnected = false;\n var fallbackTimer;\n var api = window.openai || {};\n\n function dispatchGlobals(globals) {\n Object.assign(api, globals);\n window.dispatchEvent(new CustomEvent(\"openai:set_globals\", {\n detail: { globals: globals }\n }));\n }\n\n function applyHostContext(context) {\n if (!context || typeof context !== \"object\") return;\n var globals = {};\n if (context.theme !== undefined) globals.theme = context.theme;\n if (context.displayMode !== undefined) globals.displayMode = context.displayMode;\n if (context.locale !== undefined) globals.locale = context.locale;\n if (context.view !== undefined) globals.view = context.view;\n if (context.safeAreaInsets !== undefined) {\n globals.safeArea = { insets: context.safeAreaInsets };\n }\n if (context.containerDimensions && context.containerDimensions.maxHeight !== undefined) {\n globals.maxHeight = context.containerDimensions.maxHeight;\n }\n if (context.platform !== undefined || context.deviceCapabilities !== undefined) {\n globals.userAgent = {\n device: {\n type: context.platform === \"mobile\" ? \"mobile\" : \"desktop\"\n },\n capabilities: {\n hover: !!(context.deviceCapabilities && context.deviceCapabilities.hover),\n touch: !!(context.deviceCapabilities && context.deviceCapabilities.touch)\n }\n };\n }\n dispatchGlobals(globals);\n }\n\n function markHostConnected(result) {\n hostConnected = true;\n clearTimeout(fallbackTimer);\n if (result && result.hostContext) applyHostContext(result.hostContext);\n }\n\n function postMessage(message) {\n if (window.parent === window) {\n throw new Error(\"window.openai compatibility APIs require an iframe host\");\n }\n window.parent.postMessage(message, \"*\");\n }\n\n function sendRequest(method, params) {\n var id = \"mcp-use-openai-compat-\" + (++requestId);\n return new Promise(function (resolve, reject) {\n pendingRequests.set(id, { resolve: resolve, reject: reject });\n postMessage({ jsonrpc: \"2.0\", id: id, method: method, params: params });\n window.setTimeout(function () {\n var pending = pendingRequests.get(id);\n if (!pending) return;\n pendingRequests.delete(id);\n pending.reject(new Error(\"Request timeout: \" + method));\n }, 30000);\n });\n }\n\n function sendNotification(method, params) {\n postMessage({ jsonrpc: \"2.0\", method: method, params: params });\n }\n\n window.addEventListener(\"message\", function (event) {\n if (event.source !== window.parent) return;\n var message = event.data;\n if (!message || message.jsonrpc !== \"2.0\") return;\n\n if (message.id !== undefined && (message.result !== undefined || message.error !== undefined)) {\n var pending = pendingRequests.get(message.id);\n if (pending) {\n pendingRequests.delete(message.id);\n if (message.error) pending.reject(new Error(message.error.message || \"Host request failed\"));\n else pending.resolve(message.result);\n return;\n }\n if (message.result && (message.result.hostInfo || message.result.hostContext)) {\n markHostConnected(message.result);\n }\n return;\n }\n\n if (message.id !== undefined || typeof message.method !== \"string\") return;\n var params = message.params || {};\n switch (message.method) {\n case \"ui/notifications/tool-input\":\n markHostConnected();\n dispatchGlobals({ toolInput: params.arguments || {} });\n break;\n case \"ui/notifications/tool-input-partial\":\n // window.openai has no partial-input global. Do not expose incomplete\n // or approval-gated arguments as if the final tool input had arrived.\n markHostConnected();\n break;\n case \"ui/notifications/tool-result\":\n markHostConnected();\n dispatchGlobals({\n // OpenAI defines toolOutput as structuredContent, not the complete\n // CallToolResult envelope. Keep that envelope (including hidden\n // _meta) in toolResponseMetadata instead.\n toolOutput: params.structuredContent === undefined ? null : params.structuredContent,\n toolResponseMetadata: params\n });\n break;\n case \"ui/notifications/host-context-changed\":\n markHostConnected();\n applyHostContext(params);\n break;\n }\n });\n\n api.toolInput = api.toolInput === undefined ? null : api.toolInput;\n api.toolOutput = api.toolOutput === undefined ? null : api.toolOutput;\n api.toolResponseMetadata =\n api.toolResponseMetadata === undefined ? null : api.toolResponseMetadata;\n api.widgetState = api.widgetState === undefined ? null : api.widgetState;\n api.theme = api.theme || \"light\";\n api.displayMode = api.displayMode || \"inline\";\n api.safeArea = api.safeArea || {\n insets: { top: 0, right: 0, bottom: 0, left: 0 }\n };\n api.maxHeight = api.maxHeight || 600;\n api.userAgent = api.userAgent || {\n device: { type: \"desktop\" },\n capabilities: { hover: true, touch: false }\n };\n api.locale = api.locale || \"en\";\n\n api.callTool = api.callTool || function (name, args) {\n return sendRequest(\"tools/call\", { name: name, arguments: args || {} });\n };\n api.sendFollowUpMessage = api.sendFollowUpMessage || function (request) {\n return sendRequest(\"ui/message\", {\n role: \"user\",\n content: [{ type: \"text\", text: request.prompt }]\n });\n };\n api.openExternal = api.openExternal || function (request) {\n return sendRequest(\"ui/open-link\", { url: request.href });\n };\n api.requestDisplayMode = api.requestDisplayMode || function (request) {\n return sendRequest(\"ui/request-display-mode\", { mode: request.mode });\n };\n api.setWidgetState = api.setWidgetState || function (state) {\n dispatchGlobals({ widgetState: state });\n // The Apps SDK setter is promise-based. Keep the local state update\n // synchronous, but return a promise so legacy useWidget() code can safely\n // await or chain .catch() on the compatibility API.\n return Promise.resolve();\n };\n api.notifyIntrinsicHeight = api.notifyIntrinsicHeight || function (height) {\n sendNotification(\"ui/notifications/size-changed\", { height: height });\n return Promise.resolve();\n };\n api.uploadFile = api.uploadFile || async function (file) {\n var fileId = crypto.randomUUID();\n files.set(fileId, file);\n return { fileId: fileId };\n };\n api.getFileDownloadUrl = api.getFileDownloadUrl || async function (ref) {\n var file = files.get(ref.fileId);\n if (!file) {\n throw new Error(\"File not found: \" + ref.fileId);\n }\n return { downloadUrl: URL.createObjectURL(file) };\n };\n window.openai = api;\n\n // Native V2 views initialize their own MCP Apps bridge. Only initialize this\n // compatibility bridge when no other guest handshake appears, so the file\n // helpers remain safe for both V2 views and legacy useWidget() bundles.\n fallbackTimer = window.setTimeout(function () {\n if (hostConnected) return;\n sendRequest(\"ui/initialize\", {\n appCapabilities: {},\n appInfo: { name: \"mcp-use-openai-compat\", version: \"1.0.0\" },\n protocolVersion: ${JSON.stringify(LATEST_PROTOCOL_VERSION)}\n }).then(function (result) {\n markHostConnected(result);\n sendNotification(\"ui/notifications/initialized\", {});\n }).catch(function (error) {\n console.warn(\"[window.openai compatibility] Failed to initialize:\", error);\n });\n }, 1000);\n})();\n</script>`;\n\n/**\n * Prepend the shared ChatGPT Apps SDK compatibility aliases and\n * Inspector-supported file helpers. Native V2 views keep using MCP Apps;\n * legacy useWidget() bundles receive the same tool lifecycle and host actions\n * through window.openai. Unsupported ChatGPT-only extensions remain absent so\n * apps can feature-detect them as documented.\n */\nexport function injectOpenAiFileApis(html: string): string {\n const headEnd = findOpeningConstructEnd(html, \"<head\");\n if (headEnd !== undefined) {\n return insertAt(html, headEnd, OPENAI_COMPATIBILITY_BRIDGE_SCRIPT);\n }\n const htmlEnd = findOpeningConstructEnd(html, \"<html\");\n if (htmlEnd !== undefined) {\n return insertAt(\n html,\n htmlEnd,\n \"<head>\" + OPENAI_COMPATIBILITY_BRIDGE_SCRIPT + \"</head>\"\n );\n }\n const doctypeEnd = findOpeningConstructEnd(html, \"<!doctype\");\n if (doctypeEnd !== undefined) {\n return insertAt(\n html,\n doctypeEnd,\n \"<head>\" + OPENAI_COMPATIBILITY_BRIDGE_SCRIPT + \"</head>\"\n );\n }\n return OPENAI_COMPATIBILITY_BRIDGE_SCRIPT + html;\n}\n\nfunction findOpeningConstructEnd(\n html: string,\n lowercasePrefix: string\n): number | undefined {\n const lowercaseHtml = html.toLowerCase();\n let searchFrom = 0;\n while (searchFrom < lowercaseHtml.length) {\n const start = lowercaseHtml.indexOf(lowercasePrefix, searchFrom);\n if (start === -1) return undefined;\n const boundary = lowercaseHtml[start + lowercasePrefix.length];\n if (\n boundary === \">\" ||\n boundary === \" \" ||\n boundary === \"\\t\" ||\n boundary === \"\\n\" ||\n boundary === \"\\r\" ||\n boundary === \"\\f\"\n ) {\n let quote: '\"' | \"'\" | undefined;\n for (\n let index = start + lowercasePrefix.length;\n index < html.length;\n index++\n ) {\n const character = html[index];\n if (quote) {\n if (character === quote) quote = undefined;\n continue;\n }\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n if (character === \">\") return index + 1;\n }\n return undefined;\n }\n searchFrom = start + lowercasePrefix.length;\n }\n return undefined;\n}\n\nfunction insertAt(value: string, index: number, addition: string): string {\n return value.slice(0, index) + addition + value.slice(index);\n}\n","interface InitializableBridge<TArgs extends unknown[]> {\n oninitialized: ((...args: TArgs) => void) | undefined;\n}\n\n/**\n * Synchronize host state after every guest initialize handshake.\n *\n * Vite HMR and React development runtimes can replace the guest App instance\n * inside the same iframe. Each replacement initializes again and needs the\n * invocation's one-shot input/result notifications replayed.\n */\nexport function installInitializedSync<TArgs extends unknown[]>(\n bridge: InitializableBridge<TArgs>,\n synchronize: () => void | Promise<void>,\n onLaterError: (error: unknown) => void\n): Promise<void> {\n const previous = bridge.oninitialized;\n let sawFirstInitialization = false;\n\n return new Promise<void>((resolve, reject) => {\n bridge.oninitialized = (...args: TArgs) => {\n previous?.(...args);\n const synchronization = Promise.resolve().then(synchronize);\n\n if (!sawFirstInitialization) {\n sawFirstInitialization = true;\n synchronization.then(resolve, reject);\n return;\n }\n\n void synchronization.catch(onLaterError);\n };\n });\n}\n","import { RESOURCE_MIME_TYPE } from \"./ext-apps-bridge.js\";\nimport type {\n McpUiResourceCsp,\n McpUiResourcePermissions,\n} from \"./ext-apps-bridge.js\";\nimport type { ResolvedViewResource, ViewCspMode } from \"./types.js\";\n\n/** MCP App UI metadata read from a resource listing or content block. */\ntype UiMeta = {\n csp?: McpUiResourceCsp;\n permissions?: McpUiResourcePermissions;\n prefersBorder?: boolean;\n};\n\n/**\n * Normalizes a resource response into HTML and effective MCP App policy.\n *\n * Content-level UI metadata overrides listing metadata. In permissive mode the\n * declared CSP is reported but not enforced.\n *\n * @param options - Resource response, listing metadata, CSP policy, and URI.\n * @returns The normalized view resource.\n * @throws When the first content block contains no text or base64 HTML.\n */\nexport function resolveViewResource(options: {\n resourceResult: unknown;\n listingResource?: { _meta?: { ui?: unknown } } | null;\n cspMode: ViewCspMode;\n resourceUri?: string;\n}): ResolvedViewResource {\n const { resourceResult, listingResource, cspMode, resourceUri } = options;\n const contentsArray = Array.isArray(\n (resourceResult as { contents?: unknown })?.contents\n )\n ? ((resourceResult as { contents: unknown[] }).contents as Array<{\n mimeType?: string;\n text?: string;\n blob?: string;\n _meta?: { ui?: UiMeta };\n }>)\n : [];\n\n const firstContent = contentsArray[0];\n let htmlContent = \"\";\n let mimeType: string | undefined;\n\n if (firstContent) {\n mimeType = firstContent.mimeType;\n if (typeof firstContent.text === \"string\") {\n htmlContent = firstContent.text;\n } else if (typeof firstContent.blob === \"string\") {\n htmlContent = atob(firstContent.blob);\n }\n }\n\n if (!htmlContent) {\n throw new Error(\"No HTML content in resource\");\n }\n\n const listingUiMeta = listingResource?._meta?.ui as UiMeta | undefined;\n const contentUiMeta = firstContent?._meta?.ui as UiMeta | undefined;\n const mergedUiMeta =\n listingUiMeta || contentUiMeta\n ? { ...listingUiMeta, ...contentUiMeta }\n : undefined;\n\n const declaredCsp = mergedUiMeta?.csp;\n const permissions = mergedUiMeta?.permissions;\n const prefersBorder = mergedUiMeta?.prefersBorder ?? false;\n\n const mimeTypeValid = mimeType === RESOURCE_MIME_TYPE;\n const mimeTypeWarning = !mimeTypeValid\n ? mimeType\n ? `Invalid MIME type \"${mimeType}\" - SEP-1865 requires \"${RESOURCE_MIME_TYPE}\"`\n : `Missing MIME type - SEP-1865 requires \"${RESOURCE_MIME_TYPE}\"`\n : null;\n\n if (mimeTypeWarning) {\n console.warn(\"[ViewRenderer] MIME type validation:\", mimeTypeWarning, {\n resourceUri,\n });\n }\n\n const isPermissive = cspMode === \"permissive\";\n\n return {\n html: htmlContent,\n declaredCsp,\n csp: isPermissive ? undefined : declaredCsp,\n permissions,\n prefersBorder,\n mimeType,\n mimeTypeValid,\n mimeTypeWarning,\n };\n}\n","/**\n * MCP Apps sandbox-proxy HTML for ViewRenderer blob URLs.\n *\n * Browser-only — no Node/Hono imports. The host iframe loads this document\n * from a blob: URL; it proxies postMessage to the inner widget srcdoc iframe.\n */\n\nimport type {\n McpUiResourceCsp,\n McpUiResourcePermissions,\n} from \"./ext-apps-bridge.js\";\nimport type { ViewCspMode } from \"./types.js\";\n\ntype ViewSandboxBlobUrlOptions = {\n cspMode: ViewCspMode;\n permissions?: McpUiResourcePermissions;\n widgetCsp?: McpUiResourceCsp;\n};\n\n/** Build a configured HTTP(S) sandbox proxy URL. */\nexport function buildViewSandboxUrl(\n sandboxDocumentUrl: URL,\n options: ViewSandboxBlobUrlOptions\n): URL {\n const url = new URL(sandboxDocumentUrl.href);\n applySandboxSearchParams(url, options);\n return url;\n}\n\nfunction applySandboxSearchParams(\n url: URL,\n options: ViewSandboxBlobUrlOptions\n): void {\n const { cspMode, permissions, widgetCsp } = options;\n url.searchParams.set(\n \"v\",\n JSON.stringify({ cspMode, permissions, widgetCsp })\n );\n url.searchParams.set(\"csp_mode\", cspMode);\n if (permissions && Object.keys(permissions).length > 0) {\n url.searchParams.set(\"permissions\", JSON.stringify(permissions));\n }\n if (widgetCsp && Object.keys(widgetCsp).length > 0) {\n url.searchParams.set(\"widget_csp\", JSON.stringify(widgetCsp));\n }\n}\n\n/** Build a blob: sandbox iframe URL (no backend sandbox-proxy route). */\nexport function buildViewSandboxBlobUrl(\n options: ViewSandboxBlobUrlOptions\n): URL {\n const searchUrl = new URL(\"https://sandbox.invalid/\");\n applySandboxSearchParams(searchUrl, options);\n const html = buildSandboxProxyBlobHtml(searchUrl.search);\n return new URL(URL.createObjectURL(new Blob([html], { type: \"text/html\" })));\n}\n\n/**\n * Raw sandbox-proxy document (query config via location.search or __SANDBOX_SEARCH__).\n *\n * Inner guest iframe keeps `allow-same-origin` for srcdoc widget rendering;\n * browsers may warn that allow-scripts + allow-same-origin can escape sandboxing.\n */\nconst SANDBOX_PROXY_HTML: string =\n '<!doctype html>\\n<html>\\n <head>\\n <meta charset=\"utf-8\" />\\n <meta\\n http-equiv=\"Content-Security-Policy\"\\n content=\"default-src \\'self\\'; img-src * data: blob: \\'unsafe-inline\\'; media-src * blob: data:; font-src * blob: data:; script-src * \\'wasm-unsafe-eval\\' \\'unsafe-inline\\' \\'unsafe-eval\\' blob: data:; style-src * blob: data: \\'unsafe-inline\\'; connect-src * data: blob: about:; frame-src * blob: data: http://localhost:* https://localhost:* http://127.0.0.1:* https://127.0.0.1:*;\"\\n />\\n <title>MCP Apps Sandbox Proxy</title>\\n <style>\\n html, body { margin: 0; padding: 0; height: 100%; width: 100%; overflow: hidden; }\\n * { box-sizing: border-box; }\\n iframe { display: block; background-color: transparent; border: 0px none transparent; padding: 0px; width: 100%; height: 100%; }\\n </style>\\n </head>\\n <body>\\n <script>\\n function sanitizeDomain(domain) {\\n if (typeof domain !== \"string\") return \"\";\\n return domain.replace(/[\\'\"<>;]/g, \"\").trim();\\n }\\n\\n function buildAllowAttribute(permissions) {\\n if (!permissions) return \"\";\\n const allowList = [];\\n if (permissions.camera) allowList.push(\"camera *\");\\n if (permissions.microphone) allowList.push(\"microphone *\");\\n if (permissions.geolocation) allowList.push(\"geolocation *\");\\n if (permissions.clipboardWrite) allowList.push(\"clipboard-write *\");\\n return allowList.join(\"; \");\\n }\\n\\n function buildCSP(csp) {\\n if (!csp) {\\n return [\\n \"default-src \\'none\\'\",\\n \"script-src \\'unsafe-inline\\'\",\\n \"style-src \\'unsafe-inline\\'\",\\n \"img-src data:\",\\n \"font-src data:\",\\n \"media-src data:\",\\n \"connect-src \\'none\\'\",\\n \"frame-src \\'none\\'\",\\n \"object-src \\'none\\'\",\\n \"base-uri \\'none\\'\",\\n ].join(\"; \");\\n }\\n\\n const connectDomains = (csp.connectDomains || []).map(sanitizeDomain).filter(Boolean);\\n const resourceDomains = (csp.resourceDomains || []).map(sanitizeDomain).filter(Boolean);\\n const frameDomains = (csp.frameDomains || []).map(sanitizeDomain).filter(Boolean);\\n const baseUriDomains = (csp.baseUriDomains || []).map(sanitizeDomain).filter(Boolean);\\n const scriptDirectives = (csp.scriptDirectives || []).filter(function(d) { return typeof d === \"string\" && d.length > 0; });\\n\\n const connectSrc = connectDomains.length > 0 ? connectDomains.join(\" \") : \"\\'none\\'\";\\n const resourceSrc = resourceDomains.length > 0 ? [\"data:\", \"blob:\", ...resourceDomains].join(\" \") : \"data: blob:\";\\n const frameSrc = frameDomains.length > 0 ? frameDomains.join(\" \") : \"\\'none\\'\";\\n const baseUri = baseUriDomains.length > 0 ? baseUriDomains.join(\" \") : \"\\'none\\'\";\\n const scriptSrcParts = [\"\\'unsafe-inline\\'\", \"\\'unsafe-eval\\'\", resourceSrc];\\n if (scriptDirectives.length > 0) scriptSrcParts.push(scriptDirectives.join(\" \"));\\n\\n return [\\n \"default-src \\'none\\'\",\\n \"script-src \" + scriptSrcParts.join(\" \"),\\n \"style-src \\'unsafe-inline\\' \" + resourceSrc,\\n \"img-src \" + resourceSrc,\\n \"font-src \" + resourceSrc,\\n \"media-src \" + resourceSrc,\\n \"connect-src \" + connectSrc,\\n \"frame-src \" + frameSrc,\\n \"object-src \\'none\\'\",\\n \"base-uri \" + baseUri,\\n ].join(\"; \");\\n }\\n\\n function buildViolationListenerScript() {\\n return `<script>\\ndocument.addEventListener(\\'securitypolicyviolation\\', function(e) {\\n var violation = {\\n type: \\'mcp-apps:csp-violation\\',\\n directive: e.violatedDirective,\\n blockedUri: e.blockedURI,\\n sourceFile: e.sourceFile || null,\\n lineNumber: e.lineNumber || null,\\n columnNumber: e.columnNumber || null,\\n effectiveDirective: e.effectiveDirective,\\n originalPolicy: e.originalPolicy,\\n disposition: e.disposition,\\n timestamp: Date.now()\\n };\\n console.warn(\\'[MCP Apps CSP Violation]\\', violation.directive, \\':\\', violation.blockedUri);\\n window.parent.postMessage(violation, \\'*\\');\\n});\\n\\nfunction serializeConsoleArgs(args) {\\n try {\\n return Array.from(args || []).map(function(arg) {\\n if (arg instanceof Error) {\\n return {\\n type: \\'Error\\',\\n message: arg.message,\\n stack: arg.stack,\\n name: arg.name,\\n };\\n }\\n if (typeof arg === \\'object\\' && arg !== null) {\\n try {\\n return JSON.parse(JSON.stringify(arg));\\n } catch (e) {\\n return String(arg);\\n }\\n }\\n return arg;\\n });\\n } catch (e) {\\n return [String(args)];\\n }\\n}\\n\\nfunction sendConsoleToParent(level, args) {\\n try {\\n window.parent.postMessage({\\n type: \\'iframe-console-log\\',\\n level: level,\\n args: serializeConsoleArgs(args),\\n timestamp: new Date().toISOString(),\\n url: window.location.href,\\n }, \\'*\\');\\n } catch (e) {}\\n}\\n\\nvar originalConsoleError = console.error.bind(console);\\nconsole.error = function() {\\n var args = Array.from(arguments);\\n originalConsoleError.apply(console, args);\\n sendConsoleToParent(\\'error\\', args);\\n};\\n\\nwindow.addEventListener(\\'error\\', function(event) {\\n sendConsoleToParent(\\'error\\', [{\\n message: event.message,\\n filename: event.filename,\\n lineno: event.lineno,\\n colno: event.colno,\\n error: event.error ? {\\n message: event.error.message,\\n stack: event.error.stack,\\n name: event.error.name,\\n } : null,\\n }]);\\n});\\n\\nwindow.addEventListener(\\'unhandledrejection\\', function(event) {\\n sendConsoleToParent(\\'error\\', [{\\n message: \\'Unhandled Promise Rejection\\',\\n reason: event.reason ? String(event.reason) : \\'Unknown\\',\\n error: event.reason instanceof Error ? {\\n message: event.reason.message,\\n stack: event.reason.stack,\\n name: event.reason.name,\\n } : null,\\n }]);\\n});\\n</` + `script>`;\\n }\\n\\n function injectCSP(html, cspValue) {\\n const cspMeta = \\'<meta http-equiv=\"Content-Security-Policy\" content=\"\\' + cspValue + \\'\">\\';\\n const violationListener = buildViolationListenerScript();\\n const injection = cspMeta + violationListener;\\n\\n if (html.includes(\"<head>\")) {\\n return html.replace(\"<head>\", \"<head>\" + injection);\\n } else if (html.includes(\"<HEAD>\")) {\\n return html.replace(\"<HEAD>\", \"<HEAD>\" + injection);\\n } else if (html.includes(\"<html>\")) {\\n return html.replace(\"<html>\", \"<html><head>\" + injection + \"</head>\");\\n } else if (html.includes(\"<HTML>\")) {\\n return html.replace(\"<HTML>\", \"<HTML><head>\" + injection + \"</head>\");\\n } else if (html.includes(\"<!DOCTYPE\") || html.includes(\"<!doctype\")) {\\n return html.replace(/(<!DOCTYPE[^>]*>|<!doctype[^>]*>)/i, \"$1<head>\" + injection + \"</head>\");\\n } else {\\n return injection + html;\\n }\\n }\\n\\n // Query params from host (csp_mode, permissions, widget_csp). AppFrame only\\n // sends { html, csp } in sandbox-resource-ready; we carry the rest on the URL.\\n // Blob URLs cannot reliably carry search params, so the CDN shell injects\\n // window.__SANDBOX_SEARCH__ via buildSandboxProxyBlobHtml.\\n const query = new URLSearchParams(\\n typeof window.__SANDBOX_SEARCH__ === \"string\"\\n ? window.__SANDBOX_SEARCH__\\n : location.search\\n );\\n const queryCspMode = query.get(\"csp_mode\") || \"permissive\";\\n let queryPermissions = null;\\n let queryWidgetCsp = null;\\n try {\\n const rawPerm = query.get(\"permissions\");\\n if (rawPerm) queryPermissions = JSON.parse(rawPerm);\\n } catch (e) {}\\n try {\\n const rawCsp = query.get(\"widget_csp\");\\n if (rawCsp) queryWidgetCsp = JSON.parse(rawCsp);\\n } catch (e) {}\\n\\n const inner = document.createElement(\"iframe\");\\n inner.style = \"width:100%; height:100%; border:none;\";\\n inner.setAttribute(\"sandbox\", \"allow-scripts allow-same-origin allow-forms\");\\n document.body.appendChild(inner);\\n\\n window.addEventListener(\"message\", async (event) => {\\n if (event.source === window.parent) {\\n if (event.data && event.data.method === \"ui/notifications/sandbox-resource-ready\") {\\n const params = event.data.params || {};\\n const html = params.html;\\n const sandbox = params.sandbox;\\n // Prefer message csp when present; fall back to URL widget_csp\\n const csp = params.csp != null ? params.csp : queryWidgetCsp;\\n const permissions = params.permissions != null ? params.permissions : queryPermissions;\\n const permissive =\\n typeof params.permissive === \"boolean\"\\n ? params.permissive\\n : queryCspMode === \"permissive\";\\n if (typeof sandbox === \"string\") {\\n inner.setAttribute(\"sandbox\", sandbox);\\n }\\n const allowAttribute = buildAllowAttribute(permissions);\\n if (allowAttribute) {\\n inner.setAttribute(\"allow\", allowAttribute);\\n }\\n if (typeof html === \"string\") {\\n if (permissive) {\\n const permissiveCsp = [\\n \"default-src * \\'unsafe-inline\\' \\'unsafe-eval\\' data: blob: filesystem: about:\",\\n \"script-src * \\'unsafe-inline\\' \\'unsafe-eval\\' data: blob:\",\\n \"style-src * \\'unsafe-inline\\' data: blob:\",\\n \"img-src * data: blob: https: http:\",\\n \"media-src * data: blob: https: http:\",\\n \"font-src * data: blob: https: http:\",\\n \"connect-src * data: blob: https: http: ws: wss: about:\",\\n \"frame-src * data: blob: https: http: about:\",\\n \"object-src * data: blob:\",\\n \"base-uri *\",\\n \"form-action *\",\\n ].join(\"; \");\\n const processedHtml = injectCSP(html, permissiveCsp);\\n inner.srcdoc = processedHtml;\\n } else {\\n const cspValue = buildCSP(csp);\\n const processedHtml = injectCSP(html, cspValue);\\n inner.srcdoc = processedHtml;\\n }\\n }\\n } else {\\n if (inner && inner.contentWindow) {\\n inner.contentWindow.postMessage(event.data, \"*\");\\n }\\n }\\n } else if (event.source === inner.contentWindow) {\\n window.parent.postMessage(event.data, \"*\");\\n }\\n });\\n\\n window.parent.postMessage({\\n jsonrpc: \"2.0\",\\n method: \"ui/notifications/sandbox-proxy-ready\",\\n params: {},\\n }, \"*\");\\n </script>\\n </body>\\n</html>';\n\n/**\n * Build sandbox-proxy HTML for a Blob URL, injecting search params that Blob\n * URLs cannot carry reliably.\n *\n * JSON-escapes the search string (incl. `<` → `\\\\u003c`) so it cannot break\n * out of the inline script tag.\n */\nexport function buildSandboxProxyBlobHtml(search: string): string {\n const escaped = JSON.stringify(search).replace(/</g, \"\\\\u003c\");\n const inject =\n \"<script>window.__SANDBOX_SEARCH__ = \" + escaped + \";</script>\";\n return SANDBOX_PROXY_HTML.replace(\n ` const scriptSrcParts = [\"'unsafe-inline'\", \"'unsafe-eval'\", resourceSrc];\\n`,\n ` const scriptSrcParts = [\"'unsafe-inline'\", resourceSrc];\\n`\n ).replace(\"<body>\", \"<body>\" + inject);\n}\n","import { useCallback, useEffect, type RefObject } from \"react\";\nimport type { ViewDisplayMode } from \"./types.js\";\n\nconst SHELL_BASE =\n \"w-full h-full min-h-0 bg-background flex flex-col [&:fullscreen]:h-full [&:fullscreen]:w-full [&:fullscreen]:bg-background\";\n\n// High z-index for hosts without a trapping stacking context; chat history\n// toggle also hides via data-mcp-widget-fullscreen on <html>.\nconst WIDGET_FULLSCREEN_OVERLAY_CLASSES = `fixed inset-0 z-[200] ${SHELL_BASE}`;\nconst WIDGET_PIP_SHELL_CLASSES = [\n \"fixed top-4 left-1/2 -translate-x-1/2 z-[200]\",\n \"rounded-3xl w-full min-w-[300px] h-[400px]\",\n \"shadow-2xl border overflow-hidden\",\n \"bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80\",\n \"flex flex-col\",\n].join(\" \");\n\nconst WIDGET_FULLSCREEN_DOCUMENT_ATTR = \"data-mcp-widget-fullscreen\";\nconst WIDGET_DISPLAY_MODE_ATTR = \"data-mcp-widget-display-mode\";\n\nfunction useWidgetDisplayModeDocumentChrome(\n displayMode: ViewDisplayMode\n): void {\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n if (displayMode === \"pip\" || displayMode === \"fullscreen\") {\n document.documentElement.setAttribute(\n WIDGET_DISPLAY_MODE_ATTR,\n displayMode\n );\n if (displayMode === \"fullscreen\") {\n document.documentElement.setAttribute(\n WIDGET_FULLSCREEN_DOCUMENT_ATTR,\n \"\"\n );\n } else {\n document.documentElement.removeAttribute(\n WIDGET_FULLSCREEN_DOCUMENT_ATTR\n );\n }\n return () => {\n document.documentElement.removeAttribute(WIDGET_DISPLAY_MODE_ATTR);\n document.documentElement.removeAttribute(\n WIDGET_FULLSCREEN_DOCUMENT_ATTR\n );\n };\n }\n document.documentElement.removeAttribute(WIDGET_DISPLAY_MODE_ATTR);\n document.documentElement.removeAttribute(WIDGET_FULLSCREEN_DOCUMENT_ATTR);\n }, [displayMode]);\n}\n\nexport function useViewDisplayModeControls({\n displayMode,\n setDisplayMode,\n}: {\n containerRef: RefObject<HTMLElement | null>;\n displayMode: ViewDisplayMode;\n setDisplayMode: (mode: ViewDisplayMode) => void;\n}) {\n const isFullscreen = displayMode === \"fullscreen\";\n const isPip = displayMode === \"pip\";\n\n useWidgetDisplayModeDocumentChrome(displayMode);\n\n const handleDisplayModeChange = useCallback(\n (mode: ViewDisplayMode) => setDisplayMode(mode),\n [setDisplayMode]\n );\n\n return {\n handleDisplayModeChange,\n fullscreenShellClassName: isFullscreen\n ? WIDGET_FULLSCREEN_OVERLAY_CLASSES\n : undefined,\n pipShellClassName: isPip ? WIDGET_PIP_SHELL_CLASSES : undefined,\n isFullscreen,\n isPip,\n };\n}\n\nexport const VIEW_DIMENSIONS = {\n PIP_MAX_WIDTH: 700,\n DEFAULT_HEIGHT: 400,\n FULLSCREEN_HEADER_HEIGHT: 50,\n} as const;\n","import type {\n McpUiHostCapabilities,\n McpUiSupportedContentBlockModalities,\n} from \"./ext-apps-bridge.js\";\nimport type { ViewConnection, ViewDisplayMode } from \"./types.js\";\n\n/** Inputs used to derive the capabilities advertised by an MCP App host. */\ntype CapabilityInputs = {\n hasConnection: boolean;\n hasMessageHandler: boolean;\n hasModelContextHandler: boolean;\n hasLogHandler: boolean;\n hasSamplingHandler?: boolean;\n hasDownloadHandler?: boolean;\n messageCapabilities?: McpUiSupportedContentBlockModalities;\n modelContextCapabilities?: McpUiSupportedContentBlockModalities;\n};\n\n/**\n * Builds host capabilities from the callbacks and connections the host exposes.\n *\n * @param inputs - Available host features and supported content modalities.\n * @returns Capabilities suitable for MCP App bridge initialization.\n */\nexport function buildDefaultHostCapabilities({\n hasConnection,\n hasMessageHandler,\n hasModelContextHandler,\n hasLogHandler,\n hasSamplingHandler,\n hasDownloadHandler,\n messageCapabilities,\n modelContextCapabilities,\n}: CapabilityInputs): McpUiHostCapabilities {\n return {\n openLinks: {},\n ...(hasConnection\n ? {\n serverTools: {},\n serverResources: {},\n }\n : {}),\n ...(hasLogHandler ? { logging: {} } : {}),\n ...(hasSamplingHandler ? { sampling: {} } : {}),\n ...(hasDownloadHandler ? { downloadFile: {} } : {}),\n ...(hasModelContextHandler\n ? { updateModelContext: modelContextCapabilities ?? { text: {} } }\n : {}),\n ...(hasMessageHandler\n ? { message: messageCapabilities ?? { text: {} } }\n : {}),\n };\n}\n\n/**\n * Tests whether a tool is visible to the model.\n *\n * Tools without explicit visibility metadata remain model-visible.\n *\n * @param tool - Tool metadata to inspect.\n * @returns `true` when the tool may be presented to the model.\n */\nexport function isToolVisibleToModel(tool: { _meta?: unknown }): boolean {\n if (!tool._meta || typeof tool._meta !== \"object\") return true;\n const ui = (tool._meta as Record<string, unknown>).ui;\n if (!ui || typeof ui !== \"object\") return true;\n const visibility = (ui as Record<string, unknown>).visibility;\n return (\n !Array.isArray(visibility) || visibility.some((value) => value === \"model\")\n );\n}\n\n/**\n * Validates and dispatches an MCP App `ui/message` payload.\n *\n * @param handler - Host callback that accepts message content.\n * @param content - Content blocks supplied by the app.\n * @throws When the host has no message handler or `content` is empty.\n */\nexport async function dispatchUiMessage(\n handler: ((content: unknown[]) => void | Promise<void>) | undefined,\n content: unknown[]\n): Promise<void> {\n if (!handler) {\n throw new Error(\"This host surface does not support ui/message\");\n }\n if (content.length === 0) {\n throw new Error(\"ui/message requires at least one content block\");\n }\n await handler(content);\n}\n\n/**\n * Resolves a display-mode request against host and app availability.\n *\n * @param options - Requested and current modes plus each side's supported modes.\n * @returns The requested mode when both sides support it; otherwise `current`.\n */\nexport function resolveRequestedDisplayMode({\n requested,\n current,\n hostAvailable,\n appAvailable,\n}: {\n requested: ViewDisplayMode;\n current: ViewDisplayMode;\n hostAvailable?: readonly ViewDisplayMode[];\n appAvailable?: readonly ViewDisplayMode[];\n}): ViewDisplayMode {\n const hostModes = hostAvailable ?? [\"inline\"];\n const appModes = appAvailable ?? [\"inline\"];\n return hostModes.includes(requested) && appModes.includes(requested)\n ? requested\n : current;\n}\n\n/**\n * Asserts that an MCP App may call a named server tool.\n *\n * @param tools - Tools available through the live view connection.\n * @param name - Tool name requested by the app.\n * @throws When the tool is unavailable or not visible to apps.\n */\nexport function assertAppCanCallTool(\n tools: ViewConnection[\"tools\"],\n name: string\n): void {\n const tool = tools?.find((candidate) => candidate.name === name);\n if (!tool) {\n throw new Error(`Tool \"${name}\" is not available to this app`);\n }\n\n const visibility = tool._meta?.ui?.visibility;\n if (visibility && !visibility.includes(\"app\")) {\n throw new Error(`Tool \"${name}\" is not available to this app`);\n }\n}\n","import { RESOURCE_MIME_TYPE } from \"./ext-apps-bridge.js\";\n\n/**\n * Reads the MCP App resource URI from tool metadata.\n *\n * @param toolMeta - Tool `_meta` object.\n * @returns The declared view resource URI, or `null` when none is declared.\n */\nexport function getViewResourceUri(\n toolMeta?: Record<string, unknown>\n): string | null {\n const uri = toolMeta?.ui;\n if (\n uri &&\n typeof uri === \"object\" &&\n \"resourceUri\" in uri &&\n typeof (uri as { resourceUri?: unknown }).resourceUri === \"string\"\n ) {\n return (uri as { resourceUri: string }).resourceUri;\n }\n return null;\n}\n\n/**\n * Tests whether tool metadata declares an MCP App resource.\n *\n * @param toolMeta - Tool `_meta` object.\n * @returns `true` when the tool declares a view resource URI.\n */\nexport function isViewTool(toolMeta?: Record<string, unknown>): boolean {\n return getViewResourceUri(toolMeta) !== null;\n}\n\n/**\n * Tests whether a resource uses the MCP App HTML media type.\n *\n * @param mimeType - Resource MIME type.\n * @returns `true` for the MCP App resource media type.\n */\nexport function isViewResource(mimeType?: string): boolean {\n return mimeType === RESOURCE_MIME_TYPE;\n}\n"],"mappings":"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","names":["logger","auth","useCallback","UnauthorizedError","UnauthorizedError","sessionId","response","tracker","tracker","isOAuthClientProvider","session","proxyAddress","useCallback","serverInfo","capabilities","protocolEra","protocolVersion","instructions","extensions","error","auth","parsedUrl","baseUrl","StreamableHTTPClientTransport","StreamableHTTPClientTransport","useCallback","useEffect","useMemo","useRef","useState","useCallback","useEffect","useRef","useState","useMemo","useEffect","useCallback","displayName","useRef","useState","clearRpcLogs","React","useCallback","useEffect","useMemo","useRef","useState","useCallback","useEffect","React","useRef","useState","useMemo","useCallback","useEffect"]}
1
+ {"version":3,"sources":["../../src/utils/logging.ts","../../src/react/rpc-logger.ts","../../src/core/skills.ts","../../src/react/types.ts","../../src/react/useMcp.ts","../../src/auth/popup.ts","../../src/transport/http.ts","../../src/auth/flow.ts","../../src/utils/json-schema-validator.ts","../../src/transport/base.ts","../../src/telemetry/connector-telemetry.ts","../../src/utils/version.ts","../../src/core/config.ts","../../src/auth/browser.ts","../../src/auth/storage.ts","../../src/auth/session-store.ts","../../src/auth/url.ts","../../src/core/browser.ts","../../src/telemetry/telemetry.ts","../../src/telemetry/events.ts","../../src/telemetry/tel-fetch.ts","../../src/core/base.ts","../../src/core/session.ts","../../src/telemetry/client-telemetry.ts","../../src/utils/favicon.ts","../../src/react/useMcp-helpers.ts","../../src/react/useMcp-operations.ts","../../src/react/token-expiry.ts","../../src/auth/callback.ts","../../src/react/index.ts","../../src/react/McpClientProvider.tsx","../../src/react/useMcpServerQueues.ts","../../src/react/storage.ts","../../src/react/view/ext-apps-bridge.ts","../../src/react/view/ViewRenderer.tsx","../../src/react/view/parse-custom-props.ts","../../src/react/view/inject-openai-file-apis.ts","../../src/react/view/initialized-sync.ts","../../src/react/view/resolve-view-resource.ts","../../src/react/view/sandbox-blob-url.ts","../../src/react/view/use-display-mode.ts","../../src/react/view/view-host-policy.ts","../../src/react/view/view-detection.ts"],"sourcesContent":["export type LogLevel =\n | \"silent\"\n | \"error\"\n | \"warn\"\n | \"info\"\n | \"http\"\n | \"verbose\"\n | \"debug\"\n | \"silly\";\n\ntype LogFormat = \"minimal\" | \"detailed\" | \"emoji\";\n\nconst LEVELS = [\n \"silent\",\n \"error\",\n \"warn\",\n \"info\",\n \"http\",\n \"verbose\",\n \"debug\",\n \"silly\",\n] as const satisfies readonly LogLevel[];\n\nconst EMOJI: Record<LogLevel, string> = {\n silent: \"\",\n error: \"❌\",\n warn: \"⚠️\",\n info: \"ℹ️\",\n http: \"🌐\",\n verbose: \"📝\",\n debug: \"🔍\",\n silly: \"🤪\",\n};\n\nfunction envLevel(): LogLevel {\n let raw: string | undefined;\n try {\n raw =\n typeof process !== \"undefined\"\n ? (process.env?.MCP_USE_LOG_LEVEL ?? process.env?.DEBUG)\n : undefined;\n } catch {\n // Deno may deny env access.\n }\n const v = raw?.trim().toLowerCase();\n if (v === \"2\") return \"debug\";\n if (v && (LEVELS as readonly string[]).includes(v)) return v as LogLevel;\n return \"info\";\n}\n\nclass SimpleConsoleLogger {\n constructor(\n private name = \"mcp-use\",\n public level: LogLevel = \"info\",\n public format: LogFormat = \"minimal\"\n ) {}\n\n private write(level: LogLevel, message: string, args: unknown[]): void {\n if (\n this.level === \"silent\" ||\n LEVELS.indexOf(level) > LEVELS.indexOf(this.level)\n ) {\n return;\n }\n const extra = args\n .map((a) => {\n if (typeof a === \"string\") return a;\n try {\n return JSON.stringify(a);\n } catch {\n return String(a);\n }\n })\n .join(\" \");\n const full = extra ? `${message} ${extra}` : message;\n const ts = new Date().toLocaleTimeString(\"en-US\", { hour12: false });\n const label = this.format === \"minimal\" ? level : level.toUpperCase();\n const emoji = this.format === \"emoji\" ? ` ${EMOJI[level]}` : \"\";\n const line = `${ts} [${this.name}]${emoji} ${label}: ${full}`;\n const fn =\n level === \"error\"\n ? console.error\n : level === \"warn\"\n ? console.warn\n : level === \"info\"\n ? console.info\n : level === \"debug\"\n ? console.debug\n : console.log;\n fn(line);\n }\n\n error = (m: string, ...a: unknown[]) => this.write(\"error\", m, a);\n warn = (m: string, ...a: unknown[]) => this.write(\"warn\", m, a);\n info = (m: string, ...a: unknown[]) => this.write(\"info\", m, a);\n debug = (m: string, ...a: unknown[]) => this.write(\"debug\", m, a);\n http = (m: string, ...a: unknown[]) => this.write(\"http\", m, a);\n verbose = (m: string, ...a: unknown[]) => this.write(\"verbose\", m, a);\n silly = (m: string, ...a: unknown[]) => this.write(\"silly\", m, a);\n\n setFormat(format: LogFormat): void {\n this.format = format;\n }\n}\n\nexport class Logger {\n private static instances: Record<string, SimpleConsoleLogger> = {};\n private static currentFormat: LogFormat = \"minimal\";\n private static currentLevel: LogLevel | undefined;\n\n static get(name = \"mcp-use\"): SimpleConsoleLogger {\n return (this.instances[name] ??= new SimpleConsoleLogger(\n name,\n this.currentLevel ?? envLevel(),\n this.currentFormat\n ));\n }\n\n static configure({\n level = envLevel(),\n format = \"minimal\",\n }: { level?: LogLevel; format?: LogFormat } = {}): void {\n this.currentLevel = level;\n this.currentFormat = format;\n for (const log of Object.values(this.instances)) {\n log.level = level;\n log.format = format;\n }\n }\n\n static setDebug(enabled: boolean | 0 | 1 | 2): void {\n const level: LogLevel =\n enabled === 2 || enabled === true ? \"debug\" : \"info\";\n this.currentLevel = level;\n for (const log of Object.values(this.instances)) log.level = level;\n try {\n if (typeof process !== \"undefined\" && process.env) {\n process.env.MCP_USE_LOG_LEVEL = level;\n }\n } catch {\n // optional\n }\n }\n\n static setFormat(format: LogFormat): void {\n this.configure({ format });\n }\n}\n\n/** Default package logger used by client and connector operations. */\nexport const logger = Logger.get();\n","import type {\n JSONRPCMessage,\n MessageExtraInfo,\n Transport,\n TransportSendOptions,\n} from \"@modelcontextprotocol/client\";\nimport { Logger } from \"../utils/logging.js\";\n\nconst logger = Logger.get(\"RpcLogger\");\n\n/** One JSON-RPC message captured by the React transport logger. */\nexport interface RpcLogEntry {\n /** Identifier of the server that sent or received the message. */\n serverId: string;\n /** Message direction relative to the client. */\n direction: \"send\" | \"receive\";\n /** ISO 8601 timestamp recorded when the message was observed. */\n timestamp: string;\n /** Captured JSON-RPC message. */\n message: JSONRPCMessage;\n}\n\n/**\n * Simple in-memory RPC log storage\n * Stores RPC messages for debugging purposes\n */\nclass RpcLogStore {\n private logs: RpcLogEntry[] = [];\n private listeners: Set<(entry: RpcLogEntry) => void> = new Set();\n private maxLogs = 1000;\n\n publish(entry: RpcLogEntry): void {\n logger.debug(\n \"[RPC Logger] Publishing log:\",\n entry.direction,\n entry.serverId,\n (entry.message as any)?.method\n );\n this.logs.push(entry);\n\n // Prune old logs\n if (this.logs.length > this.maxLogs) {\n this.logs = this.logs.slice(-this.maxLogs);\n }\n\n logger.debug(\n \"[RPC Logger] Total logs:\",\n this.logs.length,\n \"Listeners:\",\n this.listeners.size\n );\n\n // Notify listeners\n this.listeners.forEach((listener) => {\n try {\n listener(entry);\n } catch (err) {\n logger.error(\"[RPC Logger] Listener error:\", err);\n }\n });\n }\n\n subscribe(listener: (entry: RpcLogEntry) => void): () => void {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n }\n\n getLogsForServer(serverId: string): RpcLogEntry[] {\n return this.logs.filter((log) => log.serverId === serverId);\n }\n\n getAllLogs(): RpcLogEntry[] {\n return [...this.logs];\n }\n\n clear(serverId?: string): void {\n if (serverId) {\n this.logs = this.logs.filter((log) => log.serverId !== serverId);\n } else {\n this.logs = [];\n }\n }\n}\n\n// Global store instance\nconst rpcLogStore = new RpcLogStore();\n\n/**\n * Retrieve RPC log entries for the specified server.\n *\n * @param serverId - The server identifier to filter logs by\n * @returns All `RpcLogEntry` objects associated with `serverId`\n */\nexport function getRpcLogs(serverId: string): RpcLogEntry[] {\n return rpcLogStore.getLogsForServer(serverId);\n}\n\n/**\n * Retrieve all stored RPC log entries.\n *\n * @returns A shallow copy of the array of `RpcLogEntry` objects representing all logs\n */\nexport function getAllRpcLogs(): RpcLogEntry[] {\n return rpcLogStore.getAllLogs();\n}\n\n/**\n * Subscribe to receive RPC log entries as they are published.\n *\n * @param listener - Function invoked with each new `RpcLogEntry`\n * @returns A function that unsubscribes the listener when called\n */\nexport function subscribeToRpcLogs(\n listener: (entry: RpcLogEntry) => void\n): () => void {\n return rpcLogStore.subscribe(listener);\n}\n\n/**\n * Remove stored RPC log entries for a specific server or all servers.\n *\n * @param serverId - The server identifier whose logs should be removed. If omitted, clears all logs.\n */\nexport function clearRpcLogs(serverId?: string): void {\n rpcLogStore.clear(serverId);\n}\n\n/**\n * Create a Transport wrapper that records every sent and received JSON-RPC message tagged with the given server ID.\n *\n * @param transport - The Transport instance to wrap and forward calls to\n * @param serverId - Identifier used to attribute created log entries to a specific server\n * @returns A Transport instance that forwards operations to the provided transport and records each message as a log entry with direction `send` or `receive`\n */\nexport function wrapTransportForLogging(\n transport: Transport,\n serverId: string\n): Transport {\n class LoggingTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n\n constructor(private readonly inner: Transport) {\n // Intercept incoming messages\n this.inner.onmessage = (\n message: JSONRPCMessage,\n extra?: MessageExtraInfo\n ) => {\n // Log RPC message\n rpcLogStore.publish({\n serverId,\n direction: \"receive\",\n timestamp: new Date().toISOString(),\n message,\n });\n this.onmessage?.(message, extra);\n };\n\n this.inner.onclose = () => {\n this.onclose?.();\n };\n\n this.inner.onerror = (error: Error) => {\n this.onerror?.(error);\n };\n }\n\n async start(): Promise<void> {\n if (typeof (this.inner as any).start === \"function\") {\n await (this.inner as any).start();\n }\n }\n\n async send(\n message: JSONRPCMessage,\n options?: TransportSendOptions\n ): Promise<void> {\n // Log RPC message\n rpcLogStore.publish({\n serverId,\n direction: \"send\",\n timestamp: new Date().toISOString(),\n message,\n });\n await this.inner.send(message as any, options as any);\n }\n\n async close(): Promise<void> {\n await this.inner.close();\n }\n\n get sessionId(): string | undefined {\n return (this.inner as any).sessionId;\n }\n\n setProtocolVersion?(version: string): void {\n if (typeof this.inner.setProtocolVersion === \"function\") {\n this.inner.setProtocolVersion(version);\n }\n }\n }\n\n return new LoggingTransport(transport);\n}\n","/** Experimental Skills over MCP extension identifier. */\nexport const SKILLS_EXTENSION_ID = \"io.modelcontextprotocol/skills\" as const;\n\n/** One immutable resource advertised by a remote skill. */\nexport interface SkillResource {\n /** Absolute MCP resource URI. */\n uri: string;\n /** SHA-256 digest of the raw resource bytes. */\n digest: string;\n}\n\n/** One skill catalog entry returned by `skills/list` or `skills/get`. */\nexport interface Skill {\n /** URI of the skill's root `SKILL.md`. */\n uri: string;\n /** Verbatim parsed YAML frontmatter. */\n frontmatter: Record<string, unknown>;\n /** Complete resource manifest when the server exposes a static skill. */\n resources?: SkillResource[];\n}\n\n/** Paginated result returned by `skills/list`. */\nexport interface SkillsListResult {\n /** Skills on this page, in server order. */\n skills: Skill[];\n /** Cursor for the next page, absent on the final page. */\n nextCursor?: string;\n}\n\n/** Result returned by `skills/get`. */\nexport interface SkillGetResult {\n /** The requested skill. */\n skill: Skill;\n}\n\n/** One child returned by `resources/directory/read`. */\nexport interface SkillDirectoryEntry {\n /** Resource URI of the child. */\n uri: string;\n /** Display name of the child when the server provides one. */\n name?: string;\n /** MIME type of the child when the server provides one. */\n mimeType?: string;\n}\n\n/** Paginated result returned by `resources/directory/read`. */\nexport interface SkillDirectoryReadResult {\n /** Directory children on this page, in server order. */\n resources: SkillDirectoryEntry[];\n /** Cursor for the next page, absent on the final page. */\n nextCursor?: string;\n}\n","import type {\n ClientOptions,\n CompleteRequestParams,\n CompleteResult,\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n Notification,\n OAuthClientProvider,\n ProtocolEra,\n Transport,\n Prompt,\n Resource,\n // v2 exports the resource-template type as `ResourceTemplateType` (the bare\n // `ResourceTemplate` name is the server package's class).\n ResourceTemplateType as ResourceTemplate,\n Tool,\n VersionNegotiationMode,\n} from \"@modelcontextprotocol/client\";\nimport type { BaseMCPClient } from \"../core/base.js\";\nimport type { MCPAuthorizationInfo } from \"../core/session.js\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\n\n/** Proxy configuration for routing MCP traffic through a proxy server. */\nexport interface ProxyConfig {\n /** Proxy server address (e.g. \"http://localhost:3001/inspector/api/proxy\"). */\n proxyAddress?: string;\n /** Additional headers to include in proxied requests. */\n headers?: Record<string, string>;\n /**\n * @deprecated Use `headers` instead.\n */\n customHeaders?: Record<string, string>;\n}\n\n/**\n * SDK-level reconnection options for streamable HTTP transports.\n * Controls the retry behavior of the underlying `StreamableHTTPClientTransport`.\n */\nexport type ReconnectionOptions = {\n /** Maximum delay between reconnection attempts in ms (default: 30000) */\n maxReconnectionDelay?: number;\n /** Initial delay before first reconnection attempt in ms (default: 1000) */\n initialReconnectionDelay?: number;\n /** Multiplier applied to delay after each failed attempt (default: 1.5) */\n reconnectionDelayGrowFactor?: number;\n /** Maximum number of reconnection retries (default: 2) */\n maxRetries?: number;\n};\n\n/** Configures the {@link useMcp} hook and its browser connection lifecycle. */\nexport type UseMcpOptions = {\n /** The /sse URL of your remote MCP server */\n url?: string;\n /** Enable/disable the connection (similar to TanStack Query). When false, no connection will be attempted (default: true) */\n enabled?: boolean;\n /** Proxy configuration for routing through a proxy server */\n proxyConfig?: ProxyConfig;\n /**\n * OAuth proxy base URL (e.g. `https://inspector.example.com/inspector/api/oauth`)\n * used to route OAuth requests (`.well-known` discovery, DCR, token exchange)\n * through a transparent server-side proxy — bypassing browser CORS against\n * third-party identity providers — WITHOUT proxying MCP traffic itself.\n *\n * The proxy is transparent: it forwards requests and responses unmodified, so\n * the SDK's authorization-server issuer validation (RFC 8414 §3.3) still\n * passes. When omitted, the OAuth proxy URL is derived from\n * `proxyConfig.proxyAddress` (replacing a trailing `/proxy` with `/oauth`),\n * preserving the existing behavior for fully-proxied connections.\n */\n oauthProxyUrl?: string;\n /**\n * Connection policy for proxy routing.\n * - `auto`: start direct and use `autoProxyFallback` after a qualifying failure\n * - `direct`: never use `proxyConfig` and never fall back\n * - `proxy`: use `proxyConfig` immediately and never fall back\n *\n * When omitted, `proxyConfig` retains its legacy immediate-proxy behavior,\n * except when `autoProxyFallback` explicitly requests a direct-first attempt.\n */\n connectionMode?: \"auto\" | \"direct\" | \"proxy\";\n /**\n * Enable automatic proxy fallback when direct connection fails\n * When enabled, if a direct connection fails with FastMCP or CORS errors,\n * automatically retries using the proxy configuration\n *\n * Can be:\n * - `true`: Enable with `proxyConfig.proxyAddress`\n * - `false`: Disable automatic fallback (default)\n * - `{ enabled: boolean, proxyAddress?: string }`: Custom configuration\n *\n * @defaultValue false\n *\n * @example\n * ```typescript\n * // Use default proxy\n * useMcp({ url: '...', autoProxyFallback: true })\n *\n * // Use custom proxy\n * useMcp({\n * url: '...',\n * autoProxyFallback: {\n * enabled: true,\n * proxyAddress: 'https://my-proxy.com/api/proxy'\n * }\n * })\n * ```\n */\n autoProxyFallback?:\n | boolean\n | {\n /** Whether fallback is enabled. */\n enabled?: boolean;\n /** Proxy endpoint used after a qualifying direct failure. */\n proxyAddress?: string;\n };\n /** Custom callback URL for OAuth redirect (defaults to /oauth/callback on the current origin) */\n callbackUrl?: string;\n /** Storage key prefix for OAuth data in localStorage (defaults to \"mcp:auth\") */\n storageKeyPrefix?: string;\n /** Headers that can be used to bypass auth */\n headers?: Record<string, string>;\n /**\n * Log level for console output.\n * Set to 'silent' to suppress ALL console logging (the `mcp.log` state array is still populated).\n * @defaultValue `\"silent\"`\n */\n logLevel?:\n | \"silent\"\n | \"error\"\n | \"warn\"\n | \"info\"\n | \"http\"\n | \"verbose\"\n | \"debug\"\n | \"silly\";\n /** Auto retry connection if initial connection fails, with delay in ms (default: false) */\n autoRetry?: boolean | number;\n /**\n * Auto reconnect if an established connection is lost.\n *\n * Can be:\n * - `boolean`: Enable/disable with default 3000ms delay and 10s health check\n * - `number`: Reconnect delay in ms (enables health checks with defaults)\n * - `object`: Full configuration for reconnection and health checks\n *\n * @defaultValue `true` with a 3000 ms initial delay\n */\n autoReconnect?:\n | boolean\n | number\n | {\n /** Whether to enable automatic reconnection (default: true) */\n enabled?: boolean;\n /** Delay in ms before reconnection attempt (default: 3000) */\n initialDelay?: number;\n /**\n * Interval in ms for health check polling via HEAD requests.\n * Set to `false` to disable health checks entirely.\n * @defaultValue `10000`\n */\n healthCheckInterval?: number | false;\n /**\n * Time in ms without a successful health check before triggering reconnect.\n * @defaultValue `30000`\n */\n healthCheckTimeout?: number;\n };\n /** SDK-level reconnection options for the streamable HTTP transport */\n reconnectionOptions?: ReconnectionOptions;\n /** Popup window features string (dimensions and behavior) for OAuth */\n popupFeatures?: string;\n /**\n * Prevent automatic authentication popup/redirect on initial connection (default: true)\n * When true, the connection will enter 'pending_auth' state and wait for user to call authenticate()\n * Set to true to show a modal/button before triggering OAuth instead of auto-redirecting\n */\n preventAutoAuth?: boolean;\n /**\n * Detect OAuth protected-resource metadata after an anonymous connection so\n * mixed-auth servers can offer optional authentication without blocking use.\n * @defaultValue true\n */\n detectMixedAuth?: boolean;\n /**\n * Use full-page redirect for OAuth instead of popup window (default: false)\n * Redirect flow avoids popup blockers and provides better UX on mobile.\n * Set to true to use redirect flow instead of popup.\n */\n useRedirectFlow?: boolean;\n /**\n * Callback function that is invoked just before the authentication popup window is opened.\n * Only used when useRedirectFlow is false (popup mode).\n * @param url - The URL that will be opened in the popup.\n * @param features - The features string for the popup window.\n */\n onPopupWindow?: (\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void;\n /**\n * Additional client options passed to the underlying MCP SDK Client.\n * Use `capabilities.views: true` as shorthand for the MCP Apps UI extension,\n * or set `capabilities.extensions` directly.\n *\n * @example\n * ```typescript\n * useMcp({\n * url: '...',\n * clientOptions: {\n * capabilities: {\n * views: true,\n * },\n * },\n * })\n * ```\n */\n clientOptions?: Omit<ClientOptions, \"capabilities\"> & {\n /** MCP capabilities advertised by the underlying SDK client. */\n capabilities?: NonNullable<ClientOptions[\"capabilities\"]> & {\n /** Whether to advertise the MCP Apps UI extension shorthand. */\n views?: boolean;\n };\n };\n /**\n * Protocol version negotiation mode passed to the underlying SDK `Client`.\n * - `\"auto\"` (default): probe with `server/discover` to detect modern (2026-07-28)\n * servers, falling back to the 2025 handshake against legacy servers.\n * - `\"legacy\"`: classic 2025 `initialize` handshake, no probe.\n * - `{ pin: \"2026-07-28\" }`: modern era only, no fallback.\n */\n protocolNegotiation?: VersionNegotiationMode;\n /** Connection timeout in milliseconds for establishing initial connection (default: 30000 / 30 seconds) */\n timeout?: number;\n /** Optional callback to wrap the transport before passing it to the Client. Useful for logging, monitoring, or other transport-level interceptors. */\n wrapTransport?: (transport: Transport, serverId: string) => Transport;\n /** Stable identifier supplied to `wrapTransport`; defaults to `url`. */\n serverId?: string;\n /** Callback function that is invoked when a notification is received from the MCP server */\n onNotification?: (notification: Notification) => void;\n /**\n * Optional callback function to handle sampling requests from servers.\n * When provided, the client will declare sampling capability and handle\n * `sampling/createMessage` requests by calling this callback.\n *\n * @deprecated Sampling is deprecated by the 2026 protocol. Retained for v1\n * push requests and v2 multi-round-trip compatibility.\n */\n onSampling?: (\n params: SamplingCreateMessageParams\n ) => Promise<SamplingCreateMessageResult>;\n /**\n * Optional callback function to handle elicitation requests from servers.\n * When provided, the client will declare elicitation capability and handle\n * `elicitation/create` requests by calling this callback.\n *\n * Elicitation allows servers to request additional information from users:\n * - Form mode: Collect structured data with JSON schema validation\n * - URL mode: Direct users to external URLs for sensitive interactions\n */\n onElicitation?: (\n params: ElicitRequestFormParams | ElicitRequestURLParams\n ) => Promise<ElicitResult>;\n /** Client information advertised while establishing the MCP connection. */\n clientInfo?: {\n /** Stable programmatic client name. */\n name: string;\n /** Optional human-readable client title. */\n title?: string;\n /** Client version. */\n version: string;\n /** Optional human-readable client description. */\n description?: string;\n /** Icons representing the client. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Public website describing the client. */\n websiteUrl?: string;\n };\n /**\n * Optional custom fetch function to use for all MCP HTTP requests.\n *\n * When provided, this replaces the default global `fetch` for transport-level\n * requests. Useful for adding custom auth retry logic, logging, or proxying.\n *\n * @example\n * ```typescript\n * useMcp({\n * url: 'http://localhost:3000/mcp',\n * fetch: myCustomFetch,\n * })\n * ```\n */\n fetch?: typeof globalThis.fetch;\n /**\n * Optional external OAuth client provider.\n *\n * When provided, useMcp will use this provider directly instead of creating\n * BrowserOAuthClientProvider internally. This is useful for headless/testing\n * runtimes where popup/redirect flows are not available.\n */\n authProvider?: OAuthClientProvider;\n /**\n * OAuth client registration settings.\n *\n * Use this when the upstream auth server does **not** support Dynamic Client\n * Registration — for example, MCP servers running in proxy mode against\n * Slack, WorkOS, or similar providers. Prefer `clientMetadataUrl` when the\n * authorization server advertises CIMD support; the SDK falls back to DCR\n * when appropriate.\n *\n * @example\n * ```typescript\n * useMcp({\n * url: 'https://mcp.example.com',\n * oauth: {\n * clientId: 'my-preregistered-client-id',\n * clientMetadataUrl: 'https://app.example.com/oauth/client-metadata.json',\n * scope: 'openid profile email',\n * },\n * })\n * ```\n */\n oauth?: {\n /** Pre-registered OAuth client_id. */\n clientId?: string;\n /**\n * Public HTTPS OAuth Client ID Metadata Document URL (CIMD).\n * The document must contain a matching client_id and redirect_uris.\n */\n clientMetadataUrl?: string;\n /** OAuth scope string included in the authorize request. */\n scope?: string;\n };\n};\n\n/**\n * Serializable configuration for one server managed by `McpClientProvider`.\n * Pass this to `addServer` / `updateServer`.\n */\nexport interface McpServerConfig extends Omit<\n UseMcpOptions,\n \"onSampling\" | \"onElicitation\" | \"onNotification\"\n> {\n /** Optional user-facing alias. `server.name` always comes from MCP server metadata. */\n displayName?: string;\n /** Optional callback invoked when the provider queues sampling. */\n onSamplingRequest?: (request: PendingSamplingRequest) => void;\n /** Optional callback invoked when the provider queues elicitation. */\n onElicitationRequest?: (request: PendingElicitationRequest) => void;\n /** Optional callback invoked when the provider receives a notification. */\n onNotificationReceived?: (notification: McpNotification) => void;\n}\n\n/** @deprecated Use {@link McpServerConfig} */\nexport type McpServerOptions = McpServerConfig;\n\n/** Non-secret connection settings that built-in providers may persist. */\nexport type PersistedMcpServerConfig = Pick<\n McpServerConfig,\n | \"url\"\n | \"displayName\"\n | \"enabled\"\n | \"oauthProxyUrl\"\n | \"connectionMode\"\n | \"autoProxyFallback\"\n | \"callbackUrl\"\n | \"storageKeyPrefix\"\n | \"logLevel\"\n | \"autoRetry\"\n | \"autoReconnect\"\n | \"reconnectionOptions\"\n | \"popupFeatures\"\n | \"preventAutoAuth\"\n | \"detectMixedAuth\"\n | \"useRedirectFlow\"\n | \"protocolNegotiation\"\n | \"timeout\"\n | \"clientInfo\"\n> & {\n /** Proxy endpoint only. Proxy authorization headers are runtime-only. */\n proxyConfig?: Pick<ProxyConfig, \"proxyAddress\">;\n /** Public OAuth registration settings only. */\n oauth?: {\n /** Pre-registered public OAuth client identifier. */\n clientId?: string;\n /** Public OAuth Client ID Metadata Document URL. */\n clientMetadataUrl?: string;\n /** Space-delimited OAuth scopes. */\n scope?: string;\n };\n};\n\n/** Notification received from one managed MCP server. */\nexport interface McpNotification {\n /** Unique notification identifier generated by the provider. */\n id: string;\n /** MCP notification method name. */\n method: string;\n /** Optional notification parameters. */\n params?: Record<string, unknown>;\n /** Unix timestamp in milliseconds when the notification was received. */\n timestamp: number;\n /** Whether the consumer has marked the notification as read. */\n read: boolean;\n}\n\n/** A server sampling request awaiting UI or application approval. */\nexport interface PendingSamplingRequest {\n /** Unique request identifier generated by the provider. */\n id: string;\n /** Sampling request received from the server. */\n request: {\n /** Sampling JSON-RPC method name. */\n method: \"sampling/createMessage\";\n /** Sampling request parameters. */\n params: SamplingCreateMessageParams;\n };\n /** Unix timestamp in milliseconds when the request was received. */\n timestamp: number;\n /** Name of the server that issued the request. */\n serverName: string;\n}\n\n/** A server elicitation request awaiting UI or application approval. */\nexport interface PendingElicitationRequest {\n /** Unique request identifier generated by the provider. */\n id: string;\n /** Form or URL elicitation request received from the server. */\n request: ElicitRequestFormParams | ElicitRequestURLParams;\n /** Unix timestamp in milliseconds when the request was received. */\n timestamp: number;\n /** Name of the server that issued the request. */\n serverName: string;\n}\n\n/** Reactive state and operations returned by {@link useMcp}. */\nexport type UseMcpResult = {\n /** Name advertised by the connected MCP server. */\n name: string;\n\n /** List of tools available from the connected MCP server */\n tools: Tool[];\n /** List of resources available from the connected MCP server */\n resources: Resource[];\n /** List of resource templates available from the connected MCP server */\n resourceTemplates: ResourceTemplate[];\n /** List of prompts available from the connected MCP server */\n prompts: Prompt[];\n /** Skills advertised through the experimental Skills over MCP extension. */\n skills: import(\"../core/skills.js\").Skill[];\n /** Server information normalized for the active connection. */\n serverInfo?: {\n /** Optional human-readable server title. */\n title?: string;\n /** Stable server name. */\n name: string;\n /** Server version. */\n version?: string;\n /** Optional human-readable server description. */\n description?: string;\n /** Public website describing the server. */\n websiteUrl?: string;\n /** Icons advertised by the server. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Base64-encoded favicon auto-detected from server domain */\n icon?: string;\n };\n /** Server capabilities normalized for the active connection. */\n capabilities?: Record<string, unknown>;\n /** Optional server instructions advertised for the active connection. */\n instructions?: string;\n /** Protocol extension metadata normalized from the server capabilities. */\n extensions: Record<string, unknown>;\n /**\n * Negotiated MCP protocol era for the active connection:\n * - 'legacy': 2025-era server; lifecycle is managed internally.\n * - 'modern': 2026-07-28-era server, stateless per-request.\n * `undefined` until a connection has negotiated.\n */\n protocolEra?: ProtocolEra;\n /** Negotiated MCP protocol version string (e.g. '2025-06-18', '2026-07-28'). */\n protocolVersion?: string;\n /**\n * The current state of the MCP connection:\n * - 'discovering': Checking server existence and capabilities (including auth requirements).\n * - 'pending_auth': Authentication is required but auto-popup was prevented. User action needed.\n * - 'authenticating': Authentication is required and the process (e.g., popup) has been initiated.\n * - 'ready': Connected and ready for tool calls.\n * - 'failed': Connection or authentication failed. Check the `error` property.\n */\n state: \"discovering\" | \"pending_auth\" | \"authenticating\" | \"ready\" | \"failed\";\n /** If the state is 'failed', this provides the error message */\n error?: string;\n /**\n * If authentication requires user interaction (e.g., popup was blocked),\n * this URL can be presented to the user to complete authentication manually in a new tab.\n */\n authUrl?: string;\n /**\n * OAuth tokens if authentication was completed\n * Available when state is 'ready' and OAuth was used\n */\n authTokens?: {\n /** OAuth access token. */\n access_token: string;\n /** OAuth token type, commonly `\"Bearer\"`. */\n token_type: string;\n /** Unix timestamp in seconds when the access token expires. */\n expires_at?: number;\n /** OAuth refresh token, when issued. */\n refresh_token?: string;\n /** Space-delimited OAuth scopes granted to the token. */\n scope?: string;\n /** Canonical protected-resource URL required by some token refresh flows. */\n resource?: string;\n /**\n * OAuth token endpoint resolved during discovery (when available). Lets\n * consumers persist it so a backend can proactively refresh the token.\n */\n token_endpoint?: string;\n /**\n * OAuth client id (from Dynamic Client Registration or a static client).\n * Most token endpoints require it on refresh, so consumers can persist it\n * for server-side proactive refresh.\n */\n client_id?: string;\n /** OAuth client secret, when the provider issued a confidential client. */\n client_secret?: string;\n };\n /** OAuth availability discovered for an anonymously connected server. */\n authorization?: MCPAuthorizationInfo;\n /** Array of internal log messages (useful for debugging) */\n log: {\n /** Log severity. */\n level: \"debug\" | \"info\" | \"warn\" | \"error\";\n /** Human-readable log message. */\n message: string;\n /** Unix timestamp in milliseconds when the entry was created. */\n timestamp: number;\n }[];\n /**\n * Function to call a tool on the MCP server.\n * @param name - The name of the tool to call.\n * @param args - Optional arguments for the tool.\n * @param options - Optional request options including timeout configuration.\n * @returns A promise that resolves with the tool's result.\n * @throws If the client is not in the 'ready' state or the call fails.\n *\n * @example\n * ```typescript\n * // Simple tool call\n * const result = await mcp.callTool('my-tool', { arg: 'value' })\n *\n * // Tool call with extended timeout (e.g., for tools that trigger sampling)\n * const result = await mcp.callTool('analyze-sentiment', { text: 'Hello' }, {\n * timeout: 300000, // 5 minutes\n * resetTimeoutOnProgress: true // Reset timeout when progress notifications are received\n * })\n * ```\n */\n callTool: (\n name: string,\n args?: Record<string, unknown>,\n options?: {\n /** Timeout in milliseconds for this tool call (default: 60000 / 60 seconds) */\n timeout?: number;\n /** Maximum total timeout in milliseconds, even with progress resets */\n maxTotalTimeout?: number;\n /** Reset the timeout when progress notifications are received (default: false) */\n resetTimeoutOnProgress?: boolean;\n /** AbortSignal to cancel the request */\n signal?: AbortSignal;\n }\n ) => Promise<any>;\n /**\n * Function to list resources from the MCP server.\n * @returns A promise that resolves when resources are refreshed.\n * @throws If the client is not in the 'ready' state.\n */\n listResources: () => Promise<void>;\n /**\n * Function to read a resource from the MCP server.\n * @param uri - The URI of the resource to read.\n * @returns A promise that resolves with the resource contents.\n * @throws If the client is not in the 'ready' state or the read fails.\n */\n readResource: (uri: string) => Promise<{\n /** Content blocks returned for the resource. */\n contents: Array<{\n /** URI of the returned resource content. */\n uri: string;\n /** Content media type. */\n mimeType?: string;\n /** UTF-8 text content. */\n text?: string;\n /** Base64-encoded binary content. */\n blob?: string;\n }>;\n }>;\n /** Refresh the complete paginated skill catalog. */\n listSkills: () => Promise<void>;\n /** Resolve one skill by its canonical URI. */\n getSkill: (\n uri: string\n ) => Promise<import(\"../core/skills.js\").SkillGetResult>;\n /** Read one non-recursive directory in a remote skill. */\n readResourceDirectory: (\n uri: string,\n cursor?: string\n ) => Promise<import(\"../core/skills.js\").SkillDirectoryReadResult>;\n /**\n * Function to list prompts from the MCP server.\n * @returns A promise that resolves when prompts are refreshed.\n * @throws If the client is not in the 'ready' state.\n */\n listPrompts: () => Promise<void>;\n /**\n * Function to get a specific prompt from the MCP server.\n * @param name - The name of the prompt to get.\n * @param args - Optional arguments for the prompt.\n * @returns A promise that resolves with the prompt messages.\n * @throws If the client is not in the 'ready' state or the get fails.\n */\n getPrompt: (\n name: string,\n args?: Record<string, string>\n ) => Promise<{\n /** Messages produced from the prompt template. */\n messages: Array<{\n /** Conversation role for the prompt message. */\n role: \"user\" | \"assistant\";\n /** Prompt message content. */\n content: {\n /** MCP content block type. */\n type: string;\n /** Text value for text content blocks. */\n text?: string;\n [key: string]: any;\n };\n }>;\n }>;\n /**\n * Request completion suggestions for a prompt or resource template argument.\n * @param params - Completion request parameters specifying the ref and argument to complete.\n * @returns A promise that resolves with completion suggestions from the server.\n * @throws If the client is not in the 'ready' state or the completion request fails.\n */\n complete: (params: CompleteRequestParams) => Promise<CompleteResult>;\n /**\n * Refresh the tools list from the server.\n * Called automatically when notifications/tools/list_changed is received.\n * Can also be called manually for explicit refresh.\n */\n refreshTools: () => Promise<void>;\n /**\n * Refresh the resources list from the server.\n * Called automatically when notifications/resources/list_changed is received.\n * Can also be called manually for explicit refresh.\n */\n refreshResources: () => Promise<void>;\n /**\n * Refresh the resource templates list from the server.\n * Can be called manually for explicit refresh.\n */\n refreshResourceTemplates: () => Promise<void>;\n /**\n * Refresh the prompts list from the server.\n * Called automatically when notifications/prompts/list_changed is received.\n * Can also be called manually for explicit refresh.\n */\n refreshPrompts: () => Promise<void>;\n /**\n * Refresh all lists (tools, resources, resource templates, prompts) from the server.\n * Useful after reconnection or for manual refresh.\n */\n refreshAll: () => Promise<void>;\n /** Manually attempts to reconnect if the state is 'failed'. */\n retry: () => void;\n /** Disconnects the client from the MCP server. */\n disconnect: () => Promise<void>;\n /**\n * Manually triggers the authentication process. Useful if the initial attempt failed\n * due to a blocked popup, allowing the user to initiate it via a button click.\n * @returns A promise that resolves with the authorization URL opened (or intended to be opened),\n * or undefined if auth cannot be started.\n */\n authenticate: () => Promise<void>;\n /** Clears all stored authentication data (tokens, client info, etc.) for this server URL from localStorage. */\n clearStorage: () => void;\n /**\n * Ensure the server icon is loaded and available in serverInfo\n * Returns a promise that resolves when the icon is ready\n * Use this before server creation to guarantee the icon is available\n *\n * @returns Promise that resolves with the base64 icon or null if not available\n *\n * @example\n * ```typescript\n * // Wait for icon before creating server\n * const icon = await mcp.ensureIconLoaded();\n * // Now mcp.serverInfo.icon is guaranteed to be set (if icon exists)\n * ```\n */\n ensureIconLoaded: () => Promise<string | null>;\n /**\n * The underlying runtime-neutral MCP client instance.\n * Use this to create an MCPAgent for AI chat functionality.\n *\n * @example\n * ```typescript\n * import { MCPAgent } from \"@mcp-use/agent\"\n * import { ChatOpenAI } from '@langchain/openai'\n *\n * const mcp = useMcp({ url: 'http://localhost:3000/mcp' })\n * const llm = new ChatOpenAI({ model: 'gpt-4' })\n *\n * const agent = new MCPAgent({ llm, client: mcp.client })\n * await agent.initialize()\n *\n * for await (const event of agent.streamEvents('Hello')) {\n * console.log(event)\n * }\n * ```\n */\n client: BaseMCPClient | null;\n};\n\n/**\n * Connected MCP server: non-secret settings, live runtime headers, and state.\n * Returned from `useMcpClient().servers`.\n */\ntype LiveMcpServerConfig = Omit<PersistedMcpServerConfig, \"proxyConfig\"> & {\n /** Runtime HTTP headers. These values are never persisted. */\n headers?: Record<string, string>;\n /** Live proxy configuration, including runtime-only headers. */\n proxyConfig?: ProxyConfig;\n /** SDK client options used by the active connection. */\n clientOptions?: McpServerConfig[\"clientOptions\"];\n};\n\nexport interface McpServer extends LiveMcpServerConfig, UseMcpResult {\n /** Stable provider-managed server identifier. */\n id: string;\n /** Notifications received from this server. */\n notifications: McpNotification[];\n /** Number of notifications not yet marked as read. */\n unreadNotificationCount: number;\n /** Marks one notification as read. */\n markNotificationRead: (id: string) => void;\n /** Marks every notification as read. */\n markAllNotificationsRead: () => void;\n /** Removes every notification from local state. */\n clearNotifications: () => void;\n /** Sampling requests awaiting an application decision. */\n pendingSamplingRequests: PendingSamplingRequest[];\n /** Approves a pending sampling request with a result. */\n approveSampling: (\n requestId: string,\n result: SamplingCreateMessageResult\n ) => void;\n /** Rejects a pending sampling request. */\n rejectSampling: (requestId: string, error?: string) => void;\n /** Elicitation requests awaiting an application decision. */\n pendingElicitationRequests: PendingElicitationRequest[];\n /** Approves a pending elicitation request with a result. */\n approveElicitation: (requestId: string, result: ElicitResult) => void;\n /** Rejects a pending elicitation request. */\n rejectElicitation: (requestId: string, error?: string) => void;\n /**\n * Merge connection-affecting config and reconnect when it changed.\n * Prefer this over context `updateServer(id, …)` when you already hold the server.\n */\n updateConfig: (config: Partial<McpServerConfig>) => Promise<void>;\n /** Set HTTP headers on the connection config and reconnect. */\n setHeaders: (headers: Record<string, string> | undefined) => Promise<void>;\n /** Rename the server without disconnecting. */\n setDisplayName: (displayName: string) => Promise<void>;\n /** Disconnect and reconnect with the current config. */\n reconnect: () => Promise<void>;\n}\n\nconst PERSISTED_SERVER_CONFIG_KEYS = [\n \"url\",\n \"displayName\",\n \"enabled\",\n \"oauthProxyUrl\",\n \"connectionMode\",\n \"autoProxyFallback\",\n \"callbackUrl\",\n \"storageKeyPrefix\",\n \"logLevel\",\n \"autoRetry\",\n \"autoReconnect\",\n \"reconnectionOptions\",\n \"popupFeatures\",\n \"preventAutoAuth\",\n \"detectMixedAuth\",\n \"useRedirectFlow\",\n \"protocolNegotiation\",\n \"timeout\",\n \"clientInfo\",\n] as const satisfies readonly (keyof PersistedMcpServerConfig)[];\n\n/**\n * Extracts the non-secret subset safe for provider storage.\n *\n * @param source - Server configuration or live managed server.\n * @returns A new persistable configuration object.\n */\nexport function pickPersistedServerConfig(\n source: McpServerConfig | McpServer\n): PersistedMcpServerConfig {\n const out: PersistedMcpServerConfig = {};\n for (const key of PERSISTED_SERVER_CONFIG_KEYS) {\n const value = source[key];\n if (value !== undefined) {\n (out as Record<string, unknown>)[key] = value;\n }\n }\n if (source.proxyConfig?.proxyAddress !== undefined) {\n out.proxyConfig = { proxyAddress: source.proxyConfig.proxyAddress };\n }\n if (source.oauth) {\n const oauth: NonNullable<PersistedMcpServerConfig[\"oauth\"]> = {};\n if (source.oauth.clientId !== undefined) {\n oauth.clientId = source.oauth.clientId;\n }\n if (source.oauth.clientMetadataUrl !== undefined) {\n oauth.clientMetadataUrl = source.oauth.clientMetadataUrl;\n }\n if (source.oauth.scope !== undefined) {\n oauth.scope = source.oauth.scope;\n }\n if (Object.keys(oauth).length > 0) {\n out.oauth = oauth;\n }\n }\n return out;\n}\n\n/**\n * Extracts connection settings, including runtime-only values, from a server.\n *\n * @param source - Server configuration or live managed server.\n * @returns A new live configuration object.\n */\nexport function pickLiveServerConfig(\n source: McpServerConfig | McpServer\n): LiveMcpServerConfig {\n return {\n ...pickPersistedServerConfig(source),\n ...(source.headers !== undefined ? { headers: source.headers } : {}),\n ...(source.proxyConfig !== undefined\n ? { proxyConfig: source.proxyConfig }\n : {}),\n ...(source.clientOptions !== undefined\n ? { clientOptions: source.clientOptions }\n : {}),\n };\n}\n\n/**\n * Removes credentials, callbacks, and runtime-only values before storage.\n *\n * @param config - Configuration to sanitize.\n * @returns A new persistable configuration object.\n */\nexport function toPersistedServerConfig(\n config: McpServerConfig\n): PersistedMcpServerConfig {\n return pickPersistedServerConfig(config);\n}\n","// useMcp.ts\nimport { auth } from \"@modelcontextprotocol/client\";\nimport type {\n OAuthClientProvider,\n Prompt,\n ProtocolEra,\n Resource,\n ResourceTemplateType as ResourceTemplate,\n Tool,\n Transport,\n} from \"@modelcontextprotocol/client\";\nimport {\n runAuthPopup,\n MCP_AUTH_BROADCAST_CHANNEL,\n MCP_AUTH_CALLBACK_MESSAGE_TYPE,\n type McpAuthCallbackMessage,\n} from \"../auth/popup.js\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { BrowserMCPClient } from \"../core/browser.js\";\nimport { resolveClientOptions } from \"../core/config.js\";\nimport { Logger, type LogLevel } from \"../utils/logging.js\";\nimport type { MCPConnection } from \"../core/session.js\";\nimport { Tel } from \"../telemetry/telemetry-browser.js\";\nimport { isUnauthorized } from \"../auth/flow.js\";\nimport { assert } from \"./useMcp-helpers.js\";\nimport type { ProxyConfig } from \"./types.js\";\nimport { sanitizeUrl } from \"../auth/url.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\nimport {\n createBrowserOAuthProvider,\n deriveOAuthClientConfigFromClientInfo,\n isOAuthDiscoveryFailure,\n startConnectionHealthMonitoring,\n USE_MCP_SERVER_NAME,\n} from \"./useMcp-helpers.js\";\nimport type { UseMcpOptions, UseMcpResult } from \"./types.js\";\nimport { loadServerIcon } from \"./useMcp-helpers.js\";\nimport { useMcpOperations } from \"./useMcp-operations.js\";\nimport { getOAuthTokenExpiry } from \"./token-expiry.js\";\nimport { SKILLS_EXTENSION_ID } from \"../core/skills.js\";\n\nconst DEFAULT_RECONNECT_DELAY = 3000;\nconst DEFAULT_RETRY_DELAY = 5000;\n\n// Streamable HTTP is the only supported remote transport.\ntype TransportType = \"http\";\n\ntype UseMcpAuthProvider = OAuthClientProvider & {\n tokens?: () => Promise<\n | {\n access_token?: string;\n token_type?: string;\n refresh_token?: string;\n scope?: string;\n [key: string]: unknown;\n }\n | undefined\n >;\n clearStorage?: () => number;\n getLastAttemptedAuthUrl?: () => string | null | undefined;\n getTokenEndpoint?: () => Promise<string | null>;\n getResource?: () => Promise<string | null>;\n getClientCredentials?: () => Promise<{\n client_id: string;\n client_secret?: string;\n } | null>;\n /**\n * Returns a `fetch` scoped to this provider that routes OAuth requests\n * through the configured OAuth proxy (bypassing CORS) while leaving the\n * global `fetch` untouched. Passed to the SDK transport / `auth()` so proxy\n * behavior is confined to this server's connection.\n */\n getProxyFetch?: (baseFetch?: typeof fetch) => typeof fetch | undefined;\n serverUrl?: string;\n /** localStorage key for a given suffix (e.g. \"tokens\"). */\n getKey?: (keySuffix: string) => string;\n /** Stable hash of the server URL, used to scope OAuth result messages. */\n serverUrlHash?: string;\n};\n\ntype UseMcpInternalOptions = UseMcpOptions & {\n _initialServerInfo?: {\n name?: string;\n version?: string;\n title?: string;\n websiteUrl?: string;\n icons?: Array<{ src: string; mimeType?: string }>;\n icon?: string;\n };\n};\n\n/**\n * React hook for connecting to and interacting with MCP servers\n *\n * Provides a complete interface for MCP server connections including:\n * - Automatic connection management with reconnection\n * - OAuth authentication with automatic token refresh\n * - Tool, resource, and prompt access\n * - AI chat functionality with conversation memory\n * - Streamable HTTP transport\n *\n * @param options - Configuration options for the MCP connection\n * @returns MCP connection state and methods\n *\n * @example\n * ```typescript\n * const mcp = useMcp({\n * url: 'http://localhost:3000/mcp',\n * headers: { Authorization: 'Bearer YOUR_API_KEY' }\n * })\n *\n * // Wait for connection\n * useEffect(() => {\n * if (mcp.state === 'ready') {\n * console.log('Connected!', mcp.tools)\n * }\n * }, [mcp.state])\n *\n * // Call a tool\n * const result = await mcp.callTool('send-email', { to: 'user@example.com' })\n * ```\n */\nexport function useMcp(options: UseMcpInternalOptions): UseMcpResult {\n const {\n url,\n enabled = true,\n callbackUrl = typeof window !== \"undefined\"\n ? sanitizeUrl(\n new URL(\"/oauth/callback\", window.location.origin).toString()\n )\n : \"/oauth/callback\",\n storageKeyPrefix = \"mcp:auth\",\n authProvider: providedAuthProvider,\n headers: headersOption,\n proxyConfig,\n oauthProxyUrl: oauthProxyUrlOption,\n connectionMode,\n autoProxyFallback = false,\n logLevel: logLevelOption = \"silent\",\n autoRetry = false,\n autoReconnect = true,\n reconnectionOptions,\n preventAutoAuth = true, // Default to true - require explicit user action for OAuth\n detectMixedAuth = true,\n useRedirectFlow = false, // Default to false for backward compatibility (use popup)\n onPopupWindow,\n timeout = 30000, // 30 seconds default for connection timeout\n wrapTransport,\n serverId,\n fetch: customFetch,\n clientOptions,\n protocolNegotiation,\n onNotification,\n onSampling: onSamplingOption,\n onElicitation: onElicitationOption,\n oauth: oauthOptions,\n } = options;\n const transportType: TransportType = \"http\";\n const requestedProxyAddress = proxyConfig?.proxyAddress;\n\n const oauthClientId = oauthOptions?.clientId?.trim() || undefined;\n const oauthClientMetadataUrl =\n oauthOptions?.clientMetadataUrl?.trim() || undefined;\n const oauthScope = oauthOptions?.scope?.trim() || undefined;\n const staticClientInfo = useMemo(\n () => (oauthClientId ? { client_id: oauthClientId } : undefined),\n [oauthClientId]\n );\n\n // Create a per-instance logger so multiple useMcp instances don't clobber each other's log level.\n // Each instance gets its own named logger keyed by URL (or a fallback).\n const instanceLogger = useMemo(() => {\n const name = `useMcp:${url || \"no-url\"}`;\n const inst = Logger.get(name);\n // Configure the per-instance level when requested.\n if (logLevelOption) {\n inst.level = logLevelOption as LogLevel;\n }\n return inst;\n }, [url, logLevelOption]);\n\n const headers = headersOption ?? {};\n const effectiveClientOptions = useMemo(\n () => resolveClientOptions(clientOptions),\n [clientOptions]\n );\n\n const onSampling = onSamplingOption;\n const onElicitation = onElicitationOption;\n // Build clientInfo with defaults, merging with provided clientInfo\n const defaultClientInfo = useMemo(\n () => ({\n name: \"mcp-use\",\n title: \"mcp-use\",\n version: getPackageVersion(),\n description:\n \"mcp-use is a complete TypeScript framework for building and using MCP\",\n icons: [\n {\n src: \"https://mcp-use.com/logo.png\",\n },\n ],\n websiteUrl: \"https://mcp-use.com\",\n }),\n []\n );\n\n const mergedClientInfo = useMemo(\n () =>\n options.clientInfo\n ? { ...defaultClientInfo, ...options.clientInfo }\n : defaultClientInfo,\n [options.clientInfo, defaultClientInfo]\n );\n\n // Derive OAuth client registration config from clientInfo.\n const derivedOAuthClientConfig = useMemo(\n () => deriveOAuthClientConfigFromClientInfo(mergedClientInfo),\n [mergedClientInfo]\n );\n\n const oauthClientConfig = derivedOAuthClientConfig;\n\n // Parse autoProxyFallback configuration\n const autoProxyFallbackConfig = useMemo(() => {\n // Explicit Direct and Proxy modes never fall back. Direct must stay direct,\n // while Proxy already starts on the configured gateway.\n if (connectionMode === \"direct\" || connectionMode === \"proxy\") {\n return { enabled: false, proxyAddress: undefined };\n }\n if (!autoProxyFallback) {\n return { enabled: false, proxyAddress: undefined };\n }\n if (typeof autoProxyFallback === \"boolean\") {\n const proxyAddress = proxyConfig?.proxyAddress;\n return {\n enabled: autoProxyFallback && Boolean(proxyAddress),\n proxyAddress,\n };\n }\n const proxyAddress =\n autoProxyFallback.proxyAddress ?? proxyConfig?.proxyAddress;\n return {\n enabled: autoProxyFallback.enabled !== false && Boolean(proxyAddress),\n proxyAddress,\n };\n }, [autoProxyFallback, connectionMode, proxyConfig]);\n\n // Normalize autoReconnect into a consistent config object\n const autoReconnectConfig = useMemo(() => {\n if (autoReconnect === false) {\n return {\n enabled: false,\n initialDelay: 0,\n healthCheckInterval: false as const,\n healthCheckTimeout: 30000,\n };\n }\n if (autoReconnect === true) {\n return {\n enabled: true,\n initialDelay: DEFAULT_RECONNECT_DELAY,\n healthCheckInterval: 10000,\n healthCheckTimeout: 30000,\n };\n }\n if (typeof autoReconnect === \"number\") {\n return {\n enabled: true,\n initialDelay: autoReconnect,\n healthCheckInterval: 10000,\n healthCheckTimeout: 30000,\n };\n }\n return {\n enabled: autoReconnect.enabled !== false,\n initialDelay: autoReconnect.initialDelay ?? DEFAULT_RECONNECT_DELAY,\n healthCheckInterval: autoReconnect.healthCheckInterval ?? 10000,\n healthCheckTimeout: autoReconnect.healthCheckTimeout ?? 30000,\n };\n }, [autoReconnect]);\n\n // Runtime proxy config is set only after automatic direct -> proxy fallback.\n const [effectiveProxyConfig, setEffectiveProxyConfig] = useState<\n ProxyConfig | undefined\n >(undefined);\n\n // Reset runtime fallback when the requested connection changes.\n useEffect(() => {\n setEffectiveProxyConfig(undefined);\n }, [\n url,\n requestedProxyAddress,\n connectionMode,\n autoProxyFallbackConfig.proxyAddress,\n ]);\n\n const activeProxyConfig = useMemo(() => {\n const hasCurrentAutoFallback =\n autoProxyFallbackConfig.enabled &&\n effectiveProxyConfig?.proxyAddress ===\n autoProxyFallbackConfig.proxyAddress;\n if (hasCurrentAutoFallback && effectiveProxyConfig) {\n const latestHeaders = proxyConfig?.headers ?? {};\n return {\n ...effectiveProxyConfig,\n headers: {\n ...latestHeaders,\n ...(effectiveProxyConfig.headers ?? {}),\n },\n };\n }\n\n // Auto always starts direct, even when proxyConfig supplies the fallback\n // address. Direct also ignores stale proxyConfig left by older persisted\n // Inspector configurations. Without an explicit mode, preserve the\n // low-level API's immediate-proxy behavior unless fallback was requested.\n const startsDirect =\n connectionMode === \"auto\" ||\n connectionMode === \"direct\" ||\n (connectionMode === undefined && autoProxyFallbackConfig.enabled);\n return startsDirect ? undefined : proxyConfig;\n }, [\n effectiveProxyConfig,\n proxyConfig,\n connectionMode,\n autoProxyFallbackConfig.enabled,\n autoProxyFallbackConfig.proxyAddress,\n ]);\n\n const gatewayUrl = activeProxyConfig?.proxyAddress;\n const proxyHeaders = activeProxyConfig?.headers ?? {};\n\n // OAuth provider should ALWAYS use the original target URL for OAuth discovery,\n // not the proxy URL. The proxy is only used for making the actual HTTP requests.\n const effectiveOAuthUrl = useMemo(() => {\n return url || \"\";\n }, [url]);\n\n // Merge proxy headers with custom headers (custom headers take precedence)\n const allHeaders = useMemo(\n () => ({ ...proxyHeaders, ...headers }),\n [proxyHeaders, headers]\n );\n\n const [state, setState] = useState<UseMcpResult[\"state\"]>(\"discovering\");\n const [tools, setTools] = useState<Tool[]>([]);\n const [resources, setResources] = useState<Resource[]>([]);\n const [resourceTemplates, setResourceTemplates] = useState<\n ResourceTemplate[]\n >([]);\n const [prompts, setPrompts] = useState<Prompt[]>([]);\n const [skills, setSkills] = useState<import(\"../core/skills.js\").Skill[]>([]);\n const [serverInfo, setServerInfo] = useState<UseMcpResult[\"serverInfo\"]>(\n // Only use cached metadata if it has at least a name\n options._initialServerInfo?.name\n ? (options._initialServerInfo as UseMcpResult[\"serverInfo\"])\n : undefined\n );\n const [capabilities, setCapabilities] = useState<Record<string, any>>();\n const [protocolEra, setProtocolEra] = useState<ProtocolEra | undefined>(\n undefined\n );\n const [protocolVersion, setProtocolVersion] = useState<string | undefined>(\n undefined\n );\n const [instructions, setInstructions] = useState<string | undefined>();\n const [extensions, setExtensions] = useState<Record<string, unknown>>({});\n const [error, setError] = useState<string | undefined>(undefined);\n const [log, setLog] = useState<UseMcpResult[\"log\"]>([]);\n const [authUrl, setAuthUrl] = useState<string | undefined>(undefined);\n const [authTokens, setAuthTokens] =\n useState<UseMcpResult[\"authTokens\"]>(undefined);\n const [authorization, setAuthorization] =\n useState<UseMcpResult[\"authorization\"]>(undefined);\n\n const clientRef = useRef<BrowserMCPClient | null>(null);\n const connectionRef = useRef<MCPConnection | null>(null);\n const authProviderRef = useRef<UseMcpAuthProvider | null>(\n (providedAuthProvider as UseMcpAuthProvider | undefined) ?? null\n );\n const iconLoadingPromiseRef = useRef<Promise<string | null> | null>(null);\n const connectingRef = useRef<boolean>(false);\n const isMountedRef = useRef<boolean>(true);\n const connectAttemptRef = useRef<number>(0);\n /** Bumped at the start of each connect(); disconnect only clears clientRef if epoch unchanged. */\n const connectEpochRef = useRef(0);\n const authTimeoutRef = useRef<number | null>(null);\n const retryScheduledRef = useRef<boolean>(false);\n /**\n * True while a manual `authenticate()` popup flow owns the OAuth result.\n * The always-on `mcp_auth_callback` listener defers to the popup runner\n * during this window so a single completion doesn't trigger two reconnects.\n */\n const popupFlowActiveRef = useRef<boolean>(false);\n\n // --- Refs for values used in callbacks ---\n const stateRef = useRef(state);\n const authorizationRef = useRef(authorization);\n const authorizationServerUrlRef = useRef(url);\n authorizationRef.current = authorization;\n const autoReconnectRef = useRef(autoReconnect);\n const successfulTransportRef = useRef<TransportType | null>(null);\n // Forward refs for functions (declared later) to avoid circular dependencies\n const connectRef = useRef<(() => Promise<void>) | null>(null);\n const failConnectionRef = useRef<\n ((message: string, error?: Error) => void) | null\n >(null);\n\n // Reverse-request / notification callbacks must stay fresh without putting\n // their React identities into connect()'s dependency list (which would\n // reconnect whenever a parent re-creates inline handlers).\n //\n // Presence and implementation are tracked separately for reverse requests:\n // the current presence refs determine capabilities on the next normal\n // connect, while implementation refs retain the last defined handler so an\n // already-advertised live connection does not start failing merely because its\n // callback prop was removed before that reconnect.\n const onSamplingRef = useRef(onSampling);\n const onElicitationRef = useRef(onElicitation);\n const hasSamplingCallbackRef = useRef(onSampling !== undefined);\n const hasElicitationCallbackRef = useRef(onElicitation !== undefined);\n const onNotificationRef = useRef(onNotification);\n if (onSampling !== undefined) {\n onSamplingRef.current = onSampling;\n }\n if (onElicitation !== undefined) {\n onElicitationRef.current = onElicitation;\n }\n hasSamplingCallbackRef.current = onSampling !== undefined;\n hasElicitationCallbackRef.current = onElicitation !== undefined;\n onNotificationRef.current = onNotification;\n\n // Stable proxies passed to addServer notification wiring. Capability\n // advertisement uses current presence at connect time; once wired, reverse\n // requests dispatch to the latest defined implementation retained above.\n const stableOnSampling = useCallback<\n NonNullable<UseMcpOptions[\"onSampling\"]>\n >(async (params) => {\n // This proxy is only wired when a callback exists, and the implementation\n // ref is intentionally never cleared during that live connection.\n return onSamplingRef.current!(params);\n }, []);\n const stableOnElicitation = useCallback<\n NonNullable<UseMcpOptions[\"onElicitation\"]>\n >(async (params) => {\n return onElicitationRef.current!(params);\n }, []);\n const stableOnNotification = useCallback(\n (notification: Parameters<NonNullable<typeof onNotification>>[0]) => {\n onNotificationRef.current?.(notification);\n },\n []\n );\n\n /**\n * Effect: Keep refs in sync with state values\n * Allows callbacks to access latest state without re-creating them\n */\n useEffect(() => {\n stateRef.current = state;\n autoReconnectRef.current = autoReconnect;\n }, [state, autoReconnect]);\n\n useEffect(() => {\n authProviderRef.current =\n (providedAuthProvider as UseMcpAuthProvider | undefined) ?? null;\n }, [providedAuthProvider]);\n\n // --- Stable Callbacks ---\n /**\n * Add a log entry to the connection log.\n * Console output is routed through the per-instance logger so that\n * the configured logLevel / silent mode is respected.\n * The log state array is always populated for programmatic access.\n * @internal\n */\n const addLog = useCallback(\n (\n level: UseMcpResult[\"log\"][0][\"level\"],\n message: string,\n ...args: unknown[]\n ) => {\n const fullMessage =\n args.length > 0\n ? `${message} ${args.map((arg) => JSON.stringify(arg)).join(\" \")}`\n : message;\n // Route through per-instance logger so logLevel/silent is respected\n const logMsg = `[useMcp] ${fullMessage}`;\n switch (level) {\n case \"error\":\n instanceLogger.error(logMsg);\n break;\n case \"warn\":\n instanceLogger.warn(logMsg);\n break;\n case \"info\":\n instanceLogger.info(logMsg);\n break;\n case \"debug\":\n instanceLogger.debug(logMsg);\n break;\n default:\n instanceLogger.info(logMsg);\n }\n if (isMountedRef.current) {\n setLog((prevLog: UseMcpResult[\"log\"]) => [\n ...prevLog.slice(-100),\n { level, message: fullMessage, timestamp: Date.now() },\n ]);\n }\n },\n [instanceLogger]\n );\n\n const onAuthorizationRequired = useCallback(\n (authError: unknown) => {\n const preparedAuthUrl =\n authProviderRef.current?.getLastAttemptedAuthUrl?.() ?? undefined;\n addLog(\n \"info\",\n \"This server requires OAuth for the requested operation; waiting for authentication.\",\n authError\n );\n const authorizationRequired = {\n ...(authorizationRef.current ?? { mode: \"mixed\" as const }),\n authenticated: false,\n };\n authorizationRef.current = authorizationRequired;\n setAuthorization(authorizationRequired);\n if (preparedAuthUrl) setAuthUrl(preparedAuthUrl);\n },\n [addLog]\n );\n\n const connectionOperations = useMcpOperations({\n stateRef,\n connectionRef,\n hasClient: () => clientRef.current !== null,\n isMounted: () => isMountedRef.current,\n setTools,\n setResources,\n setResourceTemplates,\n setPrompts,\n setSkills,\n addLog,\n onAuthorizationRequired,\n });\n\n /**\n * Disconnect from the MCP server and clean up resources\n * @param quiet - If true, suppresses log messages\n */\n const disconnect = useCallback(\n async (quiet = false) => {\n if (!quiet) addLog(\"info\", \"Disconnecting...\");\n connectingRef.current = false;\n if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);\n authTimeoutRef.current = null;\n\n const epochAtStart = connectEpochRef.current;\n const clientToClose = clientRef.current;\n if (clientToClose) {\n try {\n const serverName = USE_MCP_SERVER_NAME;\n const connection =\n clientToClose === clientRef.current ? connectionRef.current : null;\n\n // Clean up health check monitoring if it exists\n if (connection && (connection as any)._healthCheckCleanup) {\n (connection as any)._healthCheckCleanup();\n (connection as any)._healthCheckCleanup = null;\n }\n\n // Only try to close if a connection exists (avoids noisy warning logs)\n if (connection) {\n await clientToClose.closeSession(serverName);\n }\n } catch (err) {\n if (!quiet) addLog(\"warn\", \"Error closing connection:\", err);\n }\n }\n // A newer connect() (e.g. dashboard environment / URL change) may have\n // bumped the epoch — possibly reusing the same client instance — while\n // closeSession was in flight. If so, this disconnect is stale: it must\n // neither null the (now newer) clientRef nor reset the live state.\n const supersededByNewerConnect = connectEpochRef.current !== epochAtStart;\n\n if (clientRef.current === clientToClose && !supersededByNewerConnect) {\n clientRef.current = null;\n connectionRef.current = null;\n }\n\n if (isMountedRef.current && !quiet && !supersededByNewerConnect) {\n setState(\"discovering\");\n setTools([]);\n setResources([]);\n setResourceTemplates([]);\n setPrompts([]);\n setSkills([]);\n setError(undefined);\n setAuthUrl(undefined);\n setAuthTokens(undefined);\n setServerInfo(undefined);\n setCapabilities(undefined);\n setProtocolEra(undefined);\n setProtocolVersion(undefined);\n setInstructions(undefined);\n setExtensions({});\n }\n },\n [addLog]\n );\n\n /**\n * Mark connection as failed with an error message\n * @internal\n * @returns true if automatic fallback was triggered (caller should not set failed state)\n */\n const failConnection = useCallback(\n (errorMessage: string, connectionError?: Error): boolean => {\n addLog(\"error\", errorMessage, connectionError ?? \"\");\n\n // Extract HTTP status code from error if available\n const errorCode =\n connectionError && \"code\" in connectionError\n ? (connectionError as any).code\n : undefined;\n\n // Check if we should try automatic proxy fallback\n // Don't use a ref to track this - it causes issues with React strict mode\n // where multiple instances share the same ref but have different state\n const shouldTryProxyFallback =\n autoProxyFallbackConfig.enabled && !activeProxyConfig?.proxyAddress; // Only fallback if not already using proxy\n\n // Detect CORS errors (these can't have status codes, so check message)\n const isCorsError =\n errorMessage.includes(\"CORS\") ||\n errorMessage.includes(\"blocked by CORS policy\") ||\n errorMessage.includes(\"Failed to fetch\");\n\n // HTTP 400 errors typically indicate session/protocol incompatibility that a proxy can resolve\n // (e.g., FastMCP missing session ID, streamable HTTP issues)\n const is400Error = errorCode === 400;\n\n // Other 4xx errors that might benefit from proxy fallback (except auth errors)\n const hasOther4xxError =\n typeof errorCode === \"number\" && errorCode >= 404 && errorCode < 500;\n\n // Don't fallback on auth errors (proxy won't help with authentication)\n const isAuthError = errorCode === 401 || errorCode === 403;\n\n const shouldFallback =\n shouldTryProxyFallback &&\n (isCorsError || is400Error || hasOther4xxError) &&\n !isAuthError;\n\n if (shouldFallback) {\n const errorType = isCorsError\n ? \"CORS error\"\n : is400Error\n ? \"HTTP 400 (Bad Request)\"\n : \"HTTP 4xx error\";\n addLog(\n \"info\",\n `Direct connection failed with ${errorType}. Trying with proxy...`\n );\n\n // Clear client/auth refs to force fresh initialization with proxy.\n // Keep externally provided auth providers intact. Synchronous clear;\n // reconnect is deferred via setTimeout below, so no disconnect race.\n clientRef.current = null;\n if (!providedAuthProvider) {\n authProviderRef.current = null;\n }\n addLog(\"debug\", \"Cleared client and auth provider for proxy fallback\");\n\n // Set proxy configuration and trigger reconnect\n setEffectiveProxyConfig({\n proxyAddress: autoProxyFallbackConfig.proxyAddress!,\n });\n\n // Explicitly set state back to \"discovering\" to prevent showing failed state\n // This ensures smooth UX during automatic retry\n if (isMountedRef.current) {\n setState(\"discovering\");\n }\n\n // Trigger reconnection after a brief delay\n setTimeout(() => {\n if (isMountedRef.current) {\n connectRef.current?.();\n }\n }, 1000);\n\n return true; // Signal that we're retrying - caller should not set failed state\n }\n\n // Normal failure handling\n if (isMountedRef.current) {\n addLog(\"info\", \"Setting state to FAILED:\", errorMessage);\n setState(\"failed\");\n setError(errorMessage);\n const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (manualUrl) {\n setAuthUrl(manualUrl);\n addLog(\n \"info\",\n \"Manual authentication URL may be available.\",\n manualUrl\n );\n }\n }\n connectingRef.current = false;\n\n // Track failed connection\n if (url) {\n Tel.getInstance()\n .trackUseMcpConnection({\n url,\n transportType: transportType,\n success: false,\n errorType: connectionError?.name || \"UnknownError\",\n hasOAuth: !!authProviderRef.current,\n hasSampling: hasSamplingCallbackRef.current,\n hasElicitation: hasElicitationCallbackRef.current,\n })\n .catch(() => {});\n }\n\n return false; // Not retrying, connection actually failed\n },\n [\n addLog,\n url,\n transportType,\n autoProxyFallbackConfig,\n activeProxyConfig,\n providedAuthProvider,\n ]\n );\n\n /**\n * Connect to the MCP server over streamable HTTP.\n * @internal\n */\n const connect = useCallback(async () => {\n // Don't connect if not enabled or no URL provided\n if (!enabled || !url) {\n addLog(\n \"debug\",\n enabled\n ? \"No server URL provided, skipping connection.\"\n : \"Connection disabled via enabled flag.\"\n );\n return;\n }\n\n if (connectingRef.current) {\n addLog(\"debug\", \"Connection attempt already in progress.\");\n return;\n }\n if (!isMountedRef.current) {\n addLog(\"debug\", \"Connect called after unmount, aborting.\");\n return;\n }\n\n connectingRef.current = true;\n connectEpochRef.current += 1;\n connectAttemptRef.current += 1;\n if (authorizationServerUrlRef.current !== url) {\n authorizationServerUrlRef.current = url;\n authorizationRef.current = undefined;\n setAuthorization(undefined);\n }\n setError(undefined);\n setAuthUrl(undefined);\n successfulTransportRef.current = null;\n setState(\"discovering\");\n setTools([]);\n setResources([]);\n setResourceTemplates([]);\n setPrompts([]);\n setSkills([]);\n setServerInfo(undefined);\n setCapabilities(undefined);\n setProtocolEra(undefined);\n setProtocolVersion(undefined);\n setInstructions(undefined);\n setExtensions({});\n addLog(\n \"info\",\n `Connecting attempt #${connectAttemptRef.current} to ${url}...`\n );\n\n // NOTE: We intentionally do NOT clear OAuth storage before connecting.\n // The clearStorage() function clears tokens and client_info which should\n // persist across connections. Clearing them would force re-authentication\n // even when valid tokens exist from a previous OAuth flow.\n //\n // Stale state/verifier items are cleaned up:\n // - By the callback handler after successful token exchange\n // - By the unmount cleanup when OAuth flow is interrupted\n // - By the state expiry check in the callback handler\n\n if (!authProviderRef.current) {\n const { provider, oauthProxyUrl } = createBrowserOAuthProvider({\n effectiveOAuthUrl,\n storageKeyPrefix,\n oauthClientConfig,\n callbackUrl,\n preventAutoAuth,\n useRedirectFlow,\n gatewayUrl,\n oauthProxyUrl: oauthProxyUrlOption,\n onPopupWindow,\n proxyOAuthRequests: true,\n staticClientInfo,\n clientMetadataUrl: oauthClientMetadataUrl,\n scope: oauthScope,\n });\n authProviderRef.current = provider;\n if (oauthProxyUrl) {\n addLog(\"debug\", `OAuth BFF enabled: ${oauthProxyUrl}`);\n }\n addLog(\n \"debug\",\n `BrowserOAuthClientProvider initialized with URL: ${effectiveOAuthUrl}, proxy: ${oauthProxyUrl ? \"enabled\" : \"disabled\"}, gateway: ${gatewayUrl ? \"enabled\" : \"disabled\"}`\n );\n }\n if (!clientRef.current) {\n clientRef.current = new BrowserMCPClient();\n addLog(\"debug\", \"BrowserMCPClient initialized in connect.\");\n } else {\n addLog(\"debug\", \"BrowserMCPClient already exists, reusing.\");\n }\n\n const tryConnectWithTransport = async (\n transportTypeParam: TransportType\n ): Promise<\"success\" | \"fallback\" | \"auth_redirect\" | \"failed\"> => {\n // Check if component unmounted\n if (!isMountedRef.current) {\n addLog(\"debug\", \"Connection attempt aborted - component unmounted\");\n return \"failed\";\n }\n\n addLog(\n \"info\",\n `Attempting connection with transport: ${transportTypeParam}`\n );\n addLog(\n \"debug\",\n `Client ref status at start of tryConnectWithTransport: ${clientRef.current ? \"initialized\" : \"NULL\"}`\n );\n\n try {\n const serverName = USE_MCP_SERVER_NAME;\n\n // Build server config\n const serverConfig: any = {\n url: url, // Use original URL, not transformed proxy URL\n timeout,\n clientInfo: mergedClientInfo,\n // Pass a fetch that scopes OAuth-proxy routing to this server's\n // transport/auth calls. getProxyFetch wraps `customFetch` (e.g. the\n // OAuth retry fetch for scope step-up), bypasses the browser cache\n // for OAuth metadata, and optionally routes OAuth through the BFF.\n // It never mutates the global fetch.\n ...(() => {\n const scopedFetch =\n authProviderRef.current?.getProxyFetch?.(customFetch) ??\n customFetch;\n return scopedFetch ? { fetch: scopedFetch } : {};\n })(),\n // Pass clientOptions for custom capabilities (e.g., MCP Apps extension)\n ...(effectiveClientOptions && {\n clientOptions: effectiveClientOptions,\n }),\n // Protocol era negotiation mode (\"legacy\" | \"auto\" | { pin }); the\n // connector defaults to automatic v1/v2 negotiation.\n ...(protocolNegotiation !== undefined && { protocolNegotiation }),\n detectMixedAuth,\n // Pass user-configurable reconnection options, or when autoReconnect\n // is disabled, disable SDK transport reconnection to prevent\n // unwanted GET polling requests\n ...(reconnectionOptions\n ? { reconnectionOptions }\n : autoReconnect === false\n ? { reconnectionOptions: { maxRetries: 0 } }\n : {}),\n };\n\n // Add gateway URL if using proxy\n if (gatewayUrl) {\n serverConfig.gatewayUrl = gatewayUrl;\n addLog(\n \"debug\",\n `Using proxy gateway: ${gatewayUrl} for target: ${url}`\n );\n }\n\n // Add custom headers if provided (includes proxy headers)\n if (allHeaders && Object.keys(allHeaders).length > 0) {\n serverConfig.headers = allHeaders;\n }\n\n // Client should be initialized by the parent connect() function\n // If it's not AND component is still mounted, this is a programming error\n if (!clientRef.current) {\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted - component unmounted, client cleaned up\"\n );\n return \"failed\";\n }\n const initError = new Error(\n \"Client not initialized - this is a bug in the connection flow\"\n );\n addLog(\n \"error\",\n \"Client ref is null in tryConnectWithTransport but component is still mounted\"\n );\n throw initError;\n }\n\n // Add server to client with OAuth provider.\n // Pass stable proxies (when a callback is present) so capability\n // advertisement happens on initial connect, while dispatch always\n // reaches the latest React handler via refs — even after reconnects\n // that reuse a connect() closure created with a different identity.\n clientRef.current.addServer(serverName, {\n ...serverConfig,\n authProvider: authProviderRef.current,\n onSampling: hasSamplingCallbackRef.current\n ? stableOnSampling\n : undefined,\n onElicitation: hasElicitationCallbackRef.current\n ? stableOnElicitation\n : undefined,\n onNotification: (\n notification: Parameters<typeof stableOnNotification>[0]\n ) => {\n addLog(\n \"debug\",\n \"Notification received:\",\n notification.method,\n notification\n );\n stableOnNotification(notification);\n\n if (notification.method === \"notifications/tools/list_changed\") {\n addLog(\"info\", \"Tools list changed, auto-refreshing...\");\n connectionOperations\n .refreshTools()\n .catch((err) =>\n addLog(\"warn\", \"Auto-refresh tools failed:\", err)\n );\n } else if (\n notification.method === \"notifications/resources/list_changed\"\n ) {\n addLog(\"info\", \"Resources list changed, auto-refreshing...\");\n const clientInfoExtensions = (\n mergedClientInfo as {\n capabilities?: { extensions?: Record<string, unknown> };\n }\n ).capabilities?.extensions;\n const optionExtensions = (\n effectiveClientOptions?.capabilities as\n | { extensions?: Record<string, unknown> }\n | undefined\n )?.extensions;\n const supportsSkills =\n optionExtensions?.[SKILLS_EXTENSION_ID] !== undefined ||\n clientInfoExtensions?.[SKILLS_EXTENSION_ID] !== undefined;\n Promise.all([\n connectionOperations.refreshResources(),\n ...(supportsSkills\n ? [connectionOperations.refreshSkills()]\n : []),\n ]).catch((err) =>\n addLog(\"warn\", \"Auto-refresh resources failed:\", err)\n );\n } else if (\n notification.method === \"notifications/prompts/list_changed\"\n ) {\n addLog(\"info\", \"Prompts list changed, auto-refreshing...\");\n connectionOperations\n .refreshPrompts()\n .catch((err) =>\n addLog(\"warn\", \"Auto-refresh prompts failed:\", err)\n );\n }\n },\n wrapTransport: wrapTransport\n ? (transport: Transport) => {\n addLog(\n \"debug\",\n \"Applying transport wrapper for server:\",\n serverName,\n \"url:\",\n url\n );\n return wrapTransport(transport, serverId ?? url);\n }\n : undefined,\n });\n\n // MCPClient owns protocol negotiation and any legacy initialization.\n // Modern connections remain stateless and are not initialized twice.\n const connection = await clientRef.current.connect(serverName);\n connectionRef.current = connection;\n\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted after connection creation - component unmounted\"\n );\n return \"failed\";\n }\n\n addLog(\"info\", \"✅ Successfully connected to MCP server\");\n addLog(\"info\", \"Server info:\", connection.info.server);\n addLog(\"info\", \"Server capabilities:\", connection.info.capabilities);\n\n // Only set up monitoring if autoReconnect is enabled and health checks are not disabled\n if (\n autoReconnectConfig.enabled &&\n autoReconnectConfig.healthCheckInterval !== false\n ) {\n const cleanup = startConnectionHealthMonitoring({\n gatewayUrl,\n url,\n allHeaders,\n getAuthHeaders: async (): Promise<Record<string, string>> => {\n try {\n const tokens = await authProviderRef.current?.tokens?.();\n if (tokens?.access_token) {\n const tokenType = tokens.token_type || \"bearer\";\n return {\n Authorization: `${tokenType.charAt(0).toUpperCase() + tokenType.slice(1)} ${tokens.access_token}`,\n };\n }\n } catch {\n // Intentionally empty - fall through to return {}\n }\n return {};\n },\n isMountedRef,\n stateRef,\n autoReconnectRef,\n setState,\n addLog,\n connect,\n defaultReconnectDelay: autoReconnectConfig.initialDelay,\n healthCheckIntervalMs: autoReconnectConfig.healthCheckInterval,\n healthCheckTimeoutMs: autoReconnectConfig.healthCheckTimeout,\n });\n\n // Store cleanup function for later\n (connection as any)._healthCheckCleanup = cleanup;\n }\n\n // Track successful connection\n Tel.getInstance()\n .trackUseMcpConnection({\n url,\n transportType: transportTypeParam,\n success: true,\n hasOAuth: !!authProviderRef.current,\n hasSampling: hasSamplingCallbackRef.current,\n hasElicitation: hasElicitationCallbackRef.current,\n })\n .catch(() => {});\n\n // Get tools, resources, and prompts through the protocol-neutral connection.\n setTools(connection.tools || []);\n\n const {\n server: serverInfo,\n capabilities,\n protocolEra,\n protocolVersion,\n instructions,\n extensions,\n authorization: connectionAuthorization,\n } = connection.info;\n\n if (connectionAuthorization) {\n setAuthorization(connectionAuthorization);\n authorizationRef.current = connectionAuthorization;\n }\n setProtocolEra(protocolEra);\n setProtocolVersion(protocolVersion);\n setInstructions(instructions);\n setExtensions(extensions);\n\n if (serverInfo) {\n addLog(\"debug\", \"Server info:\", serverInfo);\n setServerInfo(serverInfo);\n iconLoadingPromiseRef.current = loadServerIcon({\n serverInfo,\n url,\n isMounted: () => isMountedRef.current,\n setServerInfo,\n addLog,\n });\n }\n if (capabilities) {\n addLog(\"debug\", \"Server capabilities:\", capabilities);\n setCapabilities(capabilities);\n }\n\n // Tools and normalized connection metadata are sufficient for a usable\n // connection. Auxiliary inventories must populate progressively rather\n // than extending the ready-state critical path.\n successfulTransportRef.current = transportTypeParam;\n setState(\"ready\");\n // Optional OAuth metadata is not part of anonymous MCP readiness. Give\n // React a chance to paint the ready state before starting its network\n // fallbacks, which may legitimately return 404 for public servers.\n const discoverAuthorizationAfterReady = () => {\n if (!isMountedRef.current || connectionRef.current !== connection) {\n return;\n }\n const authorizationDiscovery = connection.discoverAuthorization?.();\n if (authorizationDiscovery) {\n void authorizationDiscovery.then((discovered) => {\n if (\n !discovered ||\n !isMountedRef.current ||\n connectionRef.current !== connection\n ) {\n return;\n }\n authorizationRef.current = discovered;\n setAuthorization(discovered);\n });\n }\n };\n if (typeof globalThis.requestAnimationFrame === \"function\") {\n globalThis.requestAnimationFrame(() => {\n setTimeout(discoverAuthorizationAfterReady, 0);\n });\n } else {\n setTimeout(discoverAuthorizationAfterReady, 0);\n }\n\n // Capability advertisements in the wild are not always granular: a\n // server may support resources/list while returning Method not found\n // for resources/templates/list. Inventory failures must not tear down\n // an otherwise healthy MCP connection.\n const [resourcesResult, promptsResult, templatesResult] =\n await Promise.all([\n connection.listAllResources().catch((error) => {\n addLog(\"warn\", \"Failed to load initial resources:\", error);\n return { resources: [] };\n }),\n connection.listPrompts().catch((error) => {\n addLog(\"warn\", \"Failed to load initial prompts:\", error);\n return { prompts: [] };\n }),\n connection.supports(\"resources\")\n ? connection.listResourceTemplates().catch((error) => {\n addLog(\n \"warn\",\n \"Failed to load initial resource templates:\",\n error\n );\n return { resourceTemplates: [] };\n })\n : Promise.resolve({ resourceTemplates: [] }),\n ]);\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted after discovery - component unmounted\"\n );\n return \"failed\";\n }\n setResources(resourcesResult.resources || []);\n setPrompts(promptsResult.prompts || []);\n setResourceTemplates(templatesResult.resourceTemplates || []);\n\n // Skills are another auxiliary inventory and populate progressively.\n if (isMountedRef.current) {\n if (extensions[\"io.modelcontextprotocol/skills\"] !== undefined) {\n try {\n const result = await connection.listAllSkills();\n if (isMountedRef.current) setSkills(result.skills);\n } catch (error) {\n addLog(\"warn\", \"Failed to load initial skills:\", error);\n if (isMountedRef.current) setSkills([]);\n }\n } else {\n setSkills([]);\n }\n }\n\n // Get OAuth tokens if authentication was used\n if (authProviderRef.current) {\n let tokens: Awaited<\n ReturnType<NonNullable<UseMcpAuthProvider[\"tokens\"]>>\n >;\n try {\n tokens = await authProviderRef.current.tokens?.();\n } catch (error) {\n // The MCP connection is already usable. Token projection is\n // supplemental state and must not tear down a ready connection.\n addLog(\"warn\", \"Failed to read OAuth tokens:\", error);\n tokens = undefined;\n }\n if (!isMountedRef.current) {\n addLog(\n \"debug\",\n \"Connection aborted after token fetch for auth tokens - component unmounted\"\n );\n return \"failed\";\n }\n if (tokens?.access_token) {\n if (authorizationRef.current?.mode === \"mixed\") {\n const authenticatedAuthorization = {\n ...authorizationRef.current,\n authenticated: true,\n };\n setAuthorization(authenticatedAuthorization);\n authorizationRef.current = authenticatedAuthorization;\n }\n const expiresAt = getOAuthTokenExpiry(tokens);\n\n // Best-effort: resolve the OAuth token endpoint + client credentials\n // so consumers can persist them for server-side proactive refresh.\n // Never blocks auth.\n let tokenEndpoint: string | null = null;\n let resource: string | null = null;\n let clientCreds: {\n client_id: string;\n client_secret?: string;\n } | null = null;\n try {\n tokenEndpoint =\n (await authProviderRef.current.getTokenEndpoint?.()) ?? null;\n } catch {\n tokenEndpoint = null;\n }\n try {\n resource =\n (await authProviderRef.current.getResource?.()) ?? null;\n } catch {\n resource = null;\n }\n try {\n clientCreds =\n (await authProviderRef.current.getClientCredentials?.()) ??\n null;\n } catch {\n clientCreds = null;\n }\n\n if (!isMountedRef.current) {\n addLog(\"debug\", \"Skipping state update - component unmounted\");\n return \"failed\";\n }\n setAuthTokens({\n access_token: tokens.access_token,\n token_type: tokens.token_type || \"Bearer\",\n expires_at: expiresAt,\n refresh_token: tokens.refresh_token,\n scope: tokens.scope,\n ...(tokenEndpoint ? { token_endpoint: tokenEndpoint } : {}),\n ...(resource ? { resource } : {}),\n ...(clientCreds?.client_id\n ? { client_id: clientCreds.client_id }\n : {}),\n ...(clientCreds?.client_secret\n ? { client_secret: clientCreds.client_secret }\n : {}),\n });\n }\n }\n\n return \"success\";\n } catch (err: unknown) {\n const error = err as Error & { code?: number; message?: string };\n const errorMessage = error?.message || String(err);\n\n // A prepared authorization URL means OAuth discovery already succeeded on\n // an earlier pass. A later failure (token refresh, SSE fallback, or a\n // metadata probe that fell back to the transport origin) must NOT be\n // misclassified as \"server does not support OAuth\" — that drops us to\n // `failed` and hides the Authenticate button. When we already have a\n // stored auth URL and an OAuth provider, surface `pending_auth` instead.\n const preparedAuthUrl =\n authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (preparedAuthUrl && authProviderRef.current && preventAutoAuth) {\n addLog(\n \"info\",\n \"OAuth already discovered (stored auth URL present); awaiting manual authentication.\"\n );\n if (isMountedRef.current) {\n setState(\"pending_auth\");\n setAuthUrl(preparedAuthUrl);\n }\n connectingRef.current = false;\n return \"auth_redirect\";\n }\n\n // Check if OAuth discovery failed (indicates server doesn't support OAuth)\n // This happens when a 401 triggers OAuth discovery but the server has no OAuth endpoints\n const oauthDiscoveryFailed = isOAuthDiscoveryFailure(err);\n\n // Check if this is a 401 error\n const is401Error = isUnauthorized(err);\n\n // If OAuth discovery failed with custom headers provided, this was likely a 401 with wrong credentials\n // The error message might say \"404\" (from OAuth endpoint attempts) but the root cause was 401\n if (\n oauthDiscoveryFailed &&\n headers &&\n Object.keys(headers).length > 0\n ) {\n failConnection(\n \"Authentication failed (HTTP 401). Server does not support OAuth. \" +\n \"Check your Authorization header value is correct.\"\n );\n return \"failed\";\n }\n\n // If OAuth discovery failed without custom headers, the server likely requires\n // authentication but doesn't support OAuth discovery\n // This handles cases where the server returns 401 but the error message shows \"404\"\n // from the OAuth endpoint attempts\n if (\n oauthDiscoveryFailed &&\n (!headers || Object.keys(headers).length === 0)\n ) {\n failConnection(\n \"Authentication required (HTTP 401). Server does not support OAuth. \" +\n \"Add an Authorization header in the Custom Headers section \" +\n \"(e.g., Authorization: Bearer YOUR_API_KEY).\"\n );\n return \"failed\";\n }\n\n // Handle 401 errors\n if (is401Error) {\n // If OAuth discovery failed, the server doesn't support OAuth\n // Show a clear message about this\n if (oauthDiscoveryFailed) {\n // No OAuth support and no custom headers - suggest adding API key\n failConnection(\n \"Authentication required (HTTP 401). Server does not support OAuth. \" +\n \"Add an Authorization header in the Custom Headers section \" +\n \"(e.g., Authorization: Bearer YOUR_API_KEY).\"\n );\n return \"failed\";\n }\n\n // OAuth discovery didn't fail, so OAuth might be available\n // Check if OAuth provider is configured\n if (authProviderRef.current) {\n // OAuth is configured\n addLog(\n \"info\",\n \"Authentication required. OAuth provider available.\"\n );\n\n // Check if we should trigger auth automatically or wait for user\n if (preventAutoAuth) {\n // Don't trigger auth flow automatically - let the user click \"Authenticate\"\n // This prevents unnecessary metadata discovery requests that may fail with CORS/404\n addLog(\n \"info\",\n \"Waiting for user to initiate authentication flow...\"\n );\n\n if (isMountedRef.current) {\n setState(\"pending_auth\");\n // Retrieve the stored auth URL if it was prepared during OAuth discovery\n const storedAuthUrl =\n authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (storedAuthUrl) {\n setAuthUrl(storedAuthUrl);\n addLog(\n \"info\",\n \"Retrieved stored auth URL for manual authentication\"\n );\n }\n }\n connectingRef.current = false;\n return \"auth_redirect\";\n } else {\n // preventAutoAuth is false - trigger auth flow automatically\n addLog(\n \"info\",\n \"Triggering automatic OAuth authentication flow...\"\n );\n\n try {\n // The SDK owns protected-resource discovery and parses the\n // original transport 401. Do not issue a duplicate probe.\n const authResult = await auth(authProviderRef.current, {\n serverUrl: url,\n fetchFn: authProviderRef.current.getProxyFetch?.(),\n });\n\n if (authResult === \"REDIRECT\") {\n // Step 2: Get the authorization response captured during\n // redirectToAuthorization, including RFC 9207 `iss` when\n // the provider exposes it.\n const flowProvider = authProviderRef.current as any;\n const authResponse =\n await flowProvider.getAuthorizationResponse?.();\n const authCode =\n authResponse?.code ??\n (await flowProvider.getAuthorizationCode?.());\n if (typeof authCode !== \"string\") {\n throw new Error(\n \"Authorization code not captured by headless provider\"\n );\n }\n\n // Step 3: Complete the OAuth flow by exchanging code for tokens\n await auth(authProviderRef.current, {\n serverUrl: url,\n authorizationCode: authCode,\n ...(authResponse?.iss !== undefined\n ? { iss: authResponse.iss }\n : {}),\n fetchFn: authProviderRef.current.getProxyFetch?.(),\n });\n }\n\n addLog(\"info\", \"OAuth flow completed, reconnecting...\");\n // Reconnect after successful auth\n return await tryConnectWithTransport(transportTypeParam);\n } catch (authError) {\n const authErrorMessage =\n authError instanceof Error\n ? authError.message\n : String(authError);\n failConnection(\n `Automatic OAuth authentication failed: ${authErrorMessage}`,\n authError instanceof Error\n ? authError\n : new Error(String(authError))\n );\n return \"failed\";\n }\n }\n }\n\n // Check if custom headers were provided (invalid credentials)\n if (headers && Object.keys(headers).length > 0) {\n failConnection(\n \"Authentication failed: Server returned 401 Unauthorized. \" +\n \"Check your Authorization header value is correct.\"\n );\n return \"failed\";\n }\n\n // No OAuth and no custom headers - suggest adding them\n failConnection(\n \"Authentication required: Server returned 401 Unauthorized. \" +\n \"Add an Authorization header in the Custom Headers section \" +\n \"(e.g., Authorization: Bearer YOUR_API_KEY).\"\n );\n return \"failed\";\n }\n\n // Handle other errors\n const isRetryingWithProxy = failConnection(\n errorMessage,\n error instanceof Error ? error : new Error(String(error))\n );\n // If failConnection triggered automatic proxy fallback, return a special\n // status so the caller does not treat this as a hard connection failure\n return isRetryingWithProxy ? \"auth_redirect\" : \"failed\";\n }\n };\n\n let finalStatus: \"success\" | \"auth_redirect\" | \"failed\" | \"fallback\" =\n \"failed\";\n\n addLog(\"debug\", \"Connecting via streamable HTTP\");\n finalStatus = await tryConnectWithTransport(\"http\");\n\n // Reset connecting flag for all terminal states and auth_redirect\n // auth_redirect needs to reset the flag so the auth callback can reconnect\n if (\n finalStatus === \"success\" ||\n finalStatus === \"failed\" ||\n finalStatus === \"auth_redirect\"\n ) {\n connectingRef.current = false;\n }\n\n addLog(\"debug\", `Connection sequence finished with status: ${finalStatus}`);\n }, [\n addLog,\n failConnection,\n disconnect,\n url,\n storageKeyPrefix,\n callbackUrl,\n oauthClientConfig.name,\n oauthClientConfig.version,\n oauthClientConfig.uri,\n oauthClientConfig.logo_uri,\n staticClientInfo,\n oauthClientMetadataUrl,\n oauthScope,\n headers,\n transportType,\n preventAutoAuth,\n detectMixedAuth,\n useRedirectFlow,\n onPopupWindow,\n enabled,\n timeout,\n mergedClientInfo,\n effectiveClientOptions,\n protocolNegotiation,\n // IMPORTANT: Include proxy-related dependencies so connect() uses updated values after fallback\n gatewayUrl,\n oauthProxyUrlOption,\n allHeaders,\n effectiveOAuthUrl,\n // Stable reverse-request proxies (empty-deps useCallbacks). Listed for\n // correctness; their identities never change, so they do not reconnect.\n stableOnSampling,\n stableOnElicitation,\n stableOnNotification,\n ]);\n\n /**\n * Effect: Update function refs to prevent stale closures\n * Used by retry and OAuth callback handlers\n */\n useEffect(() => {\n connectRef.current = connect;\n failConnectionRef.current = failConnection;\n }, [connect, failConnection]);\n\n /**\n * Retry connection after failure\n * Only works if current state is 'failed'\n * Note: Uses connectRef to avoid circular dependency with connect\n */\n const retry = useCallback(() => {\n if (stateRef.current === \"failed\") {\n addLog(\"info\", \"Retry requested...\");\n // Use connectRef to avoid circular dependency\n // connectRef is kept updated via useEffect\n connectRef.current?.();\n } else {\n addLog(\n \"warn\",\n `Retry called but state is not 'failed' (state: ${stateRef.current}). Ignoring.`\n );\n }\n }, [addLog]);\n\n /**\n * Trigger manual OAuth authentication flow\n *\n * Opens OAuth popup for user authorization. Use when state is 'pending_auth'\n * or to manually retry authentication.\n *\n * @example\n * ```typescript\n * if (mcp.state === 'pending_auth') {\n * mcp.authenticate() // Opens OAuth popup\n * }\n * ```\n */\n const authenticate = useCallback(async () => {\n addLog(\"info\", \"Manual authentication requested...\");\n const currentState = stateRef.current;\n const isOptionalMixedAuthentication =\n currentState === \"ready\" && authorizationRef.current?.mode === \"mixed\";\n\n if (currentState === \"failed\") {\n addLog(\"info\", \"Attempting to reconnect and authenticate via retry...\");\n retry();\n } else if (\n currentState === \"pending_auth\" ||\n (currentState === \"ready\" &&\n authorizationRef.current?.mode === \"mixed\" &&\n !authorizationRef.current.authenticated)\n ) {\n addLog(\"info\", \"Proceeding with authentication...\");\n\n try {\n assert(\n authProviderRef.current,\n \"Auth Provider not available for manual auth\"\n );\n assert(url, \"Server URL is required for authentication\");\n\n if (providedAuthProvider) {\n addLog(\n \"info\",\n \"Using provided authProvider for manual authentication\"\n );\n const parsedUrl = new URL(url);\n const baseUrl =\n parsedUrl.origin + parsedUrl.pathname.replace(/\\/+$/, \"\");\n await auth(authProviderRef.current, {\n serverUrl: baseUrl,\n fetchFn: authProviderRef.current.getProxyFetch?.(),\n });\n connectRef.current?.();\n return;\n }\n\n // Clear OAuth storage to ensure fresh authentication flow.\n // This is an explicit, user-initiated \"authenticate\" action (not a\n // lifecycle event), so wiping stale tokens/verifier here is correct.\n const clearedCount = authProviderRef.current.clearStorage?.() ?? 0;\n addLog(\n \"info\",\n `Cleared ${clearedCount} OAuth storage item(s) for fresh authentication`\n );\n\n // Update state to authenticating before redirect\n setState(\"authenticating\");\n\n // Capture the popup handle and OAuth `state` as the provider opens the\n // popup, so the opener (this window) can own the flow's lifecycle via\n // runAuthPopup() instead of waiting indefinitely for a push message.\n let capturedPopup: globalThis.Window | null = null;\n let capturedState: string | null = null;\n const captureOnPopupWindow = (\n popupUrl: string,\n features: string,\n popupWin: globalThis.Window | null\n ) => {\n capturedPopup = popupWin;\n try {\n capturedState = new URL(popupUrl).searchParams.get(\"state\");\n } catch {\n /* non-fatal: fall back to provider's last auth URL below */\n }\n onPopupWindow?.(popupUrl, features, popupWin);\n };\n\n // Recreate the auth provider WITHOUT preventAutoAuth.\n // proxyOAuthRequests is always true: the scoped OAuth proxy fetch is\n // the sole browser-CORS mechanism (the gateway no longer fronts OAuth\n // metadata — it broke RFC 8414 §3.3 issuer validation for strict\n // clients). It is a no-op when no OAuth proxy URL is configured.\n const { provider: freshAuthProvider, oauthProxyUrl } =\n createBrowserOAuthProvider({\n effectiveOAuthUrl,\n storageKeyPrefix,\n oauthClientConfig,\n callbackUrl,\n preventAutoAuth: false,\n useRedirectFlow,\n gatewayUrl,\n oauthProxyUrl: oauthProxyUrlOption,\n onPopupWindow: captureOnPopupWindow,\n proxyOAuthRequests: true,\n staticClientInfo,\n clientMetadataUrl: oauthClientMetadataUrl,\n scope: oauthScope,\n });\n\n if (oauthProxyUrl) {\n addLog(\"info\", \"Scoped OAuth proxy fetch enabled for manual auth\");\n }\n\n // Replace the auth provider\n authProviderRef.current = freshAuthProvider;\n\n addLog(\"info\", \"Triggering fresh OAuth authorization...\");\n\n // Generate a fresh authorization URL and open the popup/redirect.\n // The provider redirects/popups automatically (preventAutoAuth: false).\n const parsedUrl = new URL(url);\n const baseUrl =\n parsedUrl.origin + parsedUrl.pathname.replace(/\\/+$/, \"\");\n const authResult = await auth(freshAuthProvider, {\n serverUrl: baseUrl,\n fetchFn: freshAuthProvider.getProxyFetch?.(),\n });\n\n if (authResult === \"AUTHORIZED\") {\n addLog(\"info\", \"OAuth flow completed (tokens obtained)\");\n connectingRef.current = false;\n connectRef.current?.();\n return;\n }\n\n if (authResult !== \"REDIRECT\") {\n throw new Error(`Unexpected OAuth auth() result: ${authResult}`);\n }\n\n addLog(\"info\", \"OAuth authorization redirect initiated\");\n\n // Update authUrl with the new URL from the fresh provider\n // This is critical for the fallback link when popup is blocked\n const newAuthUrl = freshAuthProvider.getLastAttemptedAuthUrl?.();\n if (newAuthUrl) {\n setAuthUrl(newAuthUrl);\n addLog(\"info\", \"Updated auth URL for fallback:\", newAuthUrl);\n if (!capturedState) {\n try {\n capturedState = new URL(newAuthUrl).searchParams.get(\"state\");\n } catch {\n /* leave null; runAuthPopup accepts state-less results */\n }\n }\n }\n\n // Redirect flow navigates the whole page away — nothing to await here.\n if (useRedirectFlow) {\n return;\n }\n\n // Opener-owned popup flow: own the lifecycle so we can never get stuck\n // in \"authenticating\". Settles on result message / popup close / token\n // storage write / timeout (see runAuthPopup).\n const tokensKey = freshAuthProvider.getKey?.(\"tokens\");\n if (!tokensKey) {\n // Without a tokens key we can't run the supervised flow; fall back to\n // the always-on listener and leave state as authenticating.\n addLog(\n \"warn\",\n \"Could not derive tokens storage key; relying on callback listener.\"\n );\n return;\n }\n\n popupFlowActiveRef.current = true;\n let result;\n try {\n result = await runAuthPopup({\n popup: capturedPopup,\n state: capturedState,\n tokensKey,\n });\n } finally {\n popupFlowActiveRef.current = false;\n }\n\n if (!isMountedRef.current) return;\n\n switch (result.kind) {\n case \"success\":\n addLog(\n \"info\",\n \"Authentication succeeded; reconnecting to MCP server...\"\n );\n connectingRef.current = false;\n connectRef.current?.();\n break;\n case \"cancelled\":\n addLog(\n \"warn\",\n isOptionalMixedAuthentication\n ? \"Authentication popup was closed before completing. Public tools remain available.\"\n : \"Authentication popup was closed before completing. Returning to pending_auth.\"\n );\n setState(isOptionalMixedAuthentication ? \"ready\" : \"pending_auth\");\n break;\n case \"timeout\":\n addLog(\n \"warn\",\n isOptionalMixedAuthentication\n ? \"Authentication timed out waiting for the popup. Public tools remain available.\"\n : \"Authentication timed out waiting for the popup. Returning to pending_auth.\"\n );\n setState(isOptionalMixedAuthentication ? \"ready\" : \"pending_auth\");\n break;\n case \"error\":\n failConnection(`Authentication failed: ${result.error}`);\n break;\n default:\n // Exhaustive over AuthPopupResult[\"kind\"]; nothing to do.\n break;\n }\n } catch (authError) {\n if (!isMountedRef.current) return;\n const error =\n authError instanceof Error ? authError : new Error(String(authError));\n failConnection(`Manual authentication failed: ${error.message}`, error);\n }\n } else if (currentState === \"authenticating\") {\n addLog(\n \"warn\",\n \"Already attempting authentication. Check for blocked popups or wait for timeout.\"\n );\n const manualUrl = authProviderRef.current?.getLastAttemptedAuthUrl?.();\n if (manualUrl && !authUrl) {\n setAuthUrl(manualUrl);\n addLog(\"info\", \"Manual authentication URL retrieved:\", manualUrl);\n }\n } else {\n addLog(\n \"info\",\n `Client not in a state requiring manual authentication trigger (state: ${currentState}). If needed, try disconnecting and reconnecting.`\n );\n }\n }, [\n addLog,\n retry,\n failConnection,\n authUrl,\n url,\n useRedirectFlow,\n onPopupWindow,\n storageKeyPrefix,\n oauthClientConfig.name,\n oauthClientConfig.uri,\n oauthClientConfig.logo_uri,\n staticClientInfo,\n oauthClientMetadataUrl,\n oauthScope,\n callbackUrl,\n mergedClientInfo,\n providedAuthProvider,\n ]);\n\n /**\n * Clear OAuth tokens from localStorage and disconnect\n *\n * Useful for logging out or resetting authentication state.\n *\n * @example\n * ```typescript\n * mcp.clearStorage() // Removes tokens and disconnects\n * ```\n */\n const clearStorage = useCallback(() => {\n if (authProviderRef.current?.clearStorage) {\n const count = authProviderRef.current.clearStorage();\n addLog(\"info\", `Cleared ${count} item(s) from localStorage for ${url}.`);\n setAuthUrl(undefined);\n disconnect();\n } else {\n addLog(\"warn\", \"Auth provider not initialized, cannot clear storage.\");\n }\n }, [url, addLog, disconnect]);\n\n // ===== Effects =====\n\n /**\n * Effect: Listen for OAuth callback messages from popup window\n *\n * Subscribes to two transports for the same `mcp_auth_callback` payload:\n * - `window.message` (postMessage from `window.opener`): the happy path\n * when the popup retained its opener reference.\n * - `BroadcastChannel(\"mcp_auth_callback\")`: same-origin fallback used by\n * the popup callback when `window.opener` has been severed by COOP,\n * cross-origin intermediate redirects, or browser tab grouping.\n * Without this, a popup that completes auth but lost its opener leaves\n * the parent stuck in `authenticating` forever.\n *\n * The popup only emits over one transport per callback, so the two\n * listeners don't double-fire on a single auth completion.\n */\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n\n const handleCallbackPayload = (\n payload: McpAuthCallbackMessage | undefined,\n source: \"postMessage\" | \"BroadcastChannel\"\n ) => {\n // Defer to runAuthPopup while a manual authenticate() flow owns the\n // result, so a single completion doesn't trigger two reconnects.\n if (popupFlowActiveRef.current) {\n addLog(\n \"debug\",\n `Ignoring auth callback via ${source}; manual popup flow owns this result.`\n );\n return;\n }\n\n // Scope the result to this server. The callback page stamps the payload\n // with the originating server's URL hash; ignore results for other\n // servers so unrelated useMcp instances don't all reconnect at once.\n // Payloads without a hash (older callback pages) are accepted.\n const ourHash = authProviderRef.current?.serverUrlHash;\n if (\n payload?.serverUrlHash &&\n ourHash &&\n payload.serverUrlHash !== ourHash\n ) {\n addLog(\n \"debug\",\n `Ignoring auth callback via ${source} for a different server.`\n );\n return;\n }\n\n addLog(\"info\", `Received auth callback via ${source}.`, payload);\n if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);\n authTimeoutRef.current = null;\n\n if (payload?.success) {\n addLog(\n \"info\",\n \"Authentication successful via popup. Reconnecting client...\"\n );\n\n // Check if already connecting\n if (connectingRef.current) {\n addLog(\n \"debug\",\n \"Connection attempt already in progress, resetting flag to allow reconnection.\"\n );\n }\n\n // Reset the connecting flag and reconnect since auth just succeeded\n connectingRef.current = false;\n\n // Small delay to ensure state is clean before reconnecting\n setTimeout(() => {\n if (isMountedRef.current) {\n addLog(\n \"debug\",\n \"Initiating reconnection after successful auth callback.\"\n );\n connectRef.current?.();\n }\n }, 100);\n } else {\n // Don't clobber a connection that already became ready (or moved on):\n // a late/duplicate failure message must not knock a healthy client\n // back to \"failed\".\n if (\n stateRef.current !== \"authenticating\" &&\n stateRef.current !== \"pending_auth\"\n ) {\n addLog(\n \"debug\",\n `Ignoring stale auth failure callback (state=${stateRef.current}).`\n );\n return;\n }\n failConnectionRef.current?.(\n `Authentication failed in callback: ${payload?.error || \"Unknown reason.\"}`\n );\n }\n };\n\n const messageHandler = (event: globalThis.MessageEvent) => {\n if (event.origin !== window.location.origin) return;\n if (event.data?.type !== MCP_AUTH_CALLBACK_MESSAGE_TYPE) return;\n handleCallbackPayload(event.data, \"postMessage\");\n };\n window.addEventListener(\"message\", messageHandler);\n addLog(\"debug\", \"Auth callback message listener added.\");\n\n let broadcastChannel: BroadcastChannel | null = null;\n const broadcastHandler = (event: MessageEvent) => {\n if (event.data?.type !== MCP_AUTH_CALLBACK_MESSAGE_TYPE) return;\n handleCallbackPayload(event.data, \"BroadcastChannel\");\n };\n if (typeof BroadcastChannel !== \"undefined\") {\n try {\n broadcastChannel = new BroadcastChannel(MCP_AUTH_BROADCAST_CHANNEL);\n broadcastChannel.addEventListener(\"message\", broadcastHandler);\n addLog(\"debug\", \"Auth callback BroadcastChannel listener added.\");\n } catch (e) {\n addLog(\n \"warn\",\n \"Failed to open auth callback BroadcastChannel; lost-opener popups will not reach this client.\",\n e as Error\n );\n broadcastChannel = null;\n }\n }\n\n return () => {\n window.removeEventListener(\"message\", messageHandler);\n addLog(\"debug\", \"Auth callback message listener removed.\");\n if (broadcastChannel) {\n try {\n broadcastChannel.removeEventListener(\"message\", broadcastHandler);\n broadcastChannel.close();\n } catch {\n /* ignore */\n }\n addLog(\"debug\", \"Auth callback BroadcastChannel listener removed.\");\n }\n if (authTimeoutRef.current) clearTimeout(authTimeoutRef.current);\n };\n }, [addLog]);\n\n /**\n * Effect: Main connection lifecycle\n *\n * Runs on mount and when key connection parameters change.\n * - Initializes OAuth provider\n * - Initiates connection\n * - Cleans up on unmount or when URL changes\n */\n useEffect(() => {\n isMountedRef.current = true;\n\n // Skip connection if disabled or no URL provided\n if (!enabled || !url) {\n addLog(\n \"debug\",\n enabled\n ? \"No server URL provided, skipping connection.\"\n : \"Connection disabled via enabled flag.\"\n );\n setState(\"discovering\");\n return () => {\n isMountedRef.current = false;\n };\n }\n\n addLog(\"debug\", \"useMcp mounted, initiating connection.\");\n connectAttemptRef.current = 0;\n if (providedAuthProvider) {\n authProviderRef.current = providedAuthProvider as UseMcpAuthProvider;\n addLog(\"debug\", \"Using externally provided authProvider\");\n } else if (\n !authProviderRef.current ||\n authProviderRef.current.serverUrl !== effectiveOAuthUrl\n ) {\n const { provider, oauthProxyUrl } = createBrowserOAuthProvider({\n effectiveOAuthUrl,\n storageKeyPrefix,\n oauthClientConfig,\n callbackUrl,\n preventAutoAuth,\n useRedirectFlow,\n gatewayUrl,\n oauthProxyUrl: oauthProxyUrlOption,\n onPopupWindow,\n proxyOAuthRequests: true,\n staticClientInfo,\n clientMetadataUrl: oauthClientMetadataUrl,\n scope: oauthScope,\n });\n authProviderRef.current = provider;\n if (oauthProxyUrl) {\n addLog(\"debug\", `OAuth proxy URL in effect: ${oauthProxyUrl}`);\n }\n addLog(\n \"debug\",\n `BrowserOAuthClientProvider initialized/updated with URL: ${effectiveOAuthUrl}, proxy: ${oauthProxyUrl ? \"enabled\" : \"disabled\"}, gateway: ${gatewayUrl ? \"enabled\" : \"disabled\"}`\n );\n }\n connect();\n return () => {\n isMountedRef.current = false;\n addLog(\"debug\", \"useMcp unmounting, disconnecting.\");\n\n // NOTE: We intentionally do NOT clear OAuth storage on unmount, even\n // mid-flow. Wrapper remounts (provider revision changes, route\n // churn, StrictMode double-mounting) would otherwise destroy the\n // in-flight authorization state record + PKCE verifier and strand a\n // popup that completes after the remount. Stale state records carry a\n // 10-minute TTL (enforced in callback.ts) and the PKCE verifier is\n // overwritten by `saveCodeVerifier()` on the next auth start, so leaving\n // them in place is safe. Tokens that land after a remount are picked up\n // by the state-keyed callback listener / storage event and the wrapper\n // reconnects cleanly. Explicit logout still clears storage via\n // `clearStorage()` / `removeServer(id, { clearCredentials: true })`.\n\n disconnect(true);\n };\n }, [\n url,\n enabled,\n storageKeyPrefix,\n callbackUrl,\n oauthClientConfig.name,\n oauthClientConfig.version,\n oauthClientConfig.uri,\n oauthClientConfig.logo_uri,\n staticClientInfo,\n oauthClientMetadataUrl,\n oauthScope,\n useRedirectFlow,\n mergedClientInfo,\n effectiveOAuthUrl, // Triggers reconnection when proxy fallback changes OAuth URL\n proxyConfig, // Triggers reconnection when proxy config (including headers) changes\n autoProxyFallbackConfig.proxyAddress,\n providedAuthProvider,\n ]);\n\n /**\n * Effect: Auto-retry on failure\n *\n * If autoRetry is enabled and connection fails, automatically retries\n * after the specified delay.\n * Uses a ref to prevent duplicate scheduling which can cause render loops.\n */\n const retryRef = useRef(retry);\n const addLogRef = useRef(addLog);\n\n useEffect(() => {\n retryRef.current = retry;\n addLogRef.current = addLog;\n }, [retry, addLog]);\n\n useEffect(() => {\n let retryTimeoutId: number | null = null;\n\n if (state === \"failed\" && autoRetry && connectAttemptRef.current > 0) {\n // Prevent duplicate scheduling - only schedule if not already scheduled\n if (!retryScheduledRef.current) {\n retryScheduledRef.current = true;\n const delay =\n typeof autoRetry === \"number\" ? autoRetry : DEFAULT_RETRY_DELAY;\n addLogRef.current(\n \"info\",\n `Connection failed, auto-retrying in ${delay}ms...`\n );\n retryTimeoutId = setTimeout(() => {\n retryScheduledRef.current = false;\n if (isMountedRef.current && stateRef.current === \"failed\") {\n retryRef.current();\n }\n }, delay) as any;\n }\n } else if (state !== \"failed\") {\n // Reset the ref when not in failed state\n retryScheduledRef.current = false;\n }\n\n return () => {\n if (retryTimeoutId) {\n clearTimeout(retryTimeoutId);\n retryScheduledRef.current = false;\n }\n };\n }, [state, autoRetry]);\n\n /**\n * Ensure the server icon is loaded and available\n * Waits for the background icon loading to complete\n *\n * @returns Promise that resolves with the base64 icon or null\n */\n const ensureIconLoaded = useCallback(async (): Promise<string | null> => {\n if (stateRef.current !== \"ready\") {\n addLog(\"warn\", \"Cannot ensure icon loaded - not connected\");\n return null;\n }\n\n // If icon is already available, return it immediately\n if (serverInfo?.icon) {\n return serverInfo.icon;\n }\n\n // If icon loading is in progress, wait for it\n if (iconLoadingPromiseRef.current) {\n addLog(\"debug\", \"Waiting for icon to finish loading...\");\n const icon = await iconLoadingPromiseRef.current;\n return icon;\n }\n\n // No icon loading in progress and no icon available\n addLog(\"debug\", \"No icon available and no loading in progress\");\n return null;\n }, [serverInfo, addLog]);\n\n return {\n state,\n name: serverInfo?.name || url || \"\",\n tools,\n resources,\n resourceTemplates,\n prompts,\n skills,\n serverInfo,\n capabilities,\n protocolEra,\n protocolVersion,\n instructions,\n extensions,\n error,\n log,\n authUrl,\n authTokens,\n authorization,\n client: clientRef.current,\n ...connectionOperations,\n retry,\n disconnect,\n authenticate,\n clearStorage,\n ensureIconLoaded,\n };\n}\n","// popup-runner.ts\n//\n// Opener-owned OAuth popup runner. Models the pattern used by mature browser\n// OAuth libraries (auth0-spa-js `runPopup`, oidc-client-ts `AbstractChildWindow`,\n// msal-browser popup clients): the window that OPENED the popup owns a promise\n// that settles on exactly one of four terminal outcomes, so the caller can never\n// be left waiting forever.\n//\n// A flow settles on the first of:\n// 1. An `mcp_auth_callback` result message (postMessage from the popup's\n// `window.opener`, or a same-origin `BroadcastChannel` when the opener was\n// severed by COOP / cross-origin redirects / tab grouping), matched to this\n// flow by its OAuth `state` parameter.\n// 2. The popup being closed (`popup.closed` poll). Before declaring the flow\n// cancelled we check whether tokens already landed in storage — the popup\n// may have completed the exchange and closed before its message dispatched.\n// 3. A `storage` event for this flow's tokens key. This is the most robust\n// signal: the popup always persists tokens to localStorage before notifying,\n// and `storage` events fire cross-window even when message channels are\n// severed or partitioned (the MSAL \"redirect bridge partition\" gotcha).\n// 4. A timeout. Same tokens check as the close path before declaring timeout.\n\n/** Channel name shared by the popup callback notifier and every listener. */\nexport const MCP_AUTH_BROADCAST_CHANNEL = \"mcp_auth_callback\";\n\n/** Result message type posted by the OAuth callback page. */\nexport const MCP_AUTH_CALLBACK_MESSAGE_TYPE = \"mcp_auth_callback\";\n\n/**\n * Payload shape posted by the OAuth callback page over `postMessage` /\n * `BroadcastChannel`. `state` and `serverUrlHash` are used to scope a result\n * to the flow / server that initiated it; both are optional for backward\n * compatibility with callback pages built against older versions.\n */\nexport interface McpAuthCallbackMessage {\n type?: string;\n success?: boolean;\n error?: string;\n /** OAuth `state` parameter of the originating authorization request. */\n state?: string;\n /** Hash of the server URL the flow authenticated against. */\n serverUrlHash?: string;\n}\n\n/** Terminal outcome of an opener-owned popup flow. */\ntype AuthPopupResult =\n | { kind: \"success\" }\n | { kind: \"error\"; error: string }\n | { kind: \"cancelled\" }\n | { kind: \"timeout\" };\n\ninterface RunAuthPopupOptions {\n /**\n * The popup window handle returned by `window.open`. May be `null` when the\n * popup was blocked or opened out-of-band (e.g. a manual fallback link); the\n * runner then relies on the message / storage / timeout signals only.\n */\n popup: globalThis.Window | null;\n /** OAuth `state` parameter for this flow. Used to ignore unrelated results. */\n state: string | null;\n /** localStorage key under which the flow's tokens are persisted on success. */\n tokensKey: string;\n /** Overall flow timeout. Default 5 minutes. */\n timeoutMs?: number;\n /** Interval for the `popup.closed` poll. Default 1s (matches auth0-spa-js). */\n closePollMs?: number;\n /**\n * How long to keep waiting for a result after the popup reports closed\n * without tokens, before settling `cancelled`. COOP browsing-context-group\n * swaps (popup navigating cross-origin) make `popup.closed` report `true`\n * while the real window is still open mid-flow, so a closed signal is only\n * a soft hint — message/storage listeners stay alive during this grace\n * window and can still settle `success`. Default 20s.\n */\n closeGraceMs?: number;\n /**\n * Origin to accept `postMessage` results from. Defaults to the current\n * window origin. BroadcastChannel results are same-origin by definition.\n */\n expectedOrigin?: string;\n}\n\nfunction hasStoredTokens(tokensKey: string): boolean {\n try {\n return (\n typeof localStorage !== \"undefined\" && !!localStorage.getItem(tokensKey)\n );\n } catch {\n return false;\n }\n}\n\n/**\n * Run an opener-owned OAuth popup flow and resolve once it reaches a terminal\n * outcome. Never rejects — all failure modes map to an {@link AuthPopupResult}.\n */\nexport function runAuthPopup({\n popup,\n state,\n tokensKey,\n timeoutMs = 5 * 60_000,\n closePollMs = 1000,\n closeGraceMs = 20_000,\n expectedOrigin = typeof window !== \"undefined\" ? window.location.origin : \"\",\n}: RunAuthPopupOptions): Promise<AuthPopupResult> {\n return new Promise<AuthPopupResult>((resolve) => {\n let settled = false;\n let closeTimer: ReturnType<typeof setInterval> | null = null;\n let timeoutTimer: ReturnType<typeof setTimeout> | null = null;\n let graceTimer: ReturnType<typeof setTimeout> | null = null;\n let broadcastChannel: BroadcastChannel | null = null;\n\n const cleanup = () => {\n if (closeTimer) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n if (timeoutTimer) {\n clearTimeout(timeoutTimer);\n timeoutTimer = null;\n }\n if (graceTimer) {\n clearTimeout(graceTimer);\n graceTimer = null;\n }\n if (typeof window !== \"undefined\") {\n window.removeEventListener(\"message\", messageHandler);\n window.removeEventListener(\"storage\", storageHandler);\n }\n if (broadcastChannel) {\n try {\n broadcastChannel.removeEventListener(\"message\", broadcastHandler);\n broadcastChannel.close();\n } catch {\n /* ignore */\n }\n broadcastChannel = null;\n }\n };\n\n const settle = (result: AuthPopupResult) => {\n if (settled) return;\n settled = true;\n cleanup();\n resolve(result);\n };\n\n // Shared handler for postMessage + BroadcastChannel result payloads.\n const handlePayload = (payload: McpAuthCallbackMessage | undefined) => {\n if (!payload || payload.type !== MCP_AUTH_CALLBACK_MESSAGE_TYPE) return;\n // State-keyed: ignore results from a different concurrent flow. Payloads\n // without a `state` (older callback pages) are accepted for back-compat.\n if (payload.state && state && payload.state !== state) return;\n if (payload.success) {\n settle({ kind: \"success\" });\n } else {\n settle({\n kind: \"error\",\n error: payload.error ?? \"Authentication failed in callback.\",\n });\n }\n };\n\n const messageHandler = (event: globalThis.MessageEvent) => {\n if (expectedOrigin && event.origin !== expectedOrigin) return;\n handlePayload(event.data as McpAuthCallbackMessage | undefined);\n };\n\n const broadcastHandler = (event: globalThis.MessageEvent) => {\n handlePayload(event.data as McpAuthCallbackMessage | undefined);\n };\n\n const storageHandler = (event: globalThis.StorageEvent) => {\n if (event.key !== tokensKey) return;\n // A non-null new value means the popup just persisted fresh tokens.\n if (event.newValue) settle({ kind: \"success\" });\n };\n\n if (typeof window !== \"undefined\") {\n window.addEventListener(\"message\", messageHandler);\n window.addEventListener(\"storage\", storageHandler);\n }\n\n if (typeof BroadcastChannel !== \"undefined\") {\n try {\n broadcastChannel = new BroadcastChannel(MCP_AUTH_BROADCAST_CHANNEL);\n broadcastChannel.addEventListener(\"message\", broadcastHandler);\n } catch {\n broadcastChannel = null;\n }\n }\n\n // Poll for popup closure. The user may close it without completing, or it\n // may complete and close before its result message is delivered.\n if (popup) {\n closeTimer = setInterval(() => {\n if (settled) return;\n let closed = false;\n try {\n closed = popup.closed;\n } catch {\n // Cross-origin access to `.closed` can throw under some engines;\n // treat as not-closed and keep waiting for other signals.\n closed = false;\n }\n if (!closed) return;\n if (closeTimer) {\n clearInterval(closeTimer);\n closeTimer = null;\n }\n if (hasStoredTokens(tokensKey)) {\n settle({ kind: \"success\" });\n return;\n }\n // Soft-close grace window: `popup.closed` is unreliable under COOP —\n // a cross-origin navigation swaps the browsing context group and the\n // original WindowProxy reports closed while the real window is still\n // open mid-consent (observed in the field: closed at ~3s, tokens\n // landing ~7s later). Keep the message/storage listeners alive and\n // only settle `cancelled` if nothing arrives within the grace window.\n graceTimer = setTimeout(() => {\n settle(\n hasStoredTokens(tokensKey)\n ? { kind: \"success\" }\n : { kind: \"cancelled\" }\n );\n }, closeGraceMs);\n }, closePollMs);\n }\n\n timeoutTimer = setTimeout(() => {\n settle(\n hasStoredTokens(tokensKey) ? { kind: \"success\" } : { kind: \"timeout\" }\n );\n }, timeoutMs);\n });\n}\n","import {\n Client,\n discoverOAuthProtectedResourceMetadata,\n SdkError,\n SdkHttpError,\n StreamableHTTPClientTransport,\n UnauthorizedError,\n type ClientOptions,\n type OAuthClientProvider,\n type VersionNegotiationMode,\n} from \"@modelcontextprotocol/client\";\nimport { completeOAuthFlow, isOAuthInteractionRequired } from \"../auth/flow.js\";\nimport type { MCPAuthorizationInfo } from \"../core/session.js\";\nimport { DialectJsonSchemaValidator } from \"../utils/json-schema-validator.js\";\nimport { logger } from \"../utils/logging.js\";\nimport type { ConnectorInitOptions } from \"./base.js\";\nimport { BaseConnector } from \"./base.js\";\n\nconst MIXED_AUTH_DISCOVERY_TIMEOUT_MS = 2_000;\n\n/**\n * Detect a 401 anywhere in an error / cause chain. Under\n * `versionNegotiation: \"auto\"` a connect-time 401 can surface wrapped as\n * `SdkError(EraNegotiationFailed)` with the `UnauthorizedError` at\n * `error.data.cause` (rather than a bare `SdkHttpError`), so we walk the chain.\n */\nfunction detectUnauthorized(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n if (err instanceof UnauthorizedError) return true;\n if (err instanceof SdkHttpError && err.status === 401) return true;\n if (err instanceof Error) {\n if (err.cause) {\n if (detectUnauthorized(err.cause, depth + 1)) return true;\n }\n const data = err instanceof SdkError ? (err.data as any) : undefined;\n if (data?.cause && detectUnauthorized(data.cause, depth + 1)) return true;\n }\n return false;\n}\n\n/** Client identity advertised to an MCP server during connection setup. */\nexport type ClientInfo = {\n /** Stable programmatic client name. */\n name: string;\n /** Optional human-readable client title. */\n title?: string;\n /** Client version string. */\n version: string;\n /** Human-readable client description. */\n description?: string;\n /** Icons representing the client. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Public website describing the client. */\n websiteUrl?: string;\n};\n\n/** HTTP-specific connector options. */\ninterface HttpConnectorOptions extends ConnectorInitOptions {\n /** Bearer token added to the `Authorization` header. */\n authToken?: string;\n /** Fetch implementation used by transport requests. */\n fetch?: typeof fetch;\n /** Additional transport request headers. */\n headers?: Record<string, string>;\n /** Connection timeout in milliseconds. Defaults to `10000`. */\n timeout?: number;\n /** Client identity advertised to the server. */\n clientInfo?: ClientInfo;\n /**\n * Protocol version negotiation mode passed to the SDK `Client`.\n * - `\"auto\"` (mcp-use HTTP default): probe with `server/discover`, falling\n * back to the 2025 handshake against legacy servers.\n * - `\"legacy\"`: classic 2025 `initialize` handshake, no probe. This matches\n * the official SDK's default when used directly.\n * - In auto mode, the probe performs OAuth discovery on auth-required\n * servers and can fail on servers whose\n * authorization-server issuer differs from the server URL (RFC 8414 §3.3),\n * which would otherwise mask the normal 401 → auth flow.\n * - `{ pin: \"2026-07-28\" }`: modern era only, no fallback.\n */\n protocolNegotiation?: VersionNegotiationMode;\n /** Gateway endpoint through which MCP transport requests are routed. */\n gatewayUrl?: string;\n /** Server identifier forwarded to the gateway for observability. */\n serverId?: string;\n /** Retry settings for streamable HTTP reconnection. */\n reconnectionOptions?: {\n /** Maximum delay between reconnection attempts in milliseconds. */\n maxReconnectionDelay?: number;\n /** Delay before the first reconnection attempt in milliseconds. */\n initialReconnectionDelay?: number;\n /** Multiplier applied after each failed attempt. */\n reconnectionDelayGrowFactor?: number;\n /** Maximum number of reconnection attempts. */\n maxRetries?: number;\n };\n /** Detect RFC 9728 metadata after anonymous connection. Defaults to true. */\n detectMixedAuth?: boolean;\n}\n\ntype StreamableHttpFailure = {\n fallbackReason: string;\n is401Error: boolean;\n httpStatusCode?: number;\n};\n\nfunction isOAuthClientProvider(\n provider: ConnectorInitOptions[\"authProvider\"]\n): provider is OAuthClientProvider {\n return Boolean(\n provider &&\n \"redirectToAuthorization\" in provider &&\n typeof provider.redirectToAuthorization === \"function\" &&\n \"tokens\" in provider &&\n typeof provider.tokens === \"function\"\n );\n}\n\nfunction createMcpProxyFetch(\n logicalServerUrl: string,\n proxyUrl: string,\n baseFetch: typeof fetch,\n serverId?: string\n): typeof fetch {\n const logical = new URL(logicalServerUrl);\n const proxy = proxyUrl.replace(/\\/$/, \"\");\n\n return async (input, init) => {\n const request = new Request(input, init);\n const requestUrl = new URL(request.url);\n const isMcpTransportRequest =\n requestUrl.origin === logical.origin &&\n requestUrl.pathname === logical.pathname;\n\n // OAuth discovery/token requests deliberately keep their own URLs so a\n // separately injected OAuth BFF fetch can handle them.\n if (!isMcpTransportRequest) {\n return baseFetch(request);\n }\n\n const headers = new Headers(request.headers);\n headers.set(\"X-Target-URL\", request.url);\n if (serverId) headers.set(\"X-Server-Id\", serverId);\n\n const body =\n request.method === \"GET\" || request.method === \"HEAD\"\n ? undefined\n : await request.clone().arrayBuffer();\n\n return baseFetch(\n new Request(proxy, {\n method: request.method,\n headers,\n body,\n signal: request.signal,\n redirect: \"manual\",\n })\n );\n };\n}\n\nfunction createDeadlineFetch(\n baseFetch: typeof fetch,\n deadlineSignal: AbortSignal\n): typeof fetch {\n return async (input, init) => {\n const requestSignal = init?.signal;\n if (!requestSignal) {\n return baseFetch(input, { ...init, signal: deadlineSignal });\n }\n\n const controller = new AbortController();\n const abortFromRequest = () => controller.abort(requestSignal.reason);\n const abortFromDeadline = () => controller.abort(deadlineSignal.reason);\n\n if (requestSignal.aborted) abortFromRequest();\n else\n requestSignal.addEventListener(\"abort\", abortFromRequest, { once: true });\n\n if (deadlineSignal.aborted) abortFromDeadline();\n else\n deadlineSignal.addEventListener(\"abort\", abortFromDeadline, {\n once: true,\n });\n\n try {\n return await baseFetch(input, { ...init, signal: controller.signal });\n } finally {\n requestSignal.removeEventListener(\"abort\", abortFromRequest);\n deadlineSignal.removeEventListener(\"abort\", abortFromDeadline);\n }\n };\n}\n\n/**\n * Connects to an MCP server using streamable HTTP.\n *\n * The connector negotiates modern and legacy protocol eras by default and can\n * route transport requests through an HTTP gateway.\n */\nexport class HttpConnector extends BaseConnector {\n private readonly baseUrl: string;\n private readonly headers: Record<string, string>;\n private readonly timeout: number;\n private readonly customFetch?: typeof fetch;\n private readonly clientInfo: ClientInfo;\n private readonly protocolNegotiation: VersionNegotiationMode;\n private readonly gatewayUrl?: string;\n private readonly serverId?: string;\n private readonly reconnectionOptions?: HttpConnectorOptions[\"reconnectionOptions\"];\n private readonly detectMixedAuth: boolean;\n private transportType: \"streamable-http\" | null = null;\n private streamableTransport: StreamableHTTPClientTransport | null = null;\n private hadAccessTokenAtConnect = false;\n private pendingOAuthCompletion: Promise<void> | null = null;\n private authorizationDiscovery: Promise<\n MCPAuthorizationInfo | undefined\n > | null = null;\n\n /**\n * Creates an HTTP connector.\n *\n * @param baseUrl - MCP endpoint URL.\n * @param opts - Authentication, transport, SDK, and reconnection options.\n */\n constructor(baseUrl: string, opts: HttpConnectorOptions = {}) {\n super(opts);\n\n const originalUrl = baseUrl.replace(/\\/$/, \"\");\n this.baseUrl = originalUrl;\n this.headers = { ...(opts.headers ?? {}) };\n this.gatewayUrl = opts.gatewayUrl;\n this.serverId = opts.serverId;\n\n // Add auth token if provided\n if (opts.authToken) {\n this.headers.Authorization = `Bearer ${opts.authToken}`;\n }\n\n this.timeout = opts.timeout ?? 10000; // Default 10 seconds\n const baseFetch = opts.fetch ?? globalThis.fetch.bind(globalThis);\n this.customFetch = this.gatewayUrl\n ? createMcpProxyFetch(\n originalUrl,\n this.gatewayUrl,\n baseFetch,\n this.serverId\n )\n : opts.fetch;\n this.clientInfo = opts.clientInfo ?? {\n name: \"http-connector\",\n version: \"1.0.0\",\n };\n // Negotiate the most capable protocol available. The SDK safely falls back\n // to the 2025 sessionful era for v1 servers while using v2's sessionless\n // server/discover flow when it is available.\n this.protocolNegotiation = opts.protocolNegotiation ?? \"auto\";\n this.reconnectionOptions = opts.reconnectionOptions;\n this.detectMixedAuth = opts.detectMixedAuth ?? true;\n }\n\n private get oauthProvider(): OAuthClientProvider | undefined {\n return isOAuthClientProvider(this.opts.authProvider)\n ? this.opts.authProvider\n : undefined;\n }\n\n private async completeInteractiveAuthorization(): Promise<void> {\n const provider = this.oauthProvider;\n if (!provider) {\n throw new Error(\"No OAuth client provider is configured\");\n }\n if (!this.pendingOAuthCompletion) {\n this.pendingOAuthCompletion = completeOAuthFlow(provider, this.baseUrl, {\n fetchFn: this.customFetch,\n finishAuthorization: async (code, iss) => {\n const transport = this.streamableTransport;\n if (!transport) {\n throw new Error(\"OAuth transport is no longer connected\");\n }\n await transport.finishAuth(code, iss);\n },\n })\n .then(() => {\n this.authorizationCache = {\n ...(this.authorizationCache ?? { mode: \"mixed\" }),\n authenticated: true,\n };\n })\n .finally(() => {\n this.pendingOAuthCompletion = null;\n });\n }\n await this.pendingOAuthCompletion;\n }\n\n protected override async executeRequest<T>(\n operation: () => Promise<T>\n ): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n const provider = this.oauthProvider as\n | (OAuthClientProvider & { preventAutoAuth?: boolean })\n | undefined;\n if (\n !provider ||\n provider.preventAutoAuth === true ||\n !isOAuthInteractionRequired(error)\n ) {\n throw error;\n }\n await this.completeInteractiveAuthorization();\n return operation();\n }\n }\n\n /** Authenticate an already-connected server without requiring a 401 first. */\n override async authenticate(): Promise<void> {\n if (!this.connected || !this.streamableTransport) {\n throw new Error(\"MCP client is not connected\");\n }\n await this.completeInteractiveAuthorization();\n }\n\n override async discoverAuthorization(): Promise<\n MCPAuthorizationInfo | undefined\n > {\n if (\n !this.detectMixedAuth ||\n !this.oauthProvider ||\n this.hadAccessTokenAtConnect\n ) {\n return this.authorizationCache;\n }\n\n if (this.authorizationDiscovery) return this.authorizationDiscovery;\n\n this.authorizationDiscovery = this.discoverMixedAuthorization().then(\n (authorization) => {\n // A missing or temporarily unavailable RFC 9728 endpoint must not be\n // cached for the lifetime of an otherwise healthy MCP connection.\n if (!authorization) this.authorizationDiscovery = null;\n return authorization;\n }\n );\n return this.authorizationDiscovery;\n }\n\n private async discoverMixedAuthorization(): Promise<\n MCPAuthorizationInfo | undefined\n > {\n const controller = new AbortController();\n let timeout: ReturnType<typeof setTimeout> | undefined;\n const discoveryTimeout = new Promise<never>((_, reject) => {\n timeout = setTimeout(() => {\n const error = new Error(\n `Mixed-auth metadata discovery timed out after ${MIXED_AUTH_DISCOVERY_TIMEOUT_MS}ms`\n );\n controller.abort(error);\n reject(error);\n }, MIXED_AUTH_DISCOVERY_TIMEOUT_MS);\n });\n const baseFetch = this.customFetch ?? globalThis.fetch.bind(globalThis);\n\n try {\n const metadata = await Promise.race([\n discoverOAuthProtectedResourceMetadata(\n this.baseUrl,\n { protocolVersion: this.negotiatedProtocolVersion },\n createDeadlineFetch(baseFetch, controller.signal)\n ),\n discoveryTimeout,\n ]);\n this.authorizationCache = {\n mode: \"mixed\",\n authenticated: false,\n ...(metadata.resource ? { resource: metadata.resource } : {}),\n ...(metadata.scopes_supported\n ? { scopesSupported: [...metadata.scopes_supported] }\n : {}),\n };\n logger.info(\n \"OAuth protected-resource metadata found after anonymous connection; server uses mixed auth\"\n );\n } catch (error) {\n // RFC 9728 metadata is optional for anonymous servers. Discovery is a\n // best-effort classification and must never turn a valid MCP connection\n // into a failure.\n logger.debug(\"Mixed-auth metadata was not discovered:\", error);\n } finally {\n if (timeout) clearTimeout(timeout);\n }\n return this.authorizationCache;\n }\n\n private buildClientOptions(): ClientOptions {\n return {\n ...(this.opts.clientOptions || {}),\n jsonSchemaValidator:\n this.opts.clientOptions?.jsonSchemaValidator ??\n new DialectJsonSchemaValidator(),\n versionNegotiation: {\n // Allow a caller-supplied versionNegotiation in clientOptions to win.\n mode: this.protocolNegotiation,\n ...(this.opts.clientOptions?.versionNegotiation ?? {}),\n },\n listChanged: {\n tools: {\n autoRefresh: true,\n onChanged: (error, tools) =>\n void this.handleListChanged(\n \"notifications/tools/list_changed\",\n error,\n tools\n ),\n },\n resources: {\n autoRefresh: false,\n onChanged: (error) =>\n void this.handleListChanged(\n \"notifications/resources/list_changed\",\n error\n ),\n },\n prompts: {\n autoRefresh: false,\n onChanged: (error) =>\n void this.handleListChanged(\n \"notifications/prompts/list_changed\",\n error\n ),\n },\n ...(this.opts.clientOptions?.listChanged ?? {}),\n },\n capabilities: {\n ...(this.opts.clientOptions?.capabilities || {}),\n roots: { listChanged: true },\n ...(this.opts.onSampling ? { sampling: {} } : {}),\n ...(this.opts.onElicitation\n ? { elicitation: { form: {}, url: {} } }\n : {}),\n },\n };\n }\n\n // In v2 HTTP transport errors are thrown as SdkHttpError (subclass of\n // SdkError) with a numeric `.status` accessor, replacing v1's\n // StreamableHTTPError (which carried the status on `.code`).\n private unwrapStreamableError(err: unknown): SdkHttpError | null {\n if (err instanceof SdkHttpError) {\n return err;\n }\n if (err instanceof Error && err.cause instanceof SdkHttpError) {\n return err.cause;\n }\n return null;\n }\n\n private classifyStreamableHttpFailure(err: unknown): StreamableHttpFailure {\n let fallbackReason = \"Unknown error\";\n let is401Error = false;\n let httpStatusCode: number | undefined;\n\n const streamableErr = this.unwrapStreamableError(err);\n if (streamableErr) {\n const status = streamableErr.status;\n is401Error = status === 401;\n httpStatusCode = status;\n\n if (\n status === 400 &&\n streamableErr.message.includes(\"Missing session ID\")\n ) {\n fallbackReason = \"Server requires session ID\";\n logger.warn(`⚠️ ${fallbackReason}`);\n } else if (status === 404 || status === 405) {\n fallbackReason = `Server returned ${status} - server likely doesn't support streamable HTTP`;\n logger.debug(fallbackReason);\n } else {\n fallbackReason = `Server returned ${status}: ${streamableErr.message}`;\n logger.debug(fallbackReason);\n }\n\n return { fallbackReason, is401Error, httpStatusCode };\n }\n\n if (err instanceof Error) {\n const errorStr = err.toString();\n const errorMsg = err.message || \"\";\n is401Error =\n detectUnauthorized(err) ||\n errorStr.includes(\"401\") ||\n errorMsg.includes(\"Unauthorized\");\n\n if (\n errorStr.includes(\"Missing session ID\") ||\n errorStr.includes(\"Bad Request: Missing session ID\") ||\n errorMsg.includes(\"FastMCP session ID error\")\n ) {\n fallbackReason = \"Server requires session ID\";\n logger.warn(`⚠️ ${fallbackReason}`);\n } else if (\n errorStr.includes(\"405 Method Not Allowed\") ||\n errorStr.includes(\"404 Not Found\")\n ) {\n fallbackReason = \"Server doesn't support streamable HTTP (405/404)\";\n logger.debug(fallbackReason);\n } else {\n fallbackReason = `Streamable HTTP failed: ${err.message}`;\n logger.debug(fallbackReason);\n }\n }\n\n return { fallbackReason, is401Error, httpStatusCode };\n }\n\n /**\n * Establishes a streamable HTTP connection to the MCP server.\n *\n * @returns A promise that resolves after protocol negotiation completes.\n * @throws An error with `code: 401` when authentication is required.\n */\n async connect(): Promise<void> {\n if (this.connected) {\n logger.debug(\"Already connected to MCP implementation\");\n return;\n }\n\n const baseUrl = this.baseUrl;\n logger.debug(`Connecting to MCP implementation via HTTP: ${baseUrl}`);\n\n const oauthProvider = this.oauthProvider;\n if (oauthProvider) {\n try {\n this.hadAccessTokenAtConnect = Boolean(\n (await oauthProvider.tokens())?.access_token\n );\n } catch {\n this.hadAccessTokenAtConnect = false;\n }\n }\n\n try {\n await this.connectWithStreamableHttp(baseUrl);\n logger.debug(\"✅ Successfully connected via streamable HTTP\");\n } catch (err: unknown) {\n logger.debug(\"Streamable HTTP connect failed\", err);\n const { fallbackReason, is401Error, httpStatusCode } =\n this.classifyStreamableHttpFailure(err);\n\n await this.cleanupResources();\n\n if (is401Error) {\n logger.info(\"Authentication required\");\n const authError = new Error(\"Authentication required\") as any;\n authError.code = 401;\n throw authError;\n }\n\n const finalError = new Error(\n `Could not connect via streamable HTTP: ${fallbackReason}`\n );\n if (httpStatusCode !== undefined) {\n Object.defineProperty(finalError, \"code\", {\n value: httpStatusCode,\n writable: false,\n enumerable: true,\n configurable: true,\n });\n }\n throw finalError;\n }\n }\n\n /**\n * Tee an SSE response so v2 MRTR progress can be correlated even when the\n * upstream SDK does not carry the original callback to retry request IDs.\n */\n private observeSseProgress(response: Response): Response {\n if (\n !response.body ||\n !response.headers.get(\"content-type\")?.includes(\"text/event-stream\")\n ) {\n return response;\n }\n const [body, observed] = response.body.tee();\n void (async () => {\n const reader = observed.getReader();\n const decoder = new TextDecoder();\n let buffer = \"\";\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n const events = buffer.split(/\\r?\\n\\r?\\n/);\n buffer = events.pop() ?? \"\";\n for (const event of events) {\n for (const line of event.split(/\\r?\\n/)) {\n if (!line.startsWith(\"data:\")) continue;\n try {\n const message = JSON.parse(line.slice(5).trim()) as {\n method?: string;\n params?: unknown;\n };\n if (message.method === \"notifications/progress\") {\n this.forwardRoundProgress(message.params);\n }\n } catch {\n // Ignore malformed/non-JSON SSE data; the SDK remains authoritative.\n }\n }\n }\n }\n } catch (error) {\n if (!(error instanceof DOMException && error.name === \"AbortError\")) {\n logger.debug(\"Progress observer stream ended:\", error);\n }\n } finally {\n reader.releaseLock();\n }\n })();\n return new Response(body, {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n\n private async connectWithStreamableHttp(baseUrl: string): Promise<void> {\n try {\n logger.debug(\"[HttpConnector] Connecting with Streamable HTTP\", {\n baseUrl,\n originalUrl: this.baseUrl,\n gatewayUrl: this.gatewayUrl || \"none\",\n authProviderUrl:\n this.opts.authProvider &&\n \"serverUrl\" in this.opts.authProvider &&\n typeof this.opts.authProvider.serverUrl === \"string\"\n ? this.opts.authProvider.serverUrl\n : \"none\",\n headers: this.headers,\n });\n\n const baseFetch = this.customFetch ?? globalThis.fetch.bind(globalThis);\n const observedFetch: typeof fetch = async (input, init) => {\n const response = await baseFetch(input, init);\n const requestHeaders = new Headers(\n input instanceof Request ? input.headers : undefined\n );\n new Headers(init?.headers).forEach((value, key) => {\n requestHeaders.set(key, value);\n });\n // subscriptions/listen owns its SSE reader and acknowledgement state.\n // Re-wrapping that response breaks the SDK's per-request stream hooks;\n // the progress observer is only for ordinary request/response calls.\n return requestHeaders.get(\"mcp-method\") === \"subscriptions/listen\"\n ? response\n : this.observeSseProgress(response);\n };\n\n // Create StreamableHTTPClientTransport directly\n // The official SDK's StreamableHTTPClientTransport automatically handles session IDs\n // when client.connect() is called - it sends initialize, gets session ID from response header,\n // and opens the SSE stream with that session ID\n const streamableTransport = new StreamableHTTPClientTransport(\n new URL(baseUrl),\n {\n authProvider: this.opts.authProvider, // ← Pass OAuth provider to SDK\n fetch: observedFetch,\n requestInit: {\n headers: this.headers,\n },\n reconnectionOptions: {\n maxReconnectionDelay: 30000,\n initialReconnectionDelay: 1000,\n reconnectionDelayGrowFactor: 1.5,\n maxRetries: 2,\n ...this.reconnectionOptions,\n },\n // Don't pass sessionId - let the SDK generate it automatically during connect()\n }\n );\n\n // Store transport for cleanup (we'll create ConnectionManager later if needed for reconnection)\n let transport: StreamableHTTPClientTransport = streamableTransport;\n\n // Wrap transport if wrapper is provided\n if (this.opts.wrapTransport) {\n const serverId = this.baseUrl; // Use URL as server ID for now\n transport = this.opts.wrapTransport(\n transport,\n serverId\n ) as StreamableHTTPClientTransport;\n }\n\n // Create and connect the client\n // This performs both initialize AND initialized notification\n // Always advertise roots capability - server may query roots/list even if client has no roots\n const clientOptions = this.buildClientOptions();\n logger.debug(\n `Creating Client with capabilities:`,\n JSON.stringify(clientOptions.capabilities, null, 2)\n );\n this.client = new Client(this.clientInfo, clientOptions);\n\n // Register inbound handlers BEFORE connect() so they are available for the\n // entire connection lifetime (including reverse RPC during/after initialize).\n this.setupRootsHandler();\n this.setupSamplingHandler();\n this.setupElicitationHandler();\n this.setupNotificationHandler();\n logger.debug(\n \"Roots/sampling/elicitation/notification handlers registered before connect\"\n );\n\n try {\n // The SDK's StreamableHTTPClientTransport should automatically:\n // 1. Send POST initialize request\n // 2. Extract mcp-session-id from response header\n // 3. Open GET SSE stream with that session ID in header\n //\n // Keep the connection timeout outside the SDK request options so it\n // cannot leak onto streams opened during connection setup.\n let connectTimeout: ReturnType<typeof setTimeout> | undefined;\n await Promise.race([\n this.client.connect(transport),\n new Promise<never>((_, reject) => {\n connectTimeout = setTimeout(\n () =>\n reject(\n new Error(`MCP connection timed out after ${this.timeout}ms`)\n ),\n this.timeout\n );\n }),\n ]).finally(() => {\n if (connectTimeout !== undefined) clearTimeout(connectTimeout);\n });\n\n // The official SDK opens the optional v1 standalone GET stream in the\n // background after initialization. Do not gate ordinary request/response\n // readiness on that long-lived stream: proxies may buffer its headers,\n // while tools/list and other client operations are already usable.\n // Inbound request and notification handlers are registered above before\n // connect(), so the stream can attach later without racing handler setup.\n\n // Streamable HTTP servers may optionally assign a session ID.\n const sessionId = streamableTransport.sessionId;\n if (sessionId) {\n logger.debug(`Session ID obtained: ${sessionId}`);\n }\n } catch (connectErr) {\n // Check if the error is due to missing session ID during connection handshake\n if (connectErr instanceof Error) {\n const errMsg = connectErr.message || connectErr.toString();\n if (\n errMsg.includes(\"Missing session ID\") ||\n errMsg.includes(\"Bad Request: Missing session ID\") ||\n errMsg.includes(\"Mcp-Session-Id header is required\")\n ) {\n // Wrap it in a more specific error so the outer catch can detect it\n const wrappedError = new Error(\n `Session ID error: ${errMsg}. The SDK should automatically extract session ID from initialize response.`\n );\n wrappedError.cause = connectErr;\n throw wrappedError;\n }\n }\n throw connectErr;\n }\n\n // Store the transport for later cleanup\n this.streamableTransport = streamableTransport;\n // Create a minimal connection manager wrapper for cleanup purposes.\n // Note: terminateSession() is invoked from cleanupResources() *before*\n // the SDK's client.close() aborts the transport's abort controller.\n // Calling terminateSession() here would race the abort and surface a\n // spurious AbortError on every clean shutdown.\n this.connectionManager = {\n stop: async () => {\n if (this.streamableTransport) {\n try {\n await this.streamableTransport.close();\n } catch (e) {\n logger.warn(`Error closing Streamable HTTP transport: ${e}`);\n } finally {\n this.streamableTransport = null;\n }\n }\n },\n } as any;\n\n this.connected = true;\n this.transportType = \"streamable-http\";\n // Inbound request handlers (roots/sampling/elicitation) were registered before connect()\n logger.debug(\n `Successfully connected to MCP implementation via streamable HTTP: ${baseUrl}`\n );\n\n // Track connector initialization\n this.trackConnectorInit({\n serverUrl: this.baseUrl,\n publicIdentifier: `${this.baseUrl} (streamable-http)`,\n });\n } catch (err) {\n // Clean up partial resources before throwing\n await this.cleanupResources();\n throw err;\n }\n }\n\n /**\n * Returns fields that identify the endpoint and negotiated transport.\n *\n * @returns HTTP connector identity metadata.\n */\n get publicIdentifier(): Record<string, string> {\n return {\n type: \"http\",\n url: this.baseUrl,\n transport: this.transportType || \"unknown\",\n protocolEra: this.protocolEra ?? \"unknown\",\n };\n }\n\n /**\n * Returns the active transport type.\n *\n * @returns `\"streamable-http\"` after connection, otherwise `null`.\n */\n getTransportType(): \"streamable-http\" | null {\n return this.transportType;\n }\n\n // Send the streamable-HTTP DELETE *before* super.cleanupResources() invokes\n // client.close(). The SDK's transport.close() aborts the shared abort\n // controller, and terminateSession()'s DELETE fetch reuses that signal —\n // running it after close() rejects immediately with AbortError.\n protected async cleanupResources(): Promise<void> {\n // Only legacy (2025-era) connections carry an Mcp-Session-Id worth\n // terminating. Modern (2026-07-28) connections are stateless per-request,\n // so there is no session DELETE to issue.\n if (this.streamableTransport && this.protocolEra !== \"modern\") {\n let terminationTimeout: ReturnType<typeof setTimeout> | undefined;\n try {\n const terminated = await Promise.race([\n this.streamableTransport.terminateSession().then(() => true),\n new Promise<false>(\n (resolve) =>\n (terminationTimeout = setTimeout(\n () => resolve(false),\n Math.min(this.timeout, 5000)\n ))\n ),\n ]);\n if (!terminated) {\n logger.debug(\n \"Timed out terminating legacy HTTP session; closing transport\"\n );\n }\n } catch (e) {\n logger.debug(`Error terminating Streamable HTTP session: ${e}`);\n } finally {\n if (terminationTimeout) clearTimeout(terminationTimeout);\n }\n }\n await super.cleanupResources();\n this.authorizationDiscovery = null;\n }\n}\n","import {\n auth,\n InsufficientScopeError,\n UnauthorizedError,\n type OAuthClientProvider,\n} from \"@modelcontextprotocol/client\";\nimport type { NodeOAuthAuthorizationResponse } from \"./node.js\";\nimport { runAuthPopup } from \"./popup.js\";\n\nconst DEFAULT_AUTH_TIMEOUT_MS = 5 * 60_000;\n\n/** Provider extras used by the Node loopback and browser popup flows. */\ntype FlowProvider = OAuthClientProvider & {\n serverUrlHash?: string;\n hasPendingFlow?: boolean;\n getAuthorizationResponse?: () => Promise<NodeOAuthAuthorizationResponse>;\n getAuthorizationCode?: () => Promise<string>;\n getProxyFetch?: (baseFetch?: typeof fetch) => typeof fetch | undefined;\n getKey?: (keySuffix: string) => string;\n getLastAttemptedAuthUrl?: () => string | null;\n markFlowComplete?: () => void;\n preventAutoAuth?: boolean;\n startAuthorization?: () => void;\n useRedirectFlow?: boolean;\n};\n\n/** Host callback used to complete the official transport's pending OAuth flow. */\ntype FinishOAuthAuthorization = (code: string, iss?: string) => Promise<void>;\n\n/**\n * True if the error (or a wrapped cause) is an HTTP 401 / UnauthorizedError\n * that should trigger the OAuth completion dance.\n */\nexport function isUnauthorized(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n if (err instanceof UnauthorizedError) return true;\n if (err instanceof Error) {\n const code = (err as { code?: unknown }).code;\n if (code === 401) return true;\n if (err.name === \"UnauthorizedError\") return true;\n const message = err.message ?? \"\";\n if (message.includes(\"401\") || message.includes(\"Unauthorized\")) {\n return true;\n }\n if (err.cause && isUnauthorized(err.cause, depth + 1)) return true;\n const data = (err as { data?: { cause?: unknown } }).data;\n if (data?.cause && isUnauthorized(data.cause, depth + 1)) return true;\n }\n return false;\n}\n\n/**\n * True when the official SDK has started an interactive OAuth flow that the\n * host must finish before retrying the logical MCP operation.\n */\nexport function isOAuthInteractionRequired(err: unknown, depth = 0): boolean {\n if (!err || depth > 5) return false;\n if (\n err instanceof InsufficientScopeError ||\n err instanceof UnauthorizedError\n ) {\n return true;\n }\n if (err instanceof Error) {\n if (\n err.name === \"InsufficientScopeError\" ||\n err.name === \"UnauthorizedError\"\n ) {\n return true;\n }\n if (err.cause && isOAuthInteractionRequired(err.cause, depth + 1)) {\n return true;\n }\n const data = (err as { data?: { cause?: unknown } }).data;\n if (data?.cause && isOAuthInteractionRequired(data.cause, depth + 1)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Complete an in-progress or required OAuth authorization for `provider`.\n *\n * - Node loopback providers expose `getAuthorizationCode()`; we await the\n * code and finish the token exchange.\n * - Browser providers open a popup/redirect; we wait for the callback page\n * (`onMcpAuthorization`) to exchange the code and signal success over\n * `BroadcastChannel` / `postMessage`.\n *\n * Safe to call when the SDK transport already invoked `auth()` on a 401\n * (Node: `hasPendingFlow`; we skip a duplicate `auth()` in that case).\n */\nexport async function completeOAuthFlow(\n provider: OAuthClientProvider,\n serverUrl: string,\n options: {\n timeoutMs?: number;\n fetchFn?: typeof fetch;\n finishAuthorization?: FinishOAuthAuthorization;\n } = {}\n): Promise<void> {\n const flowProvider = provider as FlowProvider;\n const timeoutMs = options.timeoutMs ?? DEFAULT_AUTH_TIMEOUT_MS;\n const fetchFn =\n options.fetchFn ?? flowProvider.getProxyFetch?.() ?? undefined;\n\n if (!flowProvider.hasPendingFlow) {\n const result = await auth(provider, { serverUrl, fetchFn });\n if (result === \"AUTHORIZED\") return;\n if (result !== \"REDIRECT\") {\n throw new Error(`Unexpected OAuth auth() result: ${result}`);\n }\n }\n\n // With preventAutoAuth, redirectToAuthorization() deliberately only stores\n // the SDK-prepared URL. An explicit authenticate() call is the user gesture\n // that should launch that already-prepared request.\n if (\n flowProvider.preventAutoAuth === true &&\n typeof flowProvider.startAuthorization === \"function\"\n ) {\n flowProvider.startAuthorization();\n }\n\n if (\n typeof flowProvider.getAuthorizationResponse === \"function\" ||\n typeof flowProvider.getAuthorizationCode === \"function\"\n ) {\n const response =\n typeof flowProvider.getAuthorizationResponse === \"function\"\n ? await flowProvider.getAuthorizationResponse()\n : { code: await flowProvider.getAuthorizationCode!() };\n if (options.finishAuthorization) {\n await options.finishAuthorization(response.code, response.iss);\n } else {\n // Connect-time authorization may no longer have its failed transport.\n // Keep the official top-level helper as the fallback for that case.\n await auth(provider, {\n serverUrl,\n authorizationCode: response.code,\n ...(response.iss !== undefined ? { iss: response.iss } : {}),\n fetchFn,\n });\n }\n return;\n }\n\n await waitForBrowserAuthComplete(flowProvider, timeoutMs);\n}\n\nasync function waitForBrowserAuthComplete(\n provider: FlowProvider,\n timeoutMs: number\n): Promise<void> {\n if (typeof window === \"undefined\") {\n throw new Error(\n \"OAuth redirect requires a browser environment or a provider with getAuthorizationCode()\"\n );\n }\n\n if (provider.useRedirectFlow) {\n // Do not return to the caller and retry the MCP connection before the\n // full-page navigation replaces this JavaScript context.\n await new Promise<void>(() => {});\n return;\n }\n\n const tokensKey = provider.getKey?.(\"tokens\");\n if (!tokensKey) {\n throw new Error(\n \"Browser OAuth provider must expose getKey() for token storage\"\n );\n }\n\n let state: string | null = null;\n const authUrl = provider.getLastAttemptedAuthUrl?.();\n if (authUrl) {\n try {\n state = new URL(authUrl).searchParams.get(\"state\");\n } catch {\n // state-less fallback is supported by runAuthPopup\n }\n }\n\n try {\n const result = await runAuthPopup({\n popup: null,\n state,\n tokensKey,\n timeoutMs,\n });\n\n switch (result.kind) {\n case \"success\":\n return;\n case \"cancelled\":\n throw new Error(\"OAuth authentication was cancelled.\");\n case \"timeout\":\n throw new Error(\n `OAuth callback not received within ${timeoutMs}ms. Ensure /oauth/callback calls onMcpAuthorization().`\n );\n case \"error\":\n throw new Error(result.error);\n default:\n throw new Error(\"Unexpected OAuth popup result\");\n }\n } finally {\n provider.markFlowComplete?.();\n }\n}\n","import type {\n JsonSchemaType,\n jsonSchemaValidator,\n} from \"@modelcontextprotocol/client\";\nimport {\n CfWorkerJsonSchemaValidator,\n type CfWorkerSchemaDraft,\n} from \"@modelcontextprotocol/client/validators/cf-worker\";\n\nconst DRAFT_04_URI = \"http://json-schema.org/draft-04/schema\";\nconst DRAFT_07_URIS = new Set([\n \"http://json-schema.org/draft-07/schema\",\n \"https://json-schema.org/draft-07/schema\",\n]);\nconst DRAFT_2019_09_URIS = new Set([\n \"https://json-schema.org/draft/2019-09/schema\",\n \"http://json-schema.org/draft/2019-09/schema\",\n]);\nconst DRAFT_2020_12_URIS = new Set([\n \"https://json-schema.org/draft/2020-12/schema\",\n \"http://json-schema.org/draft/2020-12/schema\",\n]);\n\nfunction resolveDraft(schema: JsonSchemaType): CfWorkerSchemaDraft | undefined {\n if (!(\"$schema\" in schema) || typeof schema.$schema !== \"string\") {\n return \"2020-12\";\n }\n\n const normalized = schema.$schema.replace(/#$/, \"\");\n\n if (normalized === DRAFT_04_URI) return \"4\";\n if (DRAFT_07_URIS.has(normalized)) return \"7\";\n if (DRAFT_2019_09_URIS.has(normalized)) return \"2019-09\";\n if (DRAFT_2020_12_URIS.has(normalized)) return \"2020-12\";\n\n return undefined;\n}\n\n/**\n * JSON Schema validator that maps common `$schema` dialect URIs to the\n * matching `@cfworker/json-schema` draft. The v2 SDK default rejects any\n * schema not declaring JSON Schema 2020-12 as an \"unsupported dialect\", which\n * breaks `tools/call` against v1-era servers that emit draft-04/-07/2019-09\n * `$schema` on tool `outputSchema` (mcp-use#1839). Unknown `$schema` URIs\n * still fail fast via the SDK's strict default validator.\n */\nexport class DialectJsonSchemaValidator implements jsonSchemaValidator {\n getValidator<T>(schema: JsonSchemaType) {\n const draft = resolveDraft(schema);\n const delegate =\n draft !== undefined\n ? new CfWorkerJsonSchemaValidator({ draft })\n : new CfWorkerJsonSchemaValidator();\n return delegate.getValidator<T>(schema);\n }\n}\n","import type {\n CallToolResult,\n Client,\n ClientOptions,\n CompleteRequestParams,\n CompleteResult,\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n AuthProvider,\n JSONRPCMessage,\n Notification,\n OAuthClientProvider,\n ProtocolEra,\n RequestOptions,\n Root,\n Tool,\n} from \"@modelcontextprotocol/client\";\nimport { logger } from \"../utils/logging.js\";\nimport { isOAuthInteractionRequired } from \"../auth/flow.js\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\n\n/**\n * Accept-anything Standard Schema used for raw passthrough requests whose\n * method string is arbitrary (possibly non-spec). v2's `Protocol.request()`\n * requires a result schema for non-spec methods; this preserves the v1\n * \"return whatever the server sent\" behavior without importing Zod here.\n */\nconst passthroughResultSchema = {\n \"~standard\": {\n version: 1 as const,\n vendor: \"mcp-use\",\n validate: (value: unknown) => ({ value }),\n },\n};\n\nimport type { ConnectionManager } from \"./connection-manager.js\";\nimport type { ConnectorInitEventData } from \"../telemetry/events.js\";\nimport { trackConnectorTelemetry } from \"../telemetry/connector-telemetry.js\";\nimport type { MCPAuthorizationInfo, MCPServerInfo } from \"../core/session.js\";\n\n/**\n * Handles a notification received from an MCP server.\n *\n * @param notification - Notification envelope supplied by the server.\n */\nexport type NotificationHandler = (\n notification: Notification\n) => void | Promise<void>;\n\n/** Shared initialization options for all connector transports. */\nexport interface ConnectorInitOptions {\n /**\n * Options forwarded to the underlying MCP `Client` instance.\n *\n * By default, all connectors (HTTP and stdio) use `DialectJsonSchemaValidator`\n * to support common `$schema` dialects (draft-04, draft-07, 2019-09, 2020-12)\n * for cross-version compatibility with v1-era servers. Override with\n * `clientOptions.jsonSchemaValidator` if stricter validation is needed.\n */\n clientOptions?: ClientOptions;\n /**\n * Arbitrary request options (timeouts, cancellation, etc.) used by helper\n * methods when they issue SDK requests. Can be overridden per‑call.\n */\n defaultRequestOptions?: RequestOptions;\n /**\n * OAuth client provider for automatic authentication\n */\n authProvider?: AuthProvider | OAuthClientProvider;\n /**\n * Optional callback to wrap the transport before passing it to the Client.\n * Useful for logging, monitoring, or other transport-level interceptors.\n */\n wrapTransport?: (transport: any, serverId: string) => any;\n /**\n * Initial roots to provide to the server.\n * Roots allow the server to know which directories/files the client has access to.\n */\n roots?: Root[];\n /**\n * Optional callback function to handle sampling requests from servers.\n * When provided, the client will declare sampling capability and handle\n * `sampling/createMessage` requests by calling this callback.\n *\n * @deprecated Sampling is deprecated by the 2026 protocol. Retained for v1\n * push requests and v2 multi-round-trip compatibility.\n */\n onSampling?: (\n params: SamplingCreateMessageParams\n ) => Promise<SamplingCreateMessageResult>;\n /**\n * Optional callback function to handle elicitation requests from servers.\n * When provided, the client will declare elicitation capability and handle\n * `elicitation/create` requests by calling this callback.\n *\n * Elicitation allows servers to request additional information from users:\n * - Form mode: Collect structured data with JSON schema validation\n * - URL mode: Direct users to external URLs for sensitive interactions\n */\n onElicitation?: (\n params: ElicitRequestFormParams | ElicitRequestURLParams\n ) => Promise<ElicitResult>;\n /**\n * Optional callback for server notifications.\n * When provided, registered as initial notification handler.\n */\n onNotification?: NotificationHandler;\n /**\n * Reconnection options for streamable HTTP transport.\n * Controls retry behavior of the underlying `StreamableHTTPClientTransport`.\n */\n reconnectionOptions?: {\n /** Maximum delay between reconnection attempts in milliseconds. */\n maxReconnectionDelay?: number;\n /** Delay before the first reconnection attempt in milliseconds. */\n initialReconnectionDelay?: number;\n /** Multiplier applied to the delay after each failed attempt. */\n reconnectionDelayGrowFactor?: number;\n /** Maximum number of reconnection attempts. */\n maxRetries?: number;\n };\n}\n\n/**\n * Implements protocol operations shared by MCP transport connectors.\n *\n * Subclasses provide transport-specific connection setup and a public\n * identifier. Call {@link BaseConnector.connect}, then\n * {@link BaseConnector.initialize}, before invoking protocol operations.\n */\nexport abstract class BaseConnector {\n protected client: Client | null = null;\n protected connectionManager: ConnectionManager<any> | null = null;\n protected toolsCache: Tool[] | null = null;\n protected capabilitiesCache: Record<string, unknown> | null = null;\n protected serverInfoCache: MCPServerInfo | null = null;\n protected authorizationCache: MCPAuthorizationInfo | undefined;\n protected connected = false;\n protected readonly opts: ConnectorInitOptions;\n protected notificationHandlers: NotificationHandler[] = [];\n protected rootsCache: Root[] = [];\n private activeProgressHandlers = new Set<\n NonNullable<RequestOptions[\"onprogress\"]>\n >();\n\n /**\n * Creates a connector with shared SDK and callback options.\n *\n * @param opts - Connector initialization options.\n */\n constructor(opts: ConnectorInitOptions = {}) {\n this.opts = opts;\n // Initialize roots from options\n if (opts.roots) {\n this.rootsCache = [...opts.roots];\n }\n // Register initial notification handler if provided\n if (opts.onNotification) {\n this.notificationHandlers.push(opts.onNotification);\n }\n }\n\n /**\n * Track connector initialization event\n * Should be called by subclasses after successful connection\n */\n protected trackConnectorInit(\n data: Omit<ConnectorInitEventData, \"connectorType\">\n ): void {\n const connectorType = this.constructor.name;\n trackConnectorTelemetry({ connectorType, ...data });\n }\n\n /**\n * Register a handler for server notifications\n *\n * @param handler - Function to call when a notification is received\n *\n * @example\n * ```typescript\n * connector.onNotification((notification) => {\n * console.log(`Received: ${notification.method}`, notification.params);\n * });\n * ```\n */\n onNotification(handler: NotificationHandler): void {\n this.notificationHandlers.push(handler);\n // Wire up to SDK client if already connected\n if (this.client) {\n this.setupNotificationHandler();\n }\n }\n\n /** Forward a normalized notification to every registered consumer. */\n protected async forwardNotification(\n notification: Notification\n ): Promise<void> {\n for (const handler of this.notificationHandlers) {\n try {\n await handler(notification);\n } catch (err) {\n logger.error(\"Error in notification handler:\", err);\n }\n }\n }\n\n /** Handle SDK list-change callbacks identically on v1 and v2 connections. */\n protected async handleListChanged(\n method:\n | \"notifications/tools/list_changed\"\n | \"notifications/resources/list_changed\"\n | \"notifications/prompts/list_changed\",\n error: Error | null,\n tools?: Tool[] | null\n ): Promise<void> {\n if (error) {\n logger.warn(`[Auto] ${method} refresh failed:`, error);\n return;\n }\n if (method === \"notifications/tools/list_changed\" && tools) {\n this.toolsCache = [...tools];\n }\n await this.forwardNotification({ method } as Notification);\n }\n\n /**\n * Internal: wire notification handlers to the SDK client\n * Includes automatic handling for list_changed notifications per MCP spec\n */\n protected setupNotificationHandler(): void {\n if (!this.client) return;\n\n // Use fallbackNotificationHandler to catch all notifications\n this.client.fallbackNotificationHandler = async (\n notification: Notification\n ) => {\n // Auto-handle list_changed notifications per MCP spec\n // Clients SHOULD re-fetch the list when receiving these notifications\n switch (notification.method) {\n case \"notifications/tools/list_changed\":\n await this.refreshToolsCache();\n break;\n case \"notifications/resources/list_changed\":\n await this.onResourcesListChanged();\n break;\n case \"notifications/prompts/list_changed\":\n await this.onPromptsListChanged();\n break;\n default:\n break;\n }\n\n await this.forwardNotification(notification);\n };\n\n // The SDK registers specific handlers for progress and cancelled notifications\n // that bypass fallbackNotificationHandler entirely. Override them to also\n // forward to user-registered handlers so they appear in notification UIs.\n const client = this.client as any;\n const handlersMap = client._notificationHandlers as Map<\n string,\n (notification: Notification) => Promise<void>\n >;\n\n for (const method of [\n \"notifications/progress\",\n \"notifications/cancelled\",\n ]) {\n const originalHandler = handlersMap.get(method);\n if (originalHandler) {\n handlersMap.set(method, async (notification: Notification) => {\n await originalHandler(notification);\n await this.forwardNotification(notification);\n });\n }\n }\n }\n\n /**\n * Forward v2 MRTR progress whose retry request IDs are not associated with\n * the original call callback by the current SDK beta.\n *\n * ponytail: fallback is enabled only when exactly one progress-aware call is\n * active; remove it when the upstream SDK propagates handlers to MRTR rounds.\n */\n protected setupRoundProgressForwarding(): void {\n if (!this.client) return;\n const sdkClient = this.client as unknown as {\n _onnotification: (message: JSONRPCMessage) => void | Promise<void>;\n _progressHandlers?: Map<unknown, unknown>;\n };\n const original = sdkClient._onnotification.bind(this.client);\n sdkClient._onnotification = async (message: JSONRPCMessage) => {\n if (\n message &&\n typeof message === \"object\" &&\n (message as { method?: unknown }).method === \"notifications/progress\"\n ) {\n this.forwardRoundProgress((message as { params?: unknown }).params);\n }\n await original?.(message);\n };\n }\n\n /** Forward progress parsed from a transport stream to the active call. */\n protected forwardRoundProgress(params: unknown): void {\n if (this.activeProgressHandlers.size === 1) {\n const [handler] = this.activeProgressHandlers;\n handler?.(\n params as Parameters<NonNullable<RequestOptions[\"onprogress\"]>>[0]\n );\n }\n }\n\n /**\n * Auto-refresh tools cache when server sends tools/list_changed notification\n */\n protected async refreshToolsCache(): Promise<void> {\n if (!this.client) return;\n try {\n logger.debug(\n \"[Auto] Refreshing tools cache due to list_changed notification\"\n );\n const result = await this.client.listTools();\n this.toolsCache = (result.tools ?? []) as Tool[];\n logger.debug(\n `[Auto] Refreshed tools cache: ${this.toolsCache.length} tools`\n );\n } catch (err) {\n logger.warn(\"[Auto] Failed to refresh tools cache:\", err);\n }\n }\n\n /**\n * Called when server sends resources/list_changed notification\n * Resources aren't cached by default, but we log for user awareness\n */\n protected async onResourcesListChanged(): Promise<void> {\n logger.debug(\n \"[Auto] Resources list changed - clients should re-fetch if needed\"\n );\n }\n\n /**\n * Called when server sends prompts/list_changed notification\n * Prompts aren't cached by default, but we log for user awareness\n */\n protected async onPromptsListChanged(): Promise<void> {\n logger.debug(\n \"[Auto] Prompts list changed - clients should re-fetch if needed\"\n );\n }\n\n /**\n * Set roots and notify the server.\n * Roots represent directories or files that the client has access to.\n *\n * @param roots - Array of Root objects with `uri` (must start with \"file://\") and optional `name`\n *\n * @deprecated Roots are retained only for v1 compatibility.\n *\n * @example\n * ```typescript\n * await connector.setRoots([\n * { uri: \"file:///home/user/project\", name: \"My Project\" },\n * { uri: \"file:///home/user/data\" }\n * ]);\n * ```\n */\n async setRoots(roots: Root[]): Promise<void> {\n this.rootsCache = [...roots];\n if (this.client) {\n logger.debug(\n `Sending roots/list_changed notification with ${roots.length} root(s)`\n );\n await this.client.sendRootsListChanged();\n }\n }\n\n /**\n * Returns the roots currently advertised to the server.\n *\n * @returns A copy of the configured roots.\n */\n getRoots(): Root[] {\n return [...this.rootsCache];\n }\n\n /**\n * Internal: set up roots/list request handler.\n * Must be registered after Client construction and before connect() so the\n * handler is available during initialize / reverse RPC for the full session.\n */\n protected setupRootsHandler(): void {\n if (!this.client) return;\n\n // Handle roots/list requests from the server\n this.client.setRequestHandler(\"roots/list\", async () => {\n logger.debug(\n `Server requested roots list, returning ${this.rootsCache.length} root(s)`\n );\n return { roots: this.rootsCache };\n });\n }\n\n /**\n * Internal: set up sampling/createMessage request handler.\n * Must be registered after Client construction and before connect().\n */\n protected setupSamplingHandler(): void {\n if (!this.client) {\n logger.debug(\"setupSamplingHandler: No client available\");\n return;\n }\n const samplingCallback = this.opts.onSampling;\n if (!samplingCallback) {\n logger.debug(\"setupSamplingHandler: No sampling callback provided\");\n return;\n }\n\n logger.debug(\"setupSamplingHandler: Setting up sampling request handler\");\n // Handle sampling/createMessage requests from the server\n this.client.setRequestHandler(\"sampling/createMessage\", async (request) => {\n logger.debug(\"Server requested sampling, forwarding to callback\");\n return await samplingCallback(request.params);\n });\n logger.debug(\n \"setupSamplingHandler: Sampling handler registered successfully\"\n );\n }\n\n /**\n * Internal: set up elicitation/create request handler.\n * Must be registered after Client construction and before connect().\n */\n protected setupElicitationHandler(): void {\n if (!this.client) {\n logger.debug(\"setupElicitationHandler: No client available\");\n return;\n }\n const elicitationCallback = this.opts.onElicitation;\n if (!elicitationCallback) {\n logger.debug(\"setupElicitationHandler: No elicitation callback provided\");\n return;\n }\n\n logger.debug(\n \"setupElicitationHandler: Setting up elicitation request handler\"\n );\n // Handle elicitation/create requests from the server\n this.client.setRequestHandler(\"elicitation/create\", async (request) => {\n logger.debug(\"Server requested elicitation, forwarding to callback\");\n return await elicitationCallback(\n request.params as ElicitRequestFormParams | ElicitRequestURLParams\n );\n });\n logger.debug(\n \"setupElicitationHandler: Elicitation handler registered successfully\"\n );\n }\n\n /**\n * Establishes the transport connection and creates the SDK client.\n *\n * @returns A promise that resolves when the connector is connected.\n */\n abstract connect(): Promise<void>;\n\n /**\n * Returns transport-specific fields suitable for logs and telemetry.\n *\n * @returns A record identifying the connector without exposing credentials.\n */\n abstract get publicIdentifier(): Record<string, string>;\n\n /**\n * Run one logical MCP operation. HTTP connectors override this host seam to\n * finish an SDK-started interactive OAuth flow and retry exactly once.\n */\n protected async executeRequest<T>(operation: () => Promise<T>): Promise<T> {\n return operation();\n }\n\n /** OAuth state discovered for the active connection, when available. */\n get authorization(): MCPAuthorizationInfo | undefined {\n return this.authorizationCache;\n }\n\n /**\n * Discover optional authorization metadata without delaying connection\n * readiness. HTTP connectors override this with RFC 9728 discovery.\n */\n async discoverAuthorization(): Promise<MCPAuthorizationInfo | undefined> {\n return this.authorization;\n }\n\n /** Start optional OAuth for a connected mixed-auth server. */\n async authenticate(): Promise<void> {\n throw new Error(\"This connector does not support interactive OAuth\");\n }\n\n /**\n * Disconnects the SDK client and releases transport resources.\n *\n * @returns A promise that resolves after cleanup completes.\n */\n async disconnect(): Promise<void> {\n if (!this.connected) {\n logger.debug(\"Not connected to MCP implementation\");\n return;\n }\n\n logger.debug(\"Disconnecting from MCP implementation\");\n await this.cleanupResources();\n this.connected = false;\n logger.debug(\"Disconnected from MCP implementation\");\n }\n\n /** Whether an SDK client currently exists for this connector. */\n get isClientConnected(): boolean {\n return this.client != null;\n }\n\n /**\n * Initialise the MCP session **after** `connect()` has succeeded.\n *\n * In the SDK, `Client.connect(transport)` automatically performs the\n * protocol‑level `initialize` handshake, so we only need to cache the list of\n * tools and expose some server info.\n *\n * @param defaultRequestOptions - Options used while fetching the initial tool list.\n * @returns The capabilities advertised by the server.\n * @throws When {@link BaseConnector.connect} has not completed.\n */\n async initialize(\n defaultRequestOptions: RequestOptions = this.opts.defaultRequestOptions ??\n {}\n ): Promise<ReturnType<Client[\"getServerCapabilities\"]>> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(\"Caching server capabilities & tools\");\n\n // Cache server capabilities for callers who need them.\n const capabilities = this.client.getServerCapabilities();\n this.capabilitiesCache = (capabilities as Record<string, unknown>) || null;\n\n // The SDK normalizes identity from legacy initialize responses and modern\n // result metadata. Modern servers may remain anonymous.\n const serverInfo = this.client.getServerVersion();\n this.serverInfoCache = serverInfo\n ? {\n name: serverInfo.name,\n version: serverInfo.version,\n title: serverInfo.title,\n description: serverInfo.description,\n websiteUrl: serverInfo.websiteUrl,\n icons: serverInfo.icons,\n }\n : null;\n\n // Fetch and cache tools\n // Gracefully handle servers that don't implement tools/list or have no tools\n try {\n const listToolsRes = await this.executeRequest(() =>\n this.client!.listTools(undefined, defaultRequestOptions)\n );\n this.toolsCache = (listToolsRes.tools ?? []) as Tool[];\n logger.debug(`Fetched ${this.toolsCache.length} tools from server`);\n } catch (err: unknown) {\n if (isOAuthInteractionRequired(err)) throw err;\n const error = err as Error & { code?: number };\n // If tools/list is not implemented or fails, assume no tools\n // This commonly happens with blank servers that have no tools registered\n if (error.code === -32601) {\n logger.debug(\"Server does not implement tools/list, assuming no tools\");\n } else {\n logger.debug(\"Failed to list tools, assuming empty:\", error.message);\n }\n this.toolsCache = [];\n }\n\n logger.debug(\"Server capabilities:\", capabilities);\n logger.debug(\"Server info:\", serverInfo);\n return capabilities;\n }\n\n /**\n * Returns the tool list cached during initialization.\n *\n * @throws When {@link BaseConnector.initialize} has not completed.\n */\n get tools(): Tool[] {\n if (!this.toolsCache) {\n throw new Error(\"MCP client is not initialized; call initialize() first\");\n }\n return this.toolsCache;\n }\n\n /** Capabilities cached during initialization, or an empty object. */\n get serverCapabilities(): Record<string, unknown> {\n return this.capabilitiesCache || {};\n }\n\n /** Server identity cached during initialization, or `null`. */\n get serverInfo(): MCPServerInfo | null {\n return this.serverInfoCache;\n }\n\n /** Instructions supplied by the connected server, if any. */\n get instructions(): string | undefined {\n return this.client?.getInstructions?.();\n }\n\n /**\n * The negotiated protocol era for the active connection.\n * - `\"legacy\"` — 2025-era server, sessionful `initialize` handshake.\n * - `\"modern\"` — 2026-era server, stateless per-request.\n * `undefined` before the connection has negotiated.\n */\n get protocolEra(): ProtocolEra | undefined {\n return this.client?.getProtocolEra?.();\n }\n\n /** The protocol version string negotiated for the active connection. */\n get negotiatedProtocolVersion(): string | undefined {\n return this.client?.getNegotiatedProtocolVersion?.();\n }\n\n /**\n * Calls a tool on the connected server.\n *\n * @param name - Tool name.\n * @param args - Tool arguments.\n * @param options - Per-request timeout, cancellation, and progress options.\n * @returns The tool result returned by the server.\n * @throws When the connector is not connected or the tool call fails.\n */\n async callTool(\n name: string,\n args: Record<string, any>,\n options?: RequestOptions\n ): Promise<CallToolResult> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n // If resetTimeoutOnProgress is enabled but no onprogress callback is provided,\n // add a no-op callback to trigger the SDK to add progressToken to the request.\n // The SDK only adds progressToken when onprogress is present, which is required\n // for the server to send progress notifications that reset the timeout.\n const enhancedOptions = options ? { ...options } : undefined;\n if (\n enhancedOptions?.resetTimeoutOnProgress &&\n !enhancedOptions.onprogress\n ) {\n // Add no-op progress callback to trigger progressToken addition\n enhancedOptions.onprogress = () => {\n // No-op: progress notifications are handled by the SDK's timeout reset logic\n };\n logger.debug(\n `[BaseConnector] Added onprogress callback for tool '${name}' to enable progressToken`\n );\n }\n\n logger.debug(`Calling tool '${name}' with args`, args);\n const progressHandler = enhancedOptions?.onprogress;\n if (progressHandler) this.activeProgressHandlers.add(progressHandler);\n try {\n const res = await this.executeRequest(() =>\n this.client!.callTool({ name, arguments: args }, enhancedOptions)\n );\n logger.debug(`Tool '${name}' returned`, res);\n return res as CallToolResult;\n } finally {\n if (progressHandler) this.activeProgressHandlers.delete(progressHandler);\n }\n }\n\n /**\n * List all available tools from the MCP server.\n * This method fetches fresh tools from the server, unlike the `tools` getter which returns cached tools.\n *\n * @param options - Optional request options\n * @returns Array of available tools\n */\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n logger.debug(\"[listTools] Fetching fresh tools from server...\");\n const result = await this.executeRequest(() =>\n this.client!.listTools(undefined, options)\n );\n // Create a new array to ensure React detects the change (avoid reference equality issues)\n const tools = result.tools ? [...result.tools] : [];\n logger.debug(\n `[listTools] Returned ${tools.length} tools:`,\n tools.map((t) => t.name)\n );\n return tools;\n }\n\n /**\n * List resources from the server with optional pagination\n *\n * @param cursor - Optional cursor for pagination\n * @param options - Request options\n * @returns Resource list with optional nextCursor for pagination\n */\n async listResources(cursor?: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(\"Listing resources\", cursor ? `with cursor: ${cursor}` : \"\");\n return await this.executeRequest(() =>\n this.client!.listResources({ cursor }, options)\n );\n }\n\n /**\n * List all resources from the server, automatically handling pagination\n *\n * @param options - Request options\n * @returns Complete list of all resources\n */\n async listAllResources(options?: RequestOptions): Promise<{\n /** Resources returned across all result pages. */\n resources: any[];\n }> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n // Check if server advertises resources capability\n if (!this.capabilitiesCache?.resources) {\n logger.debug(\"Server does not advertise resources capability, skipping\");\n return { resources: [] };\n }\n\n try {\n logger.debug(\"Listing all resources (with auto-pagination)\");\n return await this.executeRequest(async () => {\n const allResources: any[] = [];\n let cursor: string | undefined = undefined;\n\n do {\n const result: { resources?: any[]; nextCursor?: string } =\n await this.client!.listResources({ cursor }, options);\n allResources.push(...(result.resources || []));\n cursor = result.nextCursor;\n } while (cursor);\n\n return { resources: allResources };\n });\n } catch (err: unknown) {\n const error = err as Error & { code?: number };\n // Gracefully handle if server advertises but doesn't actually support it\n if (error.code === -32601) {\n logger.debug(\"Server advertised resources but method not found\");\n return { resources: [] };\n }\n throw err;\n }\n }\n\n /**\n * List resource templates from the server\n *\n * @param options - Request options\n * @returns List of available resource templates\n */\n async listResourceTemplates(options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(\"Listing resource templates\");\n return await this.executeRequest(() =>\n this.client!.listResourceTemplates(undefined, options)\n );\n }\n\n /**\n * Request completion suggestions for a prompt or resource template argument\n *\n * @param params - Completion request parameters\n * @param options - Request options\n * @returns Completion suggestions from the server\n */\n async complete(\n params: CompleteRequestParams,\n options?: RequestOptions\n ): Promise<CompleteResult> {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n logger.debug(\"[complete] Requesting completions for:\", params.ref);\n const result = await this.executeRequest(() =>\n this.client!.complete(params, options)\n );\n logger.debug(\n `[complete] Received ${result.completion.values.length} suggestions`\n );\n return result;\n }\n\n /**\n * Reads a resource by URI.\n *\n * @param uri - Resource URI to read.\n * @param options - Per-request options.\n * @returns The resource contents returned by the server.\n */\n async readResource(uri: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Reading resource ${uri}`);\n const res = await this.executeRequest(() =>\n this.client!.readResource({ uri }, options)\n );\n return res;\n }\n\n /**\n * Subscribe to resource updates\n *\n * @param uri - URI of the resource to subscribe to\n * @param options - Request options\n */\n async subscribeToResource(uri: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Subscribing to resource: ${uri}`);\n return await this.executeRequest(() =>\n this.client!.subscribeResource({ uri }, options)\n );\n }\n\n /**\n * Unsubscribe from resource updates\n *\n * @param uri - URI of the resource to unsubscribe from\n * @param options - Request options\n */\n async unsubscribeFromResource(uri: string, options?: RequestOptions) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Unsubscribing from resource: ${uri}`);\n return await this.executeRequest(() =>\n this.client!.unsubscribeResource({ uri }, options)\n );\n }\n\n /**\n * Lists prompts exposed by the server.\n *\n * @returns The prompt list, or an empty list when prompts are unsupported.\n */\n async listPrompts() {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n // Check if server advertises prompts capability\n if (!this.capabilitiesCache?.prompts) {\n logger.debug(\"Server does not advertise prompts capability, skipping\");\n return { prompts: [] };\n }\n\n try {\n logger.debug(\"Listing prompts\");\n return await this.executeRequest(() => this.client!.listPrompts());\n } catch (err: unknown) {\n const error = err as Error & { code?: number };\n // Gracefully handle if server advertises but doesn't actually support it\n if (error.code === -32601) {\n logger.debug(\"Server advertised prompts but method not found\");\n return { prompts: [] };\n }\n throw err;\n }\n }\n\n /**\n * Gets a prompt with the supplied arguments.\n *\n * @param name - Prompt name.\n * @param args - Prompt arguments.\n * @param options - Per-request timeout, cancellation, and progress options.\n * @returns The rendered prompt returned by the server.\n */\n async getPrompt(\n name: string,\n args: Record<string, any>,\n options?: RequestOptions\n ) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Getting prompt ${name}`);\n return await this.executeRequest(() =>\n this.client!.getPrompt({ name, arguments: args }, options)\n );\n }\n\n /**\n * Sends a raw, potentially non-standard request through the SDK client.\n *\n * @param method - JSON-RPC method name.\n * @param params - Request parameters. Defaults to an empty object.\n * @param options - Per-request options.\n * @returns The unvalidated result returned by the server.\n */\n async request(\n method: string,\n params: Record<string, any> | null = null,\n options?: RequestOptions\n ) {\n if (!this.client) {\n throw new Error(\"MCP client is not connected\");\n }\n\n logger.debug(`Sending raw request '${method}' with params`, params);\n // v2 requires a result schema for non-spec methods; a passthrough schema\n // preserves the v1 behavior of returning the raw server result for any\n // method string.\n return await this.executeRequest(() =>\n this.client!.request(\n { method, params: params ?? {} },\n passthroughResultSchema,\n options\n )\n );\n }\n\n /**\n * Helper to tear down the client & connection manager safely.\n */\n protected async cleanupResources(): Promise<void> {\n const issues: string[] = [];\n\n if (this.client) {\n try {\n if (typeof this.client.close === \"function\") {\n await this.client.close();\n }\n } catch (e) {\n const msg = `Error closing client: ${e}`;\n logger.warn(msg);\n issues.push(msg);\n } finally {\n this.client = null;\n }\n }\n\n if (this.connectionManager) {\n try {\n await this.connectionManager.stop();\n } catch (e) {\n const msg = `Error stopping connection manager: ${e}`;\n logger.warn(msg);\n issues.push(msg);\n } finally {\n this.connectionManager = null;\n }\n }\n\n this.toolsCache = null;\n this.authorizationCache = undefined;\n if (issues.length) {\n logger.warn(`Resource cleanup finished with ${issues.length} issue(s)`);\n }\n }\n}\n","import type { ConnectorInitEventData } from \"./events.js\";\n\ntype ConnectorTracker = (data: ConnectorInitEventData) => Promise<void> | void;\n\nlet tracker: ConnectorTracker | undefined;\n\n/** @internal Configures the runtime-specific connector telemetry sink. */\nexport function setConnectorTelemetryTracker(\n nextTracker: ConnectorTracker | undefined\n): void {\n tracker = nextTracker;\n}\n\n/** @internal Sends connector telemetry when the active runtime configured it. */\nexport function trackConnectorTelemetry(data: ConnectorInitEventData): void {\n void tracker?.(data);\n}\n","declare const __MCP_USE_PACKAGE_VERSION__: string;\n\n/** Installed `@mcp-use/client` package version. */\nexport const VERSION = __MCP_USE_PACKAGE_VERSION__;\n\n/**\n * Returns the installed `@mcp-use/client` package version.\n *\n * @returns Package version string.\n */\nexport function getPackageVersion(): string {\n return VERSION;\n}\n","import type {\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n Notification,\n AuthProvider,\n OAuthClientInformation,\n OAuthClientProvider,\n Root,\n RequestTypeMap,\n RequestOptions,\n ResultTypeMap,\n ClientOptions,\n VersionNegotiationMode,\n} from \"@modelcontextprotocol/client\";\nimport type { BaseConnector, ConnectorInitOptions } from \"../transport/base.js\";\nimport type { ClientInfo } from \"../transport/http.js\";\nimport { HttpConnector } from \"../transport/http.js\";\nimport type { StdioStderrMode } from \"../transport/stdio.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\n\n/** Parameters accepted by the MCP `sampling/createMessage` request. */\nexport type SamplingCreateMessageParams =\n RequestTypeMap[\"sampling/createMessage\"][\"params\"];\n\n/** Result returned for the MCP `sampling/createMessage` request. */\nexport type SamplingCreateMessageResult =\n ResultTypeMap[\"sampling/createMessage\"];\n\n/**\n * Handles a sampling request initiated by an MCP server.\n *\n * @param params - Sampling request parameters supplied by the server.\n * @returns The model-generated sampling result.\n */\nexport type OnSamplingCallback = (\n params: SamplingCreateMessageParams\n) => Promise<SamplingCreateMessageResult>;\n\n/**\n * Handles a form or URL elicitation request initiated by an MCP server.\n *\n * @param params - Elicitation request parameters supplied by the server.\n * @returns The user's elicitation decision and optional content.\n */\nexport type OnElicitationCallback = (\n params: ElicitRequestFormParams | ElicitRequestURLParams\n) => Promise<ElicitResult>;\n\n/**\n * Handles a notification sent by an MCP server.\n *\n * @param notification - The notification envelope supplied by the server.\n */\nexport type OnNotificationCallback = (\n notification: Notification\n) => void | Promise<void>;\n\n/**\n * Callback options shared by per-server config and global defaults.\n */\nexport interface CallbackConfig {\n /**\n * Callback for sampling input.\n *\n * @deprecated Sampling is deprecated by the 2026 protocol. Retained for v1\n * push requests and the v2 `input_required` compatibility window.\n */\n onSampling?: OnSamplingCallback;\n /** Callback for elicitation requests from servers. */\n onElicitation?: OnElicitationCallback;\n /** Callback for notifications from servers. */\n onNotification?: OnNotificationCallback;\n}\n\n/**\n * Resolves callback handlers, preferring per-server values over global values.\n *\n * @param perServer - Callback overrides for one server.\n * @param globalDefaults - Fallback callbacks shared by all servers.\n * @returns The effective callbacks for the server.\n */\nexport function resolveCallbacks(\n perServer: CallbackConfig | undefined,\n globalDefaults: CallbackConfig | undefined\n): {\n /** Effective sampling callback. */\n onSampling?: OnSamplingCallback;\n /** Effective elicitation callback. */\n onElicitation?: OnElicitationCallback;\n /** Effective notification callback. */\n onNotification?: OnNotificationCallback;\n} {\n const pickSampling = perServer?.onSampling ?? globalDefaults?.onSampling;\n const pickElicitation =\n perServer?.onElicitation ?? globalDefaults?.onElicitation;\n const pickNotification =\n perServer?.onNotification ?? globalDefaults?.onNotification;\n\n return {\n onSampling: pickSampling,\n onElicitation: pickElicitation,\n onNotification: pickNotification,\n };\n}\n\n/**\n * Base server configuration with common optional fields\n */\n/** Options shared by HTTP and stdio server configurations. */\ninterface BaseServerConfig extends CallbackConfig {\n /** Client identity advertised to the server. */\n clientInfo?: ClientInfo;\n /** Initial roots advertised to the server. */\n roots?: Root[];\n /** Options forwarded to the official MCP SDK Client. */\n clientOptions?: ClientOptions;\n /** Default timeout/cancellation options for requests. */\n defaultRequestOptions?: RequestOptions;\n}\n\n/**\n * Configures a local MCP server launched over standard input and output.\n */\nexport interface StdioServerConfig extends BaseServerConfig {\n /** Executable used to start the server. */\n command: string;\n /** Arguments passed to {@link StdioServerConfig.command}. */\n args: string[];\n /** Environment variables merged with the current process environment. */\n env?: Record<string, string>;\n /** Working directory used to launch the server process. */\n cwd?: string;\n /**\n * How the server process's standard error is handled. Defaults to `\"pipe\"`,\n * which forwards it to the connector's `errlog`. Use `\"inherit\"` to give the\n * child the parent's stderr file descriptor instead, preserving TTY\n * detection and colorization, or `\"ignore\"` to discard it.\n */\n stderr?: StdioStderrMode;\n /**\n * Protocol version negotiation mode. Defaults to `\"legacy\"` for stdio (the\n * SDK advises against probing for spawn-per-invocation tools). See\n * {@link StdioConnector}.\n */\n protocolNegotiation?: VersionNegotiationMode;\n}\n\n/**\n * Options forwarded to the platform `createOAuthProvider` when the client\n * auto-provisions OAuth for an HTTP server. Platform-specific fields\n * (e.g. Node `openBrowser`, browser `oauthProxyUrl`) are accepted and ignored\n * by the other runtime.\n */\nexport interface AutoOAuthOptions {\n /** Prefix used for persisted OAuth session keys. */\n storageKeyPrefix?: string;\n /** OAuth client display name. */\n clientName?: string;\n /** Public URL describing the OAuth client. */\n clientUri?: string;\n /** Public URL for the OAuth client logo. */\n logoUri?: string;\n /** OAuth redirect URI. The platform provider supplies a default when omitted. */\n callbackUrl?: string;\n /** URL of an OAuth Client ID Metadata Document. */\n clientMetadataUrl?: string;\n /** Space-delimited OAuth scopes to request. */\n scope?: string;\n /** Pre-registered public client id (skips DCR). */\n staticClientInfo?: OAuthClientInformation;\n /** Preferred Node loopback port. Defaults to `33418`. */\n preferredPort?: number;\n /** Number of Node loopback ports to try. Defaults to `10`. */\n portRange?: number;\n /** Node loopback callback timeout in milliseconds. Defaults to five minutes. */\n authTimeoutMs?: number;\n /** Node: override browser launch (CLI prints the URL instead). */\n openBrowser?: (url: string) => void | Promise<void>;\n /** Browser: wait for explicit authenticate() instead of auto popup. */\n preventAutoAuth?: boolean;\n /** Browser: full-page redirect instead of popup. */\n useRedirectFlow?: boolean;\n /** Browser: same-origin OAuth BFF base URL. */\n oauthProxyUrl?: string;\n /** Whether browser OAuth HTTP uses `oauthProxyUrl`. Defaults to `true` when the URL is set. */\n proxyOAuthRequests?: boolean;\n}\n\n/**\n * Configures a remote MCP server accessed with streamable HTTP.\n */\nexport interface HttpServerConfig extends BaseServerConfig {\n /** MCP endpoint URL. */\n url: string;\n /** Headers included with MCP transport requests. */\n headers?: Record<string, string>;\n /** Fetch implementation used by the HTTP transport. */\n fetch?: typeof fetch;\n /** Bearer token added as the `Authorization` header. */\n authToken?: string;\n /** Connection timeout in milliseconds. */\n timeout?: number;\n /** OAuth provider used when the server requires authorization. */\n authProvider?: AuthProvider | OAuthClientProvider;\n /**\n * Auto-OAuth options for HTTP servers.\n * - omit / `{}`: client creates the platform provider on connect\n * - `false`: disable auto-OAuth (e.g. CLI `--no-oauth`)\n * - object: forwarded to `createOAuthProvider`\n *\n * Ignored when `authProvider` or `authToken` is set, or when `headers`\n * already includes `Authorization`.\n */\n oauth?: AutoOAuthOptions | false;\n /**\n * Detect mixed-auth servers after an anonymous connection by using the\n * official SDK's RFC 9728 protected-resource metadata discovery.\n * @defaultValue true\n */\n detectMixedAuth?: boolean;\n /**\n * Protocol version negotiation mode. Defaults to `\"auto\"` to negotiate both\n * v1 and v2 MCP servers. See {@link HttpConnector}.\n */\n protocolNegotiation?: VersionNegotiationMode;\n}\n\n/**\n * Tests whether the client should create an OAuth provider for an HTTP server.\n *\n * @param serverConfig - Server configuration to inspect.\n * @returns `true` for an HTTP configuration without explicit authorization.\n */\nexport function shouldAutoProvisionOAuth(\n serverConfig: ServerConfig\n): serverConfig is HttpServerConfig {\n if (!(\"url\" in serverConfig) || typeof serverConfig.url !== \"string\") {\n return false;\n }\n if (serverConfig.authProvider) return false;\n if (serverConfig.authToken) return false;\n if (serverConfig.oauth === false) return false;\n const headers = serverConfig.headers;\n if (headers) {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === \"authorization\") return false;\n }\n }\n return true;\n}\n\n/**\n * Configuration for either a local stdio server or a remote HTTP server.\n */\nexport type ServerConfig = StdioServerConfig | HttpServerConfig;\n\n/**\n * Top-level MCP client configuration.\n *\n * Callback and client identity values act as defaults for individual servers.\n */\nexport interface MCPClientConfigShape extends CallbackConfig {\n /** Default client identity for all servers; overridable per server. */\n clientInfo?: ClientInfo;\n /** Server configurations keyed by the name used in client methods. */\n mcpServers?: Record<string, ServerConfig>;\n}\n\n/**\n * Default clientInfo for mcp-use\n */\nfunction getDefaultClientInfo(): ClientInfo {\n return {\n name: \"mcp-use\",\n title: \"mcp-use\",\n version: getPackageVersion(),\n description:\n \"mcp-use is a complete TypeScript framework for building and using MCP\",\n icons: [\n {\n src: \"https://mcp-use.com/logo.png\",\n },\n ],\n websiteUrl: \"https://mcp-use.com\",\n };\n}\n\n/**\n * Normalizes a client identity and fills optional metadata with package defaults.\n *\n * @param input - Candidate client identity.\n * @returns The supplied identity merged with defaults, or the complete default\n * identity when `input` does not contain both `name` and `version`.\n */\nexport function normalizeClientInfo(input: unknown): ClientInfo {\n const fallback = getDefaultClientInfo();\n if (!input || typeof input !== \"object\") return fallback;\n const ci = input as Partial<ClientInfo>;\n // Require name + version (SDK/client contract)\n if (!ci.name || !ci.version) return fallback;\n return { ...fallback, ...ci };\n}\n\n/**\n * Expands the `capabilities.views` shorthand into the MCP Apps extension.\n *\n * @param clientOptions - SDK client options to normalize.\n * @returns Normalized options, or `undefined` when no options were supplied.\n */\nexport function resolveClientOptions(\n clientOptions: ClientOptions | undefined\n): ClientOptions | undefined {\n const capabilities = clientOptions?.capabilities as\n | Record<string, unknown>\n | undefined;\n if (!capabilities || capabilities.views !== true) return clientOptions;\n\n const { views: _views, ...capsWithoutViews } = capabilities;\n const extensions =\n capsWithoutViews.extensions &&\n typeof capsWithoutViews.extensions === \"object\" &&\n !Array.isArray(capsWithoutViews.extensions)\n ? { ...(capsWithoutViews.extensions as Record<string, unknown>) }\n : {};\n\n return {\n ...clientOptions,\n capabilities: {\n ...capsWithoutViews,\n extensions: {\n ...extensions,\n \"io.modelcontextprotocol/ui\": {\n mimeTypes: [\"text/html;profile=mcp-app\"],\n },\n },\n },\n };\n}\n\n/**\n * Creates an HTTP connector from a runtime-neutral server configuration.\n *\n * @param serverConfig - Server configuration to convert.\n * @param connectorOptions - Connector options that override derived values.\n * @returns An HTTP connector for the configured endpoint.\n * @throws When `serverConfig` is a stdio configuration or has no recognized transport.\n */\nexport function createConnectorFromConfig(\n serverConfig: ServerConfig,\n connectorOptions?: Partial<ConnectorInitOptions>\n): BaseConnector {\n // Normalize clientInfo to ensure required fields are present\n const clientInfo = normalizeClientInfo(serverConfig.clientInfo);\n\n if (\"command\" in serverConfig && \"args\" in serverConfig) {\n throw new Error(\n \"Stdio connector is not supported in this environment. \" +\n \"Stdio connections require Node.js and are only available in the Node.js MCPClient.\"\n );\n }\n\n if (\"url\" in serverConfig) {\n return new HttpConnector(serverConfig.url, {\n headers: serverConfig.headers,\n fetch: serverConfig.fetch,\n authToken: serverConfig.authToken,\n authProvider: serverConfig.authProvider,\n detectMixedAuth: serverConfig.detectMixedAuth,\n protocolNegotiation: serverConfig.protocolNegotiation,\n timeout: serverConfig.timeout,\n roots: serverConfig.roots,\n clientOptions: resolveClientOptions(serverConfig.clientOptions),\n defaultRequestOptions: serverConfig.defaultRequestOptions,\n clientInfo,\n ...connectorOptions,\n });\n }\n\n throw new Error(\"Cannot determine connector type from config\");\n}\n","// browser-provider.ts\nimport {\n extractWWWAuthenticateParams,\n type OAuthClientInformation,\n type OAuthClientInformationContext,\n type OAuthClientMetadata,\n type OAuthClientProvider,\n type OAuthDiscoveryState,\n type OAuthTokens,\n} from \"@modelcontextprotocol/client\";\nimport { LocalStorageKVStore } from \"./storage.js\";\nimport { OAuthSessionStore } from \"./session-store.js\";\n\n/**\n * Serialize request body for proxying\n */\nasync function serializeBody(body: BodyInit): Promise<any> {\n if (typeof body === \"string\") return body;\n if (body instanceof URLSearchParams || body instanceof FormData) {\n return Object.fromEntries(body.entries());\n }\n if (body instanceof Blob) return await body.text();\n return body;\n}\n\nfunction trimTrailingSlashes(value: string): string {\n let end = value.length;\n while (end > 0 && value.charCodeAt(end - 1) === 47) {\n end--;\n }\n return value.slice(0, end);\n}\n\n/** Options for the browser implementation of the SDK `OAuthClientProvider`. */\nexport interface BrowserOAuthOptions {\n /** Prefix used for persisted OAuth keys. */\n storageKeyPrefix?: string;\n /** Human-readable OAuth client name. */\n clientName?: string;\n /** Public website describing the OAuth client. */\n clientUri?: string;\n /** Public OAuth client logo URL. */\n logoUri?: string;\n /** OAuth redirect URI. */\n callbackUrl?: string;\n /** Whether initial connection waits for an explicit authentication action. */\n preventAutoAuth?: boolean;\n /** Whether authorization uses a full-page redirect instead of a popup. */\n useRedirectFlow?: boolean;\n /** Same-origin proxy endpoint for OAuth HTTP requests. */\n oauthProxyUrl?: string;\n /** MCP proxy URL the transport connected to, used to re-anchor discovery. */\n connectionUrl?: string;\n /** HTTPS URL serving this public client's metadata document for CIMD. */\n clientMetadataUrl?: string;\n /**\n * When true (default), OAuth requests (.well-known metadata, token,\n * registration, revocation, and introspection) are routed through\n * `oauthProxyUrl` to bypass CORS.\n * The routing is applied only to the scoped fetch returned by\n * {@link BrowserOAuthClientProvider.getProxyFetch}; it never mutates the\n * global `fetch`. Set to false to connect directly even when an OAuth proxy\n * URL is available (e.g. when the MCP gateway already proxies OAuth).\n */\n proxyOAuthRequests?: boolean;\n /**\n * Pre-registered OAuth client information. When set, the SDK skips\n * Dynamic Client Registration and uses this client_id directly.\n * Required for proxy-mode auth servers (e.g. Slack, WorkOS proxy)\n * that strip `registration_endpoint` from metadata.\n */\n staticClientInfo?: OAuthClientInformation;\n /** OAuth scope string forwarded to the SDK via clientMetadata.scope. */\n scope?: string;\n /** Called immediately before the provider opens an authorization popup. */\n onPopupWindow?: (\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void;\n}\n\n/**\n * Browser-compatible OAuth client provider for MCP using localStorage.\n */\nexport class BrowserOAuthClientProvider implements OAuthClientProvider {\n /** Protected MCP server URL associated with this provider. */\n readonly serverUrl: string;\n /** Pre-registered public client information, when configured. */\n readonly staticClientInfo?: OAuthClientInformation;\n private session: OAuthSessionStore;\n private readonly storage: LocalStorageKVStore;\n\n // Browser-only state\n /** Whether initial connection waits for explicit authentication. */\n readonly preventAutoAuth?: boolean;\n private useRedirectFlow?: boolean;\n private oauthProxyUrl?: string;\n private connectionUrl?: string;\n private proxyOAuthRequests: boolean;\n private lastAttemptedAuthUrl: string | null = null;\n private authorizationPending = false;\n /** Latest protected-resource metadata URL advertised by an MCP 401. */\n private challengedResourceMetadataUrl: string | undefined;\n /** Callback invoked immediately before an authorization popup opens. */\n readonly onPopupWindow:\n | ((\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void)\n | undefined;\n\n constructor(serverUrl: string, options: BrowserOAuthOptions = {}) {\n if (options.staticClientInfo?.client_secret) {\n throw new Error(\n \"Browser OAuth clients must be public clients; staticClientInfo.client_secret is not allowed.\"\n );\n }\n this.serverUrl = serverUrl;\n this.storage = new LocalStorageKVStore();\n this.session = new OAuthSessionStore(\n serverUrl,\n { ...options, allowClientSecret: false },\n this.storage\n );\n this.preventAutoAuth = options.preventAutoAuth;\n this.useRedirectFlow = options.useRedirectFlow;\n this.oauthProxyUrl = options.oauthProxyUrl;\n this.connectionUrl = options.connectionUrl;\n this.proxyOAuthRequests = options.proxyOAuthRequests ?? true;\n this.staticClientInfo = options.staticClientInfo;\n this.onPopupWindow = options.onPopupWindow;\n }\n\n // --- Identity / key fields exposed for callback handling ---\n\n /** Prefix used for persisted OAuth keys. */\n get storageKeyPrefix(): string {\n return this.session.storageKeyPrefix;\n }\n\n /** Stable hash used to namespace storage for this server. */\n get serverUrlHash(): string {\n return this.session.serverUrlHash;\n }\n\n /** Human-readable OAuth client name. */\n get clientName(): string {\n return this.session.clientName;\n }\n\n /** Public website describing the OAuth client. */\n get clientUri(): string {\n return this.session.clientUri;\n }\n\n /** Public OAuth client logo URL. */\n get logoUri(): string {\n return this.session.logoUri;\n }\n\n /** OAuth redirect URI. */\n get callbackUrl(): string {\n return this.session.callbackUrl;\n }\n\n /** Space-delimited OAuth scopes requested by the client. */\n get scope(): string | undefined {\n return this.session.scope;\n }\n\n get clientMetadataUrl(): string | undefined {\n return this.session.clientMetadataUrl;\n }\n\n /**\n * Returns a provider-scoped storage key.\n *\n * @param keySuffix - Suffix identifying the stored value.\n * @returns Namespaced storage key.\n */\n getKey(keySuffix: string): string {\n return this.session.getKey(keySuffix);\n }\n\n /** Whether an authorization flow is awaiting completion. */\n get hasPendingFlow(): boolean {\n return this.authorizationPending;\n }\n\n /** Marks the current authorization flow as complete. */\n markFlowComplete(): void {\n this.authorizationPending = false;\n }\n\n /**\n * Re-anchor an SDK-derived OAuth discovery URL from the MCP connection\n * (proxy) origin onto the actual MCP server.\n *\n * When MCP traffic is tunneled through a gateway/inspector proxy, the SDK\n * transport derives `/.well-known/*` URLs from the URL it connected to (the\n * proxy) whenever no `resource_metadata` hint is available — the SSE\n * transport's EventSource cannot read `WWW-Authenticate`, and token refresh\n * runs without a 401 response at hand. The proxy origin serves no OAuth\n * metadata, so discovery would fail and the server would be misclassified\n * as \"does not support OAuth\". Rewriting reproduces what a direct\n * connection would have requested: the same well-known document, anchored\n * on the server origin, with the RFC 8414 §3.1 / RFC 9728 §3.1 path\n * insertion using the server's path instead of the proxy's.\n */\n private reanchorWellKnownUrl(url: string): string {\n if (!this.connectionUrl) return url;\n try {\n const requested = new URL(url);\n const connection = new URL(this.connectionUrl);\n if (requested.origin !== connection.origin) return url;\n if (!requested.pathname.startsWith(\"/.well-known/\")) return url;\n\n const target = new URL(this.serverUrl);\n const rest = requested.pathname.slice(\"/.well-known/\".length);\n const [doc, ...suffixParts] = rest.split(\"/\");\n if (!doc) return url;\n\n const suffix = suffixParts.length ? `/${suffixParts.join(\"/\")}` : \"\";\n const connectionPath = trimTrailingSlashes(connection.pathname);\n const targetPath = trimTrailingSlashes(target.pathname);\n // Path-insertion form: swap the proxy's inserted path for the server's.\n // Root form (no suffix) stays root. Unrelated suffixes are preserved.\n const newSuffix =\n suffix && suffix === connectionPath ? targetPath : suffix;\n\n return `${target.origin}/.well-known/${doc}${newSuffix}${requested.search}`;\n } catch {\n return url;\n }\n }\n\n private rememberResourceMetadataChallenge(response: Response): boolean {\n if (response.status !== 401) return false;\n const { resourceMetadataUrl } = extractWWWAuthenticateParams(response);\n if (!resourceMetadataUrl) return false;\n this.challengedResourceMetadataUrl = resourceMetadataUrl.toString();\n return true;\n }\n\n /**\n * Returns a `fetch` function, scoped to this provider, that routes OAuth\n * metadata and non-browser OAuth endpoint requests through the configured\n * `oauthProxyUrl` to bypass CORS. Authorization endpoints are navigated by\n * the browser and all unrelated requests pass through unchanged.\n *\n * Unlike patching the global `fetch`, the returned function only affects the\n * transport/auth calls it is explicitly handed to (via the SDK transport's\n * `fetch` option or `auth({ fetchFn })`). Connecting one server \"Via Proxy\"\n * therefore never alters fetch behavior for other servers, other\n * connections, or the rest of the page.\n *\n * OAuth metadata is always fetched with `cache: \"no-store\"`, including in\n * direct mode. Authorization servers commonly vary CORS headers by Origin;\n * bypassing the browser HTTP cache prevents a revalidated response cached\n * for another localhost origin from poisoning discovery. When OAuth proxying\n * is disabled or no `oauthProxyUrl` is configured, all requests still go\n * directly to their original URLs.\n *\n * @param baseFetch - The fetch used for non-OAuth requests and for the\n * underlying proxy calls. Defaults to the global `fetch`.\n */\n getProxyFetch(baseFetch?: typeof fetch): typeof fetch | undefined {\n const base: typeof fetch = baseFetch ?? globalThis.fetch.bind(globalThis);\n const oauthProxyUrl =\n this.proxyOAuthRequests && this.oauthProxyUrl\n ? this.oauthProxyUrl\n : undefined;\n const discoveredEndpoints = new Set<string>();\n let restoredDiscovery = false;\n\n // Create scoped fetch\n return async (\n input: RequestInfo | URL,\n init?: RequestInit\n ): Promise<Response> => {\n const requestedUrl =\n typeof input === \"string\"\n ? input\n : input instanceof URL\n ? input.toString()\n : input.url;\n\n // The SDK derives discovery URLs from the transport URL. Re-anchor URLs\n // derived from an MCP proxy onto the actual MCP server before routing.\n const url = this.reanchorWellKnownUrl(requestedUrl);\n\n let pathname: string;\n try {\n pathname = new URL(url).pathname;\n } catch {\n return await base(input, init);\n }\n const isMetadata = pathname.includes(\"/.well-known/\");\n\n // Metadata responses can carry Origin-specific CORS headers. Never let\n // the browser reuse or revalidate a response cached for another origin.\n // This is scoped to discovery; MCP traffic and OAuth endpoint POSTs keep\n // their caller-provided cache behavior.\n if (!oauthProxyUrl) {\n const response = await base(\n isMetadata ? url : input,\n isMetadata ? { ...init, cache: \"no-store\" } : init\n );\n if (!isMetadata) this.rememberResourceMetadataChallenge(response);\n return response;\n }\n\n if (!restoredDiscovery) {\n restoredDiscovery = true;\n const metadata = (await this.discoveryState())\n ?.authorizationServerMetadata as Record<string, unknown> | undefined;\n for (const key of [\n \"registration_endpoint\",\n \"token_endpoint\",\n \"revocation_endpoint\",\n \"introspection_endpoint\",\n ]) {\n if (typeof metadata?.[key] === \"string\") {\n discoveredEndpoints.add(metadata[key]);\n }\n }\n }\n const isProxiedEndpoint =\n discoveredEndpoints.has(url) ||\n /\\/(?:register|registration|token|revoke|revocation|introspect|introspection)\\/?$/.test(\n pathname\n );\n\n if (!isMetadata && !isProxiedEndpoint) {\n const response = await base(input, init);\n if (this.rememberResourceMetadataChallenge(response)) {\n // Endpoints restored before the MCP request may belong to discovery\n // that the fresh challenge has just made stale. Fresh metadata will\n // repopulate this routing set as the SDK rediscovers it.\n discoveredEndpoints.clear();\n }\n return response;\n }\n\n // Don't intercept requests already going to our OAuth proxy (avoid circular proxying)\n // Check if the URL is pointing to our OAuth proxy endpoint\n try {\n const urlObj = new URL(url);\n const proxyUrlObj = new URL(oauthProxyUrl);\n // If the request is going to the same origin and path as our OAuth proxy, don't intercept\n if (\n urlObj.origin === proxyUrlObj.origin &&\n (urlObj.pathname.startsWith(proxyUrlObj.pathname) ||\n url.includes(\"/inspector/api/oauth\"))\n ) {\n return await base(input, init);\n }\n } catch {\n // If URL parsing fails, continue with interception (better safe than sorry)\n }\n\n const proxyEndpoint = isMetadata\n ? `${oauthProxyUrl}/metadata?serverUrl=${encodeURIComponent(\n this.serverUrl\n )}&url=${encodeURIComponent(url)}`\n : `${oauthProxyUrl}/proxy`;\n\n if (isMetadata) {\n const response = await base(proxyEndpoint, {\n ...init,\n method: \"GET\",\n cache: \"no-store\",\n });\n try {\n const metadata = (await response.clone().json()) as Record<\n string,\n unknown\n >;\n for (const key of [\n \"registration_endpoint\",\n \"token_endpoint\",\n \"revocation_endpoint\",\n \"introspection_endpoint\",\n ]) {\n if (typeof metadata[key] === \"string\") {\n discoveredEndpoints.add(metadata[key]);\n }\n }\n } catch {\n // The SDK owns metadata validation and will reject malformed responses.\n }\n return response;\n }\n\n const inputRequest = input instanceof Request ? input : undefined;\n const method = init?.method ?? inputRequest?.method ?? \"POST\";\n const requestHeaders = init?.headers ?? inputRequest?.headers;\n let body: unknown;\n if (init?.body !== undefined && init.body !== null) {\n body = await serializeBody(init.body);\n } else if (inputRequest?.body && method !== \"GET\" && method !== \"HEAD\") {\n body = await inputRequest.clone().text();\n }\n const response = await base(proxyEndpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n serverUrl: this.serverUrl,\n url,\n method,\n headers: requestHeaders\n ? Object.fromEntries(new Headers(requestHeaders as HeadersInit))\n : {},\n body,\n }),\n });\n const data = (await response.json()) as {\n status?: unknown;\n statusText?: unknown;\n headers?: unknown;\n body?: unknown;\n };\n if (!response.ok || typeof data.status !== \"number\") {\n return new Response(JSON.stringify(data), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n return new Response(JSON.stringify(data.body), {\n status: data.status,\n statusText:\n typeof data.statusText === \"string\" ? data.statusText : undefined,\n headers: new Headers(\n data.headers && typeof data.headers === \"object\"\n ? (data.headers as HeadersInit)\n : undefined\n ),\n });\n };\n }\n\n // --- SDK Interface Methods (delegated) ---\n\n get redirectUrl(): string {\n return this.session.redirectUrl;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return this.session.clientMetadata;\n }\n\n tokens(\n ctx?: OAuthClientInformationContext\n ): Promise<OAuthTokens | undefined> {\n return this.session.tokens(ctx);\n }\n\n saveTokens(\n tokens: OAuthTokens,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n this.lastAttemptedAuthUrl = null;\n this.authorizationPending = false;\n return this.session.saveTokens(tokens, ctx);\n }\n\n /**\n * Returns the configured or dynamically registered OAuth client information.\n *\n * @param ctx - Optional registration context.\n * @returns OAuth client information, or `undefined` when not registered.\n */\n async clientInformation(\n ctx?: OAuthClientInformationContext\n ): Promise<OAuthClientInformation | undefined> {\n // Pre-registered client info (proxy-mode servers like Slack/WorkOS proxy\n // strip registration_endpoint, so DCR is not an option). When set, this\n // bypasses any stored DCR result so a stale localStorage entry can't\n // shadow the configured client_id.\n if (this.staticClientInfo) return this.staticClientInfo;\n return this.session.clientInformation(ctx);\n }\n\n /**\n * Persists public OAuth client registration information.\n *\n * Static client configuration takes precedence, and browser providers discard\n * any client secret returned for a public client.\n *\n * @param clientInformation - Registration information to save.\n * @param ctx - Optional registration context.\n */\n async saveClientInformation(\n clientInformation: OAuthClientInformation,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n // When a pre-registered client_id is configured, never persist DCR results\n // — the static client_id is the source of truth.\n if (this.staticClientInfo) return;\n\n // Browser clients always register as public clients\n // (`token_endpoint_auth_method: \"none\"`). Some authorization servers,\n // including Auth0 DCR, still include a generated client_secret in the\n // registration response even though the public client must not use or\n // retain it. Persist only the public portion of the response. Keep the\n // session store's secret rejection intact as a defense-in-depth guard for\n // every other browser persistence path.\n const { client_secret: discardedClientSecret, ...publicClientInformation } =\n clientInformation;\n if (discardedClientSecret) {\n console.info(\n `[${this.storageKeyPrefix}] Discarded client_secret returned for a public browser OAuth client.`\n );\n }\n return this.session.saveClientInformation(\n publicClientInformation as OAuthClientInformation,\n ctx\n );\n }\n\n codeVerifier(): Promise<string> {\n return this.session.codeVerifier();\n }\n\n saveCodeVerifier(codeVerifier: string): Promise<void> {\n return this.session.saveCodeVerifier(codeVerifier);\n }\n\n invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"\n ): Promise<void> {\n return this.session.invalidateCredentials(scope);\n }\n\n /**\n * Persist OAuth discovery state (SEP-2352). Delegated to the session store;\n * implementing this silences the SDK's per-callback warning and enables the\n * authorization-server mix-up defense on the callback leg.\n */\n saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n return this.session.saveDiscoveryState(state);\n }\n\n /** Return previously saved OAuth discovery state, or `undefined`. */\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n const state = await this.session.discoveryState();\n const challengedUrl = this.challengedResourceMetadataUrl;\n this.challengedResourceMetadataUrl = undefined;\n\n if (challengedUrl && state) {\n // A fresh MCP challenge is authoritative. RFC 9728 section 5.2 says it\n // can indicate that protected-resource metadata has changed even when\n // the metadata URL itself is unchanged. Always rediscover after such a\n // challenge instead of trusting a complete-but-stale persisted document.\n // Let the SDK rediscover from the challenge while preserving issuer-keyed\n // tokens and client registrations until normal issuer validation decides\n // whether either credential is reusable.\n await this.session.invalidateCredentials(\"discovery\");\n return undefined;\n }\n\n return state;\n }\n\n /**\n * Return the token endpoint from the SDK's persisted discovery state.\n * Returns `null` before a successful authorization discovery.\n */\n getTokenEndpoint(): Promise<string | null> {\n return this.session.getTokenEndpoint();\n }\n\n /** Return the protected-resource URL selected during OAuth discovery. */\n getResource(): Promise<string | null> {\n return this.session.getResource();\n }\n\n /**\n * Return the stored public OAuth client ID. Browser providers do not retain\n * client secrets.\n */\n async getClientCredentials(): Promise<{\n /** Public OAuth client identifier. */\n client_id: string;\n } | null> {\n const info = await this.clientInformation();\n return info?.client_id ? { client_id: info.client_id } : null;\n }\n\n /**\n * Generates and persists `StoredState` for an authorization request,\n * and returns the sanitized URL with the `state` param appended. Does NOT\n * open a popup or redirect —\n * use `redirectToAuthorization` for that.\n */\n async prepareAuthorizationUrl(authorizationUrl: URL): Promise<string> {\n const prepared = await this.session.storeAuthorizationState(\n authorizationUrl,\n {\n extraProviderOptions: {\n oauthProxyUrl: this.oauthProxyUrl,\n ...(this.clientMetadataUrl\n ? { clientMetadataUrl: this.clientMetadataUrl }\n : {}),\n ...(this.staticClientInfo\n ? { staticClientInfo: this.staticClientInfo }\n : {}),\n ...(this.scope ? { scope: this.scope } : {}),\n },\n flowType: this.useRedirectFlow ? \"redirect\" : \"popup\",\n returnUrl:\n typeof window !== \"undefined\" ? window.location.href : undefined,\n }\n );\n this.lastAttemptedAuthUrl = prepared;\n this.authorizationPending = true;\n return prepared;\n }\n\n /**\n * Redirects the user agent to the authorization URL, storing necessary state.\n * @param authorizationUrl - The fully constructed authorization URL from the SDK.\n */\n async redirectToAuthorization(authorizationUrl: URL): Promise<void> {\n await this.prepareAuthorizationUrl(authorizationUrl);\n\n // If auto-auth is prevented, just store the URL but don't redirect/popup\n if (this.preventAutoAuth) {\n console.info(\n `[${this.storageKeyPrefix}] Auto-auth prevented. Authorization URL stored for manual trigger.`\n );\n return;\n }\n\n this.startAuthorization();\n }\n\n /**\n * Open the authorization URL prepared by the official SDK.\n *\n * This is the explicit-user-action counterpart to `preventAutoAuth`: the\n * provider still lets the SDK own discovery and PKCE state, while a host can\n * launch the stored authorization request later from an Authenticate button.\n */\n startAuthorization(): void {\n const authorizationUrl = this.lastAttemptedAuthUrl;\n if (!authorizationUrl) {\n throw new Error(\"No prepared OAuth authorization is available\");\n }\n\n // Use redirect flow if enabled (avoids popup blockers)\n if (this.useRedirectFlow) {\n console.info(\n `[${this.storageKeyPrefix}] Redirecting to authorization URL (full-page redirect).`\n );\n window.location.href = authorizationUrl;\n return;\n }\n\n // Otherwise, use popup flow (legacy behavior)\n const popupFeatures =\n \"width=600,height=700,resizable=yes,scrollbars=yes,status=yes\";\n try {\n const popup = window.open(\n authorizationUrl,\n `mcp_auth_${this.serverUrlHash}`,\n popupFeatures\n );\n\n if (this.onPopupWindow) {\n this.onPopupWindow(authorizationUrl, popupFeatures, popup);\n }\n\n if (!popup || popup.closed || typeof popup.closed === \"undefined\") {\n console.warn(\n `[${this.storageKeyPrefix}] Popup likely blocked by browser. Manual navigation might be required using the stored URL.`\n );\n } else {\n popup.focus();\n console.info(\n `[${this.storageKeyPrefix}] Redirecting to authorization URL in popup.`\n );\n }\n } catch (e) {\n console.error(\n `[${this.storageKeyPrefix}] Error opening popup window:`,\n e\n );\n }\n }\n\n /**\n * Retrieves the last URL passed to `redirectToAuthorization`. Useful for manual fallback.\n */\n getLastAttemptedAuthUrl(): string | null {\n return this.lastAttemptedAuthUrl;\n }\n\n /**\n * Removes OAuth state stored for this server.\n *\n * @returns The number of storage entries removed.\n */\n clearStorage(): number {\n this.lastAttemptedAuthUrl = null;\n this.authorizationPending = false;\n const prefixPattern = `${this.storageKeyPrefix}_${this.serverUrlHash}_`;\n const keysToRemove: string[] = [];\n let count = 0;\n\n for (const key of this.storage.keys()) {\n if (key.startsWith(prefixPattern)) {\n keysToRemove.push(key);\n }\n }\n\n const uniqueKeysToRemove = [...new Set(keysToRemove)];\n uniqueKeysToRemove.forEach((key) => {\n this.storage.remove(key);\n count++;\n });\n return count;\n }\n}\n\n/**\n * Creates the browser OAuth provider used by the root client entry.\n */\nexport async function createOAuthProvider(\n serverUrl: string,\n options: BrowserOAuthOptions = {}\n): Promise<OAuthClientProvider> {\n return new BrowserOAuthClientProvider(serverUrl, options);\n}\n\nexport type { BrowserOAuthOptions as OAuthProviderOptions };\n","/**\n * Minimal key/value storage abstraction used by OAuthSessionStore.\n *\n * Browser-safe module — Node filesystem KV lives in `storage-file.ts`.\n *\n * @internal\n */\nexport interface KVStore {\n get(key: string): Promise<string | null> | string | null;\n set(key: string, value: string): Promise<void> | void;\n remove(key: string): Promise<void> | void;\n keys(): Promise<string[]> | string[];\n}\n\ntype EncryptedEnvelope = {\n v: 1;\n alg: \"A256GCM\";\n iv: string;\n ciphertext: string;\n};\n\nconst AUTH_CRYPTO_DATABASE = \"mcp-use-oauth-crypto\";\nconst AUTH_CRYPTO_STORE = \"keys\";\nconst AUTH_CRYPTO_KEY = \"aes-gcm-v1\";\nconst textEncoder = new TextEncoder();\nconst textDecoder = new TextDecoder();\n\n/**\n * Encrypted `KVStore` backed by `globalThis.localStorage`.\n *\n * Values use AES-256-GCM with a non-extractable origin key held by IndexedDB.\n * Legacy plaintext values are encrypted on first read. When durable browser\n * cryptography is unavailable, the store removes plaintext and falls back to\n * memory for the lifetime of this instance.\n *\n * @internal\n */\nexport class LocalStorageKVStore implements KVStore {\n private readonly fallback = new Map<string, string>();\n private keyPromise: Promise<CryptoKey> | undefined;\n private durable = true;\n\n async get(key: string): Promise<string | null> {\n if (!this.durable) return this.fallback.get(key) ?? null;\n\n let stored: string | null;\n try {\n stored = localStorage.getItem(key);\n } catch {\n this.durable = false;\n return this.fallback.get(key) ?? null;\n }\n if (stored === null) return null;\n\n const envelope = parseEncryptedEnvelope(stored);\n if (!envelope) {\n await this.set(key, stored);\n return stored;\n }\n\n try {\n const cryptoKey = await this.getCryptoKey();\n const plaintext = await globalThis.crypto.subtle.decrypt(\n {\n name: \"AES-GCM\",\n iv: decodeBase64(envelope.iv),\n additionalData: textEncoder.encode(key),\n },\n cryptoKey,\n decodeBase64(envelope.ciphertext)\n );\n return textDecoder.decode(plaintext);\n } catch {\n await this.remove(key);\n return null;\n }\n }\n\n async set(key: string, value: string): Promise<void> {\n if (!this.durable) {\n this.fallback.set(key, value);\n return;\n }\n\n try {\n const cryptoKey = await this.getCryptoKey();\n const iv = globalThis.crypto.getRandomValues(new Uint8Array(12));\n const ciphertext = await globalThis.crypto.subtle.encrypt(\n {\n name: \"AES-GCM\",\n iv,\n additionalData: textEncoder.encode(key),\n },\n cryptoKey,\n textEncoder.encode(value)\n );\n const envelope: EncryptedEnvelope = {\n v: 1,\n alg: \"A256GCM\",\n iv: encodeBase64(iv),\n ciphertext: encodeBase64(new Uint8Array(ciphertext)),\n };\n localStorage.setItem(key, JSON.stringify(envelope));\n this.fallback.delete(key);\n } catch {\n this.durable = false;\n try {\n localStorage.removeItem(key);\n } catch {\n // Storage may be disabled entirely.\n }\n this.fallback.set(key, value);\n }\n }\n\n remove(key: string): void {\n this.fallback.delete(key);\n try {\n localStorage.removeItem(key);\n } catch {\n this.durable = false;\n }\n }\n\n keys(): string[] {\n const out = new Set(this.fallback.keys());\n if (this.durable) {\n try {\n for (let i = 0; i < localStorage.length; i++) {\n const key = localStorage.key(i);\n if (key) out.add(key);\n }\n } catch {\n this.durable = false;\n }\n }\n return [...out];\n }\n\n private getCryptoKey(): Promise<CryptoKey> {\n this.keyPromise ??= getOrCreateCryptoKey();\n return this.keyPromise;\n }\n}\n\nfunction parseEncryptedEnvelope(value: string): EncryptedEnvelope | undefined {\n try {\n const parsed: unknown = JSON.parse(value);\n if (\n !parsed ||\n typeof parsed !== \"object\" ||\n !(\"v\" in parsed) ||\n parsed.v !== 1 ||\n !(\"alg\" in parsed) ||\n parsed.alg !== \"A256GCM\" ||\n !(\"iv\" in parsed) ||\n typeof parsed.iv !== \"string\" ||\n !(\"ciphertext\" in parsed) ||\n typeof parsed.ciphertext !== \"string\"\n ) {\n return undefined;\n }\n return parsed as EncryptedEnvelope;\n } catch {\n return undefined;\n }\n}\n\nasync function getOrCreateCryptoKey(): Promise<CryptoKey> {\n if (!globalThis.crypto?.subtle || typeof indexedDB === \"undefined\") {\n throw new Error(\"Durable browser cryptography is unavailable\");\n }\n\n const candidate = await globalThis.crypto.subtle.generateKey(\n { name: \"AES-GCM\", length: 256 },\n false,\n [\"encrypt\", \"decrypt\"]\n );\n const database = await openCryptoDatabase();\n try {\n return await new Promise<CryptoKey>((resolve, reject) => {\n const transaction = database.transaction(AUTH_CRYPTO_STORE, \"readwrite\");\n const store = transaction.objectStore(AUTH_CRYPTO_STORE);\n const request = store.get(AUTH_CRYPTO_KEY);\n let selected: CryptoKey | undefined;\n\n request.onsuccess = () => {\n selected = request.result as CryptoKey | undefined;\n if (!selected) {\n selected = candidate;\n store.put(candidate, AUTH_CRYPTO_KEY);\n }\n };\n request.onerror = () => reject(request.error);\n transaction.oncomplete = () => {\n if (selected) resolve(selected);\n else reject(new Error(\"OAuth encryption key was not initialized\"));\n };\n transaction.onerror = () => reject(transaction.error);\n transaction.onabort = () => reject(transaction.error);\n });\n } finally {\n database.close();\n }\n}\n\nfunction openCryptoDatabase(): Promise<IDBDatabase> {\n return new Promise((resolve, reject) => {\n const request = indexedDB.open(AUTH_CRYPTO_DATABASE, 1);\n request.onupgradeneeded = () => {\n const database = request.result;\n if (!database.objectStoreNames.contains(AUTH_CRYPTO_STORE)) {\n database.createObjectStore(AUTH_CRYPTO_STORE);\n }\n };\n request.onsuccess = () => resolve(request.result);\n request.onerror = () => reject(request.error);\n request.onblocked = () =>\n reject(new Error(\"OAuth encryption database is blocked\"));\n });\n}\n\nfunction encodeBase64(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) binary += String.fromCharCode(byte);\n return btoa(binary);\n}\n\nfunction decodeBase64(value: string): Uint8Array<ArrayBuffer> {\n const binary = atob(value);\n const bytes = new Uint8Array(binary.length);\n for (let index = 0; index < binary.length; index++) {\n bytes[index] = binary.charCodeAt(index);\n }\n return bytes;\n}\n","import type {\n OAuthClientInformation,\n OAuthClientInformationContext,\n OAuthClientMetadata,\n OAuthDiscoveryState,\n StoredOAuthTokens,\n} from \"@modelcontextprotocol/client\";\nimport { validateClientMetadataUrl } from \"@modelcontextprotocol/client\";\nimport { sanitizeUrl } from \"./url.js\";\nimport type { KVStore } from \"./storage.js\";\n\n/**\n * Internal type for storing OAuth state during the OAuth flow.\n * @internal\n */\nexport interface StoredState {\n expiry: number;\n serverUrlHash: string;\n providerOptions: {\n serverUrl: string;\n storageKeyPrefix: string;\n clientName: string;\n clientUri: string;\n callbackUrl: string;\n oauthProxyUrl?: string;\n clientMetadataUrl?: string;\n staticClientInfo?: OAuthClientInformation;\n scope?: string;\n };\n flowType?: \"popup\" | \"redirect\";\n returnUrl?: string;\n}\n\n/**\n * Common options for OAuthSessionStore.\n *\n * @internal\n */\nexport interface OAuthSessionStoreOptions {\n /** Prefix used for persisted OAuth keys. */\n storageKeyPrefix?: string;\n /** Human-readable OAuth client name. */\n clientName?: string;\n /** Public website describing the OAuth client. */\n clientUri?: string;\n /** Public OAuth client logo URL. */\n logoUri?: string;\n /** OAuth redirect URI. */\n callbackUrl?: string;\n /** OAuth Client ID Metadata Document URL. */\n clientMetadataUrl?: string;\n /** Whether this platform may persist confidential-client credentials. */\n allowClientSecret?: boolean;\n /** OAuth scope string forwarded to the SDK via clientMetadata.scope. */\n scope?: string;\n}\n\n/**\n * Options passed by the platform provider when persisting an authorization\n * request prior to redirecting the user agent.\n *\n * @internal\n */\ninterface StoreAuthorizationStateOptions {\n /**\n * Platform-specific provider options that should round-trip through the\n * stored state so the callback handler can rebuild the provider.\n */\n extraProviderOptions?: Record<string, unknown>;\n flowType?: \"popup\" | \"redirect\";\n returnUrl?: string;\n}\n\n/**\n * Platform-neutral helper that owns OAuth session persistence and refresh\n * logic. Used by `BrowserOAuthClientProvider` and `NodeOAuthClientProvider`\n * — each platform provider implements `OAuthClientProvider` directly and\n * delegates the generic methods here.\n *\n * @internal\n */\nexport class OAuthSessionStore {\n readonly serverUrl: string;\n readonly storageKeyPrefix: string;\n readonly serverUrlHash: string;\n readonly clientName: string;\n readonly clientUri: string;\n readonly logoUri: string;\n readonly callbackUrl: string;\n readonly clientMetadataUrl?: string;\n readonly scope?: string;\n\n private store: KVStore;\n private allowClientSecret: boolean;\n\n constructor(\n serverUrl: string,\n options: OAuthSessionStoreOptions,\n store: KVStore\n ) {\n validateClientMetadataUrl(options.clientMetadataUrl);\n this.serverUrl = serverUrl;\n this.storageKeyPrefix = options.storageKeyPrefix || \"mcp:auth\";\n this.serverUrlHash = OAuthSessionStore.hashString(serverUrl);\n this.clientName = options.clientName || \"mcp-use\";\n this.clientUri =\n options.clientUri ||\n (typeof window !== \"undefined\"\n ? window.location.origin\n : \"https://mcp-use.com\");\n this.logoUri = options.logoUri || \"https://mcp-use.com/logo.png\";\n this.callbackUrl = sanitizeUrl(\n options.callbackUrl ||\n (typeof window !== \"undefined\"\n ? new URL(\"/oauth/callback\", window.location.origin).toString()\n : \"/oauth/callback\")\n );\n this.clientMetadataUrl = options.clientMetadataUrl;\n this.scope = options.scope;\n this.store = store;\n this.allowClientSecret = options.allowClientSecret ?? true;\n }\n\n getKey(keySuffix: string): string {\n return `${this.storageKeyPrefix}_${this.serverUrlHash}_${keySuffix}`;\n }\n\n static hashString(str: string): string {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(16);\n }\n\n // --- SDK Interface Methods (delegated) ---\n\n get redirectUrl(): string {\n return this.callbackUrl;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n redirect_uris: [this.redirectUrl],\n token_endpoint_auth_method: \"none\",\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n client_name: this.clientName,\n client_uri: this.clientUri,\n logo_uri: this.logoUri,\n ...(this.scope ? { scope: this.scope } : {}),\n };\n }\n\n private credentialKey(\n kind: \"client_info\" | \"tokens\",\n ctx?: OAuthClientInformationContext\n ): string {\n return ctx\n ? this.getKey(`${kind}_${encodeURIComponent(ctx.issuer)}`)\n : this.getKey(kind);\n }\n\n private async readCredential<T extends { issuer?: string }>(\n kind: \"client_info\" | \"tokens\",\n ctx?: OAuthClientInformationContext\n ): Promise<{ key: string; value: T } | undefined> {\n const key = this.credentialKey(kind, ctx);\n const data = await this.store.get(key);\n if (!data && ctx) {\n const legacyKey = this.credentialKey(kind);\n const legacyData = await this.store.get(legacyKey);\n if (legacyData) {\n try {\n const legacyValue = JSON.parse(legacyData) as T;\n if (!legacyValue.issuer || legacyValue.issuer === ctx.issuer) {\n const migratedValue = {\n ...legacyValue,\n issuer: ctx.issuer,\n };\n const migratedData = JSON.stringify(migratedValue);\n await this.store.set(key, migratedData);\n await this.store.set(legacyKey, migratedData);\n return { key, value: migratedValue };\n }\n } catch {\n await this.store.remove(legacyKey);\n }\n }\n return undefined;\n }\n if (!data) return undefined;\n try {\n return { key, value: JSON.parse(data) as T };\n } catch (e) {\n console.warn(\n `[${this.storageKeyPrefix}] Failed to parse ${kind.replace(\"_\", \" \")}:`,\n e\n );\n await this.store.remove(key);\n return undefined;\n }\n }\n\n async tokens(\n ctx?: OAuthClientInformationContext\n ): Promise<StoredOAuthTokens | undefined> {\n return (await this.readCredential<StoredOAuthTokens>(\"tokens\", ctx))?.value;\n }\n\n async saveTokens(\n tokens: StoredOAuthTokens,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n // Persist tokens BEFORE clearing the verifier / last_auth_url so a failed\n // write can't strand the auth flow with no way to recover.\n const serialized = JSON.stringify(tokens);\n await this.store.set(this.credentialKey(\"tokens\", ctx), serialized);\n // The no-context SDK read is the transport's latest bearer token lookup.\n if (ctx) await this.store.set(this.credentialKey(\"tokens\"), serialized);\n await this.store.remove(this.getKey(\"code_verifier\"));\n await this.store.remove(this.getKey(\"last_auth_url\"));\n await this.store.remove(this.getKey(\"last_auth_callback_url\"));\n }\n\n async clientInformation(\n ctx?: OAuthClientInformationContext\n ): Promise<OAuthClientInformation | undefined> {\n if (!this.allowClientSecret) {\n const registeredRedirectUri = await this.store.get(\n this.getKey(\"client_info_redirect_uri\")\n );\n if (registeredRedirectUri !== this.redirectUrl) {\n await this.invalidateCredentials(\"registration\");\n console.info(\n `[${this.storageKeyPrefix}] Re-registering browser OAuth client after its Inspector callback changed or could not be verified.`\n );\n return undefined;\n }\n }\n\n const stored = await this.readCredential<\n OAuthClientInformation & {\n issuer?: string;\n redirect_uris?: string[];\n client_secret?: string;\n }\n >(\"client_info\", ctx);\n if (!stored) return undefined;\n const { key, value: clientInfo } = stored;\n try {\n if (!this.allowClientSecret && clientInfo.client_secret) {\n await this.invalidateCredentials(\"registration\");\n console.warn(\n `[${this.storageKeyPrefix}] Recovered stale browser OAuth credentials containing a client_secret.`\n );\n return undefined;\n }\n const storedRedirectUris = Array.isArray(clientInfo.redirect_uris)\n ? clientInfo.redirect_uris\n : [];\n // Node clients can retain registrations from servers that omit\n // redirect_uris. Browser clients cannot: the same origin may serve both\n // embedded and standalone Inspectors at different callback paths.\n const hasMatchingRedirect =\n (storedRedirectUris.length === 0 && this.allowClientSecret) ||\n storedRedirectUris.includes(this.redirectUrl);\n\n if (!hasMatchingRedirect) {\n console.info(\n `[${this.storageKeyPrefix}] Recovering cached OAuth credentials after a redirect URI change.`\n );\n await this.invalidateCredentials(\"registration\");\n return undefined;\n }\n\n return clientInfo;\n } catch {\n await this.store.remove(key);\n return undefined;\n }\n }\n\n async saveClientInformation(\n clientInformation: OAuthClientInformation,\n ctx?: OAuthClientInformationContext\n ): Promise<void> {\n const info = clientInformation as OAuthClientInformation & {\n client_secret?: string;\n };\n if (!this.allowClientSecret && info.client_secret) {\n await this.store.remove(this.credentialKey(\"client_info\", ctx));\n if (ctx) await this.store.remove(this.credentialKey(\"client_info\"));\n throw new Error(\n \"Browser OAuth clients must be public clients; client_secret persistence is not allowed.\"\n );\n }\n const persistedClientInformation =\n !this.allowClientSecret &&\n (!(\"redirect_uris\" in clientInformation) ||\n !Array.isArray(\n (clientInformation as { redirect_uris?: unknown }).redirect_uris\n ) ||\n (clientInformation as { redirect_uris: unknown[] }).redirect_uris\n .length === 0)\n ? { ...clientInformation, redirect_uris: [this.redirectUrl] }\n : clientInformation;\n const serialized = JSON.stringify(persistedClientInformation);\n await this.store.set(this.credentialKey(\"client_info\", ctx), serialized);\n if (ctx) {\n await this.store.set(this.credentialKey(\"client_info\"), serialized);\n }\n if (!this.allowClientSecret) {\n await this.store.set(\n this.getKey(\"client_info_redirect_uri\"),\n this.redirectUrl\n );\n }\n }\n\n async saveCodeVerifier(codeVerifier: string): Promise<void> {\n await this.store.set(this.getKey(\"code_verifier\"), codeVerifier);\n }\n\n async codeVerifier(): Promise<string> {\n const key = this.getKey(\"code_verifier\");\n const verifier = await this.store.get(key);\n if (!verifier) {\n throw new Error(\n `[${this.storageKeyPrefix}] Code verifier not found in storage for key ${key}. Auth flow likely corrupted or timed out.`\n );\n }\n return verifier;\n }\n\n async invalidateCredentials(\n scope:\n | \"all\"\n | \"registration\"\n | \"client\"\n | \"tokens\"\n | \"verifier\"\n | \"discovery\"\n ): Promise<void> {\n const removeCredentialKeys = async (\n kind: \"client_info\" | \"tokens\"\n ): Promise<void> => {\n const prefix = `${this.getKey(kind)}_`;\n for (const key of await this.store.keys()) {\n if (key === this.getKey(kind) || key.startsWith(prefix)) {\n await this.store.remove(key);\n }\n }\n };\n\n switch (scope) {\n case \"registration\":\n // The SDK saves freshly discovered issuer metadata before it asks for\n // client information. Preserve that callback-leg binding while\n // replacing stale browser registration and authorization artifacts.\n await removeCredentialKeys(\"tokens\");\n await removeCredentialKeys(\"client_info\");\n await this.store.remove(this.getKey(\"code_verifier\"));\n await this.store.remove(this.getKey(\"last_auth_url\"));\n await this.store.remove(this.getKey(\"last_auth_callback_url\"));\n await this.store.remove(this.getKey(\"client_info_redirect_uri\"));\n await this.store.remove(this.getKey(\"token_endpoint\"));\n break;\n case \"all\":\n await removeCredentialKeys(\"tokens\");\n await removeCredentialKeys(\"client_info\");\n await this.store.remove(this.getKey(\"code_verifier\"));\n await this.store.remove(this.getKey(\"last_auth_url\"));\n await this.store.remove(this.getKey(\"last_auth_callback_url\"));\n await this.store.remove(this.getKey(\"client_info_redirect_uri\"));\n await this.store.remove(this.getKey(\"discovery_state\"));\n await this.store.remove(this.getKey(\"token_endpoint\"));\n break;\n case \"client\":\n await removeCredentialKeys(\"client_info\");\n break;\n case \"tokens\":\n await removeCredentialKeys(\"tokens\");\n break;\n case \"verifier\":\n await this.store.remove(this.getKey(\"code_verifier\"));\n break;\n case \"discovery\":\n await this.store.remove(this.getKey(\"discovery_state\"));\n break;\n default:\n break;\n }\n }\n\n /**\n * Persist the OAuth discovery state (authorization-server metadata resolved\n * during the auth flow). Stored with the same durability as the code\n * verifier so the callback leg can verify it is exchanging the code at the\n * same authorization server the redirect targeted (SEP-2352 mix-up defense).\n */\n async saveDiscoveryState(state: OAuthDiscoveryState): Promise<void> {\n await this.store.set(this.getKey(\"discovery_state\"), JSON.stringify(state));\n }\n\n /** Return the previously saved discovery state, or `undefined`. */\n async discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n const data = await this.store.get(this.getKey(\"discovery_state\"));\n if (!data) return undefined;\n try {\n return JSON.parse(data) as OAuthDiscoveryState;\n } catch {\n await this.store.remove(this.getKey(\"discovery_state\"));\n return undefined;\n }\n }\n\n // --- Helper / non-SDK methods ---\n\n /**\n * Generates and persists `StoredState` for an authorization request,\n * appends the `state` query param to the URL, and persists the sanitized\n * URL to `last_auth_url` so it can be replayed on popup-blocker fallback.\n *\n * @returns The sanitized authorization URL string with the `state` param appended.\n */\n async storeAuthorizationState(\n authorizationUrl: URL,\n opts: StoreAuthorizationStateOptions = {}\n ): Promise<string> {\n const state = globalThis.crypto.randomUUID();\n const stateKey = `${this.storageKeyPrefix}_${this.serverUrlHash}_state_${state}`;\n\n const stateData: StoredState = {\n serverUrlHash: this.serverUrlHash,\n expiry: Date.now() + 1000 * 60 * 10, // State expires in 10 minutes\n providerOptions: {\n serverUrl: this.serverUrl,\n storageKeyPrefix: this.storageKeyPrefix,\n clientName: this.clientName,\n clientUri: this.clientUri,\n callbackUrl: this.callbackUrl,\n ...(this.clientMetadataUrl\n ? { clientMetadataUrl: this.clientMetadataUrl }\n : {}),\n ...(opts.extraProviderOptions ?? {}),\n },\n flowType: opts.flowType,\n returnUrl: opts.returnUrl,\n };\n\n authorizationUrl.searchParams.set(\"state\", state);\n const sanitizedAuthUrl = sanitizeUrl(authorizationUrl.toString());\n\n // Persist the state record BEFORE the last_auth_url so a partial failure\n // can't leave behind an auth URL whose state has no backing record.\n await this.store.set(stateKey, JSON.stringify(stateData));\n await this.store.set(\n this.getKey(\"last_auth_callback_url\"),\n this.redirectUrl\n );\n await this.store.set(this.getKey(\"last_auth_url\"), sanitizedAuthUrl);\n\n return sanitizedAuthUrl;\n }\n\n /**\n * Return the token endpoint from SDK-managed discovery state. The SDK\n * persists this state during `auth()`, avoiding a second discovery flow.\n */\n async getTokenEndpoint(): Promise<string | null> {\n return (\n (await this.discoveryState())?.authorizationServerMetadata\n ?.token_endpoint ?? null\n );\n }\n\n /**\n * Return the protected-resource URL selected during OAuth discovery.\n * Consumers can persist it and reuse it for server-side refresh exchanges.\n */\n async getResource(): Promise<string | null> {\n const resource = (await this.discoveryState())?.resourceMetadata?.resource;\n return typeof resource === \"string\" ? resource : null;\n }\n}\n","/**\n * URL sanitization utility\n *\n * Sanitizes URLs to prevent security issues by:\n * - Restricting to http/https protocols only\n * - Encoding URL components properly\n * - Validating hostnames\n */\n\n/**\n * Sanitizes a URL string by encoding all components and validating the protocol.\n *\n * @param raw - The raw URL string to sanitize\n * @returns The sanitized URL as a string\n * @throws Error if the URL is invalid or uses an unsupported protocol\n */\nexport function sanitizeUrl(raw: string): string {\n const abort = () => {\n throw new Error(`Invalid url to pass to open(): ${raw}`);\n };\n\n let url!: URL;\n\n try {\n url = new URL(raw);\n } catch (_) {\n abort();\n }\n\n // Don't allow any other scheme than http(s)\n if (url.protocol !== \"https:\" && url.protocol !== \"http:\") abort();\n\n // Hostnames can't be updated, but let's reject if they contain anything suspicious\n if (url.hostname !== encodeURIComponent(url.hostname)) abort();\n\n // Forcibly sanitise all the pieces of the URL\n if (url.username) url.username = encodeURIComponent(url.username);\n if (url.password) url.password = encodeURIComponent(url.password);\n url.pathname =\n url.pathname.slice(0, 1) +\n encodeURIComponent(url.pathname.slice(1)).replace(/%2f/gi, \"/\");\n url.search =\n url.search.slice(0, 1) +\n Array.from(url.searchParams.entries()).map(sanitizeParam).join(\"&\");\n url.hash = url.hash.slice(0, 1) + encodeURIComponent(url.hash.slice(1));\n\n return url.href;\n}\n\n/**\n * Helper function to sanitize URL search parameters\n */\nfunction sanitizeParam([k, v]: [string, string]): string {\n return `${encodeURIComponent(k)}${v.length > 0 ? `=${encodeURIComponent(v)}` : \"\"}`;\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/client\";\nimport type { AutoOAuthOptions, CallbackConfig } from \"./config.js\";\nimport { normalizeClientInfo, resolveCallbacks } from \"./config.js\";\nimport type { BaseConnector } from \"../transport/base.js\";\nimport { HttpConnector } from \"../transport/http.js\";\nimport {\n createOAuthProvider,\n type BrowserOAuthOptions,\n} from \"../auth/browser.js\";\nimport { logger } from \"../utils/logging.js\";\nimport { Tel } from \"../telemetry/telemetry-browser.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\nimport { BaseMCPClient } from \"./base.js\";\n\n/**\n * Manages MCP server connections in browsers and other Web API runtimes.\n *\n * The browser client supports HTTP servers and the connection-management\n * operations inherited from its runtime-neutral base client. It does not spawn local\n * processes or read configuration files.\n */\nfunction trackBrowserClientInit(config: Record<string, any>): void {\n const servers = Object.keys(config.mcpServers ?? {});\n Tel.getInstance()\n .trackMCPClientInit({\n codeMode: false,\n sandbox: false,\n allCallbacks: false,\n verify: false,\n servers,\n numServers: servers.length,\n isBrowser: true,\n })\n .catch((e: unknown) =>\n logger.debug(`Failed to track BrowserMCPClient init: ${e}`)\n );\n}\n\nexport class BrowserMCPClient extends BaseMCPClient {\n /**\n * Returns the installed `@mcp-use/client` package version.\n *\n * @returns The package version string.\n */\n public static getPackageVersion(): string {\n return getPackageVersion();\n }\n\n /**\n * Creates a browser MCP client.\n *\n * @param config - Client configuration containing an optional `mcpServers` map.\n */\n constructor(config?: Record<string, any>) {\n super(config);\n trackBrowserClientInit(this.config);\n }\n\n /**\n * Creates a browser client from an inline configuration object.\n *\n * @param cfg - Client configuration containing an optional `mcpServers` map.\n * @returns A browser client initialized with `cfg`.\n */\n public static fromDict(cfg: Record<string, any>): BrowserMCPClient {\n return new BrowserMCPClient(cfg);\n }\n\n protected async createDefaultOAuthProvider(\n serverUrl: string,\n options: AutoOAuthOptions = {}\n ): Promise<OAuthClientProvider> {\n return createOAuthProvider(serverUrl, options as BrowserOAuthOptions);\n }\n\n /**\n * Create a connector from server configuration (Browser version)\n * Supports HTTP connector only\n */\n protected createConnectorFromConfig(\n serverConfig: Record<string, any>\n ): BaseConnector {\n const {\n url,\n headers,\n fetch: configuredFetch,\n authToken,\n authProvider,\n detectMixedAuth,\n wrapTransport,\n clientOptions,\n protocolNegotiation,\n timeout,\n gatewayUrl,\n serverId,\n reconnectionOptions,\n } = serverConfig;\n\n if (!url) {\n throw new Error(\"Server URL is required\");\n }\n\n // Resolve callbacks: per-server overrides global (from config root)\n const globalDefaults = this.config as CallbackConfig;\n const resolved = resolveCallbacks(\n serverConfig as CallbackConfig,\n globalDefaults\n );\n\n // Root clientInfo as fallback when server config omits it\n const clientInfo = normalizeClientInfo(\n serverConfig.clientInfo ?? this.config.clientInfo\n );\n\n // Prepare connector options\n const connectorOptions = {\n headers,\n fetch: configuredFetch ?? globalThis.fetch.bind(globalThis),\n authToken,\n authProvider,\n detectMixedAuth,\n wrapTransport,\n clientOptions,\n onSampling: resolved.onSampling,\n onElicitation: resolved.onElicitation,\n onNotification: resolved.onNotification,\n protocolNegotiation,\n timeout,\n clientInfo,\n gatewayUrl,\n serverId,\n reconnectionOptions,\n };\n\n logger.debug(\n `[BrowserMCPClient] Connector options prepared (clientOptions: ${clientOptions ? \"provided\" : \"none\"})`\n );\n\n return new HttpConnector(url, connectorOptions);\n }\n}\n","/**\n * Cross-compatible telemetry: PostHog via fetch, Web Crypto, feature-detected\n * opt-out. Optional {@link TelemetryStorage} (fs from node entry, localStorage\n * when available) for durable user ids.\n */\nimport { logger } from \"../utils/logging.js\";\nimport { getPackageVersion } from \"../utils/version.js\";\nimport type {\n BaseTelemetryEvent,\n ConnectorInitEventData,\n MCPAgentExecutionEventData,\n MCPClientInitEventData,\n} from \"./events.js\";\nimport {\n ClientAddServerEvent,\n ClientRemoveServerEvent,\n ConnectorInitEvent,\n MCPAgentExecutionEvent,\n MCPClientInitEvent,\n} from \"./events.js\";\nimport { capturePostHog } from \"./tel-fetch.js\";\n\nfunction generateUUID(): string {\n return globalThis.crypto.randomUUID();\n}\n\nfunction secureRandomString(): string {\n const array = new Uint8Array(8);\n globalThis.crypto.getRandomValues(array);\n return Array.from(array, (v) => v.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport type TelemetryStorage = {\n getUserId(): string | null;\n setUserId(id: string): void;\n};\n\ntype RuntimeEnvironment =\n | \"browser\"\n | \"node\"\n | \"cloudflare-workers\"\n | \"edge\"\n | \"deno\"\n | \"bun\"\n | \"unknown\";\n\ntype StorageCapability = \"persistent\" | \"session-only\";\n\nconst USER_ID_STORAGE_KEY = \"mcp_use_user_id\";\nconst PROJECT_API_KEY = \"phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI\";\nconst HOST = \"https://eu.i.posthog.com\";\n\n/** Install before first `getInstance()` — node entry wires fs storage here. */\nlet configuredStorage: TelemetryStorage | null = null;\n\nexport function configureTelemetryStorage(storage: TelemetryStorage): void {\n configuredStorage = storage;\n}\n\nfunction isLocalStorageFunctional(): boolean {\n return (\n typeof localStorage !== \"undefined\" &&\n typeof localStorage.getItem === \"function\" &&\n typeof localStorage.setItem === \"function\" &&\n typeof localStorage.removeItem === \"function\"\n );\n}\n\nfunction createLocalStorageBackend(): TelemetryStorage | null {\n if (!isLocalStorageFunctional()) return null;\n try {\n localStorage.setItem(\"__mcp_use_test__\", \"1\");\n localStorage.removeItem(\"__mcp_use_test__\");\n } catch {\n return null;\n }\n return {\n getUserId() {\n try {\n return localStorage.getItem(USER_ID_STORAGE_KEY);\n } catch {\n return null;\n }\n },\n setUserId(id: string) {\n try {\n localStorage.setItem(USER_ID_STORAGE_KEY, id);\n } catch {\n // ignore\n }\n },\n };\n}\n\nfunction detectRuntimeEnvironment(): RuntimeEnvironment {\n try {\n if (typeof (globalThis as { Bun?: unknown }).Bun !== \"undefined\") {\n return \"bun\";\n }\n if (typeof (globalThis as { Deno?: unknown }).Deno !== \"undefined\") {\n return \"deno\";\n }\n if (\n typeof navigator !== \"undefined\" &&\n navigator.userAgent?.includes(\"Cloudflare-Workers\")\n ) {\n return \"cloudflare-workers\";\n }\n if (\n typeof (globalThis as { EdgeRuntime?: unknown }).EdgeRuntime !==\n \"undefined\"\n ) {\n return \"edge\";\n }\n if (typeof window !== \"undefined\" && typeof document !== \"undefined\") {\n return \"browser\";\n }\n if (\n typeof process !== \"undefined\" &&\n typeof process.versions?.node !== \"undefined\"\n ) {\n return \"node\";\n }\n return \"unknown\";\n } catch {\n return \"unknown\";\n }\n}\n\nfunction readSourceHint(): string | undefined {\n if (typeof process !== \"undefined\" && process.env?.MCP_USE_TELEMETRY_SOURCE) {\n return process.env.MCP_USE_TELEMETRY_SOURCE;\n }\n try {\n if (isLocalStorageFunctional()) {\n return localStorage.getItem(\"MCP_USE_TELEMETRY_SOURCE\") ?? undefined;\n }\n } catch {\n // ignore\n }\n return undefined;\n}\n\nfunction isTelemetryDisabled(): boolean {\n if (\n typeof window !== \"undefined\" &&\n (window as unknown as { __MCP_USE_ANONYMIZED_TELEMETRY__?: boolean })\n .__MCP_USE_ANONYMIZED_TELEMETRY__ === false\n ) {\n return true;\n }\n if (\n typeof process !== \"undefined\" &&\n process.env?.MCP_USE_ANONYMIZED_TELEMETRY?.toLowerCase() === \"false\"\n ) {\n return true;\n }\n try {\n if (\n isLocalStorageFunctional() &&\n localStorage.getItem(\"MCP_USE_ANONYMIZED_TELEMETRY\") === \"false\"\n ) {\n return true;\n }\n } catch {\n // ignore\n }\n return false;\n}\n\nfunction sessionId(): string {\n try {\n return `session-${generateUUID()}`;\n } catch {\n return `session-${Date.now()}-${secureRandomString()}`;\n }\n}\n\n/**\n * Shared telemetry singleton for node and browser.\n *\n * Usage: `Tel.getInstance().trackMCPClientInit(...)`\n */\nexport class Telemetry {\n private static instance: Telemetry | null = null;\n\n private readonly UNKNOWN_USER_ID = \"UNKNOWN_USER_ID\";\n\n private _currUserId: string | null = null;\n private _telemetryEnabled = false;\n private _pending = new Set<Promise<void>>();\n private _runtimeEnvironment: RuntimeEnvironment;\n private _storageCapability: StorageCapability;\n private _storage: TelemetryStorage | null;\n private _source: string;\n private _productVersion?: string;\n\n private constructor() {\n this._runtimeEnvironment = detectRuntimeEnvironment();\n this._storage = configuredStorage ?? createLocalStorageBackend() ?? null;\n this._storageCapability = this._storage ? \"persistent\" : \"session-only\";\n this._source = readSourceHint() || this._runtimeEnvironment;\n\n const disabled = isTelemetryDisabled();\n const canSupport = this._runtimeEnvironment !== \"unknown\";\n\n if (disabled) {\n this._telemetryEnabled = false;\n logger.debug(\"Telemetry disabled via opt-out\");\n } else if (!canSupport) {\n this._telemetryEnabled = false;\n logger.debug(\n `Telemetry disabled - unknown environment: ${this._runtimeEnvironment}`\n );\n } else {\n logger.debug(\n \"Anonymized telemetry enabled. Set MCP_USE_ANONYMIZED_TELEMETRY=false to disable.\"\n );\n this._telemetryEnabled = true;\n }\n }\n\n get runtimeEnvironment(): RuntimeEnvironment {\n return this._runtimeEnvironment;\n }\n\n get storageCapability(): StorageCapability {\n return this._storageCapability;\n }\n\n static getInstance(): Telemetry {\n if (!Telemetry.instance) {\n Telemetry.instance = new Telemetry();\n }\n return Telemetry.instance;\n }\n\n setSource(source: string): void {\n this._source = source;\n try {\n if (isLocalStorageFunctional()) {\n localStorage.setItem(\"MCP_USE_TELEMETRY_SOURCE\", source);\n }\n } catch {\n // ignore\n }\n logger.debug(`Telemetry source set to: ${source}`);\n }\n\n getSource(): string {\n return this._source;\n }\n\n setProductVersion(version: string): void {\n this._productVersion = version;\n }\n\n get isEnabled(): boolean {\n return this._telemetryEnabled;\n }\n\n get userId(): string {\n if (this._currUserId) return this._currUserId;\n\n try {\n if (this._storage) {\n const existing = this._storage.getUserId();\n if (existing) {\n this._currUserId = existing;\n return existing;\n }\n const id = generateUUID();\n this._storage.setUserId(id);\n this._currUserId = id;\n return id;\n }\n this._currUserId = sessionId();\n } catch {\n this._currUserId = this.UNKNOWN_USER_ID;\n }\n return this._currUserId;\n }\n\n async capture(event: BaseTelemetryEvent): Promise<void> {\n if (!this._telemetryEnabled) return;\n\n const currentUserId = this.userId;\n const properties: Record<string, unknown> = {\n ...event.properties,\n mcp_use_version: this._productVersion ?? getPackageVersion(),\n language: \"typescript\",\n source: this._source,\n runtime: this._runtimeEnvironment,\n };\n\n const p = capturePostHog({\n host: HOST,\n apiKey: PROJECT_API_KEY,\n event: event.name,\n distinctId: currentUserId,\n properties,\n });\n this._pending.add(p);\n void p.finally(() => this._pending.delete(p));\n }\n\n async trackAgentExecution(data: MCPAgentExecutionEventData): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new MCPAgentExecutionEvent(data));\n }\n\n async trackMCPClientInit(data: MCPClientInitEventData): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new MCPClientInitEvent(data));\n }\n\n async trackConnectorInit(data: ConnectorInitEventData): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new ConnectorInitEvent(data));\n }\n\n async trackClientAddServer(\n serverName: string,\n serverConfig: Record<string, any>\n ): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new ClientAddServerEvent({ serverName, serverConfig }));\n }\n\n async trackClientRemoveServer(serverName: string): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture(new ClientRemoveServerEvent({ serverName }));\n }\n\n async trackUseMcpConnection(data: {\n url: string;\n transportType: string;\n success: boolean;\n errorType?: string | null;\n connectionTimeMs?: number | null;\n hasOAuth: boolean;\n hasSampling: boolean;\n hasElicitation: boolean;\n }): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture({\n name: \"usemcp_connection\",\n properties: {\n url_domain: new URL(data.url).hostname,\n transport_type: data.transportType,\n success: data.success,\n error_type: data.errorType ?? null,\n connection_time_ms: data.connectionTimeMs ?? null,\n has_oauth: data.hasOAuth,\n has_sampling: data.hasSampling,\n has_elicitation: data.hasElicitation,\n },\n });\n }\n\n async trackUseMcpToolCall(data: {\n toolName: string;\n success: boolean;\n errorType?: string | null;\n executionTimeMs?: number | null;\n }): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture({\n name: \"usemcp_tool_call\",\n properties: {\n tool_name: data.toolName,\n success: data.success,\n error_type: data.errorType ?? null,\n execution_time_ms: data.executionTimeMs ?? null,\n },\n });\n }\n\n async trackUseMcpResourceRead(data: {\n resourceUri: string;\n success: boolean;\n errorType?: string | null;\n }): Promise<void> {\n if (!this.isEnabled) return;\n await this.capture({\n name: \"usemcp_resource_read\",\n properties: {\n resource_uri_scheme: data.resourceUri.split(\":\")[0],\n success: data.success,\n error_type: data.errorType ?? null,\n },\n });\n }\n\n identify(userId: string, properties?: Record<string, unknown>): void {\n this._currUserId = userId;\n this._storage?.setUserId(userId);\n if (this._telemetryEnabled) {\n void capturePostHog({\n host: HOST,\n apiKey: PROJECT_API_KEY,\n event: \"$identify\",\n distinctId: userId,\n properties: { $set: properties ?? {} },\n });\n }\n }\n\n reset(): void {\n this._currUserId = null;\n }\n\n flush(): void {\n void Promise.allSettled([...this._pending]);\n }\n\n async shutdown(): Promise<void> {\n try {\n await Promise.allSettled([...this._pending]);\n logger.debug(\"Telemetry fetch captures flushed\");\n } catch (e) {\n logger.debug(`Error flushing telemetry captures: ${e}`);\n }\n }\n}\n\n/**\n * Backward-compatible name for {@link Telemetry}.\n *\n * @alias\n */\nexport const Tel = Telemetry;\n\nexport function setTelemetrySource(source: string): void {\n Tel.getInstance().setSource(source);\n}\n\nexport function setProductVersion(version: string): void {\n Tel.getInstance().setProductVersion(version);\n}\n","export abstract class BaseTelemetryEvent {\n abstract get name(): string;\n abstract get properties(): Record<string, any>;\n}\n\n// ============================================================================\n// MCPAgentExecutionEvent\n// ============================================================================\n\nexport interface MCPAgentExecutionEventData {\n // Execution method and context\n executionMethod: string; // \"run\" or \"astream\"\n query: string; // The actual user query\n success: boolean;\n\n // Agent configuration\n modelProvider: string;\n modelName: string;\n serverCount: number;\n serverIdentifiers: Array<Record<string, string>>;\n totalToolsAvailable: number;\n toolsAvailableNames: string[];\n maxStepsConfigured: number;\n memoryEnabled: boolean;\n useServerManager: boolean;\n\n // Execution PARAMETERS\n maxStepsUsed: number | null;\n manageConnector: boolean;\n externalHistoryUsed: boolean;\n\n // Execution results\n stepsTaken?: number | null;\n toolsUsedCount?: number | null;\n toolsUsedNames?: string[] | null;\n response?: string | null; // The actual response\n executionTimeMs?: number | null;\n errorType?: string | null;\n\n // Context\n conversationHistoryLength?: number | null;\n}\n\nexport class MCPAgentExecutionEvent extends BaseTelemetryEvent {\n constructor(private data: MCPAgentExecutionEventData) {\n super();\n }\n\n get name(): string {\n return \"mcp_agent_execution\";\n }\n\n get properties(): Record<string, any> {\n return {\n // Core execution info\n execution_method: this.data.executionMethod,\n query_length: this.data.query.length,\n success: this.data.success,\n // Agent configuration\n model_provider: this.data.modelProvider,\n model_name: this.data.modelName,\n server_count: this.data.serverCount,\n total_tools_available: this.data.totalToolsAvailable,\n max_steps_configured: this.data.maxStepsConfigured,\n memory_enabled: this.data.memoryEnabled,\n use_server_manager: this.data.useServerManager,\n // Execution parameters (always include, even if null)\n max_steps_used: this.data.maxStepsUsed,\n manage_connector: this.data.manageConnector,\n external_history_used: this.data.externalHistoryUsed,\n // Execution results (always include, even if null)\n steps_taken: this.data.stepsTaken ?? null,\n tools_used_count: this.data.toolsUsedCount ?? null,\n response_length: this.data.response ? this.data.response.length : null,\n execution_time_ms: this.data.executionTimeMs ?? null,\n error_type: this.data.errorType ?? null,\n conversation_history_length: this.data.conversationHistoryLength ?? null,\n };\n }\n}\n\n// ============================================================================\n// MCPClientInitEvent\n// ============================================================================\n\nexport interface MCPClientInitEventData {\n codeMode: boolean;\n sandbox: boolean;\n allCallbacks: boolean;\n verify: boolean;\n servers: string[];\n numServers: number;\n isBrowser: boolean; // true for BrowserMCPClient, false for Node.js MCPClient\n}\n\nexport class MCPClientInitEvent extends BaseTelemetryEvent {\n constructor(private data: MCPClientInitEventData) {\n super();\n }\n\n get name(): string {\n return \"mcpclient_init\";\n }\n\n get properties(): Record<string, any> {\n return {\n code_mode: this.data.codeMode,\n sandbox: this.data.sandbox,\n all_callbacks: this.data.allCallbacks,\n verify: this.data.verify,\n servers: this.data.servers,\n num_servers: this.data.numServers,\n is_browser: this.data.isBrowser,\n };\n }\n}\n\n// ============================================================================\n// ConnectorInitEvent\n// ============================================================================\n\nexport interface ConnectorInitEventData {\n connectorType: string;\n serverCommand?: string | null;\n serverArgs?: string[] | null;\n serverUrl?: string | null;\n publicIdentifier?: string | null;\n}\n\nexport class ConnectorInitEvent extends BaseTelemetryEvent {\n constructor(private data: ConnectorInitEventData) {\n super();\n }\n\n get name(): string {\n return \"connector_init\";\n }\n\n get properties(): Record<string, any> {\n return {\n connector_type: this.data.connectorType,\n server_command: this.data.serverCommand ?? null,\n server_args: this.data.serverArgs ?? null,\n server_url: this.data.serverUrl ?? null,\n public_identifier: this.data.publicIdentifier ?? null,\n };\n }\n}\n\n// ============================================================================\n// ClientAddServerEvent\n// ============================================================================\n\n/**\n * Raw input data for tracking server addition.\n * The event class will extract the necessary properties.\n */\ninterface ClientAddServerEventInput {\n serverName: string;\n serverConfig: Record<string, any>;\n}\n\nexport class ClientAddServerEvent extends BaseTelemetryEvent {\n constructor(private data: ClientAddServerEventInput) {\n super();\n }\n\n get name(): string {\n return \"client_add_server\";\n }\n\n get properties(): Record<string, any> {\n const { serverName, serverConfig } = this.data;\n const url = serverConfig.url;\n\n return {\n server_name: serverName,\n server_url_domain: url ? this._extractHostname(url) : null,\n transport: serverConfig.transport ?? null,\n has_auth: !!(serverConfig.authToken || serverConfig.authProvider),\n };\n }\n\n private _extractHostname(url: string): string | null {\n try {\n return new URL(url).hostname;\n } catch {\n return null;\n }\n }\n}\n\n// ============================================================================\n// ClientRemoveServerEvent\n// ============================================================================\n\n/**\n * Raw input data for tracking server removal.\n */\ninterface ClientRemoveServerEventInput {\n serverName: string;\n}\n\nexport class ClientRemoveServerEvent extends BaseTelemetryEvent {\n constructor(private data: ClientRemoveServerEventInput) {\n super();\n }\n\n get name(): string {\n return \"client_remove_server\";\n }\n\n get properties(): Record<string, any> {\n return {\n server_name: this.data.serverName,\n };\n }\n}\n","/**\n * Fire-and-forget telemetry HTTP request. Never surfaces network/HTTP failures\n * to the host app — telemetry must not log or throw into user code.\n */\nexport async function telFetch(url: string, init?: RequestInit): Promise<void> {\n try {\n await fetch(url, init);\n } catch {\n // Telemetry must never break or log into the host app.\n }\n}\n\nexport const POSTHOG_HOST = \"https://eu.i.posthog.com\";\nexport const POSTHOG_API_KEY =\n \"phc_lyTtbYwvkdSbrcMQNPiKiiRWrrM1seyKIMjycSvItEI\";\n\nconst CONTENT_PROPERTY =\n /(^|_)(arguments?|args|body|command|headers?|location|message|query|response|secret|subject|token|uri|url|user_agent)(_|$)/i;\nconst IDENTIFYING_PROPERTY =\n /(^|_)(server_identifiers?|server_names?|servers|tool_names?|tools_(available|used)_names)(_|$)/i;\nconst AGGREGATE_PROPERTY =\n /(_count|_length|_duration(?:_ms)?|_time_ms|(^|_)num_[a-z0-9_]+)$/i;\n\nfunction normalizePropertyKey(key: string): string {\n return key\n .replace(/([a-z0-9])([A-Z])/g, \"$1_$2\")\n .replace(/[^a-z0-9_$]+/gi, \"_\")\n .toLowerCase();\n}\n\nfunction sanitizeValue(value: unknown, seen: WeakSet<object>): unknown {\n if (Array.isArray(value)) {\n if (seen.has(value)) {\n throw new TypeError(\"Cyclic telemetry properties are not supported\");\n }\n seen.add(value);\n const sanitized = value.map((item) => sanitizeValue(item, seen));\n seen.delete(value);\n return sanitized;\n }\n\n if (\n value !== null &&\n typeof value === \"object\" &&\n (Object.getPrototypeOf(value) === Object.prototype ||\n Object.getPrototypeOf(value) === null)\n ) {\n if (seen.has(value)) {\n throw new TypeError(\"Cyclic telemetry properties are not supported\");\n }\n seen.add(value);\n const sanitized = sanitizeProperties(\n value as Record<string, unknown>,\n seen\n );\n seen.delete(value);\n return sanitized;\n }\n\n return value;\n}\n\nfunction sanitizeProperties(\n properties: Record<string, unknown>,\n seen = new WeakSet<object>()\n): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(properties)) {\n const normalizedKey = normalizePropertyKey(key);\n if (AGGREGATE_PROPERTY.test(normalizedKey)) {\n if (value === null || typeof value === \"number\") {\n sanitized[key] = value;\n }\n continue;\n }\n if (\n IDENTIFYING_PROPERTY.test(normalizedKey) ||\n CONTENT_PROPERTY.test(normalizedKey)\n ) {\n continue;\n }\n sanitized[key] = sanitizeValue(value, seen);\n }\n return sanitized;\n}\n\n/**\n * Send a single event to PostHog's public capture endpoint using `fetch` only\n * (no `posthog-js` / `posthog-node` SDK dependency). Errors are swallowed.\n */\nexport async function capturePostHog(params: {\n host?: string;\n apiKey?: string;\n event: string;\n distinctId: string;\n properties: Record<string, unknown>;\n}): Promise<void> {\n try {\n const host = params.host ?? POSTHOG_HOST;\n const apiKey = params.apiKey ?? POSTHOG_API_KEY;\n const body = JSON.stringify({\n api_key: apiKey,\n event: params.event,\n distinct_id: params.distinctId,\n properties: sanitizeProperties(params.properties),\n timestamp: new Date().toISOString(),\n });\n await telFetch(`${host}/i/v0/e/`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n keepalive: true,\n body,\n });\n } catch {\n // Invalid telemetry data must never surface into host application code.\n }\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/client\";\nimport type { BaseConnector } from \"../transport/base.js\";\nimport type {\n AutoOAuthOptions,\n HttpServerConfig,\n MCPClientConfigShape,\n ServerConfig,\n} from \"./config.js\";\nimport { shouldAutoProvisionOAuth } from \"./config.js\";\nimport { completeOAuthFlow, isUnauthorized } from \"../auth/flow.js\";\nimport { logger } from \"../utils/logging.js\";\nimport { MCPSession } from \"./session.js\";\nimport type { MCPConnection } from \"./session.js\";\nimport {\n trackClientAddServer,\n trackClientRemoveServer,\n} from \"../telemetry/client-telemetry.js\";\n\nfunction isOAuthClientProvider(\n provider: unknown\n): provider is OAuthClientProvider {\n return (\n !!provider &&\n typeof provider === \"object\" &&\n \"redirectUrl\" in provider &&\n \"clientMetadata\" in provider\n );\n}\n\n/**\n * Base MCPClient class with shared functionality across all environments.\n *\n * This abstract class provides the core client logic for managing MCP servers,\n * sessions, and configurations. It works in both Node.js and browser environments\n * by delegating platform-specific operations to concrete implementations.\n *\n * Platform-specific implementations such as the Node.js `MCPClient` should\n * extend this class and override the abstract {@link createConnectorFromConfig}\n * method to provide environment-specific connector creation.\n *\n * @example\n * ```typescript\n * // Typically used through concrete implementations\n * import { MCPClient } from \"@mcp-use/client\";\n *\n * const client = new MCPClient({\n * mcpServers: {\n * 'my-server': {\n * command: 'node',\n * args: ['server.js']\n * }\n * }\n * });\n * ```\n *\n * @see {@link MCPSession} for session management\n */\nexport abstract class BaseMCPClient {\n /**\n * Internal configuration object containing MCP server definitions.\n */\n protected config: MCPClientConfigShape = {};\n\n /**\n * Map of server names to their active sessions.\n */\n protected sessions: Record<string, MCPSession> = {};\n\n /**\n * Tracks teardown by session identity so overlapping cleanup paths share the\n * same disconnect. In particular, createSession() can replace a session while\n * closeSession() is already disconnecting it.\n */\n private readonly sessionDisconnects = new WeakMap<\n MCPSession,\n Promise<void>\n >();\n\n /**\n * List of server names that have active sessions.\n * This array is kept in sync with the sessions map and can be used\n * to iterate over active connections.\n *\n * @example\n * ```typescript\n * console.log(`Active servers: ${client.activeSessions.join(', ')}`);\n * ```\n */\n public activeSessions: string[] = [];\n\n /**\n * Creates a new BaseMCPClient instance.\n *\n * @param config - Optional configuration object with MCP server definitions\n *\n * @example\n * ```typescript\n * const client = new MCPClient({\n * mcpServers: {\n * 'example': {\n * command: 'node',\n * args: ['server.js']\n * }\n * }\n * });\n * ```\n */\n constructor(config?: MCPClientConfigShape) {\n if (config) {\n this.config = config;\n }\n }\n\n private disconnectSession(session: MCPSession): Promise<void> {\n const existingDisconnect = this.sessionDisconnects.get(session);\n if (existingDisconnect) {\n return existingDisconnect;\n }\n\n // Install the promise before invoking the connector so even synchronous\n // re-entry observes and reuses this teardown.\n const disconnect = Promise.resolve().then(() => session.disconnect());\n this.sessionDisconnects.set(session, disconnect);\n return disconnect;\n }\n\n /**\n * Creates a client instance from a configuration dictionary.\n *\n * This static factory method must be implemented by concrete subclasses\n * to provide proper type information and platform-specific initialization.\n *\n * @param _cfg - Configuration dictionary\n * @returns Client instance\n * @throws If called on the base class instead of a concrete implementation\n *\n * @example\n * ```typescript\n * const client = MCPClient.fromDict({\n * mcpServers: {\n * 'my-server': { command: 'node', args: ['server.js'] }\n * }\n * });\n * ```\n */\n public static fromDict(_cfg: MCPClientConfigShape): BaseMCPClient {\n // This will be overridden by concrete implementations\n throw new Error(\"fromDict must be implemented by concrete class\");\n }\n\n /**\n * Adds a new MCP server configuration to the client.\n *\n * This method adds or updates a server configuration dynamically without\n * needing to restart the client. The server can then be used to create\n * new sessions.\n *\n * @param name - Unique name for the server\n * @param serverConfig - Server configuration object (connector type, command, args, etc.)\n *\n * @example\n * ```typescript\n * client.addServer('new-server', {\n * command: 'python',\n * args: ['server.py']\n * });\n *\n * // Now you can create a session\n * const session = await client.createSession('new-server');\n * ```\n *\n * @see {@link removeServer} for removing servers\n * @see {@link getServerConfig} for retrieving configurations\n */\n public addServer(name: string, serverConfig: ServerConfig): void {\n this.config.mcpServers = this.config.mcpServers || {};\n this.config.mcpServers[name] = serverConfig;\n trackClientAddServer(name, serverConfig);\n }\n\n /**\n * Removes an MCP server configuration from the client.\n *\n * This method removes a server configuration and cleans up any active\n * sessions associated with that server. If there's an active session,\n * it will be removed from the active sessions list.\n *\n * @param name - Name of the server to remove\n *\n * @example\n * ```typescript\n * // Remove a server configuration\n * await client.removeServer('old-server');\n *\n * // The server name will no longer appear in getServerNames()\n * console.log(client.getServerNames()); // 'old-server' is gone\n * ```\n *\n * @see {@link addServer} for adding servers\n * @see {@link closeSession} for properly closing sessions before removal\n */\n public async removeServer(name: string): Promise<void> {\n if (!this.config.mcpServers?.[name]) return;\n\n await this.closeSession(name);\n delete this.config.mcpServers[name];\n trackClientRemoveServer(name);\n }\n\n /**\n * Gets the names of all configured MCP servers.\n *\n * @returns Array of server names defined in the configuration\n *\n * @example\n * ```typescript\n * const serverNames = client.getServerNames();\n * console.log(`Configured servers: ${serverNames.join(', ')}`);\n *\n * // Create sessions for all servers\n * for (const name of serverNames) {\n * await client.createSession(name);\n * }\n * ```\n *\n * @see {@link activeSessions} for servers with active sessions\n */\n public getServerNames(): string[] {\n return Object.keys(this.config.mcpServers ?? {});\n }\n\n /**\n * Gets the configuration for a specific MCP server.\n *\n * @param name - Name of the server\n * @returns Server configuration object, or undefined if not found\n *\n * @example\n * ```typescript\n * const config = client.getServerConfig('my-server');\n * if (config) {\n * console.log(`Command: ${config.command}`);\n * console.log(`Args: ${config.args.join(' ')}`);\n * }\n * ```\n *\n * @see {@link getConfig} for retrieving the entire configuration\n */\n public getServerConfig(name: string): ServerConfig | undefined {\n return this.config.mcpServers?.[name];\n }\n\n /**\n * Gets the complete client configuration.\n *\n * @returns Complete configuration object including all server definitions\n *\n * @example\n * ```typescript\n * const config = client.getConfig();\n * console.log(`Total servers: ${Object.keys(config.mcpServers).length}`);\n * ```\n *\n * @see {@link getServerConfig} for retrieving individual server configurations\n */\n public getConfig(): MCPClientConfigShape {\n return this.config ?? {};\n }\n\n /**\n * Creates a connector from server configuration.\n *\n * This abstract method must be implemented by platform-specific subclasses\n * to create the appropriate connector type (Stdio, HTTP, WebSocket, etc.)\n * based on the server configuration and runtime environment.\n *\n * @param serverConfig - Server configuration object\n * @returns Platform-specific connector instance\n */\n protected abstract createConnectorFromConfig(\n serverConfig: ServerConfig\n ): BaseConnector | Promise<BaseConnector>;\n\n /**\n * Platform OAuth provider used when an HTTP server has no bearer token /\n * `authProvider`. Node and browser entries implement this via their\n * `createOAuthProvider` export.\n */\n protected abstract createDefaultOAuthProvider(\n serverUrl: string,\n options?: AutoOAuthOptions\n ): Promise<OAuthClientProvider>;\n\n /**\n * Creates a new session for connecting to an MCP server.\n *\n * @deprecated Use {@link connect}; modern MCP servers are sessionless.\n *\n * This method initializes a connection to the specified server using the\n * configuration provided during client construction. Sessions manage the\n * lifecycle of connections and provide methods for calling tools, listing\n * resources, and more.\n *\n * If a session already exists for the server, it will be replaced with a new\n * one and the previous session is disconnected; any previously returned\n * reference to it becomes unusable.\n *\n * @param serverName - The name of the server as defined in the client configuration\n * @param autoInitialize - Whether to automatically initialize the session (default: true)\n * @returns A promise that resolves to the created MCPSession instance\n * @throws If the server is not found in the configuration\n *\n * @example\n * ```typescript\n * // Create and initialize a session\n * const session = await client.createSession('my-server');\n * const tools = await session.listTools();\n *\n * // Create without auto-initialization\n * const session = await client.createSession('my-server', false);\n * await session.connect();\n * await session.initialize();\n * ```\n *\n * @see {@link MCPSession} for session management methods\n * @see {@link closeSession} for closing sessions\n * @see {@link getSession} for retrieving existing sessions\n */\n public async createSession(\n serverName: string,\n autoInitialize = true\n ): Promise<MCPSession> {\n const servers = this.config.mcpServers ?? {};\n\n if (Object.keys(servers).length === 0) {\n logger.warn(\"No MCP servers defined in config\");\n }\n\n if (!servers[serverName]) {\n throw new Error(`Server '${serverName}' not found in config`);\n }\n\n let serverConfig: ServerConfig = { ...servers[serverName] };\n let oauthProvider: OAuthClientProvider | undefined;\n\n if (shouldAutoProvisionOAuth(serverConfig)) {\n const oauthOptions =\n serverConfig.oauth === false ? undefined : (serverConfig.oauth ?? {});\n oauthProvider = await this.createDefaultOAuthProvider(\n serverConfig.url,\n oauthOptions\n );\n serverConfig = {\n ...serverConfig,\n authProvider: oauthProvider,\n };\n } else if (\n \"authProvider\" in serverConfig &&\n serverConfig.authProvider &&\n isOAuthClientProvider(serverConfig.authProvider)\n ) {\n oauthProvider = serverConfig.authProvider;\n }\n\n const openSession = async (): Promise<MCPSession> => {\n const connector = await Promise.resolve(\n this.createConnectorFromConfig(serverConfig)\n );\n const session = new MCPSession(connector);\n if (autoInitialize) {\n await session.initialize();\n }\n return session;\n };\n\n let session: MCPSession;\n try {\n session = await openSession();\n } catch (err) {\n const httpConfig = serverConfig as HttpServerConfig;\n if (\n !autoInitialize ||\n !oauthProvider ||\n !(\"url\" in httpConfig) ||\n !isUnauthorized(err)\n ) {\n throw err;\n }\n if (\n (\n oauthProvider as OAuthClientProvider & {\n preventAutoAuth?: boolean;\n }\n ).preventAutoAuth\n ) {\n throw err;\n }\n logger.info(\n `[MCPClient] Unauthorized connecting to '${serverName}'; completing OAuth…`\n );\n await completeOAuthFlow(oauthProvider, httpConfig.url);\n session = await openSession();\n }\n\n const previous = this.sessions[serverName];\n this.sessions[serverName] = session;\n if (!this.activeSessions.includes(serverName)) {\n this.activeSessions.push(serverName);\n }\n\n // The slot only holds one session per server, so a replaced session would\n // no longer be reachable from closeSession()/closeAllSessions(). Disconnect\n // it here, after the new session is installed, so consumers calling\n // getSession() during the await still see a live session.\n if (previous && previous !== session) {\n try {\n logger.debug(`Disconnecting replaced session for server ${serverName}`);\n await this.disconnectSession(previous);\n } catch (e) {\n logger.error(\n `Error disconnecting replaced session for server '${serverName}': ${e}`\n );\n }\n }\n\n return session;\n }\n\n /**\n * Connect to a configured MCP server and return a ready, protocol-neutral\n * connection.\n *\n * The returned connection represents either a legacy sessionful server or a\n * modern sessionless server uniformly. Inspect {@link MCPConnection.info} for\n * the negotiated protocol version and normalized server metadata.\n *\n * @param serverName - The configured server name.\n */\n public async connect(serverName: string): Promise<MCPConnection> {\n return this.createSession(serverName);\n }\n\n /**\n * Creates sessions for all configured MCP servers.\n *\n * This is a convenience method that iterates through all servers in the\n * configuration and creates a session for each one. Sessions are created\n * sequentially to avoid overwhelming the system.\n *\n * @param autoInitialize - Whether to automatically initialize each session (default: true)\n * @returns A promise that resolves to a map of server names to sessions\n *\n * @example\n * ```typescript\n * // Create sessions for all configured servers\n * const sessions = await client.createAllSessions();\n * console.log(`Created ${Object.keys(sessions).length} sessions`);\n *\n * // List tools from all servers\n * for (const [name, session] of Object.entries(sessions)) {\n * const tools = await session.listTools();\n * console.log(`${name}: ${tools.length} tools`);\n * }\n * ```\n *\n * @see {@link createSession} for creating individual sessions\n * @see {@link closeAllSessions} for closing all sessions\n */\n public async createAllSessions(\n autoInitialize = true\n ): Promise<Record<string, MCPSession>> {\n const servers = this.config.mcpServers ?? {};\n\n if (Object.keys(servers).length === 0) {\n logger.warn(\"No MCP servers defined in config\");\n }\n\n for (const name of Object.keys(servers)) {\n await this.createSession(name, autoInitialize);\n }\n\n return this.sessions;\n }\n\n /**\n * Connect to every configured server sequentially.\n *\n * Each result uses the same {@link MCPConnection} API regardless of whether\n * the negotiated protocol is legacy/sessionful or modern/sessionless.\n */\n public async connectAll(): Promise<Record<string, MCPConnection>> {\n return this.createAllSessions();\n }\n\n /**\n * Retrieves an existing session by server name.\n *\n * This method returns null if no session exists, making it safe for\n * checking session existence without throwing errors.\n *\n * @param serverName - Name of the server\n * @returns The session instance or null if not found\n *\n * @example\n * ```typescript\n * const session = client.getSession('my-server');\n * if (session) {\n * const tools = await session.listTools();\n * } else {\n * console.log('Session not found, creating...');\n * await client.createSession('my-server');\n * }\n * ```\n *\n * @see {@link requireSession} for getting a session that throws if not found\n * @see {@link createSession} for creating sessions\n */\n public getSession(serverName: string): MCPSession | null {\n const session = this.sessions[serverName];\n if (!session) {\n return null;\n }\n return session;\n }\n\n /**\n * Retrieves an existing session by server name, throwing if not found.\n *\n * This method is useful when you need to ensure a session exists before\n * proceeding. It throws a descriptive error if the session is not found.\n *\n * @param serverName - Name of the server\n * @returns The session instance\n * @throws If the session is not found\n *\n * @example\n * ```typescript\n * try {\n * const session = client.requireSession('my-server');\n * const tools = await session.listTools();\n * } catch (error) {\n * console.error('Session not found:', error.message);\n * }\n * ```\n *\n * @see {@link getSession} for a null-returning alternative\n * @see {@link createSession} for creating sessions\n */\n public requireSession(serverName: string): MCPSession {\n const session = this.sessions[serverName];\n if (!session) {\n throw new Error(\n `Session '${serverName}' not found. Available sessions: ${this.activeSessions.join(\", \") || \"none\"}`\n );\n }\n return session;\n }\n\n /**\n * Gets all active sessions as a map of server names to sessions.\n *\n * @returns Map of server names to their active sessions\n *\n * @example\n * ```typescript\n * const sessions = client.getAllActiveSessions();\n *\n * // Iterate over all active sessions\n * for (const [name, session] of Object.entries(sessions)) {\n * console.log(`Server: ${name}`);\n * const tools = await session.listTools();\n * console.log(` Tools: ${tools.length}`);\n * }\n * ```\n *\n * @see {@link activeSessions} for just the list of server names\n * @see {@link getSession} for retrieving individual sessions\n */\n public getAllActiveSessions(): Record<string, MCPSession> {\n return Object.fromEntries(\n this.activeSessions.map((n) => [n, this.sessions[n]])\n );\n }\n\n /**\n * Closes a session and cleans up its resources.\n *\n * This method gracefully disconnects from the server and removes the\n * session from the active sessions list. It's safe to call even if\n * the session doesn't exist.\n *\n * @param serverName - Name of the server whose session should be closed\n *\n * @example\n * ```typescript\n * // Close a specific session\n * await client.closeSession('my-server');\n *\n * // Verify it's closed\n * console.log(client.activeSessions.includes('my-server')); // false\n * ```\n *\n * @see {@link closeAllSessions} for closing all sessions at once\n * @see {@link createSession} for creating new sessions\n */\n public async closeSession(serverName: string): Promise<void> {\n const session = this.sessions[serverName];\n if (!session) {\n logger.warn(\n `No session exists for server ${serverName}, nothing to close`\n );\n return;\n }\n try {\n logger.debug(`Closing session for server ${serverName}`);\n await this.disconnectSession(session);\n } catch (e) {\n logger.error(`Error closing session for server '${serverName}': ${e}`);\n } finally {\n // Only remove the slot if it still references the session we captured.\n // A parallel createSession() (e.g. URL/env change in useMcp) may have\n // written a new session here while we were awaiting `session.disconnect()`;\n // wiping that would leave consumers with `getSession() === null` and\n // surface as \"No active session found\".\n if (this.sessions[serverName] === session) {\n delete this.sessions[serverName];\n this.activeSessions = this.activeSessions.filter(\n (n) => n !== serverName\n );\n }\n }\n }\n\n /**\n * Closes all active sessions and cleans up their resources.\n *\n * This method iterates through all sessions and attempts to close each one\n * gracefully. If any session fails to close, the error is logged but the\n * method continues to close remaining sessions.\n *\n * This is particularly useful for cleanup on application shutdown.\n *\n * @example\n * ```typescript\n * // Clean shutdown\n * try {\n * await client.closeAllSessions();\n * console.log('All sessions closed successfully');\n * } catch (error) {\n * console.error('Error during cleanup:', error);\n * }\n * ```\n *\n * @example\n * ```typescript\n * // Use in application shutdown handler\n * process.on('SIGINT', async () => {\n * console.log('Shutting down...');\n * await client.closeAllSessions();\n * process.exit(0);\n * });\n * ```\n *\n * @see {@link closeSession} for closing individual sessions\n * @see {@link createAllSessions} for creating sessions\n */\n public async closeAllSessions(): Promise<void> {\n const serverNames = Object.keys(this.sessions);\n const errors: string[] = [];\n for (const serverName of serverNames) {\n try {\n logger.debug(`Closing session for server ${serverName}`);\n await this.closeSession(serverName);\n } catch (e: any) {\n const errorMsg = `Failed to close session for server '${serverName}': ${e}`;\n logger.error(errorMsg);\n errors.push(errorMsg);\n }\n }\n if (errors.length) {\n logger.error(\n `Encountered ${errors.length} errors while closing sessions`\n );\n } else {\n logger.debug(\"All sessions closed successfully\");\n }\n }\n\n /** Close every active MCP connection. */\n public async close(): Promise<void> {\n await this.closeAllSessions();\n }\n}\n","import type {\n CallToolResult,\n CompleteRequestParams,\n CompleteResult,\n MetaObject,\n Notification,\n ProtocolEra,\n RequestOptions,\n Root,\n Tool,\n} from \"@modelcontextprotocol/client\";\nimport type { BaseConnector, NotificationHandler } from \"../transport/base.js\";\n\n/** Negotiated protocol era: `\"legacy\"` or `\"modern\"`. */\nexport type MCPProtocolEra = ProtocolEra;\n\n/** OAuth availability inferred after an anonymous MCP connection succeeds. */\nexport interface MCPAuthorizationInfo {\n /** Mixed auth means public MCP operations succeeded while OAuth is available. */\n mode: \"mixed\";\n /** Whether this client currently has OAuth access tokens. */\n authenticated: boolean;\n /** Canonical protected-resource identifier from RFC 9728 metadata. */\n resource?: string;\n /** Scopes advertised by the protected resource, when provided. */\n scopesSupported?: string[];\n}\n\n/**\n * Server information normalized across legacy sessionful and modern sessionless\n * MCP protocols.\n */\nexport interface MCPServerInfo {\n /** Stable server name. */\n name: string;\n /** Server version reported during initialization. */\n version?: string;\n /** Optional human-readable server title. */\n title?: string;\n /** Optional human-readable server description. */\n description?: string;\n /** Public website describing the server. */\n websiteUrl?: string;\n /** Icons advertised by the server. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n}\n\n/**\n * Connection metadata available after the MCP SDK has negotiated a protocol.\n *\n * `extensions` retains protocol-specific extensions without requiring\n * callers to branch on the negotiated era.\n */\nexport interface MCPConnectionInfo {\n /** Negotiated protocol era. */\n protocolEra: MCPProtocolEra;\n /** Negotiated MCP protocol version. */\n protocolVersion: string;\n /** Server identity reported during negotiation, when provided. */\n server?: MCPServerInfo;\n /** Capabilities advertised by the server. */\n capabilities: Record<string, unknown>;\n /** Instructions advertised by the server. */\n instructions?: string;\n /** Protocol extension metadata advertised by the server. */\n extensions: Record<string, unknown>;\n /** Optional OAuth state discovered without forcing authentication. */\n authorization?: MCPAuthorizationInfo;\n}\n\n/**\n * A ready connection to an MCP server.\n *\n * The connection has the same public API for legacy, sessionful MCP servers\n * and modern, sessionless MCP servers. The underlying SDK owns the lifecycle\n * distinction and protocol negotiation.\n *\n * Sessions handle:\n * - Connection lifecycle (connect, disconnect, initialize)\n * - Tool invocation\n * - Resource access\n * - Prompt retrieval\n * - Notification handling\n * - Root directory management\n *\n * Sessions are typically created by `MCPClient.createSession()` rather than\n * being instantiated directly.\n *\n * @example\n * ```typescript\n * // Create via client\n * const client = new MCPClient('./config.json');\n * const session = await client.createSession('my-server');\n *\n * // Use the session\n * const tools = await session.listTools();\n * const result = await session.callTool('my-tool', { arg: 'value' });\n * ```\n *\n * @example\n * ```typescript\n * // Manual creation (advanced)\n * import { StdioConnector } from \"@mcp-use/client\";\n *\n * const connector = new StdioConnector({\n * command: 'node',\n * args: ['server.js']\n * });\n * const session = new MCPSession(connector);\n * await session.initialize();\n * ```\n *\n * @see {@link BaseConnector} for connector implementations\n */\nexport class MCPConnection {\n /**\n * The underlying connector managing the transport layer.\n * This is the Stdio, HTTP, or WebSocket connector handling actual communication.\n */\n readonly connector: BaseConnector;\n\n /**\n * Whether to automatically connect when initializing.\n * @internal\n */\n private autoConnect: boolean;\n\n /**\n * Creates a new MCP session.\n *\n * @param connector - The connector to use for communication (Stdio, HTTP, WebSocket)\n * @param autoConnect - Whether to automatically connect during initialization (default: true)\n *\n * @example\n * ```typescript\n * const connector = new HttpConnector({ url: 'http://localhost:3000/mcp' });\n * const session = new MCPSession(connector);\n * await session.initialize(); // Auto-connects and initializes\n * ```\n *\n * @example\n * ```typescript\n * // Manual connection control\n * const session = new MCPSession(connector, false);\n * await session.connect();\n * await session.initialize();\n * ```\n */\n constructor(connector: BaseConnector, autoConnect = true) {\n this.connector = connector;\n this.autoConnect = autoConnect;\n }\n\n /**\n * Establishes the connection to the MCP server.\n *\n * This method starts the underlying transport (spawns process for Stdio,\n * opens WebSocket, etc.) but does not perform the MCP initialization\n * handshake. Call {@link initialize} after connecting.\n *\n * @returns Promise that resolves when connected\n *\n * @example\n * ```typescript\n * await session.connect();\n * await session.initialize();\n * ```\n *\n * @see {@link initialize} for performing the MCP handshake\n * @see {@link disconnect} for closing the connection\n */\n async connect(): Promise<void> {\n await this.connector.connect();\n }\n\n /**\n * Closes the connection to the MCP server.\n *\n * This method gracefully shuts down the transport and cleans up resources.\n * After disconnecting, the session cannot be used until reconnected.\n *\n * @returns Promise that resolves when disconnected\n *\n * @example\n * ```typescript\n * await session.disconnect();\n * console.log('Session closed');\n * ```\n *\n * @see {@link connect} for establishing connections\n */\n async disconnect(): Promise<void> {\n await this.connector.disconnect();\n }\n\n /**\n * Initializes the MCP session with the server.\n *\n * This method performs the MCP initialization handshake, exchanging\n * capabilities and metadata with the server. If `autoConnect` is true\n * and the session is not yet connected, it will connect first.\n *\n * After initialization, you can list and call tools, read resources, etc.\n *\n * @returns Promise that resolves when initialized\n *\n * @example\n * ```typescript\n * const session = await client.createSession('my-server', false);\n * await session.connect();\n * await session.initialize();\n * // Now ready to use\n * const tools = await session.listTools();\n * ```\n *\n * @see {@link connect} for establishing the connection first\n */\n async initialize(): Promise<void> {\n if (!this.isConnected && this.autoConnect) {\n await this.connect();\n }\n await this.connector.initialize();\n }\n\n /**\n * Checks if the session is currently connected to the server.\n *\n * @returns True if connected, false otherwise\n *\n * @example\n * ```typescript\n * if (session.isConnected) {\n * const tools = await session.listTools();\n * }\n * ```\n */\n get isConnected(): boolean {\n return this.connector && this.connector.isClientConnected;\n }\n\n /**\n * Register an event handler for session events\n *\n * @param event - The event type to listen for\n * @param handler - The handler function to call when the event occurs\n *\n * @example\n * ```typescript\n * session.on(\"notification\", async (notification) => {\n * console.log(`Received: ${notification.method}`, notification.params);\n *\n * if (notification.method === \"notifications/tools/list_changed\") {\n * // Refresh tools list\n * }\n * });\n * ```\n */\n on(event: \"notification\", handler: NotificationHandler): void {\n if (event === \"notification\") {\n this.connector.onNotification(handler);\n }\n }\n\n /**\n * Set roots and notify the server.\n * Roots represent directories or files that the client has access to.\n *\n * @param roots - Array of Root objects with `uri` (must start with \"file://\") and optional `name`\n *\n * @deprecated Roots are a v1 compatibility feature and are not part of the\n * sessionless v2 protocol.\n *\n * @example\n * ```typescript\n * await session.setRoots([\n * { uri: \"file:///home/user/project\", name: \"My Project\" },\n * { uri: \"file:///home/user/data\" }\n * ]);\n * ```\n */\n async setRoots(roots: Root[]): Promise<void> {\n return this.connector.setRoots(roots);\n }\n\n /**\n * Gets the current roots advertised to the server.\n *\n * Roots represent directories or files that the client has provided access to.\n * The server may use this information to scope its operations.\n *\n * @returns Array of Root objects\n *\n * @example\n * ```typescript\n * const roots = session.getRoots();\n * console.log(`Current roots: ${roots.map(r => r.uri).join(', ')}`);\n * ```\n *\n * @see {@link setRoots} for updating roots\n */\n getRoots(): Root[] {\n return this.connector.getRoots();\n }\n\n /**\n * Get the cached list of tools from the server.\n *\n * @returns Array of available tools\n *\n * @example\n * ```typescript\n * const tools = session.tools;\n * console.log(`Available tools: ${tools.map(t => t.name).join(\", \")}`);\n * ```\n */\n get tools(): Tool[] {\n return this.connector.tools;\n }\n\n /**\n * List all available tools from the MCP server.\n * This method fetches fresh tools from the server, unlike the `tools` getter which returns cached tools.\n *\n * @param options - Optional request options\n * @returns Array of available tools\n *\n * @example\n * ```typescript\n * const tools = await session.listTools();\n * console.log(`Available tools: ${tools.map(t => t.name).join(\", \")}`);\n * ```\n */\n async listTools(options?: RequestOptions): Promise<Tool[]> {\n return this.connector.listTools(options);\n }\n\n /**\n * Get the server capabilities advertised during initialization.\n *\n * @returns Server capabilities object\n */\n get serverCapabilities(): Record<string, unknown> {\n return this.connector.serverCapabilities;\n }\n\n /**\n * Get the server information (name and version).\n *\n * @returns Server info object or null if not available\n */\n get serverInfo(): MCPServerInfo | null {\n return this.connector.serverInfo;\n }\n\n /** OAuth state discovered for this connection, when available. */\n get authorization(): MCPAuthorizationInfo | undefined {\n return this.connector.authorization;\n }\n\n /** Discover optional OAuth metadata without delaying MCP readiness. */\n async discoverAuthorization(): Promise<MCPAuthorizationInfo | undefined> {\n return this.connector.discoverAuthorization();\n }\n\n /** Authenticate an already-connected mixed-auth server. */\n async authenticate(): Promise<void> {\n await this.connector.authenticate();\n }\n\n /**\n * The negotiated protocol era for this session's connection:\n * `\"legacy\"` (2025-era) or `\"modern\"` (2026-07-28-era).\n * `undefined` before the connection has negotiated.\n */\n get protocolEra(): MCPProtocolEra | undefined {\n return this.connector.protocolEra;\n }\n\n /** The negotiated protocol version string for this session's connection. */\n get negotiatedProtocolVersion(): string | undefined {\n return this.connector.negotiatedProtocolVersion;\n }\n\n /**\n * Normalized server metadata for this ready connection.\n *\n * @throws When called before protocol negotiation completes.\n */\n get info(): MCPConnectionInfo {\n const protocolEra = this.protocolEra;\n const protocolVersion = this.negotiatedProtocolVersion;\n const server = this.serverInfo;\n\n if (!protocolEra || !protocolVersion) {\n throw new Error(\"MCP connection is not initialized\");\n }\n\n const capabilities = this.serverCapabilities;\n const extensions =\n capabilities.extensions &&\n typeof capabilities.extensions === \"object\" &&\n !Array.isArray(capabilities.extensions)\n ? (capabilities.extensions as Record<string, unknown>)\n : {};\n\n return {\n protocolEra,\n protocolVersion,\n ...(server ? { server } : {}),\n capabilities,\n instructions: this.connector.instructions,\n extensions,\n ...(this.authorization ? { authorization: this.authorization } : {}),\n };\n }\n\n /**\n * Whether the server advertised a named MCP capability.\n *\n * @param capability - A top-level capability name such as `\"tools\"` or\n * `\"resources\"`.\n */\n supports(capability: string): boolean {\n return capability in this.serverCapabilities;\n }\n\n /**\n * Call a tool on the server.\n *\n * @param name - Name of the tool to call\n * @param args - Arguments to pass to the tool (defaults to empty object)\n * @param options - Optional request options (timeout, progress handlers, etc.)\n * @returns Result from the tool execution\n *\n * @example\n * ```typescript\n * const result = await session.callTool(\"add\", { a: 5, b: 3 });\n * console.log(`Result: ${result.content[0].text}`);\n * ```\n */\n async callTool(\n name: string,\n args: Record<string, any> = {},\n options?: RequestOptions\n ): Promise<CallToolResult> {\n return this.connector.callTool(name, args, options);\n }\n\n /**\n * List resources from the server with optional pagination.\n *\n * @param cursor - Optional cursor for pagination\n * @param options - Request options\n * @returns Resource list with optional nextCursor for pagination\n *\n * @example\n * ```typescript\n * const result = await session.listResources();\n * console.log(`Found ${result.resources.length} resources`);\n * ```\n */\n async listResources(cursor?: string, options?: RequestOptions) {\n return this.connector.listResources(cursor, options);\n }\n\n /**\n * List all resources from the server, automatically handling pagination.\n *\n * @param options - Request options\n * @returns Complete list of all resources\n *\n * @example\n * ```typescript\n * const result = await session.listAllResources();\n * console.log(`Total resources: ${result.resources.length}`);\n * ```\n */\n async listAllResources(options?: RequestOptions) {\n return this.connector.listAllResources(options);\n }\n\n /**\n * List resource templates from the server.\n *\n * @param options - Request options\n * @returns List of available resource templates\n *\n * @example\n * ```typescript\n * const result = await session.listResourceTemplates();\n * console.log(`Available templates: ${result.resourceTemplates.length}`);\n * ```\n */\n async listResourceTemplates(options?: RequestOptions) {\n return this.connector.listResourceTemplates(options);\n }\n\n /**\n * Request completion suggestions for a prompt or resource template argument.\n *\n * @param params - Completion request parameters\n * @param options - Request options\n * @returns Completion suggestions from the server\n *\n * @example\n * ```typescript\n * // Complete a prompt argument\n * const result = await session.complete({\n * ref: { type: \"ref/prompt\", name: \"my-prompt\" },\n * argument: { name: \"language\", value: \"py\" }\n * });\n * console.log(result.completion.values); // [\"python\"]\n * ```\n */\n async complete(\n params: CompleteRequestParams,\n options?: RequestOptions\n ): Promise<CompleteResult> {\n return this.connector.complete(params, options);\n }\n\n /**\n * Read a resource by URI.\n *\n * @param uri - URI of the resource to read\n * @param options - Request options\n * @returns Resource content\n *\n * @example\n * ```typescript\n * const resource = await session.readResource(\"file:///path/to/file.txt\");\n * console.log(resource.contents);\n * ```\n */\n async readResource(uri: string, options?: RequestOptions) {\n return this.connector.readResource(uri, options);\n }\n\n /**\n * Subscribe to resource updates.\n *\n * @param uri - URI of the resource to subscribe to\n * @param options - Request options\n *\n * @example\n * ```typescript\n * await session.subscribeToResource(\"file:///path/to/file.txt\");\n * // Now you'll receive notifications when this resource changes\n * ```\n */\n async subscribeToResource(uri: string, options?: RequestOptions) {\n return this.connector.subscribeToResource(uri, options);\n }\n\n /**\n * Unsubscribe from resource updates.\n *\n * @param uri - URI of the resource to unsubscribe from\n * @param options - Request options\n *\n * @example\n * ```typescript\n * await session.unsubscribeFromResource(\"file:///path/to/file.txt\");\n * ```\n */\n async unsubscribeFromResource(uri: string, options?: RequestOptions) {\n return this.connector.unsubscribeFromResource(uri, options);\n }\n\n /**\n * List available prompts from the server.\n *\n * @returns List of available prompts\n *\n * @example\n * ```typescript\n * const result = await session.listPrompts();\n * console.log(`Available prompts: ${result.prompts.length}`);\n * ```\n */\n async listPrompts() {\n return this.connector.listPrompts();\n }\n\n /**\n * Get a specific prompt with arguments.\n *\n * @param name - Name of the prompt to get\n * @param args - Arguments for the prompt\n * @param options - Per-request timeout, cancellation, and progress options\n * @returns Prompt result\n *\n * @example\n * ```typescript\n * const prompt = await session.getPrompt(\"greeting\", { name: \"Alice\" });\n * console.log(prompt.messages);\n * ```\n */\n async getPrompt(\n name: string,\n args: Record<string, any>,\n options?: RequestOptions\n ) {\n return this.connector.getPrompt(name, args, options);\n }\n\n /**\n * Send a raw request through the client.\n *\n * @param method - MCP method name\n * @param params - Request parameters\n * @param options - Request options\n * @returns Response from the server\n *\n * @example\n * ```typescript\n * const result = await session.request(\"custom/method\", { key: \"value\" });\n * ```\n */\n async request(\n method: string,\n params: Record<string, any> | null = null,\n options?: RequestOptions\n ) {\n return this.connector.request(method, params, options);\n }\n\n /** List one page of skills advertised through the experimental extension. */\n async listSkills(cursor?: string, options?: RequestOptions) {\n return (await this.request(\n \"skills/list\",\n cursor === undefined ? {} : { cursor },\n options\n )) as import(\"./skills.js\").SkillsListResult;\n }\n\n /** List the complete skill catalog, following pagination defensively. */\n async listAllSkills(options?: RequestOptions) {\n const skills: import(\"./skills.js\").Skill[] = [];\n const seenCursors = new Set<string>();\n let cursor: string | undefined;\n do {\n const page = await this.listSkills(cursor, options);\n skills.push(...(Array.isArray(page.skills) ? page.skills : []));\n cursor = page.nextCursor;\n if (cursor !== undefined) {\n if (seenCursors.has(cursor)) {\n throw new Error(\"skills/list returned a repeated pagination cursor\");\n }\n seenCursors.add(cursor);\n }\n } while (cursor !== undefined);\n return { skills };\n }\n\n /** Get one skill by its canonical `SKILL.md` URI. */\n async getSkill(uri: string, options?: RequestOptions) {\n return (await this.request(\n \"skills/get\",\n { uri },\n options\n )) as import(\"./skills.js\").SkillGetResult;\n }\n\n /** Read one non-recursive skill directory. */\n async readResourceDirectory(\n uri: string,\n cursor?: string,\n options?: RequestOptions\n ) {\n return (await this.request(\n \"resources/directory/read\",\n cursor === undefined ? { uri } : { uri, cursor },\n options\n )) as import(\"./skills.js\").SkillDirectoryReadResult;\n }\n}\n\n/** @deprecated Use {@link MCPConnection}. */\nexport { MCPConnection as MCPSession };\n\n// Re-export types for convenience\nexport type { CallToolResult, MetaObject, Notification, Root, Tool };\nexport type {\n Skill,\n SkillDirectoryEntry,\n SkillDirectoryReadResult,\n SkillGetResult,\n SkillResource,\n SkillsListResult,\n} from \"./skills.js\";\nexport { SKILLS_EXTENSION_ID } from \"./skills.js\";\n","import type { ServerConfig } from \"../core/config.js\";\n\ninterface ClientTelemetryTracker {\n addServer(name: string, config: ServerConfig): Promise<void> | void;\n removeServer(name: string): Promise<void> | void;\n}\n\nlet tracker: ClientTelemetryTracker | undefined;\n\n/** @internal Configures the runtime-specific client telemetry sink. */\nexport function setClientTelemetryTracker(\n nextTracker: ClientTelemetryTracker | undefined\n): void {\n tracker = nextTracker;\n}\n\n/** @internal Records that a configured server was added. */\nexport function trackClientAddServer(name: string, config: ServerConfig): void {\n void tracker?.addServer(name, config);\n}\n\n/** @internal Records that a configured server was removed. */\nexport function trackClientRemoveServer(name: string): void {\n void tracker?.removeServer(name);\n}\n","const FAVICON_API = \"https://favicon.tools.mcp-use.com\";\n\nconst IPV4_RE = /^\\d{1,3}(\\.\\d{1,3}){3}$/;\n\nfunction parseHostname(serverUrl: string): string | null {\n try {\n const raw = serverUrl.includes(\"://\") ? serverUrl : `https://${serverUrl}`;\n return new URL(raw).hostname;\n } catch {\n return null;\n }\n}\n\nfunction isLocalHost(hostname: string): boolean {\n const h = hostname.toLowerCase();\n if (h === \"localhost\" || h.endsWith(\".localhost\")) return true;\n if (h === \"host.docker.internal\" || h === \"0.0.0.0\") return true;\n if (!IPV4_RE.test(h)) return false;\n\n if (h === \"127.0.0.1\" || h.startsWith(\"127.\")) return true;\n if (h.startsWith(\"10.\")) return true;\n if (h.startsWith(\"192.168.\")) return true;\n\n const m = /^172\\.(\\d+)\\./.exec(h);\n if (m) {\n const second = Number.parseInt(m[1]!, 10);\n if (second >= 16 && second <= 31) return true;\n }\n\n return false;\n}\n\nfunction subdomainLevels(hostname: string): string[] {\n const parts = hostname.split(\".\");\n return Array.from({ length: parts.length - 1 }, (_, i) =>\n parts.slice(i).join(\".\")\n );\n}\n\nfunction blobToDataUrl(blob: Blob): Promise<string> {\n return new Promise((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n}\n\n/**\n * Detect and retrieve an MCP server's favicon as a base64 data URL.\n * Skips local/private hosts; walks subdomain levels until a non-default favicon is found.\n */\nexport async function detectFavicon(serverUrl: string): Promise<string | null> {\n try {\n const hostname = parseHostname(serverUrl);\n if (!hostname || isLocalHost(hostname)) return null;\n\n for (const domain of subdomainLevels(hostname)) {\n try {\n const res = await fetch(`${FAVICON_API}/${domain}?response=json`, {\n signal: AbortSignal.timeout(2000),\n });\n if (!res.ok) continue;\n\n const data = (await res.json()) as { url: string; source: string };\n if (data.source === \"default\") continue;\n\n const imageUrl = data.url.replace(/^http:\\/\\//, \"https://\");\n const img = await fetch(imageUrl, {\n signal: AbortSignal.timeout(2000),\n });\n if (!img.ok) continue;\n\n return await blobToDataUrl(await img.blob());\n } catch {\n continue;\n }\n }\n\n return null;\n } catch (error) {\n console.warn(\"[favicon] Error detecting favicon:\", error);\n return null;\n }\n}\n","import { BrowserOAuthClientProvider } from \"../auth/browser.js\";\nimport type { OAuthClientInformation } from \"@modelcontextprotocol/client\";\nimport type { MCPServerInfo } from \"../core/session.js\";\nimport { detectFavicon } from \"../utils/favicon.js\";\n\nexport const USE_MCP_SERVER_NAME = \"inspector-server\";\n\n/** Asserts that a condition is true, throwing an error if not. */\nexport function assert(condition: unknown, message: string): asserts condition {\n if (!condition) {\n throw new Error(message);\n }\n}\n\ntype ServerInfoWithIcon = MCPServerInfo & { icon?: string };\ntype AddLog = (\n level: \"debug\" | \"info\" | \"warn\" | \"error\",\n message: string,\n ...args: unknown[]\n) => void;\n\n/** Resolve a server-provided icon, then fall back to domain favicon discovery. */\nexport async function loadServerIcon(params: {\n serverInfo: MCPServerInfo;\n url?: string;\n isMounted: () => boolean;\n setServerInfo: (\n update: (previous?: ServerInfoWithIcon) => ServerInfoWithIcon | undefined\n ) => void;\n addLog: AddLog;\n}): Promise<string | null> {\n try {\n const iconUrl = params.serverInfo.icons?.[0]?.src;\n if (iconUrl) {\n params.addLog(\"info\", \"Server provided icon:\", iconUrl);\n const response = await fetch(iconUrl);\n const blob = await response.blob();\n const base64 = await new Promise<string>((resolve, reject) => {\n const reader = new FileReader();\n reader.onloadend = () => resolve(reader.result as string);\n reader.onerror = reject;\n reader.readAsDataURL(blob);\n });\n\n if (params.isMounted()) {\n params.setServerInfo((previous) =>\n previous ? { ...previous, icon: base64 } : undefined\n );\n params.addLog(\"debug\", \"Server icon converted to base64\");\n }\n return base64;\n }\n\n if (params.url) {\n const favicon = await detectFavicon(params.url);\n if (!params.isMounted()) {\n params.addLog(\n \"debug\",\n \"Connection aborted after favicon detection - component unmounted\"\n );\n return null;\n }\n if (favicon) {\n params.setServerInfo((previous) =>\n previous ? { ...previous, icon: favicon } : undefined\n );\n params.addLog(\"debug\", \"Favicon detected and added to serverInfo\");\n return favicon;\n }\n }\n\n return null;\n } catch (error) {\n params.addLog(\"debug\", \"Icon loading failed (non-critical):\", error);\n return null;\n }\n}\n\n/** Human-readable reason when MCP operations run before the client is usable. */\nexport function formatMcpNotReadyReason(\n state: string,\n hasClient: boolean\n): string {\n return !hasClient ? `client disconnected (state=${state})` : `state=${state}`;\n}\n\ntype OAuthClientConfig = {\n name?: string;\n version?: string;\n uri?: string;\n logo_uri?: string;\n};\n\nexport function deriveOAuthClientConfigFromClientInfo(clientInfo: {\n name: string;\n title?: string;\n version: string;\n description?: string;\n icons?: Array<{\n src: string;\n mimeType?: string;\n sizes?: string[];\n }>;\n websiteUrl?: string;\n}): OAuthClientConfig {\n return {\n name: clientInfo.name,\n version: clientInfo.version,\n uri: clientInfo.websiteUrl,\n logo_uri: clientInfo.icons?.[0]?.src,\n };\n}\n\nexport function isOAuthDiscoveryFailure(error: Error | unknown): boolean {\n const errorMessage = error instanceof Error ? error.message : String(error);\n const msg = errorMessage.toLowerCase();\n\n return (\n msg.includes(\"oauth discovery failed\") ||\n msg.includes(\"oauth-authorization-server\") ||\n msg.includes(\"not valid json\") ||\n (msg.includes(\"404\") &&\n (msg.includes(\"openid-configuration\") ||\n msg.includes(\"oauth-protected-resources\") ||\n msg.includes(\"oauth-authorization-url\") ||\n msg.includes(\"register\"))) ||\n (msg.includes(\"invalid oauth error response\") && msg.includes(\"not found\"))\n );\n}\n\n/**\n * Derive the companion OAuth proxy endpoint from an MCP proxy endpoint.\n *\n * The Inspector proxy convention is `/proxy` for MCP traffic and `/oauth` for\n * OAuth metadata/token requests. An explicit OAuth URL always takes priority.\n */\nexport function deriveOAuthProxyUrl(\n gatewayUrl: string | undefined,\n explicitOAuthProxyUrl: string | undefined\n): string | undefined {\n if (explicitOAuthProxyUrl) return explicitOAuthProxyUrl;\n if (!gatewayUrl) return undefined;\n\n try {\n const url = new URL(gatewayUrl);\n url.pathname = url.pathname.replace(/\\/proxy\\/?$/, \"/oauth\");\n return url.toString();\n } catch {\n return undefined;\n }\n}\n\nexport function createBrowserOAuthProvider(params: {\n effectiveOAuthUrl: string;\n storageKeyPrefix: string;\n oauthClientConfig: OAuthClientConfig;\n callbackUrl: string;\n preventAutoAuth: boolean;\n useRedirectFlow: boolean;\n /** MCP proxy URL used to derive the companion OAuth proxy when needed. */\n gatewayUrl?: string;\n /**\n * Explicit OAuth proxy base URL. Takes precedence over the URL derived from\n * `gatewayUrl`. Lets consumers proxy OAuth traffic (CORS bypass) while\n * keeping MCP traffic direct.\n */\n oauthProxyUrl?: string;\n onPopupWindow?: (\n url: string,\n features: string,\n window: globalThis.Window | null\n ) => void;\n /**\n * Whether the provider should route OAuth requests through the derived\n * OAuth proxy (to bypass CORS). The provider exposes this via its scoped\n * `getProxyFetch()` — it never patches the global `fetch`.\n */\n proxyOAuthRequests: boolean;\n staticClientInfo?: OAuthClientInformation;\n clientMetadataUrl?: string;\n scope?: string;\n}): {\n provider: BrowserOAuthClientProvider;\n oauthProxyUrl?: string;\n} {\n const oauthProxyUrl = deriveOAuthProxyUrl(\n params.gatewayUrl,\n params.oauthProxyUrl\n );\n const provider = new BrowserOAuthClientProvider(params.effectiveOAuthUrl, {\n storageKeyPrefix: params.storageKeyPrefix,\n clientName: params.oauthClientConfig.name,\n clientUri: params.oauthClientConfig.uri,\n logoUri:\n params.oauthClientConfig.logo_uri || \"https://mcp-use.com/logo.png\",\n callbackUrl: params.callbackUrl,\n preventAutoAuth: params.preventAutoAuth,\n useRedirectFlow: params.useRedirectFlow,\n oauthProxyUrl,\n connectionUrl: params.gatewayUrl,\n onPopupWindow: params.onPopupWindow,\n proxyOAuthRequests: params.proxyOAuthRequests,\n staticClientInfo: params.staticClientInfo,\n clientMetadataUrl: params.clientMetadataUrl,\n scope: params.scope,\n });\n\n return { provider, oauthProxyUrl };\n}\n\ntype LogLevel = \"debug\" | \"info\" | \"warn\" | \"error\";\n\nexport function startConnectionHealthMonitoring(params: {\n gatewayUrl?: string;\n url?: string;\n allHeaders?: Record<string, string>;\n getAuthHeaders?: () => Promise<Record<string, string>>;\n isMountedRef: { current: boolean };\n stateRef: { current: string };\n autoReconnectRef: { current: boolean | number | Record<string, unknown> };\n setState: (state: \"discovering\") => void;\n addLog: (level: LogLevel, message: string, ...args: unknown[]) => void;\n connect: () => void;\n defaultReconnectDelay: number;\n healthCheckIntervalMs?: number;\n healthCheckTimeoutMs?: number;\n}): () => void {\n let healthCheckInterval: ReturnType<typeof setInterval> | null = null;\n let lastSuccessfulCheck = Date.now();\n // ponytail: many MCP servers only accept POST; one 405/404 disables HEAD polling.\n let headProbeUnsupported = false;\n const healthCheckIntervalMs = params.healthCheckIntervalMs ?? 10000;\n const healthCheckTimeoutMs = params.healthCheckTimeoutMs ?? 30000;\n\n const checkConnectionHealth = async () => {\n if (headProbeUnsupported) {\n return;\n }\n if (!params.isMountedRef.current || params.stateRef.current !== \"ready\") {\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n return;\n }\n\n try {\n const healthCheckUrl = params.gatewayUrl || params.url;\n if (!healthCheckUrl) {\n return;\n }\n\n const authHeaders = params.getAuthHeaders\n ? await params.getAuthHeaders()\n : {};\n const healthCheckHeaders = {\n ...params.allHeaders,\n ...authHeaders,\n ...(params.gatewayUrl && params.url\n ? { \"X-Target-URL\": params.url }\n : {}),\n };\n const response = await fetch(healthCheckUrl, {\n method: \"HEAD\",\n headers: healthCheckHeaders,\n signal: AbortSignal.timeout(5000),\n });\n\n if (response.status === 405 || response.status === 404) {\n headProbeUnsupported = true;\n lastSuccessfulCheck = Date.now();\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n return;\n }\n\n if (response.ok || response.status < 500) {\n lastSuccessfulCheck = Date.now();\n } else {\n throw new Error(`Server returned ${response.status}`);\n }\n } catch {\n const timeSinceLastSuccess = Date.now() - lastSuccessfulCheck;\n if (timeSinceLastSuccess > healthCheckTimeoutMs) {\n params.addLog(\n \"warn\",\n `Connection appears to be broken (no response for ${Math.round(timeSinceLastSuccess / 1000)}s), attempting to reconnect...`\n );\n\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n\n if (params.autoReconnectRef.current && params.isMountedRef.current) {\n params.setState(\"discovering\");\n params.addLog(\"info\", \"Auto-reconnecting to MCP server...\");\n\n setTimeout(\n () => {\n if (\n params.isMountedRef.current &&\n params.stateRef.current === \"discovering\"\n ) {\n params.connect();\n }\n },\n typeof params.autoReconnectRef.current === \"number\"\n ? params.autoReconnectRef.current\n : params.defaultReconnectDelay\n );\n }\n }\n }\n };\n\n healthCheckInterval = setInterval(\n checkConnectionHealth,\n healthCheckIntervalMs\n );\n return () => {\n if (healthCheckInterval) {\n clearInterval(healthCheckInterval);\n healthCheckInterval = null;\n }\n };\n}\n","import type {\n CompleteRequestParams,\n CompleteResult,\n Prompt,\n Resource,\n ResourceTemplateType as ResourceTemplate,\n Tool,\n} from \"@modelcontextprotocol/client\";\nimport {\n useCallback,\n type Dispatch,\n type RefObject,\n type SetStateAction,\n} from \"react\";\nimport type { MCPConnection } from \"../core/session.js\";\nimport { isOAuthInteractionRequired } from \"../auth/flow.js\";\nimport { Tel } from \"../telemetry/telemetry-browser.js\";\nimport { formatMcpNotReadyReason } from \"./useMcp-helpers.js\";\nimport type { UseMcpResult } from \"./types.js\";\n\ntype AddLog = (\n level: UseMcpResult[\"log\"][number][\"level\"],\n message: string,\n ...args: unknown[]\n) => void;\n\ntype Params = {\n stateRef: RefObject<UseMcpResult[\"state\"]>;\n connectionRef: RefObject<MCPConnection | null>;\n hasClient: () => boolean;\n isMounted: () => boolean;\n setTools: Dispatch<SetStateAction<Tool[]>>;\n setResources: Dispatch<SetStateAction<Resource[]>>;\n setResourceTemplates: Dispatch<SetStateAction<ResourceTemplate[]>>;\n setPrompts: Dispatch<SetStateAction<Prompt[]>>;\n setSkills: Dispatch<SetStateAction<import(\"../core/skills.js\").Skill[]>>;\n addLog: AddLog;\n onAuthorizationRequired: (error: unknown) => void;\n};\n\nfunction requireConnection(params: Params, operation: string): MCPConnection {\n const connection = params.connectionRef.current;\n if (\n params.stateRef.current !== \"ready\" ||\n !params.hasClient() ||\n !connection\n ) {\n throw new Error(\n `MCP client is not ready (${formatMcpNotReadyReason(\n params.stateRef.current,\n params.hasClient()\n )}). Cannot ${operation}.`\n );\n }\n return connection;\n}\n\nasync function executeWithAuthorizationSignal<T>(\n params: Params,\n operation: () => Promise<T>\n): Promise<T> {\n try {\n return await operation();\n } catch (error) {\n if (isOAuthInteractionRequired(error)) {\n params.onAuthorizationRequired(error);\n }\n throw error;\n }\n}\n\nexport function useMcpOperations(params: Params) {\n const callTool = useCallback<UseMcpResult[\"callTool\"]>(\n async (name, args, options) => {\n const connection = requireConnection(params, `call tool \"${name}\"`);\n params.addLog(\"info\", `Calling tool: ${name}`, args);\n const startedAt = Date.now();\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.callTool(name, args || {}, options)\n );\n params.addLog(\"info\", `Tool \"${name}\" call successful:`, result);\n Tel.getInstance()\n .trackUseMcpToolCall({\n toolName: name,\n success: true,\n executionTimeMs: Date.now() - startedAt,\n })\n .catch(() => {});\n return result;\n } catch (error) {\n params.addLog(\"error\", `Tool \"${name}\" call failed:`, error);\n Tel.getInstance()\n .trackUseMcpToolCall({\n toolName: name,\n success: false,\n errorType: error instanceof Error ? error.name : \"UnknownError\",\n executionTimeMs: Date.now() - startedAt,\n })\n .catch(() => {});\n throw error;\n }\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const listResources = useCallback(async () => {\n const connection = requireConnection(params, \"list resources\");\n params.addLog(\"info\", \"Listing resources\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listAllResources()\n );\n params.setResources(result.resources || []);\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const readResource = useCallback(\n async (uri: string) => {\n const connection = requireConnection(params, \"read resource\");\n params.addLog(\"info\", `Reading resource: ${uri}`);\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.readResource(uri)\n );\n Tel.getInstance()\n .trackUseMcpResourceRead({ resourceUri: uri, success: true })\n .catch(() => {});\n return result;\n } catch (error) {\n Tel.getInstance()\n .trackUseMcpResourceRead({\n resourceUri: uri,\n success: false,\n errorType: error instanceof Error ? error.name : \"UnknownError\",\n })\n .catch(() => {});\n throw error;\n }\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const listSkills = useCallback(async () => {\n const connection = requireConnection(params, \"list skills\");\n params.addLog(\"info\", \"Listing skills\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listAllSkills()\n );\n params.setSkills(result.skills);\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const getSkill = useCallback(\n async (uri: string) => {\n const connection = requireConnection(params, \"get skill\");\n params.addLog(\"info\", `Getting skill: ${uri}`);\n return executeWithAuthorizationSignal(params, () =>\n connection.getSkill(uri)\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const readResourceDirectory = useCallback(\n async (uri: string, cursor?: string) => {\n const connection = requireConnection(params, \"read resource directory\");\n params.addLog(\"info\", `Reading resource directory: ${uri}`);\n return executeWithAuthorizationSignal(params, () =>\n connection.readResourceDirectory(uri, cursor)\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const listPrompts = useCallback(async () => {\n const connection = requireConnection(params, \"list prompts\");\n params.addLog(\"info\", \"Listing prompts\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listPrompts()\n );\n params.setPrompts(result.prompts || []);\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshTools = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n params.setTools(\n (await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listTools()\n )) || []\n );\n } catch (error) {\n params.addLog(\"error\", \"Failed to refresh tools:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshResources = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listAllResources()\n );\n params.setResources(result.resources || []);\n } catch (error) {\n params.addLog(\"warn\", \"Failed to refresh resources:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshPrompts = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listPrompts()\n );\n params.setPrompts(result.prompts || []);\n } catch (error) {\n params.addLog(\"warn\", \"Failed to refresh prompts:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshSkills = useCallback(async () => {\n if (params.stateRef.current !== \"ready\" || !params.connectionRef.current)\n return;\n try {\n const result = await executeWithAuthorizationSignal(params, () =>\n params.connectionRef.current!.listAllSkills()\n );\n params.setSkills(result.skills);\n } catch (error) {\n // A development reload may remove the final skills directory, in which\n // case the replacement server intentionally no longer exposes the\n // extension. Clear the prior snapshot without treating that transition\n // as a connection failure.\n params.setSkills([]);\n params.addLog(\"debug\", \"Skills are unavailable after refresh:\", error);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshResourceTemplates = useCallback(async () => {\n const connection = requireConnection(params, \"refresh resource templates\");\n const result = await executeWithAuthorizationSignal(params, () =>\n connection.listResourceTemplates()\n );\n if (params.isMounted()) {\n params.setResourceTemplates(result.resourceTemplates || []);\n }\n }, [params.addLog, params.onAuthorizationRequired]);\n\n const refreshAll = useCallback(\n () =>\n Promise.all([\n refreshTools(),\n refreshResources(),\n refreshResourceTemplates(),\n refreshPrompts(),\n ]).then(() => undefined),\n [refreshTools, refreshResources, refreshResourceTemplates, refreshPrompts]\n );\n\n const getPrompt = useCallback(\n async (name: string, args?: Record<string, unknown>) => {\n const connection = requireConnection(params, \"get prompt\");\n return executeWithAuthorizationSignal(params, () =>\n connection.getPrompt(name, args || {})\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n const complete = useCallback(\n async (request: CompleteRequestParams): Promise<CompleteResult> => {\n const connection = requireConnection(params, \"request completion\");\n return executeWithAuthorizationSignal(params, () =>\n connection.complete(request)\n );\n },\n [params.addLog, params.onAuthorizationRequired]\n );\n\n return {\n callTool,\n listResources,\n readResource,\n listSkills,\n getSkill,\n readResourceDirectory,\n listPrompts,\n refreshTools,\n refreshResources,\n refreshPrompts,\n refreshSkills,\n refreshResourceTemplates,\n refreshAll,\n getPrompt,\n complete,\n };\n}\n","/**\n * Resolve an OAuth token's absolute expiry. JWT `exp` is authoritative when\n * available; `expires_in` is only a fallback for opaque tokens.\n */\nexport function getOAuthTokenExpiry(tokens: {\n access_token?: string;\n expires_in?: unknown;\n}): number | undefined {\n try {\n const payload = JSON.parse(atob(tokens.access_token?.split(\".\")[1] ?? \"\"));\n if (typeof payload.exp === \"number\") return payload.exp * 1000;\n } catch {\n // Opaque tokens do not contain a JWT expiry claim.\n }\n return typeof tokens.expires_in === \"number\"\n ? Date.now() + tokens.expires_in * 1000\n : undefined;\n}\n","import { StreamableHTTPClientTransport } from \"@modelcontextprotocol/client\";\nimport { BrowserOAuthClientProvider } from \"./browser.js\";\nimport {\n MCP_AUTH_BROADCAST_CHANNEL,\n MCP_AUTH_CALLBACK_MESSAGE_TYPE,\n type McpAuthCallbackMessage,\n} from \"./popup.js\";\nimport type { StoredState } from \"./session-store.js\";\nimport { LocalStorageKVStore } from \"./storage.js\";\n\ninterface AuthCallbackMeta {\n state?: string | null;\n serverUrlHash?: string | null;\n}\n\nlet inFlightCallback: Promise<void> | null = null;\n\nfunction isMcpAuthPopupWindow(): boolean {\n return typeof window !== \"undefined\" && window.name.startsWith(\"mcp_auth_\");\n}\n\nfunction buildCallbackPayload(\n success: boolean,\n error: string | undefined,\n meta: AuthCallbackMeta\n): McpAuthCallbackMessage {\n return {\n type: MCP_AUTH_CALLBACK_MESSAGE_TYPE,\n success,\n ...(success ? {} : { error: error ?? \"Unknown error\" }),\n ...(meta.state ? { state: meta.state } : {}),\n ...(meta.serverUrlHash ? { serverUrlHash: meta.serverUrlHash } : {}),\n };\n}\n\nfunction broadcastCallback(payload: McpAuthCallbackMessage): void {\n if (typeof BroadcastChannel === \"undefined\") return;\n\n let channel: BroadcastChannel | undefined;\n try {\n channel = new BroadcastChannel(MCP_AUTH_BROADCAST_CHANNEL);\n channel.postMessage(payload);\n } catch (error) {\n console.warn(\"[mcp-callback] Failed to broadcast callback result:\", error);\n } finally {\n if (channel) {\n setTimeout(() => {\n try {\n channel?.close();\n } catch {\n // Best-effort signaling only.\n }\n }, 0);\n }\n }\n}\n\nfunction renderResult(\n title: string,\n message: string,\n error: boolean,\n returnUrl?: string\n): void {\n if (typeof document === \"undefined\") return;\n\n document.body.innerHTML = \"\";\n const container = document.createElement(\"div\");\n container.style.fontFamily = \"sans-serif\";\n container.style.padding = \"20px\";\n\n const heading = document.createElement(\"h1\");\n heading.textContent = title;\n container.appendChild(heading);\n\n const text = document.createElement(\"p\");\n text.textContent = message;\n if (error) {\n text.style.color = \"red\";\n text.style.backgroundColor = \"#ffebeb\";\n text.style.border = \"1px solid red\";\n text.style.padding = \"10px\";\n text.style.borderRadius = \"4px\";\n }\n container.appendChild(text);\n\n const close = document.createElement(\"a\");\n close.href = \"#\";\n close.textContent = \"Close this window\";\n close.onclick = (event) => {\n event.preventDefault();\n window.close();\n return false;\n };\n container.appendChild(close);\n\n if (returnUrl) {\n const separator = document.createTextNode(\" or \");\n const back = document.createElement(\"a\");\n back.href = returnUrl;\n back.textContent = \"return to the app\";\n container.append(separator, back);\n }\n\n document.body.appendChild(container);\n}\n\nasync function findStoredState(state: string): Promise<{\n key: string;\n value: StoredState;\n store: LocalStorageKVStore;\n}> {\n const store = new LocalStorageKVStore();\n const legacySuffix = `:state_${state}`;\n const scopedSuffix = `_state_${state}`;\n const key = (await store.keys()).find(\n (candidate) =>\n candidate.endsWith(legacySuffix) || candidate.endsWith(scopedSuffix)\n );\n const serialized = key ? await store.get(key) : null;\n if (!key || !serialized) {\n throw new Error(`Invalid or expired OAuth state \"${state}\".`);\n }\n\n let value: StoredState;\n try {\n value = JSON.parse(serialized) as StoredState;\n } catch {\n await store.remove(key);\n throw new Error(\"Failed to parse stored OAuth state.\");\n }\n\n return { key, value, store };\n}\n\nfunction redirectWithError(returnUrl: string, message: string): void {\n const url = new URL(returnUrl);\n url.searchParams.set(\"auth_error\", \"oauth_callback_failed\");\n url.searchParams.set(\"auth_error_description\", message);\n window.location.href = url.toString();\n}\n\nfunction signalResult(\n success: boolean,\n error: string | undefined,\n storedState: StoredState | null,\n meta: AuthCallbackMeta\n): void {\n const payload = buildCallbackPayload(success, error, meta);\n const returnUrl = storedState?.returnUrl;\n const popup = storedState?.flowType === \"popup\" || isMcpAuthPopupWindow();\n\n if (storedState?.flowType === \"redirect\" && returnUrl) {\n if (success) window.location.href = returnUrl;\n else redirectWithError(returnUrl, error ?? \"Authentication failed.\");\n return;\n }\n\n if (window.opener && !window.opener.closed) {\n window.opener.postMessage(payload, window.location.origin);\n window.close();\n return;\n }\n\n if (popup) {\n broadcastCallback(payload);\n renderResult(\n success ? \"Authentication Successful!\" : \"Authentication Error\",\n success\n ? \"You're authenticated. You can close this window and return to the app.\"\n : (error ?? \"Authentication failed.\"),\n !success,\n returnUrl\n );\n try {\n window.close();\n } catch {\n // The browser may forbid closing after a COOP browsing-context swap.\n }\n return;\n }\n\n if (returnUrl) {\n if (success) window.location.href = returnUrl;\n else redirectWithError(returnUrl, error ?? \"Authentication failed.\");\n return;\n }\n\n if (!success) {\n renderResult(\n \"Authentication Error\",\n error ?? \"Authentication failed.\",\n true\n );\n return;\n }\n\n window.location.href = \"/\";\n}\n\n/**\n * Completes the browser OAuth callback once per page load.\n *\n * This host validates the CSRF state and restores the browser provider. The MCP\n * SDK transport owns callback parameter parsing, issuer validation, OAuth error\n * handling, and the authorization-code exchange.\n */\nexport function onMcpAuthorization(): Promise<void> {\n if (!inFlightCallback) inFlightCallback = completeAuthorization();\n return inFlightCallback;\n}\n\nasync function completeAuthorization(): Promise<void> {\n const callbackParams = new URLSearchParams(window.location.search);\n const state = callbackParams.get(\"state\");\n let stateKey: string | null = null;\n let stateStore: LocalStorageKVStore | null = null;\n let storedState: StoredState | null = null;\n let provider: BrowserOAuthClientProvider | null = null;\n\n try {\n if (!state) {\n throw new Error(\"OAuth callback is missing the state parameter.\");\n }\n\n const stored = await findStoredState(state);\n stateKey = stored.key;\n stateStore = stored.store;\n storedState = stored.value;\n\n if (!storedState.expiry || storedState.expiry < Date.now()) {\n await stateStore.remove(stateKey);\n throw new Error(\n \"OAuth state has expired. Please start authentication again.\"\n );\n }\n\n if (!storedState.providerOptions) {\n throw new Error(\"Stored OAuth state is missing provider options.\");\n }\n\n const { serverUrl, ...providerOptions } = storedState.providerOptions;\n provider = new BrowserOAuthClientProvider(serverUrl, providerOptions);\n\n const transport = new StreamableHTTPClientTransport(new URL(serverUrl), {\n authProvider: provider,\n fetch: provider.getProxyFetch(),\n });\n\n await transport.finishAuth(callbackParams);\n await stateStore.remove(stateKey);\n signalResult(true, undefined, storedState, {\n state,\n serverUrlHash: storedState.serverUrlHash,\n });\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n console.error(\"[mcp-callback] OAuth callback failed:\", error);\n\n if (stateKey && stateStore) await stateStore.remove(stateKey);\n if (provider) {\n await (stateStore ?? new LocalStorageKVStore()).remove(\n provider.getKey(\"last_auth_url\")\n );\n }\n\n signalResult(false, message, storedState, {\n state,\n serverUrlHash: storedState?.serverUrlHash,\n });\n }\n}\n","/**\n * React entry point for the MCP connection console.\n *\n * Provides the `useMcp` hook, the multi-server `McpClientProvider`, and the\n * supporting storage / logging utilities for connecting to MCP servers from a\n * React app. MCP Apps host rendering lives in {@link ViewRenderer}.\n */\n\nexport type {\n UseMcpOptions,\n UseMcpResult,\n ReconnectionOptions,\n McpServer,\n McpServerConfig,\n /** @deprecated Use McpServerConfig */\n McpServerOptions,\n PersistedMcpServerConfig,\n McpNotification,\n PendingSamplingRequest,\n PendingElicitationRequest,\n} from \"./types.js\";\nexport type {\n Skill,\n SkillDirectoryEntry,\n SkillDirectoryReadResult,\n SkillGetResult,\n SkillResource,\n SkillsListResult,\n} from \"../core/skills.js\";\nexport { SKILLS_EXTENSION_ID } from \"../core/skills.js\";\nexport { pickPersistedServerConfig, toPersistedServerConfig } from \"./types.js\";\nexport { useMcp } from \"./useMcp.js\";\nexport { detectFavicon } from \"../utils/favicon.js\";\n\n// Re-export auth callback handler for the OAuth flow\nexport { onMcpAuthorization } from \"../auth/callback.js\";\nexport { isOAuthInteractionRequired } from \"../auth/flow.js\";\n\n// Re-export browser telemetry (browser-specific implementation)\nexport {\n Tel,\n Telemetry,\n setTelemetrySource,\n} from \"../telemetry/telemetry-browser.js\";\n\n// Protocol types re-exported so consumers need only @mcp-use/client/react.\nexport type {\n CallToolResult,\n ContentBlock,\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n GetPromptResult,\n JSONRPCMessage,\n Prompt,\n ReadResourceResult,\n Resource,\n ResourceTemplateType,\n Tool,\n Transport,\n} from \"@modelcontextprotocol/client\";\nexport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\n/** JSON-RPC envelope for `sampling/createMessage`. */\nexport type SamplingCreateMessageRequest = {\n /** JSON-RPC method name. */\n method: \"sampling/createMessage\";\n /** Sampling request parameters. */\n params: SamplingCreateMessageParams;\n};\n/** @deprecated Use {@link SamplingCreateMessageRequest}. */\nexport type { SamplingCreateMessageRequest as CreateMessageRequest };\n/** @deprecated Use {@link SamplingCreateMessageResult}. */\nexport type { SamplingCreateMessageResult as CreateMessageResult };\nexport { specTypeSchemas } from \"@modelcontextprotocol/client\";\n\n// Multi-server client provider and hooks\nexport {\n McpClientProvider,\n useMcpClient,\n useMcpServer,\n} from \"./McpClientProvider.js\";\nexport type {\n McpClientContextType,\n McpClientProviderProps,\n} from \"./McpClientProvider.js\";\n\n// Storage providers\nexport {\n LocalStorageProvider,\n MemoryStorageProvider,\n type CachedServerMetadata,\n type StorageProvider,\n} from \"./storage.js\";\n\n// RPC logger utilities\nexport {\n getRpcLogs,\n getAllRpcLogs,\n subscribeToRpcLogs,\n clearRpcLogs,\n type RpcLogEntry,\n} from \"./rpc-logger.js\";\n\n// MCP Apps host renderer\nexport {\n ViewRenderer,\n resolveViewResource,\n getViewResourceUri,\n isViewResource,\n isViewTool,\n isToolVisibleToModel,\n parseCustomProps,\n buildSandboxProxyBlobHtml,\n buildViewSandboxBlobUrl,\n buildViewSandboxUrl,\n type ViewRendererProps,\n type ViewConnection,\n type ViewDisplayMode,\n type ViewCspMode,\n type ViewRendererSource,\n type ResolvedViewResource,\n type ViewCspViolation,\n type ViewLifecycleEvent,\n type ViewLifecycleStatus,\n type ViewAppToolConnection,\n type McpUiDownloadFileRequest,\n type McpUiDownloadFileResult,\n type McpUiHostCapabilities,\n type McpUiHostContext,\n type McpUiResourceCsp,\n type McpUiResourcePermissions,\n type McpUiSupportedContentBlockModalities,\n} from \"./view/ViewRenderer.js\";\n","import type { ElicitResult, Transport } from \"@modelcontextprotocol/client\";\nimport type { SamplingCreateMessageResult } from \"../core/config.js\";\nimport React, {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode,\n} from \"react\";\nimport { Logger } from \"../utils/logging.js\";\nimport type { StorageProvider } from \"./storage.js\";\nimport type {\n McpServer,\n McpServerConfig,\n PendingElicitationRequest,\n PendingSamplingRequest,\n PersistedMcpServerConfig,\n} from \"./types.js\";\nimport { pickLiveServerConfig, toPersistedServerConfig } from \"./types.js\";\nimport { useMcp } from \"./useMcp.js\";\nimport { useMcpServerQueues } from \"./useMcpServerQueues.js\";\n\n// Module-level logger for McpClientProvider & friends\nconst providerLogger = Logger.get(\"McpClientProvider\");\n\n// ===== Types =====\n\n/**\n * Context value for multi-server management\n */\nexport interface McpClientContextType {\n /** Managed servers and their current reactive state. */\n servers: McpServer[];\n /** Idempotent — safe to call multiple times with the same id; duplicates are silently ignored. */\n addServer: (id: string, config: McpServerConfig) => void;\n /**\n * Remove a server from the provider.\n *\n * By default this only tears down the live connection and leaves persisted\n * OAuth credentials (tokens / client_info / PKCE verifier) intact, so routine\n * remove+add churn (config refetches, deployment-status flips, env-scoped\n * wrappers sharing a URL hash) does not silently log the user out.\n *\n * Pass `{ clearCredentials: true }` for an explicit logout / \"forget this\n * server\" action to also wipe the persisted OAuth storage.\n */\n removeServer: (\n id: string,\n opts?: { clearCredentials?: boolean }\n ) => Promise<void>;\n /** Updates cached presentation metadata for a managed server. */\n updateServerMetadata: (\n id: string,\n metadata: { name: string }\n ) => Promise<void>;\n /** Merges configuration changes into a managed server. */\n updateServer: (\n id: string,\n options: Partial<McpServerConfig>\n ) => Promise<void>;\n /** Returns a managed server by ID. */\n getServer: (id: string) => McpServer | undefined;\n /** Whether storage has finished loading (true if no storage provider) */\n storageLoaded: boolean;\n}\n\n// ===== Context =====\n\nconst McpClientContext = createContext<McpClientContextType | null>(null);\n\n// ===== Constants =====\n\nfunction sameSerializedValue(left: unknown, right: unknown): boolean {\n return JSON.stringify(left) === JSON.stringify(right);\n}\n\n/**\n * Compares the serializable provider-facing state for one MCP connection.\n *\n * The wrapper and provider both use this comparison so metadata-only updates\n * (including negotiated v1/v2 details) cannot be dropped at either boundary.\n */\nfunction isSameMcpServer(left: McpServer, right: McpServer): boolean {\n return (\n left.id === right.id &&\n sameSerializedValue(\n pickLiveServerConfig(left),\n pickLiveServerConfig(right)\n ) &&\n left.name === right.name &&\n left.state === right.state &&\n left.error === right.error &&\n left.authUrl === right.authUrl &&\n sameSerializedValue(left.authTokens, right.authTokens) &&\n sameSerializedValue(left.authorization, right.authorization) &&\n left.protocolEra === right.protocolEra &&\n left.protocolVersion === right.protocolVersion &&\n sameSerializedValue(left.serverInfo, right.serverInfo) &&\n sameSerializedValue(left.capabilities, right.capabilities) &&\n left.instructions === right.instructions &&\n sameSerializedValue(left.extensions, right.extensions) &&\n sameSerializedValue(left.tools, right.tools) &&\n sameSerializedValue(left.resources, right.resources) &&\n sameSerializedValue(left.resourceTemplates, right.resourceTemplates) &&\n sameSerializedValue(left.prompts, right.prompts) &&\n sameSerializedValue(left.skills, right.skills) &&\n sameSerializedValue(left.notifications, right.notifications) &&\n left.unreadNotificationCount === right.unreadNotificationCount &&\n sameSerializedValue(\n left.pendingSamplingRequests,\n right.pendingSamplingRequests\n ) &&\n sameSerializedValue(\n left.pendingElicitationRequests,\n right.pendingElicitationRequests\n ) &&\n left.client === right.client\n );\n}\n\ninterface ServerConfig {\n id: string;\n options: McpServerConfig;\n}\n\ninterface McpServerWrapperProps {\n id: string;\n options: McpServerConfig;\n defaultCallbackUrl?: string;\n defaultOAuthProxyUrl?: string;\n defaultProxyConfig?: {\n proxyAddress?: string;\n headers?: Record<string, string>;\n };\n defaultAutoProxyFallback?:\n | boolean\n | {\n enabled?: boolean;\n proxyAddress?: string;\n };\n /** Default connection config merged under each server (per-server wins). */\n defaultServerConfig?: Partial<McpServerConfig>;\n clientInfo?: {\n name: string;\n title?: string;\n version: string;\n description?: string;\n icons?: Array<{\n src: string;\n mimeType?: string;\n sizes?: string[];\n }>;\n websiteUrl?: string;\n /**\n * Default capabilities advertised to all servers managed by this provider.\n * Per-server `clientOptions.capabilities` are merged on top, with per-server\n * values taking precedence. Stripped from the MCP `clientInfo` wire field.\n */\n capabilities?: Record<string, unknown>;\n };\n cachedMetadata?: import(\"./storage.js\").CachedServerMetadata;\n onUpdate: (server: McpServer) => void;\n onUpdateConfig: (\n id: string,\n config: Partial<McpServerConfig>\n ) => Promise<void>;\n onUpdateDisplayName: (id: string, displayName: string) => Promise<void>;\n onReconnect: (id: string) => Promise<void>;\n rpcWrapTransport?: (transport: Transport, serverId: string) => Transport;\n onGlobalSamplingRequest?: (\n request: PendingSamplingRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: SamplingCreateMessageResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n onGlobalElicitationRequest?: (\n request: PendingElicitationRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: ElicitResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n}\n\n/**\n * Wraps a single MCP connection (useMcp) and manages per-server notifications,\n * pending sampling and elicitation requests, and exposes state updates to a parent.\n *\n * This internal component wires the MCP hook callbacks to local queues/handlers,\n * applies optional transport wrappers (e.g., RPC logging), maintains notification\n * history with unread tracking, and calls `onUpdate` with an enriched `McpServer`\n * view when meaningful server state changes occur.\n *\n * @param id - Unique identifier for the server instance\n * @param options - Configuration passed to the underlying MCP hook; callbacks for sampling, elicitation, and notifications are handled by this wrapper and therefore excluded from the forwarded options\n * @param onUpdate - Callback invoked with the current `McpServer` representation when the server's meaningful state changes\n * @param rpcWrapTransport - Optional transport wrapper (typically for RPC logging) that will be composed with the user's `wrapTransport` if provided\n * @param onGlobalSamplingRequest - Optional global handler invoked whenever a sampling request is enqueued; receives the request, server id/name, and approve/reject handlers\n * @param onGlobalElicitationRequest - Optional global handler invoked whenever an elicitation request is enqueued; receives the request, server id/name, and approve/reject handlers\n */\nfunction McpServerWrapper({\n id,\n options,\n defaultCallbackUrl,\n defaultOAuthProxyUrl,\n defaultProxyConfig,\n defaultAutoProxyFallback,\n clientInfo: providerClientInfo,\n cachedMetadata,\n onUpdate,\n onUpdateConfig,\n onUpdateDisplayName,\n onReconnect,\n rpcWrapTransport,\n onGlobalSamplingRequest,\n onGlobalElicitationRequest,\n}: McpServerWrapperProps) {\n // Extract callback options (these don't need to be passed to useMcp)\n const {\n displayName,\n onSamplingRequest,\n onElicitationRequest,\n onNotificationReceived,\n wrapTransport: optionsWrapTransport,\n } = options;\n\n // Memoize the options passed to useMcp to prevent render loops\n // The spread operator creates new objects every render, which causes\n // useMcp's callbacks (connect, retry) to be recreated, triggering the\n // autoRetry effect repeatedly\n const mcpOptions = useMemo(() => {\n const {\n displayName: _displayName,\n onSamplingRequest: _onSamplingRequest,\n onElicitationRequest: _onElicitationRequest,\n onNotificationReceived: _onNotificationReceived,\n wrapTransport: _wrapTransport,\n ...rest\n } = options;\n\n // Merge defaults from provider with server-specific options\n // Server-specific options take precedence over defaults\n return {\n ...rest,\n // Use server-specific callbackUrl if provided, otherwise use provider default\n callbackUrl: rest.callbackUrl || defaultCallbackUrl,\n oauthProxyUrl: rest.oauthProxyUrl || defaultOAuthProxyUrl,\n // Use server-specific proxyConfig if provided, otherwise use default\n proxyConfig: rest.proxyConfig || defaultProxyConfig,\n // Use server-specific autoProxyFallback if provided, otherwise use default\n autoProxyFallback:\n rest.autoProxyFallback !== undefined\n ? rest.autoProxyFallback\n : defaultAutoProxyFallback,\n // Merge provider clientInfo with server-specific clientInfo\n // Server-specific takes precedence\n clientInfo: rest.clientInfo\n ? providerClientInfo\n ? { ...providerClientInfo, ...rest.clientInfo }\n : rest.clientInfo\n : providerClientInfo,\n // Pass cached metadata as initial server info if available\n _initialServerInfo: cachedMetadata,\n serverId: id,\n };\n }, [\n options,\n defaultCallbackUrl,\n defaultOAuthProxyUrl,\n defaultProxyConfig,\n defaultAutoProxyFallback,\n providerClientInfo,\n cachedMetadata,\n ]);\n\n // Merge user's wrapTransport with RPC logging wrapper\n const combinedWrapTransport = useMemo(() => {\n if (!rpcWrapTransport && !optionsWrapTransport) return undefined;\n\n return (transport: Transport) => {\n let wrapped = transport;\n\n // Apply RPC logging first if enabled\n if (rpcWrapTransport) {\n wrapped = rpcWrapTransport(wrapped, id);\n }\n\n // Then apply user's wrapper if provided\n if (optionsWrapTransport) {\n wrapped = optionsWrapTransport(wrapped, id);\n }\n\n return wrapped;\n };\n }, [rpcWrapTransport, optionsWrapTransport, id]);\n\n const queues = useMcpServerQueues({\n serverId: id,\n serverName: displayName || id,\n onNotificationReceived,\n onSamplingRequest,\n onElicitationRequest,\n onGlobalSamplingRequest,\n onGlobalElicitationRequest,\n });\n\n // Use the core useMcp hook with our callbacks\n const mcp = useMcp({\n ...mcpOptions,\n onNotification: queues.onNotification,\n onSampling: queues.onSampling,\n onElicitation: queues.onElicitation,\n wrapTransport: combinedWrapTransport,\n });\n\n useEffect(() => {\n if (mcp.state !== \"ready\") {\n queues.rejectAll(\"MCP server connection is no longer active\");\n }\n }, [mcp.state, queues.rejectAll]);\n\n const updateConfig = useCallback(\n (config: Partial<McpServerConfig>) => onUpdateConfig(id, config),\n [id, onUpdateConfig]\n );\n\n const setHeaders = useCallback(\n (headers: Record<string, string> | undefined) => {\n const proxyAddress = options.proxyConfig?.proxyAddress?.trim();\n if (options.connectionMode === \"proxy\" && proxyAddress) {\n return onUpdateConfig(id, {\n proxyConfig: {\n ...options.proxyConfig,\n proxyAddress,\n ...(headers ? { headers } : {}),\n },\n headers: undefined,\n });\n }\n return onUpdateConfig(id, { headers });\n },\n [id, options.connectionMode, options.proxyConfig, onUpdateConfig]\n );\n\n const setDisplayName = useCallback(\n (displayName: string) => onUpdateDisplayName(id, displayName),\n [id, onUpdateDisplayName]\n );\n\n const reconnect = useCallback(() => onReconnect(id), [id, onReconnect]);\n\n // Update parent when state changes\n const onUpdateRef = useRef(onUpdate);\n const prevServerRef = useRef<McpServer | null>(null);\n\n useEffect(() => {\n onUpdateRef.current = onUpdate;\n }, [onUpdate]);\n\n useEffect(() => {\n const server: McpServer = {\n ...pickLiveServerConfig(options),\n ...mcp,\n id,\n displayName: displayName || options.displayName || id,\n notifications: queues.notifications,\n unreadNotificationCount: queues.unreadNotificationCount,\n markNotificationRead: queues.markNotificationRead,\n markAllNotificationsRead: queues.markAllNotificationsRead,\n clearNotifications: queues.clearNotifications,\n pendingSamplingRequests: queues.pendingSamplingRequests,\n approveSampling: queues.approveSampling,\n rejectSampling: queues.rejectSampling,\n pendingElicitationRequests: queues.pendingElicitationRequests,\n approveElicitation: queues.approveElicitation,\n rejectElicitation: queues.rejectElicitation,\n updateConfig,\n setHeaders,\n setDisplayName,\n reconnect,\n };\n\n // Only update if something actually changed\n const prevServer = prevServerRef.current;\n if (!prevServer || !isSameMcpServer(prevServer, server)) {\n prevServerRef.current = server;\n onUpdateRef.current(server);\n } else {\n providerLogger.debug(\n `[McpServerWrapper ${id}] No meaningful changes detected, skipping onUpdate`\n );\n }\n }, [\n id,\n displayName,\n options,\n options.url,\n // Primitive values that indicate meaningful state changes\n mcp.state,\n mcp.error,\n mcp.authUrl,\n mcp.tools,\n mcp.resources,\n mcp.resourceTemplates,\n mcp.prompts,\n mcp.skills,\n mcp.serverInfo,\n mcp.capabilities,\n mcp.protocolEra,\n mcp.protocolVersion,\n mcp.instructions,\n mcp.extensions,\n mcp.authTokens,\n mcp.authorization,\n // Functions excluded - they're stable via useCallback in useMcp\n // mcp.log excluded - log changes shouldn't trigger provider updates\n // mcp.client excluded - client reference stability handled by manual check\n queues,\n updateConfig,\n setHeaders,\n setDisplayName,\n reconnect,\n ]);\n\n return null;\n}\n\n// ===== Provider =====\n\n/**\n * Props for McpClientProvider\n */\nexport interface McpClientProviderProps {\n /** React subtree that can access the MCP client context. */\n children: ReactNode;\n\n /**\n * Initial servers configuration (like Python MCPClient.from_dict)\n * Servers defined here will be auto-connected on mount\n */\n mcpServers?: Record<string, McpServerConfig>;\n\n /**\n * Default OAuth callback URL for all servers.\n * Can be overridden per-server via the callbackUrl option in addServer().\n * Useful when the app is mounted at a sub-path (e.g. /inspector) so the\n * OAuth redirect lands on the correct route without requiring a server-side\n * redirect shim.\n */\n defaultCallbackUrl?: string;\n\n /** Default same-origin OAuth BFF URL for browser OAuth requests. */\n defaultOAuthProxyUrl?: string;\n\n /**\n * Default proxy configuration for all servers\n * Can be overridden per-server in addServer() options\n */\n defaultProxyConfig?: {\n /** Default MCP proxy endpoint. */\n proxyAddress?: string;\n /** Default headers sent to the MCP proxy. */\n headers?: Record<string, string>;\n };\n\n /**\n * Enable automatic proxy fallback for all servers by default\n * When enabled, if a direct connection fails with FastMCP or CORS errors,\n * automatically retries using proxy configuration\n * @defaultValue false\n */\n defaultAutoProxyFallback?:\n | boolean\n | {\n /** Whether automatic proxy fallback is enabled. */\n enabled?: boolean;\n /** Proxy endpoint used after direct connection fails. */\n proxyAddress?: string;\n };\n\n /**\n * Default connection options merged under each server's options (per-server wins).\n * Useful for app-wide auth UX such as `preventAutoAuth` or `useRedirectFlow`.\n */\n defaultServerConfig?: Partial<McpServerConfig>;\n\n /**\n * Client info for all servers (used for OAuth registration and server capabilities).\n * Can be overridden per-server in addServer() options.\n *\n * The optional `capabilities` field sets default MCP capabilities advertised to\n * every server managed by this provider (e.g. MCP Apps / SEP-1865 extensions).\n * It is merged with per-server `clientOptions.capabilities` (per-server takes\n * precedence) and is stripped from the actual MCP `clientInfo` wire field.\n */\n clientInfo?: {\n /** Client name displayed on OAuth consent pages (required) */\n name: string;\n /** Client title/display name */\n title?: string;\n /** Client version (required) */\n version: string;\n /** Client description */\n description?: string;\n /** Client icons (first icon used as logo_uri for OAuth) */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n /** Supported icon sizes, such as `\"48x48\"`. */\n sizes?: string[];\n }>;\n /** Client website URL (used as client_uri for OAuth) */\n websiteUrl?: string;\n /**\n * Default capabilities advertised to all servers managed by this provider.\n * Per-server `clientOptions.capabilities` are merged on top, with per-server\n * values taking precedence. Stripped from the MCP `clientInfo` wire field.\n *\n * @example\n * ```tsx\n * capabilities: {\n * views: true,\n * // or explicitly:\n * extensions: {\n * \"io.modelcontextprotocol/ui\": { mimeTypes: [\"text/html;profile=mcp-app\"] },\n * },\n * }\n * ```\n */\n capabilities?: Record<string, unknown>;\n };\n\n /**\n * Storage provider for persisting server configurations\n * When provided, automatically loads servers on mount and saves on changes\n */\n storageProvider?: StorageProvider;\n\n /**\n * Enable RPC logging for debugging (browser only)\n * Logs all MCP protocol messages to console\n */\n enableRpcLogging?: boolean;\n\n /**\n * Callback when a server is added\n */\n onServerAdded?: (id: string, server: McpServer) => void;\n\n /**\n * Callback when a server is removed\n */\n onServerRemoved?: (id: string) => void;\n\n /**\n * Callback when a server's state changes\n */\n onServerStateChange?: (id: string, state: McpServer[\"state\"]) => void;\n\n /**\n * Callback when a sampling request is received from any server\n * @param request - The sampling request details\n * @param serverId - The ID of the server that sent the request\n * @param serverName - The name of the server\n * @param approve - Function to approve the request\n * @param reject - Function to reject the request\n */\n onSamplingRequest?: (\n request: PendingSamplingRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: SamplingCreateMessageResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n\n /**\n * Callback when an elicitation request is received from any server\n * @param request - The elicitation request details\n * @param serverId - The ID of the server that sent the request\n * @param serverName - The name of the server\n * @param approve - Function to approve the request\n * @param reject - Function to reject the request\n */\n onElicitationRequest?: (\n request: PendingElicitationRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: ElicitResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n}\n\n/**\n * Provider for managing multiple MCP server connections\n *\n * Provides a context for adding/removing servers and accessing their state.\n * Each server maintains its own connection, notification history, and\n * pending sampling/elicitation requests.\n *\n * Supports:\n * - Initial server configuration via `mcpServers` prop\n * - Persistence via pluggable `storageProvider`\n * - RPC logging for debugging\n * - Lifecycle callbacks for state changes\n *\n * @example\n * ```tsx\n * // With initial servers\n * <McpClientProvider\n * mcpServers={{\n * linear: { url: \"https://mcp.linear.app/sse\" },\n * github: { url: \"https://mcp.github.com/mcp\" }\n * }}\n * >\n * <MyApp />\n * </McpClientProvider>\n *\n * // With persistence\n * <McpClientProvider\n * storageProvider={new LocalStorageProvider(\"my-servers\")}\n * enableRpcLogging={true}\n * >\n * <MyApp />\n * </McpClientProvider>\n * ```\n */\nexport function McpClientProvider({\n children,\n mcpServers,\n defaultCallbackUrl,\n defaultOAuthProxyUrl,\n defaultProxyConfig,\n defaultAutoProxyFallback = false,\n defaultServerConfig,\n clientInfo,\n storageProvider,\n enableRpcLogging = false,\n onServerAdded,\n onServerRemoved,\n onServerStateChange,\n onSamplingRequest,\n onElicitationRequest,\n}: McpClientProviderProps) {\n const [serverConfigs, setServerConfigs] = useState<ServerConfig[]>([]);\n const [servers, setServers] = useState<McpServer[]>([]);\n const [serverRevisions, setServerRevisions] = useState<\n Record<string, number>\n >({});\n const [storageLoaded, setStorageLoaded] = useState(false);\n const didLoadInitialServers = useRef(false);\n\n // Mirror of `servers` for synchronous access from event handlers\n // (specifically `removeServer` / `updateServer`). Reading the latest\n // servers from a ref lets us run the wrapper teardown side effects\n // (`disconnect()` / `clearStorage()`) OUTSIDE the `setServers` updater\n // function. Those wrapper callbacks fire synchronous setStates on the\n // wrapper itself (`setLog` via `addLog`, `setAuthUrl`); when invoked\n // inside an updater they land during the provider's render phase, which\n // React reports as\n // \"Cannot update a component (`McpServerWrapper`) while rendering a\n // different component (`McpClientProvider`)\".\n // Reading from the ref keeps the callback identities stable too — we\n // don't have to add `servers` to their dependency arrays, which would\n // re-create the callbacks on every connection-state tick and trigger\n // downstream effects in consumers.\n const serversRef = useRef<McpServer[]>([]);\n useEffect(() => {\n serversRef.current = servers;\n }, [servers]);\n\n // Store cached server metadata\n const cachedMetadataRef = useRef<\n Record<string, import(\"./storage.js\").CachedServerMetadata>\n >({});\n\n // Load RPC transport wrapper if enabled\n const [rpcWrapTransport, setRpcWrapTransport] = useState<\n ((transport: any, serverId: string) => any) | undefined\n >(undefined);\n const [rpcLoggingReady, setRpcLoggingReady] = useState(false);\n\n useEffect(() => {\n if (!enableRpcLogging || typeof window === \"undefined\") {\n setRpcWrapTransport(undefined);\n setRpcLoggingReady(true); // RPC logging not needed, mark as ready\n return;\n }\n\n // Load the RPC logger dynamically\n import(\"./rpc-logger.js\")\n .then((module) => {\n providerLogger.debug(\"[McpClientProvider] RPC logger loaded\");\n setRpcWrapTransport(() => module.wrapTransportForLogging);\n setRpcLoggingReady(true); // RPC logging loaded, mark as ready\n })\n .catch((err) => {\n providerLogger.error(\n \"[McpClientProvider] Failed to load RPC logger:\",\n err\n );\n setRpcWrapTransport(undefined);\n setRpcLoggingReady(true); // Failed to load, but still mark as ready to unblock\n });\n }, [enableRpcLogging]);\n\n // Load servers from storage on mount\n // Wait for RPC logging to be ready before loading servers\n useEffect(() => {\n if (!rpcLoggingReady) {\n providerLogger.debug(\n \"[McpClientProvider] Waiting for RPC logging to be ready before loading servers\"\n );\n return;\n }\n if (didLoadInitialServers.current) return;\n didLoadInitialServers.current = true;\n\n const loadServers = async () => {\n providerLogger.debug(\n \"[McpClientProvider] Loading servers, storageProvider:\",\n !!storageProvider,\n \"mcpServers:\",\n mcpServers\n );\n\n if (!storageProvider) {\n // No storage provider - just load from mcpServers prop if provided\n if (mcpServers) {\n const configs = Object.entries(mcpServers).map(([id, options]) => ({\n id,\n options,\n }));\n providerLogger.debug(\n \"[McpClientProvider] Loaded from mcpServers prop:\",\n configs.length\n );\n setServerConfigs(configs);\n }\n setStorageLoaded(true);\n return;\n }\n\n // Has storage provider - load from storage and merge with mcpServers\n try {\n const storedServers = await Promise.resolve(\n storageProvider.getServers()\n );\n\n providerLogger.debug(\n \"[McpClientProvider] Loaded from storage:\",\n Object.keys(storedServers).length\n );\n\n // Load cached metadata if supported by storage provider\n if (storageProvider.getServerMetadata) {\n try {\n const serverIds = Object.keys(storedServers);\n const metadataPromises = serverIds.map(async (id) => {\n const metadata = await Promise.resolve(\n storageProvider.getServerMetadata!(id)\n );\n return [id, metadata] as const;\n });\n const metadataEntries = await Promise.all(metadataPromises);\n cachedMetadataRef.current = Object.fromEntries(\n metadataEntries.filter(\n (\n entry\n ): entry is [\n string,\n import(\"./storage.js\").CachedServerMetadata,\n ] => entry[1] !== undefined\n )\n );\n providerLogger.debug(\n \"[McpClientProvider] Loaded cached metadata for\",\n Object.keys(cachedMetadataRef.current).length,\n \"servers\"\n );\n } catch (metadataError) {\n providerLogger.warn(\n \"[McpClientProvider] Failed to load cached metadata:\",\n metadataError\n );\n }\n }\n\n // Merge with initial mcpServers (mcpServers takes precedence)\n const mergedServers = { ...storedServers, ...mcpServers };\n\n // Convert to ServerConfig array\n const configs = Object.entries(mergedServers).map(([id, options]) => ({\n id,\n options,\n }));\n\n providerLogger.debug(\n \"[McpClientProvider] Total servers after merge:\",\n configs.length\n );\n setServerConfigs(configs);\n setStorageLoaded(true);\n } catch (error) {\n providerLogger.error(\n \"[McpClientProvider] Failed to load from storage:\",\n error\n );\n // Fall back to mcpServers only\n if (mcpServers) {\n const configs = Object.entries(mcpServers).map(([id, options]) => ({\n id,\n options,\n }));\n setServerConfigs(configs);\n }\n setStorageLoaded(true);\n }\n };\n\n loadServers();\n }, [storageProvider, mcpServers, rpcLoggingReady]);\n\n // Save servers to storage when they change\n useEffect(() => {\n if (!storageProvider || !storageLoaded) return;\n\n const saveServers = async () => {\n try {\n const serversToSave = serverConfigs.reduce(\n (acc, config) => {\n acc[config.id] = toPersistedServerConfig(config.options);\n return acc;\n },\n {} as Record<string, PersistedMcpServerConfig>\n );\n\n await Promise.resolve(storageProvider.setServers(serversToSave));\n } catch (error) {\n providerLogger.error(\n \"[McpClientProvider] Failed to save to storage:\",\n error\n );\n }\n };\n\n saveServers();\n }, [serverConfigs, storageProvider, storageLoaded]);\n\n const handleServerUpdate = useCallback(\n (updatedServer: McpServer) => {\n providerLogger.debug(\n `[McpClientProvider] handleServerUpdate called for server ${updatedServer.id}`,\n {\n toolCount: updatedServer.tools.length,\n state: updatedServer.state,\n }\n );\n\n const callbacksToRun: Array<() => void> = [];\n\n setServers((prev) => {\n const index = prev.findIndex((s) => s.id === updatedServer.id);\n const isNewServer = index === -1;\n\n if (isNewServer) {\n providerLogger.debug(\n `[McpClientProvider] Adding new server ${updatedServer.id} to state`\n );\n // Defer callbacks outside the state updater to avoid triggering\n // render-phase updates in user-provided handlers.\n callbacksToRun.push(() =>\n onServerAdded?.(updatedServer.id, updatedServer)\n );\n return [...prev, updatedServer];\n }\n\n // Check if actually changed to avoid loops\n const current = prev[index];\n const stateChanged = current.state !== updatedServer.state;\n const serverInfoChanged =\n current.serverInfo !== updatedServer.serverInfo;\n\n providerLogger.debug(\n `[McpClientProvider] Comparing server ${updatedServer.id}:`,\n {\n toolsChanged: current.tools !== updatedServer.tools,\n currentToolCount: current.tools.length,\n updatedToolCount: updatedServer.tools.length,\n stateChanged,\n }\n );\n\n if (isSameMcpServer(current, updatedServer)) {\n providerLogger.debug(\n `[McpClientProvider] No changes detected for server ${updatedServer.id}, skipping update`\n );\n return prev;\n }\n\n providerLogger.debug(\n `[McpClientProvider] Updating server ${updatedServer.id} in state`\n );\n\n // State changed - call callback\n if (stateChanged) {\n callbacksToRun.push(() =>\n onServerStateChange?.(updatedServer.id, updatedServer.state)\n );\n }\n\n // Server info changed - update cached metadata\n if (\n serverInfoChanged &&\n updatedServer.serverInfo &&\n storageProvider?.setServerMetadata\n ) {\n const metadata: import(\"./storage.js\").CachedServerMetadata = {\n name: updatedServer.serverInfo.name,\n version: updatedServer.serverInfo.version,\n title: updatedServer.serverInfo.title,\n websiteUrl: updatedServer.serverInfo.websiteUrl,\n icons: updatedServer.serverInfo.icons,\n icon: updatedServer.serverInfo.icon,\n };\n\n // Update cached metadata ref\n cachedMetadataRef.current[updatedServer.id] = metadata;\n\n // Save to storage asynchronously\n Promise.resolve(\n storageProvider.setServerMetadata(updatedServer.id, metadata)\n ).catch((err) => {\n providerLogger.error(\n \"[McpClientProvider] Failed to save server metadata:\",\n err\n );\n });\n }\n\n const newServers = [...prev];\n newServers[index] = updatedServer;\n return newServers;\n });\n\n if (callbacksToRun.length > 0) {\n queueMicrotask(() => {\n callbacksToRun.forEach((callback) => callback());\n });\n }\n },\n [onServerAdded, onServerStateChange, storageProvider]\n );\n\n const addServer = useCallback((id: string, options: McpServerConfig) => {\n setServerConfigs((prev) => {\n if (prev.find((s) => s.id === id)) return prev;\n providerLogger.debug(\n \"[McpClientProvider] Adding new server to configs:\",\n id\n );\n return [...prev, { id, options }];\n });\n }, []);\n\n const removeServer = useCallback(\n async (id: string, opts?: { clearCredentials?: boolean }) => {\n // Capture the wrapper from the latest state BEFORE scheduling state\n // updates. The wrapper teardown (`disconnect()` / `clearStorage()`)\n // synchronously fires setState on the wrapper itself; running it here\n // — in the event-handler context — keeps those updates out of the\n // `setServers` updater, which would otherwise execute during the\n // provider's render phase and trigger\n // \"Cannot update a component (`McpServerWrapper`) while rendering\n // a different component (`McpClientProvider`)\".\n const captured = serversRef.current.find((s) => s.id === id);\n\n setServers((prev) => prev.filter((s) => s.id !== id));\n setServerConfigs((prev) => prev.filter((s) => s.id !== id));\n setServerRevisions((prev) => {\n const { [id]: _removed, ...remaining } = prev;\n return remaining;\n });\n\n if (captured?.disconnect) await captured.disconnect();\n // Only wipe persisted OAuth credentials on an explicit logout/forget.\n // Routine removal (and the remove+add churn callers use) must preserve\n // tokens — wrappers sharing a URL hash would otherwise destroy each\n // other's freshly minted credentials.\n if (opts?.clearCredentials && captured?.clearStorage) {\n await captured.clearStorage();\n }\n\n if (enableRpcLogging) {\n const { clearRpcLogs } = await import(\"./rpc-logger.js\");\n clearRpcLogs(id);\n }\n onServerRemoved?.(id);\n },\n [enableRpcLogging, onServerRemoved]\n );\n\n const updateServer = useCallback(\n async (id: string, options: Partial<McpServerConfig>) => {\n const currentConfig = serverConfigs.find((s) => s.id === id);\n if (!currentConfig) {\n providerLogger.warn(\n `[McpClientProvider] Cannot update server \"${id}\" - not found`\n );\n return;\n }\n\n const updatedOptions: McpServerConfig = {\n ...currentConfig.options,\n ...options,\n };\n\n if (\n sameSerializedValue(\n pickLiveServerConfig(currentConfig.options),\n pickLiveServerConfig(updatedOptions)\n )\n ) {\n return;\n }\n\n const captured = serversRef.current.find((s) => s.id === id);\n\n // Complete teardown before remounting so an old transport cannot race\n // the replacement connection.\n await captured?.disconnect();\n\n setServers((prev) => prev.filter((s) => s.id !== id));\n setServerConfigs((prev) =>\n prev.map((server) =>\n server.id === id ? { id, options: updatedOptions } : server\n )\n );\n setServerRevisions((prev) => ({\n ...prev,\n [id]: (prev[id] ?? 0) + 1,\n }));\n },\n [serverConfigs]\n );\n\n const reconnectServer = useCallback(\n async (id: string) => {\n const currentConfig = serverConfigs.find((s) => s.id === id);\n if (!currentConfig) {\n providerLogger.warn(\n `[McpClientProvider] Cannot reconnect server \"${id}\" - not found`\n );\n return;\n }\n\n const captured = serversRef.current.find((s) => s.id === id);\n await captured?.disconnect();\n\n setServers((prev) => prev.filter((s) => s.id !== id));\n setServerRevisions((prev) => ({\n ...prev,\n [id]: (prev[id] ?? 0) + 1,\n }));\n },\n [serverConfigs]\n );\n\n const updateServerMetadata = useCallback(\n async (id: string, metadata: { name: string }) => {\n return new Promise<void>((resolve) => {\n const currentConfig = serverConfigs.find((s) => s.id === id);\n if (!currentConfig) {\n providerLogger.warn(\n `[McpClientProvider] Cannot update server metadata for \"${id}\" - not found`\n );\n resolve();\n return;\n }\n\n const updatedOptions: McpServerConfig = {\n ...currentConfig.options,\n displayName: metadata.name,\n };\n\n setServers((prev) =>\n prev.map((server) =>\n server.id === id\n ? { ...server, displayName: metadata.name }\n : server\n )\n );\n\n setServerConfigs((prev) => {\n const updated = prev.map((s) =>\n s.id === id ? { id, options: updatedOptions } : s\n );\n setTimeout(() => resolve(), 0);\n return updated;\n });\n });\n },\n [serverConfigs]\n );\n\n const getServer = useCallback(\n (id: string) => {\n return servers.find((s) => s.id === id);\n },\n [servers]\n );\n\n const contextValue = useMemo(\n () => ({\n servers,\n addServer,\n removeServer,\n updateServerMetadata,\n updateServer,\n getServer,\n storageLoaded,\n }),\n [\n servers,\n addServer,\n removeServer,\n updateServerMetadata,\n updateServer,\n getServer,\n storageLoaded,\n ]\n );\n\n // Strip `capabilities` from clientInfo — it is a provider-level default for\n // MCP capabilities, not a standard MCP clientInfo wire field.\n const { capabilities: defaultCapabilities, ...clientInfoWithoutCaps } =\n clientInfo || {};\n const clientInfoForWrapper = useMemo(\n () =>\n Object.keys(clientInfoWithoutCaps).length\n ? (clientInfoWithoutCaps as typeof clientInfo)\n : undefined,\n [clientInfo]\n );\n\n // Merge defaultCapabilities into each server's clientOptions.capabilities.\n // Memoized so the merged options objects are stable references across renders —\n // a new object on every render would cause McpServerWrapper to reconnect.\n const mergedServerConfigs = useMemo(\n () =>\n serverConfigs.map((config) => {\n let options: McpServerConfig = defaultServerConfig\n ? { ...defaultServerConfig, ...config.options }\n : config.options;\n\n if (defaultCapabilities) {\n options = {\n ...options,\n clientOptions: {\n ...options.clientOptions,\n capabilities: {\n ...defaultCapabilities,\n ...options.clientOptions?.capabilities,\n },\n },\n };\n }\n\n return { id: config.id, options };\n }),\n [serverConfigs, defaultCapabilities, defaultServerConfig]\n );\n\n // ponytail: OAuth callback must not auto-connect saved servers — a 401 on that\n // page runs SDK auth() and overwrites the in-flight PKCE verifier before finishAuth.\n const skipServerConnections =\n typeof window !== \"undefined\" &&\n /\\/oauth\\/callback\\/?$/.test(window.location.pathname);\n\n return (\n <McpClientContext.Provider value={contextValue}>\n {children}\n {!skipServerConnections &&\n mergedServerConfigs.map((config) => (\n <McpServerWrapper\n key={`${config.id}-v${serverRevisions[config.id] ?? 0}`}\n id={config.id}\n options={config.options}\n defaultCallbackUrl={defaultCallbackUrl}\n defaultOAuthProxyUrl={defaultOAuthProxyUrl}\n defaultProxyConfig={defaultProxyConfig}\n defaultAutoProxyFallback={defaultAutoProxyFallback}\n clientInfo={clientInfoForWrapper}\n cachedMetadata={cachedMetadataRef.current[config.id]}\n onUpdate={handleServerUpdate}\n onUpdateConfig={updateServer}\n onUpdateDisplayName={(id, displayName) =>\n updateServerMetadata(id, { name: displayName })\n }\n onReconnect={reconnectServer}\n rpcWrapTransport={rpcWrapTransport}\n onGlobalSamplingRequest={onSamplingRequest}\n onGlobalElicitationRequest={onElicitationRequest}\n />\n ))}\n </McpClientContext.Provider>\n );\n}\n\n// ===== Hooks =====\n\n/**\n * Hook to access the MCP client context\n *\n * Provides access to all servers and management functions.\n * Must be used within a McpClientProvider.\n *\n * @example\n * ```tsx\n * const {\n * servers,\n * addServer,\n * removeServer,\n * updateServer,\n * updateServerMetadata,\n * } = useMcpClient();\n *\n * // Add a server\n * addServer(\"linear\", { url: \"https://mcp.linear.app/sse\" });\n *\n * // Update a server's configured display name without reconnecting\n * await updateServerMetadata(\"linear\", { name: \"Linear Production\" });\n *\n * // Update connection-affecting configuration and reconnect\n * await updateServer(\"linear\", { headers: { Authorization: \"Bearer ...\" } });\n * // Or from a connected server handle:\n * await servers[0].setHeaders({ Authorization: \"Bearer ...\" });\n *\n * // Rename without reconnecting\n * await servers[0].setDisplayName(\"Linear Production\");\n *\n * // Access servers\n * servers.forEach(server => {\n * console.log(server.id, server.state);\n * });\n * ```\n */\nexport function useMcpClient(): McpClientContextType {\n const context = useContext(McpClientContext);\n if (!context) {\n throw new Error(\"useMcpClient must be used within a McpClientProvider\");\n }\n return context;\n}\n\n/**\n * Retrieve the McpServer object for a given server id.\n *\n * @returns The `McpServer` for the provided `id`, or `undefined` if no matching server is registered.\n * @throws If called outside of a `McpClientProvider` (context not available).\n */\nexport function useMcpServer(id: string): McpServer | undefined {\n const { servers } = useMcpClient();\n return useMemo(\n () => servers.find((server) => server.id === id),\n [id, servers]\n );\n}\n","import type {\n ElicitRequestFormParams,\n ElicitRequestURLParams,\n ElicitResult,\n Notification,\n} from \"@modelcontextprotocol/client\";\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport type {\n SamplingCreateMessageParams,\n SamplingCreateMessageResult,\n} from \"../core/config.js\";\nimport type {\n McpNotification,\n PendingElicitationRequest,\n PendingSamplingRequest,\n} from \"./types.js\";\n\nconst MAX_NOTIFICATIONS = 500;\nconst REVERSE_REQUEST_TIMEOUT_MS = 5 * 60_000;\n\ntype PendingResolver<T> = {\n resolve: (value: T) => void;\n reject: (reason: Error) => void;\n timeout: ReturnType<typeof setTimeout>;\n};\n\n/** Per-server UI queues for notifications, sampling, and elicitation. */\nexport function useMcpServerQueues(params: {\n serverId: string;\n serverName: string;\n onNotificationReceived?: (notification: McpNotification) => void;\n onSamplingRequest?: (request: PendingSamplingRequest) => void;\n onElicitationRequest?: (request: PendingElicitationRequest) => void;\n onGlobalSamplingRequest?: (\n request: PendingSamplingRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: SamplingCreateMessageResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n onGlobalElicitationRequest?: (\n request: PendingElicitationRequest,\n serverId: string,\n serverName: string,\n approve: (requestId: string, result: ElicitResult) => void,\n reject: (requestId: string, error?: string) => void\n ) => void;\n}) {\n const [notifications, setNotifications] = useState<McpNotification[]>([]);\n const [pendingSamplingRequests, setPendingSamplingRequests] = useState<\n PendingSamplingRequest[]\n >([]);\n const [pendingElicitationRequests, setPendingElicitationRequests] = useState<\n PendingElicitationRequest[]\n >([]);\n const samplingCounter = useRef(0);\n const elicitationCounter = useRef(0);\n const samplingResolvers = useRef(\n new Map<string, PendingResolver<SamplingCreateMessageResult>>()\n );\n const elicitationResolvers = useRef(\n new Map<string, PendingResolver<ElicitResult>>()\n );\n\n const rejectAll = useCallback((reason: string) => {\n for (const resolver of samplingResolvers.current.values()) {\n clearTimeout(resolver.timeout);\n resolver.reject(new Error(reason));\n }\n samplingResolvers.current.clear();\n for (const resolver of elicitationResolvers.current.values()) {\n clearTimeout(resolver.timeout);\n resolver.reject(new Error(reason));\n }\n elicitationResolvers.current.clear();\n setPendingSamplingRequests([]);\n setPendingElicitationRequests([]);\n }, []);\n\n useEffect(\n () => () => rejectAll(\"MCP server connection was removed\"),\n [rejectAll]\n );\n\n const onNotification = useCallback(\n (notification: Notification) => {\n const entry: McpNotification = {\n id:\n globalThis.crypto?.randomUUID?.() ?? `${Date.now()}-${Math.random()}`,\n method: notification.method,\n params: notification.params as Record<string, unknown> | undefined,\n timestamp: Date.now(),\n read: false,\n };\n setNotifications((previous) =>\n [entry, ...previous].slice(0, MAX_NOTIFICATIONS)\n );\n params.onNotificationReceived?.(entry);\n },\n [params.onNotificationReceived]\n );\n\n const approveSampling = useCallback(\n (id: string, result: SamplingCreateMessageResult) => {\n const resolver = samplingResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n samplingResolvers.current.delete(id);\n setPendingSamplingRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.resolve(result);\n },\n []\n );\n\n const rejectSampling = useCallback((id: string, error?: string) => {\n const resolver = samplingResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n samplingResolvers.current.delete(id);\n setPendingSamplingRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.reject(new Error(error ?? \"User rejected sampling request\"));\n }, []);\n\n const onSampling = useCallback(\n (requestParams: SamplingCreateMessageParams) =>\n new Promise<SamplingCreateMessageResult>((resolve, reject) => {\n const id = `sampling-${samplingCounter.current++}`;\n const request: PendingSamplingRequest = {\n id,\n request: { method: \"sampling/createMessage\", params: requestParams },\n timestamp: Date.now(),\n serverName: params.serverName,\n };\n const timeout = setTimeout(\n () => rejectSampling(id, \"Sampling request timed out\"),\n REVERSE_REQUEST_TIMEOUT_MS\n );\n samplingResolvers.current.set(id, { resolve, reject, timeout });\n setPendingSamplingRequests((previous) => [...previous, request]);\n params.onSamplingRequest?.(request);\n params.onGlobalSamplingRequest?.(\n request,\n params.serverId,\n params.serverName,\n approveSampling,\n rejectSampling\n );\n }),\n [approveSampling, params, rejectSampling]\n );\n\n const approveElicitation = useCallback((id: string, result: ElicitResult) => {\n const resolver = elicitationResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n elicitationResolvers.current.delete(id);\n setPendingElicitationRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.resolve(result);\n }, []);\n\n const rejectElicitation = useCallback((id: string, error?: string) => {\n const resolver = elicitationResolvers.current.get(id);\n if (!resolver) return;\n clearTimeout(resolver.timeout);\n elicitationResolvers.current.delete(id);\n setPendingElicitationRequests((previous) =>\n previous.filter((request) => request.id !== id)\n );\n resolver.reject(new Error(error ?? \"User rejected elicitation request\"));\n }, []);\n\n const onElicitation = useCallback(\n (requestParams: ElicitRequestFormParams | ElicitRequestURLParams) =>\n new Promise<ElicitResult>((resolve, reject) => {\n const id = `elicitation-${elicitationCounter.current++}`;\n const request: PendingElicitationRequest = {\n id,\n request: requestParams,\n timestamp: Date.now(),\n serverName: params.serverName,\n };\n const timeout = setTimeout(\n () => rejectElicitation(id, \"Elicitation request timed out\"),\n REVERSE_REQUEST_TIMEOUT_MS\n );\n elicitationResolvers.current.set(id, { resolve, reject, timeout });\n setPendingElicitationRequests((previous) => [...previous, request]);\n params.onElicitationRequest?.(request);\n params.onGlobalElicitationRequest?.(\n request,\n params.serverId,\n params.serverName,\n approveElicitation,\n rejectElicitation\n );\n }),\n [approveElicitation, params, rejectElicitation]\n );\n\n const markNotificationRead = useCallback((id: string) => {\n setNotifications((previous) =>\n previous.map((notification) =>\n notification.id === id ? { ...notification, read: true } : notification\n )\n );\n }, []);\n const markAllNotificationsRead = useCallback(\n () =>\n setNotifications((previous) =>\n previous.map((entry) => ({ ...entry, read: true }))\n ),\n []\n );\n const clearNotifications = useCallback(() => setNotifications([]), []);\n\n return {\n notifications,\n pendingSamplingRequests,\n pendingElicitationRequests,\n unreadNotificationCount: notifications.filter((entry) => !entry.read)\n .length,\n markNotificationRead,\n markAllNotificationsRead,\n clearNotifications,\n approveSampling,\n rejectSampling,\n approveElicitation,\n rejectElicitation,\n onNotification,\n onSampling,\n onElicitation,\n rejectAll,\n };\n}\n","import {\n toPersistedServerConfig,\n type McpServerConfig,\n type PersistedMcpServerConfig,\n} from \"./types.js\";\n\n/** Cached presentation metadata for a managed MCP server. */\nexport interface CachedServerMetadata {\n /** Programmatic server name. */\n name?: string;\n /** Server version. */\n version?: string;\n /** Human-readable server title. */\n title?: string;\n /** Public server website. */\n websiteUrl?: string;\n /** Icons advertised by the server. */\n icons?: Array<{\n /** Icon URL. */\n src: string;\n /** Icon media type. */\n mimeType?: string;\n }>;\n /** Resolved icon data URL used by the UI. */\n icon?: string;\n /** Unix timestamp in milliseconds when the metadata was cached. */\n cachedAt?: number;\n}\n\n/**\n * Persists managed server configurations and optional presentation metadata.\n *\n * Implementations may be synchronous or asynchronous.\n */\nexport interface StorageProvider {\n /** Returns all saved server configurations keyed by server ID. */\n getServers():\n | Promise<Record<string, PersistedMcpServerConfig>>\n | Record<string, PersistedMcpServerConfig>;\n /** Replaces all saved server configurations. */\n setServers(\n servers: Record<string, PersistedMcpServerConfig>\n ): Promise<void> | void;\n /** Saves one server configuration. */\n setServer(id: string, config: PersistedMcpServerConfig): Promise<void> | void;\n /** Removes one saved server configuration. */\n removeServer(id: string): Promise<void> | void;\n /** Removes all saved configurations and metadata. */\n clear(): Promise<void> | void;\n /** Returns cached metadata for one server, when supported. */\n getServerMetadata?(\n id: string\n ):\n | Promise<CachedServerMetadata | undefined>\n | CachedServerMetadata\n | undefined;\n /** Saves cached metadata for one server, when supported. */\n setServerMetadata?(\n id: string,\n metadata: CachedServerMetadata\n ): Promise<void> | void;\n /** Removes cached metadata for one server, when supported. */\n removeServerMetadata?(id: string): Promise<void> | void;\n}\n\n/** Stores managed server configurations in browser `localStorage`. */\nexport class LocalStorageProvider implements StorageProvider {\n private metadataKey: string;\n\n /**\n * Creates a browser storage provider.\n *\n * @param storageKey - Key used for configurations. Metadata uses the same key\n * with a `-metadata` suffix. Defaults to `\"mcp-client-servers\"`.\n */\n constructor(private storageKey: string = \"mcp-client-servers\") {\n this.metadataKey = `${storageKey}-metadata`;\n }\n\n /** Returns sanitized server configurations from `localStorage`. */\n getServers(): Record<string, PersistedMcpServerConfig> {\n try {\n const stored = localStorage.getItem(this.storageKey);\n if (!stored) return {};\n const parsed: unknown = JSON.parse(stored);\n if (!parsed || typeof parsed !== \"object\" || Array.isArray(parsed)) {\n return {};\n }\n const sanitized = Object.fromEntries(\n Object.entries(parsed).flatMap(([id, config]) =>\n config && typeof config === \"object\" && !Array.isArray(config)\n ? [\n [\n id,\n toPersistedServerConfig(config as McpServerConfig),\n ] as const,\n ]\n : []\n )\n );\n const serialized = JSON.stringify(sanitized);\n if (serialized !== stored) {\n try {\n localStorage.setItem(this.storageKey, serialized);\n } catch {\n console.error(\n \"[LocalStorageProvider] Failed to persist sanitized servers.\"\n );\n }\n }\n return sanitized;\n } catch {\n console.error(\"[LocalStorageProvider] Failed to load servers.\");\n return {};\n }\n }\n\n /** Replaces all saved server configurations. */\n setServers(servers: Record<string, PersistedMcpServerConfig>): void {\n try {\n const sanitized = Object.fromEntries(\n Object.entries(servers).map(([id, config]) => [\n id,\n toPersistedServerConfig(config),\n ])\n );\n localStorage.setItem(this.storageKey, JSON.stringify(sanitized));\n } catch {\n console.error(\"[LocalStorageProvider] Failed to save servers.\");\n }\n }\n\n /** Saves one server configuration. */\n setServer(id: string, config: PersistedMcpServerConfig): void {\n const servers = this.getServers();\n servers[id] = config;\n this.setServers(servers);\n }\n\n /** Removes one server and its cached metadata. */\n removeServer(id: string): void {\n const servers = this.getServers();\n delete servers[id];\n this.setServers(servers);\n this.removeServerMetadata(id);\n }\n\n /** Removes all saved configurations and metadata. */\n clear(): void {\n try {\n localStorage.removeItem(this.storageKey);\n localStorage.removeItem(this.metadataKey);\n } catch {\n console.error(\"[LocalStorageProvider] Failed to clear.\");\n }\n }\n\n private getAllMetadata(): Record<string, CachedServerMetadata> {\n try {\n const stored = localStorage.getItem(this.metadataKey);\n return stored ? JSON.parse(stored) : {};\n } catch {\n console.error(\"[LocalStorageProvider] Failed to load metadata.\");\n return {};\n }\n }\n\n private setAllMetadata(metadata: Record<string, CachedServerMetadata>): void {\n try {\n localStorage.setItem(this.metadataKey, JSON.stringify(metadata));\n } catch {\n console.error(\"[LocalStorageProvider] Failed to save metadata.\");\n }\n }\n\n /** Returns cached presentation metadata for a server. */\n getServerMetadata(id: string): CachedServerMetadata | undefined {\n return this.getAllMetadata()[id];\n }\n\n /** Saves presentation metadata and stamps the current cache time. */\n setServerMetadata(id: string, metadata: CachedServerMetadata): void {\n const allMetadata = this.getAllMetadata();\n allMetadata[id] = { ...metadata, cachedAt: Date.now() };\n this.setAllMetadata(allMetadata);\n }\n\n /** Removes cached presentation metadata for a server. */\n removeServerMetadata(id: string): void {\n const allMetadata = this.getAllMetadata();\n delete allMetadata[id];\n this.setAllMetadata(allMetadata);\n }\n}\n\n/** Stores managed server configurations in memory for tests or ephemeral UIs. */\nexport class MemoryStorageProvider implements StorageProvider {\n private storage: Record<string, PersistedMcpServerConfig> = {};\n private metadata: Record<string, CachedServerMetadata> = {};\n\n /** Returns a shallow copy of all stored server configurations. */\n getServers(): Record<string, PersistedMcpServerConfig> {\n return { ...this.storage };\n }\n\n /** Replaces all stored server configurations. */\n setServers(servers: Record<string, PersistedMcpServerConfig>): void {\n this.storage = Object.fromEntries(\n Object.entries(servers).map(([id, config]) => [\n id,\n toPersistedServerConfig(config),\n ])\n );\n }\n\n /** Stores one server configuration. */\n setServer(id: string, config: PersistedMcpServerConfig): void {\n this.storage[id] = toPersistedServerConfig(config);\n }\n\n /** Removes one server and its cached metadata. */\n removeServer(id: string): void {\n delete this.storage[id];\n this.removeServerMetadata(id);\n }\n\n /** Removes all configurations and metadata. */\n clear(): void {\n this.storage = {};\n this.metadata = {};\n }\n\n /** Returns cached presentation metadata for a server. */\n getServerMetadata(id: string): CachedServerMetadata | undefined {\n return this.metadata[id];\n }\n\n /** Saves presentation metadata and stamps the current cache time. */\n setServerMetadata(id: string, metadata: CachedServerMetadata): void {\n this.metadata[id] = { ...metadata, cachedAt: Date.now() };\n }\n\n /** Removes cached presentation metadata for a server. */\n removeServerMetadata(id: string): void {\n delete this.metadata[id];\n }\n}\n","export {\n AppBridge,\n PostMessageTransport,\n buildAllowAttribute,\n RESOURCE_MIME_TYPE,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\n\nexport type {\n McpUiDownloadFileRequest,\n McpUiDownloadFileResult,\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiMessageRequest,\n McpUiOpenLinkRequest,\n McpUiRequestDisplayModeRequest,\n McpUiResourceCsp,\n McpUiResourcePermissions,\n McpUiSizeChangedNotification,\n McpUiSupportedContentBlockModalities,\n McpUiUpdateModelContextRequest,\n} from \"@modelcontextprotocol/ext-apps/app-bridge\";\n","import {\n AppBridge,\n PostMessageTransport,\n buildAllowAttribute,\n type McpUiDownloadFileRequest,\n type McpUiHostCapabilities,\n type McpUiMessageRequest,\n type McpUiOpenLinkRequest,\n type McpUiRequestDisplayModeRequest,\n type McpUiSizeChangedNotification,\n type McpUiUpdateModelContextRequest,\n} from \"./ext-apps-bridge.js\";\nimport type {\n CallToolRequest,\n LoggingMessageNotificationParams,\n ReadResourceRequest,\n Tool,\n Transport,\n} from \"@modelcontextprotocol/client\";\nimport React, {\n memo,\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n} from \"react\";\nimport { parseCustomProps } from \"./parse-custom-props.js\";\nimport { injectOpenAiFileApis } from \"./inject-openai-file-apis.js\";\nimport { installInitializedSync } from \"./initialized-sync.js\";\nimport { resolveViewResource } from \"./resolve-view-resource.js\";\nimport { buildViewSandboxBlobUrl } from \"./sandbox-blob-url.js\";\nimport type {\n ResolvedViewResource,\n ViewDisplayMode,\n ViewRendererProps,\n} from \"./types.js\";\nimport {\n useViewDisplayModeControls,\n VIEW_DIMENSIONS,\n} from \"./use-display-mode.js\";\nimport {\n assertAppCanCallTool,\n buildDefaultHostCapabilities,\n dispatchUiMessage,\n resolveRequestedDisplayMode,\n} from \"./view-host-policy.js\";\n\nconst DEFAULT_HOST_INFO = { name: \"mcp-use-client\", version: \"2.0.0\" } as const;\nconst DEFAULT_TOOL_CALL_TIMEOUT = 600_000;\nconst SANDBOX_PROXY_READY = \"ui/notifications/sandbox-proxy-ready\";\n\nfunction CloseIcon() {\n return (\n <svg\n width=\"14\"\n height=\"14\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\nfunction waitForSandboxProxyReady(iframe: HTMLIFrameElement): Promise<void> {\n return new Promise((resolve) => {\n const listener = (event: MessageEvent) => {\n if (\n event.source === iframe.contentWindow &&\n event.data?.method === SANDBOX_PROXY_READY\n ) {\n window.removeEventListener(\"message\", listener);\n resolve();\n }\n };\n window.addEventListener(\"message\", listener);\n });\n}\n\nfunction buildToolResultPayload(\n toolOutput: unknown,\n customProps?: Record<string, string>\n): Parameters<AppBridge[\"sendToolResult\"]>[0] | null {\n const structuredContent = parseCustomProps(customProps);\n if (Object.keys(structuredContent).length > 0) {\n return {\n ...(typeof toolOutput === \"object\" && toolOutput !== null\n ? toolOutput\n : {}),\n structuredContent,\n } as Parameters<AppBridge[\"sendToolResult\"]>[0];\n }\n if (toolOutput === undefined || toolOutput === null) return null;\n return toolOutput as Parameters<AppBridge[\"sendToolResult\"]>[0];\n}\n\nfunction ViewRendererBase({\n viewId,\n source,\n sandboxUrl,\n toolName = \"view\",\n toolInput,\n toolOutput,\n partialToolInput,\n customProps,\n cancelled,\n hostInfo = DEFAULT_HOST_INFO,\n hostContext,\n hostCapabilities,\n messageCapabilities,\n modelContextCapabilities,\n cspMode = \"widget-declared\",\n displayMode: displayModeProp,\n onDisplayModeChange,\n inlineMaxWidth = 768,\n chromeless,\n onMessage,\n onSamplingRequest,\n onDownloadFile,\n onAppToolsChanged,\n onModelContextUpdate,\n onLog,\n onReady,\n onLifecycleChange,\n onError,\n onCspViolation,\n onResourceResolved,\n wrapTransport,\n toolCallTimeout = DEFAULT_TOOL_CALL_TIMEOUT,\n mockOpenAiFileApis = false,\n onInlineHeightChange,\n fullscreenHeader,\n renderFullscreenClose,\n className,\n testId = \"mcp-app-frame\",\n invoking,\n invoked,\n}: ViewRendererProps) {\n const iframeRef = useRef<HTMLIFrameElement | null>(null);\n const bridgeRef = useRef<AppBridge | null>(null);\n const containerRef = useRef<HTMLDivElement | null>(null);\n const pendingBlobRevocationsRef = useRef(\n new Map<string, ReturnType<typeof setTimeout>>()\n );\n const connectionRef = useRef(\n source.kind === \"live\" ? source.connection : null\n );\n\n const [resolved, setResolved] = useState<ResolvedViewResource | null>(null);\n const [activeSandboxUrl, setActiveSandboxUrl] = useState<URL | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n const [initCount, setInitCount] = useState(0);\n const [inlineHeight, setInlineHeight] = useState<number>(\n VIEW_DIMENSIONS.DEFAULT_HEIGHT\n );\n const [internalDisplayMode, setInternalDisplayMode] =\n useState<ViewDisplayMode>(\"inline\");\n const displayMode = displayModeProp ?? internalDisplayMode;\n const hasMessageHandler = onMessage !== undefined;\n const hasModelContextHandler = onModelContextUpdate !== undefined;\n const hasLogHandler = onLog !== undefined;\n const hasSamplingHandler = onSamplingRequest !== undefined;\n const hasDownloadHandler = onDownloadFile !== undefined;\n const effectiveHostCapabilities = useMemo<McpUiHostCapabilities>(\n () => ({\n ...buildDefaultHostCapabilities({\n hasConnection: source.kind === \"live\",\n hasMessageHandler,\n hasModelContextHandler,\n hasLogHandler,\n hasSamplingHandler,\n hasDownloadHandler,\n messageCapabilities,\n modelContextCapabilities,\n }),\n ...hostCapabilities,\n }),\n [\n hostCapabilities,\n hasLogHandler,\n hasSamplingHandler,\n hasDownloadHandler,\n hasMessageHandler,\n hasModelContextHandler,\n messageCapabilities,\n modelContextCapabilities,\n source.kind,\n ]\n );\n\n // Guest hostContext must track the shell's displayMode even when the parent\n // only uses ViewRenderer's internal state (e.g. inspector chat).\n const effectiveHostContext = useMemo(() => {\n if (!hostContext) return hostContext;\n if (hostContext.displayMode === displayMode) return hostContext;\n return { ...hostContext, displayMode };\n }, [hostContext, displayMode]);\n\n const hostContextRef = useRef(effectiveHostContext);\n hostContextRef.current = effectiveHostContext;\n const onMessageRef = useRef(onMessage);\n onMessageRef.current = onMessage;\n const onSamplingRequestRef = useRef(onSamplingRequest);\n onSamplingRequestRef.current = onSamplingRequest;\n const onDownloadFileRef = useRef(onDownloadFile);\n onDownloadFileRef.current = onDownloadFile;\n const onAppToolsChangedRef = useRef(onAppToolsChanged);\n onAppToolsChangedRef.current = onAppToolsChanged;\n const toolInputRef = useRef(toolInput);\n toolInputRef.current = toolInput;\n const partialToolInputRef = useRef(partialToolInput);\n partialToolInputRef.current = partialToolInput;\n const toolOutputRef = useRef(toolOutput);\n toolOutputRef.current = toolOutput;\n const customPropsRef = useRef(customProps);\n customPropsRef.current = customProps;\n const onResourceResolvedRef = useRef(onResourceResolved);\n onResourceResolvedRef.current = onResourceResolved;\n const onModelContextUpdateRef = useRef(onModelContextUpdate);\n onModelContextUpdateRef.current = onModelContextUpdate;\n const onLogRef = useRef(onLog);\n onLogRef.current = onLog;\n const onErrorRef = useRef(onError);\n onErrorRef.current = onError;\n const onCspViolationRef = useRef(onCspViolation);\n onCspViolationRef.current = onCspViolation;\n const onReadyRef = useRef(onReady);\n onReadyRef.current = onReady;\n const onLifecycleChangeRef = useRef(onLifecycleChange);\n onLifecycleChangeRef.current = onLifecycleChange;\n const onInlineHeightChangeRef = useRef(onInlineHeightChange);\n onInlineHeightChangeRef.current = onInlineHeightChange;\n const sandboxUrlRef = useRef(sandboxUrl);\n sandboxUrlRef.current = sandboxUrl;\n const cspModeRef = useRef(cspMode);\n cspModeRef.current = cspMode;\n const mockOpenAiFileApisRef = useRef(mockOpenAiFileApis);\n mockOpenAiFileApisRef.current = mockOpenAiFileApis;\n\n const resolveSandboxUrl = useCallback((next: ResolvedViewResource): URL => {\n const custom = sandboxUrlRef.current;\n if (custom) {\n return typeof custom === \"function\" ? custom(next) : custom;\n }\n return buildViewSandboxBlobUrl({\n cspMode: cspModeRef.current,\n permissions: next.permissions,\n widgetCsp: next.declaredCsp,\n });\n }, []);\n\n const setDisplayMode = useCallback(\n (mode: ViewDisplayMode) => {\n if (onDisplayModeChange) onDisplayModeChange(mode);\n else setInternalDisplayMode(mode);\n },\n [onDisplayModeChange]\n );\n\n const {\n handleDisplayModeChange,\n fullscreenShellClassName,\n pipShellClassName,\n isFullscreen,\n isPip,\n } = useViewDisplayModeControls({\n containerRef,\n displayMode,\n setDisplayMode,\n });\n\n const handleDisplayModeChangeRef = useRef(handleDisplayModeChange);\n handleDisplayModeChangeRef.current = handleDisplayModeChange;\n const displayModeRef = useRef(displayMode);\n displayModeRef.current = displayMode;\n\n const liveResourceUri =\n source.kind === \"live\" ? source.resourceUri : undefined;\n const preloadedHtml = source.kind === \"preloaded\" ? source.html : undefined;\n\n if (source.kind === \"live\") {\n connectionRef.current = source.connection;\n }\n\n // Resolve widget HTML from live connection or preloaded source\n useEffect(() => {\n let cancelledEffect = false;\n onLifecycleChangeRef.current?.({ status: \"resolving\" });\n\n const applyResolved = (next: ResolvedViewResource) => {\n setResolved(next);\n onLifecycleChangeRef.current?.({ status: \"sandbox-loading\" });\n const nextSandbox = resolveSandboxUrl(next);\n setActiveSandboxUrl((prev) =>\n prev?.href === nextSandbox.href ? prev : nextSandbox\n );\n onResourceResolvedRef.current?.(next);\n };\n\n if (source.kind === \"preloaded\") {\n const preloaded: ResolvedViewResource = {\n html: source.html,\n declaredCsp: source.csp,\n csp: cspMode === \"permissive\" ? undefined : source.csp,\n permissions: source.permissions,\n prefersBorder: source.prefersBorder ?? false,\n mimeType: \"text/html;profile=mcp-app\",\n mimeTypeValid: true,\n mimeTypeWarning: null,\n };\n applyResolved(preloaded);\n return;\n }\n\n const { connection, resourceUri } = source;\n connectionRef.current = connection;\n\n (async () => {\n try {\n const resourceResult = await connection.readResource(resourceUri);\n if (cancelledEffect) return;\n const listingResource = connection.resources?.find(\n (r) => r.uri === resourceUri\n ) as { _meta?: { ui?: unknown } } | undefined;\n const next = resolveViewResource({\n resourceResult,\n listingResource,\n cspMode,\n resourceUri,\n });\n if (!next.mimeTypeValid) {\n const message =\n next.mimeTypeWarning ||\n 'Invalid MIME type - SEP-1865 requires \"text/html;profile=mcp-app\"';\n setLoadError(message);\n onLifecycleChangeRef.current?.({ status: \"error\", error: message });\n return;\n }\n applyResolved(next);\n } catch (err) {\n if (cancelledEffect) return;\n setLoadError(\n err instanceof Error ? err.message : \"Failed to prepare view\"\n );\n onLifecycleChangeRef.current?.({\n status: \"error\",\n error: err instanceof Error ? err.message : \"Failed to prepare view\",\n });\n }\n })();\n\n return () => {\n cancelledEffect = true;\n };\n }, [source.kind, liveResourceUri, preloadedHtml, cspMode, resolveSandboxUrl]);\n\n // Delay revocation so React StrictMode's development-only effect cleanup can\n // be cancelled by the matching setup before the iframe navigation commits.\n useEffect(() => {\n const url = activeSandboxUrl;\n if (!url || url.protocol !== \"blob:\") return;\n\n const pending = pendingBlobRevocationsRef.current.get(url.href);\n if (pending) {\n clearTimeout(pending);\n pendingBlobRevocationsRef.current.delete(url.href);\n }\n\n return () => {\n const timer = setTimeout(() => {\n URL.revokeObjectURL(url.href);\n pendingBlobRevocationsRef.current.delete(url.href);\n }, 1_000);\n pendingBlobRevocationsRef.current.set(url.href, timer);\n };\n }, [activeSandboxUrl]);\n\n const isBlobSandbox = activeSandboxUrl?.protocol === \"blob:\";\n const sandboxOrigin =\n !activeSandboxUrl || isBlobSandbox\n ? null\n : (() => {\n try {\n return activeSandboxUrl.origin;\n } catch {\n return null;\n }\n })();\n\n // CSP violations + iframe console forwarding\n useEffect(() => {\n if (!sandboxOrigin && !isBlobSandbox) return;\n\n const handleMessage = (event: MessageEvent) => {\n const iframe = iframeRef.current;\n if (!iframe?.contentWindow) return;\n if (event.source !== iframe.contentWindow) return;\n if (\n !isBlobSandbox &&\n event.origin !== sandboxOrigin &&\n sandboxOrigin !== \"*\"\n ) {\n return;\n }\n\n if (event.data?.type === \"mcp-apps:csp-violation\") {\n onCspViolationRef.current?.({\n directive: event.data.directive,\n effectiveDirective: event.data.effectiveDirective,\n blockedUri: event.data.blockedUri,\n sourceFile: event.data.sourceFile,\n lineNumber: event.data.lineNumber,\n columnNumber: event.data.columnNumber,\n originalPolicy: event.data.originalPolicy,\n timestamp: event.data.timestamp || Date.now(),\n });\n return;\n }\n\n if (event.data?.type === \"iframe-console-log\") {\n // Console records share the iframe postMessage channel with MCP Apps\n // JSON-RPC. Consume them before PostMessageTransport sees them.\n event.stopImmediatePropagation();\n onLogRef.current?.({\n level: event.data.level ?? \"log\",\n data: event.data.args,\n });\n return;\n }\n };\n\n window.addEventListener(\"message\", handleMessage, true);\n return () => window.removeEventListener(\"message\", handleMessage, true);\n }, [sandboxOrigin, isBlobSandbox]);\n\n // Bridge lifecycle: sandbox → connect → resource-ready → initialized\n useEffect(() => {\n if (!resolved || !activeSandboxUrl) return;\n const iframe = iframeRef.current;\n if (!iframe) return;\n\n let disposed = false;\n let bridge: AppBridge | null = null;\n\n const run = async () => {\n try {\n onLifecycleChangeRef.current?.({ status: \"connecting\" });\n iframe.setAttribute(\n \"sandbox\",\n \"allow-scripts allow-same-origin allow-forms\"\n );\n const allowAttribute = buildAllowAttribute(resolved.permissions);\n if (allowAttribute) {\n iframe.setAttribute(\"allow\", allowAttribute);\n }\n\n const readyPromise = waitForSandboxProxyReady(iframe);\n if (activeSandboxUrl.protocol === \"blob:\") {\n const response = await fetch(activeSandboxUrl.href);\n const sandboxHtml = await response.text();\n if (disposed) return;\n iframe.srcdoc = sandboxHtml;\n } else {\n iframe.src = activeSandboxUrl.href;\n }\n await readyPromise;\n if (disposed) return;\n\n const capabilities: McpUiHostCapabilities = {\n ...effectiveHostCapabilities,\n sandbox: {\n csp: cspMode === \"permissive\" ? undefined : resolved.csp,\n permissions: resolved.permissions,\n },\n };\n\n bridge = new AppBridge(null, hostInfo, capabilities, {\n hostContext: hostContextRef.current,\n });\n\n if (capabilities.message) {\n bridge.onmessage = async ({\n content,\n }: McpUiMessageRequest[\"params\"]) => {\n await dispatchUiMessage(onMessageRef.current, content);\n return {};\n };\n }\n\n if (capabilities.sampling) {\n bridge.oncreatesamplingmessage = async (params) => {\n const handler = onSamplingRequestRef.current;\n if (!handler) {\n throw new Error(\"This host surface does not support sampling\");\n }\n return handler(params);\n };\n }\n\n if (capabilities.downloadFile) {\n bridge.ondownloadfile = async (\n params: McpUiDownloadFileRequest[\"params\"]\n ) => {\n const handler = onDownloadFileRef.current;\n if (!handler) {\n throw new Error(\"This host surface does not support downloads\");\n }\n return handler(params);\n };\n }\n\n bridge.onopenlink = async ({ url }: McpUiOpenLinkRequest[\"params\"]) => {\n if (url) window.open(url, \"_blank\", \"noopener,noreferrer\");\n return {};\n };\n\n if (capabilities.serverTools) {\n bridge.oncalltool = (async ({\n name,\n arguments: args,\n }: CallToolRequest[\"params\"]) => {\n const conn = connectionRef.current;\n if (!conn) throw new Error(\"Server connection not available\");\n assertAppCanCallTool(conn.tools, name);\n try {\n return await conn.callTool(name, args || {}, {\n timeout: toolCallTimeout,\n resetTimeoutOnProgress: true,\n });\n } catch (error) {\n bridge?.sendToolCancelled({\n reason: error instanceof Error ? error.message : String(error),\n });\n throw error;\n }\n }) as typeof bridge.oncalltool;\n }\n\n if (capabilities.serverResources) {\n bridge.onreadresource = (async ({\n uri,\n }: ReadResourceRequest[\"params\"]) => {\n const conn = connectionRef.current;\n if (!conn) throw new Error(\"Server connection not available\");\n return (await conn.readResource(uri)) as object;\n }) as NonNullable<AppBridge[\"onreadresource\"]>;\n\n bridge.onlistresources = (async () => {\n const conn = connectionRef.current;\n if (!conn) throw new Error(\"Server connection not available\");\n return { resources: [...(conn.resources ?? [])] } as object;\n }) as NonNullable<AppBridge[\"onlistresources\"]>;\n }\n\n bridge.onrequestdisplaymode = async ({\n mode,\n }: McpUiRequestDisplayModeRequest[\"params\"]) => {\n const requested = (mode ?? \"inline\") as ViewDisplayMode;\n const effective = resolveRequestedDisplayMode({\n requested,\n current: displayModeRef.current,\n hostAvailable: hostContextRef.current?.availableDisplayModes,\n appAvailable: bridge?.getAppCapabilities()?.availableDisplayModes,\n });\n await handleDisplayModeChangeRef.current(effective);\n return { mode: effective };\n };\n\n if (capabilities.updateModelContext) {\n bridge.onupdatemodelcontext = async ({\n content,\n structuredContent,\n }: McpUiUpdateModelContextRequest[\"params\"]) => {\n if (!onModelContextUpdateRef.current) {\n throw new Error(\n \"This host surface does not support model context updates\"\n );\n }\n await onModelContextUpdateRef.current({\n content,\n structuredContent,\n });\n return {};\n };\n }\n\n if (capabilities.logging) {\n bridge.onloggingmessage = async ({\n level,\n data,\n }: LoggingMessageNotificationParams) => {\n onLogRef.current?.({ level, data });\n return {};\n };\n }\n\n bridge.onsizechange = async ({\n height,\n }: McpUiSizeChangedNotification[\"params\"]) => {\n if (displayModeRef.current !== \"inline\") return;\n if (height !== undefined) {\n setInlineHeight(height);\n onInlineHeightChangeRef.current?.(height);\n }\n };\n\n let publishedAppToolsSignature: string | null = null;\n const publishAppTools = async () => {\n const handler = onAppToolsChangedRef.current;\n if (!bridge || !handler) return;\n const appCapabilities = bridge.getAppCapabilities();\n if (!appCapabilities?.tools) {\n handler(null);\n return;\n }\n const result = await bridge.listTools({});\n if (disposed || !bridge) return;\n const signature = JSON.stringify(result.tools);\n if (signature === publishedAppToolsSignature) return;\n publishedAppToolsSignature = signature;\n const currentBridge = bridge;\n handler({\n tools: result.tools as Tool[],\n callTool: (name, args) =>\n currentBridge.callTool({\n name,\n arguments: args ?? {},\n }),\n });\n };\n\n bridge.setNotificationHandler(\n \"notifications/tools/list_changed\",\n async () => {\n await publishAppTools();\n }\n );\n\n const syncGuestToolState = async () => {\n if (!bridge || disposed) return;\n\n const currentPartialToolInput = partialToolInputRef.current;\n const hasCompletedToolResult =\n toolOutputRef.current !== undefined &&\n toolOutputRef.current !== null;\n if (currentPartialToolInput && !hasCompletedToolResult) {\n await bridge.sendToolInputPartial({\n arguments: currentPartialToolInput,\n });\n } else {\n const mergedArgs = {\n ...toolInputRef.current,\n ...parseCustomProps(customPropsRef.current),\n };\n await bridge.sendToolInput({ arguments: mergedArgs });\n }\n\n const toolResultPayload = buildToolResultPayload(\n toolOutputRef.current,\n customPropsRef.current\n );\n if (toolResultPayload) {\n await bridge.sendToolResult(toolResultPayload);\n }\n };\n\n const initPromise = installInitializedSync(\n bridge,\n syncGuestToolState,\n (error) => {\n if (disposed) return;\n const message =\n error instanceof Error\n ? error.message\n : \"Failed to synchronize view state\";\n onErrorRef.current?.(message);\n onLifecycleChangeRef.current?.({\n status: \"error\",\n error: message,\n });\n }\n );\n let transport: Transport = new PostMessageTransport(\n iframe.contentWindow!,\n iframe.contentWindow!\n );\n if (wrapTransport) {\n transport = wrapTransport(transport, viewId);\n }\n await bridge.connect(transport);\n if (disposed) return;\n\n await bridge.sendSandboxResourceReady({\n html: mockOpenAiFileApisRef.current\n ? injectOpenAiFileApis(resolved.html)\n : resolved.html,\n csp: resolved.csp,\n permissions: resolved.permissions,\n });\n await initPromise;\n if (disposed) return;\n\n bridgeRef.current = bridge;\n setInitCount((c) => c + 1);\n onLifecycleChangeRef.current?.({ status: \"initialized\" });\n\n await publishAppTools();\n\n onLifecycleChangeRef.current?.({ status: \"ready\" });\n } catch (err) {\n if (!disposed) {\n const message =\n err instanceof Error ? err.message : \"Failed to connect view\";\n setLoadError(message);\n onErrorRef.current?.(message);\n onLifecycleChangeRef.current?.({ status: \"error\", error: message });\n }\n }\n };\n\n void run();\n\n return () => {\n disposed = true;\n const toClose = bridge;\n bridgeRef.current = null;\n onAppToolsChangedRef.current?.(null);\n if (!toClose) return;\n onLifecycleChangeRef.current?.({ status: \"tearing-down\" });\n void (async () => {\n try {\n await Promise.race([\n toClose.teardownResource({}),\n new Promise((_, reject) =>\n setTimeout(() => reject(new Error(\"teardown timeout\")), 2000)\n ),\n ]);\n } catch {\n // proceed\n } finally {\n toClose.close().catch(() => {});\n onLifecycleChangeRef.current?.({ status: \"closed\" });\n }\n })();\n };\n }, [\n resolved,\n activeSandboxUrl,\n hostInfo,\n effectiveHostCapabilities,\n cspMode,\n viewId,\n wrapTransport,\n toolCallTimeout,\n mockOpenAiFileApis,\n ]);\n\n // Host context updates after init\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (!bridge || initCount === 0 || !effectiveHostContext) return;\n void bridge.setHostContext(effectiveHostContext);\n }, [effectiveHostContext, initCount]);\n\n // Partial tool input\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (\n !bridge ||\n initCount === 0 ||\n !partialToolInput ||\n (toolOutput !== undefined && toolOutput !== null)\n ) {\n return;\n }\n void bridge.sendToolInputPartial({ arguments: partialToolInput });\n }, [initCount, partialToolInput, toolOutput]);\n\n // Tool input + custom props\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (\n !bridge ||\n initCount === 0 ||\n (partialToolInput && (toolOutput === undefined || toolOutput === null))\n ) {\n return;\n }\n const mergedArgs = {\n ...toolInput,\n ...parseCustomProps(customProps),\n };\n void bridge.sendToolInput({ arguments: mergedArgs });\n }, [initCount, toolInput, partialToolInput, customProps, toolOutput]);\n\n // Tool output\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (!bridge || initCount === 0) return;\n const toolResultPayload = buildToolResultPayload(toolOutput, customProps);\n if (!toolResultPayload) return;\n void bridge.sendToolResult(toolResultPayload);\n }, [initCount, toolOutput, customProps]);\n\n // Cancellation\n useEffect(() => {\n const bridge = bridgeRef.current;\n if (!bridge || initCount === 0 || !cancelled) return;\n void bridge.sendToolCancelled({ reason: \"Cancelled by user\" });\n }, [cancelled, initCount]);\n\n const readyFiredRef = useRef(false);\n useEffect(() => {\n if (readyFiredRef.current || initCount === 0) return;\n readyFiredRef.current = true;\n onReadyRef.current?.();\n }, [initCount]);\n\n const showHostBorder =\n resolved !== null && resolved.prefersBorder && displayMode !== \"fullscreen\";\n\n if (loadError) {\n return (\n <div className={className}>\n <div className=\"border border-red-200/50 dark:border-red-800/50 bg-red-50/30 dark:bg-red-950/20 rounded-lg p-4\">\n <p className=\"text-sm text-red-600 dark:text-red-400\">\n Failed to load view: {loadError}\n </p>\n </div>\n </div>\n );\n }\n\n if (!resolved) {\n return (\n <div className={className}>\n <div className=\"flex items-center justify-center w-full h-[200px]\">\n <span className=\"text-sm text-muted-foreground\">Loading view…</span>\n </div>\n </div>\n );\n }\n\n const containerClassName =\n fullscreenShellClassName ??\n pipShellClassName ??\n \"flex group flex-1 items-center justify-center\";\n\n const frameStyle: CSSProperties = {\n height: isFullscreen || isPip ? \"100%\" : `${inlineHeight}px`,\n width: \"100%\",\n maxWidth: displayMode === \"inline\" ? `${inlineMaxWidth}px` : \"100%\",\n transition: isFullscreen || isPip ? undefined : \"height 300ms ease-out\",\n };\n\n const viewShell = (\n <div\n ref={containerRef}\n className={\n isFullscreen\n ? `${containerClassName} flex flex-col`\n : containerClassName\n }\n style={\n isPip\n ? {\n height: VIEW_DIMENSIONS.DEFAULT_HEIGHT,\n maxWidth: VIEW_DIMENSIONS.PIP_MAX_WIDTH,\n zIndex: 100,\n }\n : isFullscreen\n ? { zIndex: 100 }\n : undefined\n }\n >\n {isFullscreen && (\n // ponytail: inspector Tailwind may not emit client arbitrary classes\n // (h-[50px], grid-cols-[auto_1fr_auto]) — use inline layout instead.\n <header\n className=\"grid shrink-0 items-center border-b border-zinc-200 bg-background px-3 dark:border-zinc-700\"\n style={{\n height: VIEW_DIMENSIONS.FULLSCREEN_HEADER_HEIGHT,\n gridTemplateColumns: \"auto 1fr auto\",\n }}\n >\n {renderFullscreenClose ? (\n renderFullscreenClose({\n onClick: () => void handleDisplayModeChange(\"inline\"),\n \"data-testid\": \"debugger-exit-fullscreen-button\",\n \"aria-label\": \"Exit fullscreen\",\n })\n ) : (\n <button\n type=\"button\"\n data-testid=\"debugger-exit-fullscreen-button\"\n aria-label=\"Exit fullscreen\"\n className=\"flex size-8 cursor-pointer items-center justify-center rounded-full border border-zinc-200 bg-background text-foreground shadow-sm hover:bg-muted dark:border-zinc-700\"\n onClick={() => void handleDisplayModeChange(\"inline\")}\n >\n <CloseIcon />\n </button>\n )}\n <div className=\"flex min-w-0 items-center justify-center gap-2 px-2\">\n {fullscreenHeader?.iconUrl ? (\n <img\n src={fullscreenHeader.iconUrl}\n alt=\"\"\n className=\"size-6 shrink-0 rounded-md object-contain\"\n />\n ) : null}\n <span className=\"truncate text-sm font-medium text-foreground\">\n {fullscreenHeader?.title ?? toolName}\n </span>\n </div>\n <div className=\"size-8 shrink-0\" aria-hidden />\n </header>\n )}\n {isPip &&\n (renderFullscreenClose ? (\n <div className=\"absolute right-3 top-3\" style={{ zIndex: 110 }}>\n {renderFullscreenClose({\n onClick: () => void handleDisplayModeChange(\"inline\"),\n \"data-testid\": \"debugger-exit-pip-button\",\n \"aria-label\": \"Exit picture-in-picture\",\n })}\n </div>\n ) : (\n <button\n type=\"button\"\n data-testid=\"debugger-exit-pip-button\"\n aria-label=\"Exit picture-in-picture\"\n className=\"absolute right-3 top-3 z-[110] flex size-8 cursor-pointer items-center justify-center rounded-full border border-border bg-background/90 text-foreground shadow-sm backdrop-blur-sm hover:bg-background\"\n style={{ zIndex: 110 }}\n onClick={() => void handleDisplayModeChange(\"inline\")}\n >\n <CloseIcon />\n </button>\n ))}\n <div\n className={\n isFullscreen\n ? \"relative flex min-h-0 w-full flex-1 flex-col\"\n : isPip\n ? \"relative w-full h-full min-h-0 flex flex-1 flex-col\"\n : \"relative w-full flex flex-1 justify-center items-center\"\n }\n >\n {!isPip && !isFullscreen && (invoking || invoked) && (\n <div className=\"absolute -top-8 left-2 z-10 whitespace-nowrap pointer-events-none text-xs text-muted-foreground\">\n {invoking && !toolOutput ? invoking : invoked}\n </div>\n )}\n <div\n data-testid={testId}\n data-mcp-app-tool={toolName}\n className={\n displayMode === \"fullscreen\"\n ? \"w-full h-full overflow-hidden\"\n : \"w-full overflow-hidden\"\n }\n style={frameStyle}\n >\n <iframe\n ref={iframeRef}\n title={`MCP App: ${toolName}`}\n className={\n showHostBorder\n ? \"w-full h-full bg-transparent border border-border rounded-xl\"\n : \"w-full h-full bg-transparent border-0\"\n }\n />\n </div>\n </div>\n </div>\n );\n\n // ponytail: do not portal — moving the shell remounts the iframe and wipes\n // the guest. Chat history chrome hides via data-mcp-widget-fullscreen instead.\n return <div className={className}>{viewShell}</div>;\n}\n\nfunction viewRendererAreEqual(\n prev: ViewRendererProps,\n next: ViewRendererProps\n): boolean {\n if (prev.viewId !== next.viewId) return false;\n if (prev.source !== next.source) return false;\n if (prev.sandboxUrl !== next.sandboxUrl) return false;\n if (prev.displayMode !== next.displayMode) return false;\n if (prev.cancelled !== next.cancelled) return false;\n if (prev.toolInput !== next.toolInput) return false;\n if (prev.toolOutput !== next.toolOutput) return false;\n if (prev.partialToolInput !== next.partialToolInput) return false;\n if (prev.customProps !== next.customProps) return false;\n if (prev.hostContext !== next.hostContext) return false;\n if (prev.hostCapabilities !== next.hostCapabilities) return false;\n if (prev.messageCapabilities !== next.messageCapabilities) return false;\n if (prev.modelContextCapabilities !== next.modelContextCapabilities)\n return false;\n if (prev.onMessage !== next.onMessage) return false;\n if (prev.onSamplingRequest !== next.onSamplingRequest) return false;\n if (prev.onDownloadFile !== next.onDownloadFile) return false;\n if (prev.onAppToolsChanged !== next.onAppToolsChanged) return false;\n if (prev.onModelContextUpdate !== next.onModelContextUpdate) return false;\n if (prev.cspMode !== next.cspMode) return false;\n if (prev.mockOpenAiFileApis !== next.mockOpenAiFileApis) return false;\n if (prev.onInlineHeightChange !== next.onInlineHeightChange) return false;\n if (prev.fullscreenHeader !== next.fullscreenHeader) return false;\n if (prev.renderFullscreenClose !== next.renderFullscreenClose) return false;\n if (prev.className !== next.className) return false;\n if (prev.onReady !== next.onReady) return false;\n if (prev.onLifecycleChange !== next.onLifecycleChange) return false;\n return true;\n}\n\n/**\n * Renders an MCP App inside an isolated iframe and bridges host capabilities.\n *\n * The renderer resolves live MCP resources or accepts preloaded HTML, applies\n * the selected CSP policy, and forwards tool state and host callbacks through\n * the MCP Apps bridge.\n */\nexport const ViewRenderer = memo(ViewRendererBase, viewRendererAreEqual);\n\nexport type { ViewRendererProps } from \"./types.js\";\nexport { resolveViewResource } from \"./resolve-view-resource.js\";\nexport {\n getViewResourceUri,\n isViewResource,\n isViewTool,\n} from \"./view-detection.js\";\nexport { isToolVisibleToModel } from \"./view-host-policy.js\";\nexport { parseCustomProps } from \"./parse-custom-props.js\";\nexport {\n buildSandboxProxyBlobHtml,\n buildViewSandboxBlobUrl,\n buildViewSandboxUrl,\n} from \"./sandbox-blob-url.js\";\nexport type {\n ViewConnection,\n ViewDisplayMode,\n ViewCspMode,\n ViewRendererSource,\n ResolvedViewResource,\n ViewCspViolation,\n ViewLifecycleEvent,\n ViewLifecycleStatus,\n ViewAppToolConnection,\n} from \"./types.js\";\nexport type {\n McpUiDownloadFileRequest,\n McpUiDownloadFileResult,\n McpUiHostCapabilities,\n McpUiHostContext,\n McpUiResourceCsp,\n McpUiResourcePermissions,\n McpUiSupportedContentBlockModalities,\n} from \"./ext-apps-bridge.js\";\n","/**\n * Parses JSON object and array values from string-valued custom properties.\n *\n * Invalid JSON and scalar-looking strings are preserved unchanged.\n *\n * @param customProps - Properties supplied by a host integration.\n * @returns A new record containing parsed object and array values.\n */\nexport function parseCustomProps(\n customProps?: Record<string, string>\n): Record<string, unknown> {\n const parsed: Record<string, unknown> = {};\n if (!customProps) return parsed;\n for (const [k, v] of Object.entries(customProps)) {\n if (\n typeof v === \"string\" &&\n (v.trim().startsWith(\"[\") || v.trim().startsWith(\"{\"))\n ) {\n try {\n parsed[k] = JSON.parse(v);\n } catch {\n parsed[k] = v;\n }\n } else {\n parsed[k] = v;\n }\n }\n return parsed;\n}\n","import { LATEST_PROTOCOL_VERSION } from \"@modelcontextprotocol/ext-apps/app-bridge\";\n\nconst OPENAI_COMPATIBILITY_BRIDGE_SCRIPT = `<script>\n(function () {\n var files = new Map();\n var pendingRequests = new Map();\n var requestId = 0;\n var hostConnected = false;\n var fallbackTimer;\n var api = window.openai || {};\n\n function dispatchGlobals(globals) {\n Object.assign(api, globals);\n window.dispatchEvent(new CustomEvent(\"openai:set_globals\", {\n detail: { globals: globals }\n }));\n }\n\n function applyHostContext(context) {\n if (!context || typeof context !== \"object\") return;\n var globals = {};\n if (context.theme !== undefined) globals.theme = context.theme;\n if (context.displayMode !== undefined) globals.displayMode = context.displayMode;\n if (context.locale !== undefined) globals.locale = context.locale;\n if (context.view !== undefined) globals.view = context.view;\n if (context.safeAreaInsets !== undefined) {\n globals.safeArea = { insets: context.safeAreaInsets };\n }\n if (context.containerDimensions && context.containerDimensions.maxHeight !== undefined) {\n globals.maxHeight = context.containerDimensions.maxHeight;\n }\n if (context.platform !== undefined || context.deviceCapabilities !== undefined) {\n globals.userAgent = {\n device: {\n type: context.platform === \"mobile\" ? \"mobile\" : \"desktop\"\n },\n capabilities: {\n hover: !!(context.deviceCapabilities && context.deviceCapabilities.hover),\n touch: !!(context.deviceCapabilities && context.deviceCapabilities.touch)\n }\n };\n }\n dispatchGlobals(globals);\n }\n\n function markHostConnected(result) {\n hostConnected = true;\n clearTimeout(fallbackTimer);\n if (result && result.hostContext) applyHostContext(result.hostContext);\n }\n\n function postMessage(message) {\n if (window.parent === window) {\n throw new Error(\"window.openai compatibility APIs require an iframe host\");\n }\n window.parent.postMessage(message, \"*\");\n }\n\n function sendRequest(method, params) {\n var id = \"mcp-use-openai-compat-\" + (++requestId);\n return new Promise(function (resolve, reject) {\n pendingRequests.set(id, { resolve: resolve, reject: reject });\n postMessage({ jsonrpc: \"2.0\", id: id, method: method, params: params });\n window.setTimeout(function () {\n var pending = pendingRequests.get(id);\n if (!pending) return;\n pendingRequests.delete(id);\n pending.reject(new Error(\"Request timeout: \" + method));\n }, 30000);\n });\n }\n\n function sendNotification(method, params) {\n postMessage({ jsonrpc: \"2.0\", method: method, params: params });\n }\n\n window.addEventListener(\"message\", function (event) {\n if (event.source !== window.parent) return;\n var message = event.data;\n if (!message || message.jsonrpc !== \"2.0\") return;\n\n if (message.id !== undefined && (message.result !== undefined || message.error !== undefined)) {\n var pending = pendingRequests.get(message.id);\n if (pending) {\n pendingRequests.delete(message.id);\n if (message.error) pending.reject(new Error(message.error.message || \"Host request failed\"));\n else pending.resolve(message.result);\n return;\n }\n if (message.result && (message.result.hostInfo || message.result.hostContext)) {\n markHostConnected(message.result);\n }\n return;\n }\n\n if (message.id !== undefined || typeof message.method !== \"string\") return;\n var params = message.params || {};\n switch (message.method) {\n case \"ui/notifications/tool-input\":\n markHostConnected();\n dispatchGlobals({ toolInput: params.arguments || {} });\n break;\n case \"ui/notifications/tool-input-partial\":\n // window.openai has no partial-input global. Do not expose incomplete\n // or approval-gated arguments as if the final tool input had arrived.\n markHostConnected();\n break;\n case \"ui/notifications/tool-result\":\n markHostConnected();\n dispatchGlobals({\n // OpenAI defines toolOutput as structuredContent, not the complete\n // CallToolResult envelope. Keep that envelope (including hidden\n // _meta) in toolResponseMetadata instead.\n toolOutput: params.structuredContent === undefined ? null : params.structuredContent,\n toolResponseMetadata: params\n });\n break;\n case \"ui/notifications/host-context-changed\":\n markHostConnected();\n applyHostContext(params);\n break;\n }\n });\n\n api.toolInput = api.toolInput === undefined ? null : api.toolInput;\n api.toolOutput = api.toolOutput === undefined ? null : api.toolOutput;\n api.toolResponseMetadata =\n api.toolResponseMetadata === undefined ? null : api.toolResponseMetadata;\n api.widgetState = api.widgetState === undefined ? null : api.widgetState;\n api.theme = api.theme || \"light\";\n api.displayMode = api.displayMode || \"inline\";\n api.safeArea = api.safeArea || {\n insets: { top: 0, right: 0, bottom: 0, left: 0 }\n };\n api.maxHeight = api.maxHeight || 600;\n api.userAgent = api.userAgent || {\n device: { type: \"desktop\" },\n capabilities: { hover: true, touch: false }\n };\n api.locale = api.locale || \"en\";\n\n api.callTool = api.callTool || function (name, args) {\n return sendRequest(\"tools/call\", { name: name, arguments: args || {} });\n };\n api.sendFollowUpMessage = api.sendFollowUpMessage || function (request) {\n return sendRequest(\"ui/message\", {\n role: \"user\",\n content: [{ type: \"text\", text: request.prompt }]\n });\n };\n api.openExternal = api.openExternal || function (request) {\n return sendRequest(\"ui/open-link\", { url: request.href });\n };\n api.requestDisplayMode = api.requestDisplayMode || function (request) {\n return sendRequest(\"ui/request-display-mode\", { mode: request.mode });\n };\n api.setWidgetState = api.setWidgetState || function (state) {\n dispatchGlobals({ widgetState: state });\n // The Apps SDK setter is promise-based. Keep the local state update\n // synchronous, but return a promise so legacy useWidget() code can safely\n // await or chain .catch() on the compatibility API.\n return Promise.resolve();\n };\n api.notifyIntrinsicHeight = api.notifyIntrinsicHeight || function (height) {\n sendNotification(\"ui/notifications/size-changed\", { height: height });\n return Promise.resolve();\n };\n api.uploadFile = api.uploadFile || async function (file) {\n var fileId = crypto.randomUUID();\n files.set(fileId, file);\n return { fileId: fileId };\n };\n api.getFileDownloadUrl = api.getFileDownloadUrl || async function (ref) {\n var file = files.get(ref.fileId);\n if (!file) {\n throw new Error(\"File not found: \" + ref.fileId);\n }\n return { downloadUrl: URL.createObjectURL(file) };\n };\n window.openai = api;\n\n // Native V2 views initialize their own MCP Apps bridge. Only initialize this\n // compatibility bridge when no other guest handshake appears, so the file\n // helpers remain safe for both V2 views and legacy useWidget() bundles.\n fallbackTimer = window.setTimeout(function () {\n if (hostConnected) return;\n sendRequest(\"ui/initialize\", {\n appCapabilities: {},\n appInfo: { name: \"mcp-use-openai-compat\", version: \"1.0.0\" },\n protocolVersion: ${JSON.stringify(LATEST_PROTOCOL_VERSION)}\n }).then(function (result) {\n markHostConnected(result);\n sendNotification(\"ui/notifications/initialized\", {});\n }).catch(function (error) {\n console.warn(\"[window.openai compatibility] Failed to initialize:\", error);\n });\n }, 1000);\n})();\n</script>`;\n\n/**\n * Prepend the shared ChatGPT Apps SDK compatibility aliases and\n * Inspector-supported file helpers. Native V2 views keep using MCP Apps;\n * legacy useWidget() bundles receive the same tool lifecycle and host actions\n * through window.openai. Unsupported ChatGPT-only extensions remain absent so\n * apps can feature-detect them as documented.\n */\nexport function injectOpenAiFileApis(html: string): string {\n const headEnd = findOpeningConstructEnd(html, \"<head\");\n if (headEnd !== undefined) {\n return insertAt(html, headEnd, OPENAI_COMPATIBILITY_BRIDGE_SCRIPT);\n }\n const htmlEnd = findOpeningConstructEnd(html, \"<html\");\n if (htmlEnd !== undefined) {\n return insertAt(\n html,\n htmlEnd,\n \"<head>\" + OPENAI_COMPATIBILITY_BRIDGE_SCRIPT + \"</head>\"\n );\n }\n const doctypeEnd = findOpeningConstructEnd(html, \"<!doctype\");\n if (doctypeEnd !== undefined) {\n return insertAt(\n html,\n doctypeEnd,\n \"<head>\" + OPENAI_COMPATIBILITY_BRIDGE_SCRIPT + \"</head>\"\n );\n }\n return OPENAI_COMPATIBILITY_BRIDGE_SCRIPT + html;\n}\n\nfunction findOpeningConstructEnd(\n html: string,\n lowercasePrefix: string\n): number | undefined {\n const lowercaseHtml = html.toLowerCase();\n let searchFrom = 0;\n while (searchFrom < lowercaseHtml.length) {\n const start = lowercaseHtml.indexOf(lowercasePrefix, searchFrom);\n if (start === -1) return undefined;\n const boundary = lowercaseHtml[start + lowercasePrefix.length];\n if (\n boundary === \">\" ||\n boundary === \" \" ||\n boundary === \"\\t\" ||\n boundary === \"\\n\" ||\n boundary === \"\\r\" ||\n boundary === \"\\f\"\n ) {\n let quote: '\"' | \"'\" | undefined;\n for (\n let index = start + lowercasePrefix.length;\n index < html.length;\n index++\n ) {\n const character = html[index];\n if (quote) {\n if (character === quote) quote = undefined;\n continue;\n }\n if (character === '\"' || character === \"'\") {\n quote = character;\n continue;\n }\n if (character === \">\") return index + 1;\n }\n return undefined;\n }\n searchFrom = start + lowercasePrefix.length;\n }\n return undefined;\n}\n\nfunction insertAt(value: string, index: number, addition: string): string {\n return value.slice(0, index) + addition + value.slice(index);\n}\n","interface InitializableBridge<TArgs extends unknown[]> {\n oninitialized: ((...args: TArgs) => void) | undefined;\n}\n\n/**\n * Synchronize host state after every guest initialize handshake.\n *\n * Vite HMR and React development runtimes can replace the guest App instance\n * inside the same iframe. Each replacement initializes again and needs the\n * invocation's one-shot input/result notifications replayed.\n */\nexport function installInitializedSync<TArgs extends unknown[]>(\n bridge: InitializableBridge<TArgs>,\n synchronize: () => void | Promise<void>,\n onLaterError: (error: unknown) => void\n): Promise<void> {\n const previous = bridge.oninitialized;\n let sawFirstInitialization = false;\n\n return new Promise<void>((resolve, reject) => {\n bridge.oninitialized = (...args: TArgs) => {\n previous?.(...args);\n const synchronization = Promise.resolve().then(synchronize);\n\n if (!sawFirstInitialization) {\n sawFirstInitialization = true;\n synchronization.then(resolve, reject);\n return;\n }\n\n void synchronization.catch(onLaterError);\n };\n });\n}\n","import { RESOURCE_MIME_TYPE } from \"./ext-apps-bridge.js\";\nimport type {\n McpUiResourceCsp,\n McpUiResourcePermissions,\n} from \"./ext-apps-bridge.js\";\nimport type { ResolvedViewResource, ViewCspMode } from \"./types.js\";\n\n/** MCP App UI metadata read from a resource listing or content block. */\ntype UiMeta = {\n csp?: McpUiResourceCsp;\n permissions?: McpUiResourcePermissions;\n prefersBorder?: boolean;\n};\n\n/**\n * Normalizes a resource response into HTML and effective MCP App policy.\n *\n * Content-level UI metadata overrides listing metadata. In permissive mode the\n * declared CSP is reported but not enforced.\n *\n * @param options - Resource response, listing metadata, CSP policy, and URI.\n * @returns The normalized view resource.\n * @throws When the first content block contains no text or base64 HTML.\n */\nexport function resolveViewResource(options: {\n resourceResult: unknown;\n listingResource?: { _meta?: { ui?: unknown } } | null;\n cspMode: ViewCspMode;\n resourceUri?: string;\n}): ResolvedViewResource {\n const { resourceResult, listingResource, cspMode, resourceUri } = options;\n const contentsArray = Array.isArray(\n (resourceResult as { contents?: unknown })?.contents\n )\n ? ((resourceResult as { contents: unknown[] }).contents as Array<{\n mimeType?: string;\n text?: string;\n blob?: string;\n _meta?: { ui?: UiMeta };\n }>)\n : [];\n\n const firstContent = contentsArray[0];\n let htmlContent = \"\";\n let mimeType: string | undefined;\n\n if (firstContent) {\n mimeType = firstContent.mimeType;\n if (typeof firstContent.text === \"string\") {\n htmlContent = firstContent.text;\n } else if (typeof firstContent.blob === \"string\") {\n htmlContent = atob(firstContent.blob);\n }\n }\n\n if (!htmlContent) {\n throw new Error(\"No HTML content in resource\");\n }\n\n const listingUiMeta = listingResource?._meta?.ui as UiMeta | undefined;\n const contentUiMeta = firstContent?._meta?.ui as UiMeta | undefined;\n const mergedUiMeta =\n listingUiMeta || contentUiMeta\n ? { ...listingUiMeta, ...contentUiMeta }\n : undefined;\n\n const declaredCsp = mergedUiMeta?.csp;\n const permissions = mergedUiMeta?.permissions;\n const prefersBorder = mergedUiMeta?.prefersBorder ?? false;\n\n const mimeTypeValid = mimeType === RESOURCE_MIME_TYPE;\n const mimeTypeWarning = !mimeTypeValid\n ? mimeType\n ? `Invalid MIME type \"${mimeType}\" - SEP-1865 requires \"${RESOURCE_MIME_TYPE}\"`\n : `Missing MIME type - SEP-1865 requires \"${RESOURCE_MIME_TYPE}\"`\n : null;\n\n if (mimeTypeWarning) {\n console.warn(\"[ViewRenderer] MIME type validation:\", mimeTypeWarning, {\n resourceUri,\n });\n }\n\n const isPermissive = cspMode === \"permissive\";\n\n return {\n html: htmlContent,\n declaredCsp,\n csp: isPermissive ? undefined : declaredCsp,\n permissions,\n prefersBorder,\n mimeType,\n mimeTypeValid,\n mimeTypeWarning,\n };\n}\n","/**\n * MCP Apps sandbox-proxy HTML for ViewRenderer blob URLs.\n *\n * Browser-only — no Node/Hono imports. The host iframe loads this document\n * from a blob: URL; it proxies postMessage to the inner widget srcdoc iframe.\n */\n\nimport type {\n McpUiResourceCsp,\n McpUiResourcePermissions,\n} from \"./ext-apps-bridge.js\";\nimport type { ViewCspMode } from \"./types.js\";\n\ntype ViewSandboxBlobUrlOptions = {\n cspMode: ViewCspMode;\n permissions?: McpUiResourcePermissions;\n widgetCsp?: McpUiResourceCsp;\n};\n\n/** Build a configured HTTP(S) sandbox proxy URL. */\nexport function buildViewSandboxUrl(\n sandboxDocumentUrl: URL,\n options: ViewSandboxBlobUrlOptions\n): URL {\n const url = new URL(sandboxDocumentUrl.href);\n applySandboxSearchParams(url, options);\n return url;\n}\n\nfunction applySandboxSearchParams(\n url: URL,\n options: ViewSandboxBlobUrlOptions\n): void {\n const { cspMode, permissions, widgetCsp } = options;\n url.searchParams.set(\n \"v\",\n JSON.stringify({ cspMode, permissions, widgetCsp })\n );\n url.searchParams.set(\"csp_mode\", cspMode);\n if (permissions && Object.keys(permissions).length > 0) {\n url.searchParams.set(\"permissions\", JSON.stringify(permissions));\n }\n if (widgetCsp && Object.keys(widgetCsp).length > 0) {\n url.searchParams.set(\"widget_csp\", JSON.stringify(widgetCsp));\n }\n}\n\n/** Build a blob: sandbox iframe URL (no backend sandbox-proxy route). */\nexport function buildViewSandboxBlobUrl(\n options: ViewSandboxBlobUrlOptions\n): URL {\n const searchUrl = new URL(\"https://sandbox.invalid/\");\n applySandboxSearchParams(searchUrl, options);\n const html = buildSandboxProxyBlobHtml(searchUrl.search);\n return new URL(URL.createObjectURL(new Blob([html], { type: \"text/html\" })));\n}\n\n/**\n * Raw sandbox-proxy document (query config via location.search or __SANDBOX_SEARCH__).\n *\n * Inner guest iframe keeps `allow-same-origin` for srcdoc widget rendering;\n * browsers may warn that allow-scripts + allow-same-origin can escape sandboxing.\n */\nconst SANDBOX_PROXY_HTML: string =\n '<!doctype html>\\n<html>\\n <head>\\n <meta charset=\"utf-8\" />\\n <meta\\n http-equiv=\"Content-Security-Policy\"\\n content=\"default-src \\'self\\'; img-src * data: blob: \\'unsafe-inline\\'; media-src * blob: data:; font-src * blob: data:; script-src * \\'wasm-unsafe-eval\\' \\'unsafe-inline\\' \\'unsafe-eval\\' blob: data:; style-src * blob: data: \\'unsafe-inline\\'; connect-src * data: blob: about:; frame-src * blob: data: http://localhost:* https://localhost:* http://127.0.0.1:* https://127.0.0.1:*;\"\\n />\\n <title>MCP Apps Sandbox Proxy</title>\\n <style>\\n html, body { margin: 0; padding: 0; height: 100%; width: 100%; overflow: hidden; }\\n * { box-sizing: border-box; }\\n iframe { display: block; background-color: transparent; border: 0px none transparent; padding: 0px; width: 100%; height: 100%; }\\n </style>\\n </head>\\n <body>\\n <script>\\n function sanitizeDomain(domain) {\\n if (typeof domain !== \"string\") return \"\";\\n return domain.replace(/[\\'\"<>;]/g, \"\").trim();\\n }\\n\\n function buildAllowAttribute(permissions) {\\n if (!permissions) return \"\";\\n const allowList = [];\\n if (permissions.camera) allowList.push(\"camera *\");\\n if (permissions.microphone) allowList.push(\"microphone *\");\\n if (permissions.geolocation) allowList.push(\"geolocation *\");\\n if (permissions.clipboardWrite) allowList.push(\"clipboard-write *\");\\n return allowList.join(\"; \");\\n }\\n\\n function buildCSP(csp) {\\n if (!csp) {\\n return [\\n \"default-src \\'none\\'\",\\n \"script-src \\'unsafe-inline\\'\",\\n \"style-src \\'unsafe-inline\\'\",\\n \"img-src data:\",\\n \"font-src data:\",\\n \"media-src data:\",\\n \"connect-src \\'none\\'\",\\n \"frame-src \\'none\\'\",\\n \"object-src \\'none\\'\",\\n \"base-uri \\'none\\'\",\\n ].join(\"; \");\\n }\\n\\n const connectDomains = (csp.connectDomains || []).map(sanitizeDomain).filter(Boolean);\\n const resourceDomains = (csp.resourceDomains || []).map(sanitizeDomain).filter(Boolean);\\n const frameDomains = (csp.frameDomains || []).map(sanitizeDomain).filter(Boolean);\\n const baseUriDomains = (csp.baseUriDomains || []).map(sanitizeDomain).filter(Boolean);\\n const scriptDirectives = (csp.scriptDirectives || []).filter(function(d) { return typeof d === \"string\" && d.length > 0; });\\n\\n const connectSrc = connectDomains.length > 0 ? connectDomains.join(\" \") : \"\\'none\\'\";\\n const resourceSrc = resourceDomains.length > 0 ? [\"data:\", \"blob:\", ...resourceDomains].join(\" \") : \"data: blob:\";\\n const frameSrc = frameDomains.length > 0 ? frameDomains.join(\" \") : \"\\'none\\'\";\\n const baseUri = baseUriDomains.length > 0 ? baseUriDomains.join(\" \") : \"\\'none\\'\";\\n const scriptSrcParts = [\"\\'unsafe-inline\\'\", \"\\'unsafe-eval\\'\", resourceSrc];\\n if (scriptDirectives.length > 0) scriptSrcParts.push(scriptDirectives.join(\" \"));\\n\\n return [\\n \"default-src \\'none\\'\",\\n \"script-src \" + scriptSrcParts.join(\" \"),\\n \"style-src \\'unsafe-inline\\' \" + resourceSrc,\\n \"img-src \" + resourceSrc,\\n \"font-src \" + resourceSrc,\\n \"media-src \" + resourceSrc,\\n \"connect-src \" + connectSrc,\\n \"frame-src \" + frameSrc,\\n \"object-src \\'none\\'\",\\n \"base-uri \" + baseUri,\\n ].join(\"; \");\\n }\\n\\n function buildViolationListenerScript() {\\n return `<script>\\ndocument.addEventListener(\\'securitypolicyviolation\\', function(e) {\\n var violation = {\\n type: \\'mcp-apps:csp-violation\\',\\n directive: e.violatedDirective,\\n blockedUri: e.blockedURI,\\n sourceFile: e.sourceFile || null,\\n lineNumber: e.lineNumber || null,\\n columnNumber: e.columnNumber || null,\\n effectiveDirective: e.effectiveDirective,\\n originalPolicy: e.originalPolicy,\\n disposition: e.disposition,\\n timestamp: Date.now()\\n };\\n console.warn(\\'[MCP Apps CSP Violation]\\', violation.directive, \\':\\', violation.blockedUri);\\n window.parent.postMessage(violation, \\'*\\');\\n});\\n\\nfunction serializeConsoleArgs(args) {\\n try {\\n return Array.from(args || []).map(function(arg) {\\n if (arg instanceof Error) {\\n return {\\n type: \\'Error\\',\\n message: arg.message,\\n stack: arg.stack,\\n name: arg.name,\\n };\\n }\\n if (typeof arg === \\'object\\' && arg !== null) {\\n try {\\n return JSON.parse(JSON.stringify(arg));\\n } catch (e) {\\n return String(arg);\\n }\\n }\\n return arg;\\n });\\n } catch (e) {\\n return [String(args)];\\n }\\n}\\n\\nfunction sendConsoleToParent(level, args) {\\n try {\\n window.parent.postMessage({\\n type: \\'iframe-console-log\\',\\n level: level,\\n args: serializeConsoleArgs(args),\\n timestamp: new Date().toISOString(),\\n url: window.location.href,\\n }, \\'*\\');\\n } catch (e) {}\\n}\\n\\nvar originalConsoleError = console.error.bind(console);\\nconsole.error = function() {\\n var args = Array.from(arguments);\\n originalConsoleError.apply(console, args);\\n sendConsoleToParent(\\'error\\', args);\\n};\\n\\nwindow.addEventListener(\\'error\\', function(event) {\\n sendConsoleToParent(\\'error\\', [{\\n message: event.message,\\n filename: event.filename,\\n lineno: event.lineno,\\n colno: event.colno,\\n error: event.error ? {\\n message: event.error.message,\\n stack: event.error.stack,\\n name: event.error.name,\\n } : null,\\n }]);\\n});\\n\\nwindow.addEventListener(\\'unhandledrejection\\', function(event) {\\n sendConsoleToParent(\\'error\\', [{\\n message: \\'Unhandled Promise Rejection\\',\\n reason: event.reason ? String(event.reason) : \\'Unknown\\',\\n error: event.reason instanceof Error ? {\\n message: event.reason.message,\\n stack: event.reason.stack,\\n name: event.reason.name,\\n } : null,\\n }]);\\n});\\n</` + `script>`;\\n }\\n\\n function injectCSP(html, cspValue) {\\n const cspMeta = \\'<meta http-equiv=\"Content-Security-Policy\" content=\"\\' + cspValue + \\'\">\\';\\n const violationListener = buildViolationListenerScript();\\n const injection = cspMeta + violationListener;\\n\\n if (html.includes(\"<head>\")) {\\n return html.replace(\"<head>\", \"<head>\" + injection);\\n } else if (html.includes(\"<HEAD>\")) {\\n return html.replace(\"<HEAD>\", \"<HEAD>\" + injection);\\n } else if (html.includes(\"<html>\")) {\\n return html.replace(\"<html>\", \"<html><head>\" + injection + \"</head>\");\\n } else if (html.includes(\"<HTML>\")) {\\n return html.replace(\"<HTML>\", \"<HTML><head>\" + injection + \"</head>\");\\n } else if (html.includes(\"<!DOCTYPE\") || html.includes(\"<!doctype\")) {\\n return html.replace(/(<!DOCTYPE[^>]*>|<!doctype[^>]*>)/i, \"$1<head>\" + injection + \"</head>\");\\n } else {\\n return injection + html;\\n }\\n }\\n\\n // Query params from host (csp_mode, permissions, widget_csp). AppFrame only\\n // sends { html, csp } in sandbox-resource-ready; we carry the rest on the URL.\\n // Blob URLs cannot reliably carry search params, so the CDN shell injects\\n // window.__SANDBOX_SEARCH__ via buildSandboxProxyBlobHtml.\\n const query = new URLSearchParams(\\n typeof window.__SANDBOX_SEARCH__ === \"string\"\\n ? window.__SANDBOX_SEARCH__\\n : location.search\\n );\\n const queryCspMode = query.get(\"csp_mode\") || \"permissive\";\\n let queryPermissions = null;\\n let queryWidgetCsp = null;\\n try {\\n const rawPerm = query.get(\"permissions\");\\n if (rawPerm) queryPermissions = JSON.parse(rawPerm);\\n } catch (e) {}\\n try {\\n const rawCsp = query.get(\"widget_csp\");\\n if (rawCsp) queryWidgetCsp = JSON.parse(rawCsp);\\n } catch (e) {}\\n\\n const inner = document.createElement(\"iframe\");\\n inner.style = \"width:100%; height:100%; border:none;\";\\n inner.setAttribute(\"sandbox\", \"allow-scripts allow-same-origin allow-forms\");\\n document.body.appendChild(inner);\\n\\n window.addEventListener(\"message\", async (event) => {\\n if (event.source === window.parent) {\\n if (event.data && event.data.method === \"ui/notifications/sandbox-resource-ready\") {\\n const params = event.data.params || {};\\n const html = params.html;\\n const sandbox = params.sandbox;\\n // Prefer message csp when present; fall back to URL widget_csp\\n const csp = params.csp != null ? params.csp : queryWidgetCsp;\\n const permissions = params.permissions != null ? params.permissions : queryPermissions;\\n const permissive =\\n typeof params.permissive === \"boolean\"\\n ? params.permissive\\n : queryCspMode === \"permissive\";\\n if (typeof sandbox === \"string\") {\\n inner.setAttribute(\"sandbox\", sandbox);\\n }\\n const allowAttribute = buildAllowAttribute(permissions);\\n if (allowAttribute) {\\n inner.setAttribute(\"allow\", allowAttribute);\\n }\\n if (typeof html === \"string\") {\\n if (permissive) {\\n const permissiveCsp = [\\n \"default-src * \\'unsafe-inline\\' \\'unsafe-eval\\' data: blob: filesystem: about:\",\\n \"script-src * \\'unsafe-inline\\' \\'unsafe-eval\\' data: blob:\",\\n \"style-src * \\'unsafe-inline\\' data: blob:\",\\n \"img-src * data: blob: https: http:\",\\n \"media-src * data: blob: https: http:\",\\n \"font-src * data: blob: https: http:\",\\n \"connect-src * data: blob: https: http: ws: wss: about:\",\\n \"frame-src * data: blob: https: http: about:\",\\n \"object-src * data: blob:\",\\n \"base-uri *\",\\n \"form-action *\",\\n ].join(\"; \");\\n const processedHtml = injectCSP(html, permissiveCsp);\\n inner.srcdoc = processedHtml;\\n } else {\\n const cspValue = buildCSP(csp);\\n const processedHtml = injectCSP(html, cspValue);\\n inner.srcdoc = processedHtml;\\n }\\n }\\n } else {\\n if (inner && inner.contentWindow) {\\n inner.contentWindow.postMessage(event.data, \"*\");\\n }\\n }\\n } else if (event.source === inner.contentWindow) {\\n window.parent.postMessage(event.data, \"*\");\\n }\\n });\\n\\n window.parent.postMessage({\\n jsonrpc: \"2.0\",\\n method: \"ui/notifications/sandbox-proxy-ready\",\\n params: {},\\n }, \"*\");\\n </script>\\n </body>\\n</html>';\n\n/**\n * Build sandbox-proxy HTML for a Blob URL, injecting search params that Blob\n * URLs cannot carry reliably.\n *\n * JSON-escapes the search string (incl. `<` → `\\\\u003c`) so it cannot break\n * out of the inline script tag.\n */\nexport function buildSandboxProxyBlobHtml(search: string): string {\n const escaped = JSON.stringify(search).replace(/</g, \"\\\\u003c\");\n const inject =\n \"<script>window.__SANDBOX_SEARCH__ = \" + escaped + \";</script>\";\n return SANDBOX_PROXY_HTML.replace(\n ` const scriptSrcParts = [\"'unsafe-inline'\", \"'unsafe-eval'\", resourceSrc];\\n`,\n ` const scriptSrcParts = [\"'unsafe-inline'\", resourceSrc];\\n`\n ).replace(\"<body>\", \"<body>\" + inject);\n}\n","import { useCallback, useEffect, type RefObject } from \"react\";\nimport type { ViewDisplayMode } from \"./types.js\";\n\nconst SHELL_BASE =\n \"w-full h-full min-h-0 bg-background flex flex-col [&:fullscreen]:h-full [&:fullscreen]:w-full [&:fullscreen]:bg-background\";\n\n// High z-index for hosts without a trapping stacking context; chat history\n// toggle also hides via data-mcp-widget-fullscreen on <html>.\nconst WIDGET_FULLSCREEN_OVERLAY_CLASSES = `fixed inset-0 z-[200] ${SHELL_BASE}`;\nconst WIDGET_PIP_SHELL_CLASSES = [\n \"fixed top-4 left-1/2 -translate-x-1/2 z-[200]\",\n \"rounded-3xl w-full min-w-[300px] h-[400px]\",\n \"shadow-2xl border overflow-hidden\",\n \"bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/80\",\n \"flex flex-col\",\n].join(\" \");\n\nconst WIDGET_FULLSCREEN_DOCUMENT_ATTR = \"data-mcp-widget-fullscreen\";\nconst WIDGET_DISPLAY_MODE_ATTR = \"data-mcp-widget-display-mode\";\n\nfunction useWidgetDisplayModeDocumentChrome(\n displayMode: ViewDisplayMode\n): void {\n useEffect(() => {\n if (typeof document === \"undefined\") return;\n if (displayMode === \"pip\" || displayMode === \"fullscreen\") {\n document.documentElement.setAttribute(\n WIDGET_DISPLAY_MODE_ATTR,\n displayMode\n );\n if (displayMode === \"fullscreen\") {\n document.documentElement.setAttribute(\n WIDGET_FULLSCREEN_DOCUMENT_ATTR,\n \"\"\n );\n } else {\n document.documentElement.removeAttribute(\n WIDGET_FULLSCREEN_DOCUMENT_ATTR\n );\n }\n return () => {\n document.documentElement.removeAttribute(WIDGET_DISPLAY_MODE_ATTR);\n document.documentElement.removeAttribute(\n WIDGET_FULLSCREEN_DOCUMENT_ATTR\n );\n };\n }\n document.documentElement.removeAttribute(WIDGET_DISPLAY_MODE_ATTR);\n document.documentElement.removeAttribute(WIDGET_FULLSCREEN_DOCUMENT_ATTR);\n }, [displayMode]);\n}\n\nexport function useViewDisplayModeControls({\n displayMode,\n setDisplayMode,\n}: {\n containerRef: RefObject<HTMLElement | null>;\n displayMode: ViewDisplayMode;\n setDisplayMode: (mode: ViewDisplayMode) => void;\n}) {\n const isFullscreen = displayMode === \"fullscreen\";\n const isPip = displayMode === \"pip\";\n\n useWidgetDisplayModeDocumentChrome(displayMode);\n\n const handleDisplayModeChange = useCallback(\n (mode: ViewDisplayMode) => setDisplayMode(mode),\n [setDisplayMode]\n );\n\n return {\n handleDisplayModeChange,\n fullscreenShellClassName: isFullscreen\n ? WIDGET_FULLSCREEN_OVERLAY_CLASSES\n : undefined,\n pipShellClassName: isPip ? WIDGET_PIP_SHELL_CLASSES : undefined,\n isFullscreen,\n isPip,\n };\n}\n\nexport const VIEW_DIMENSIONS = {\n PIP_MAX_WIDTH: 700,\n DEFAULT_HEIGHT: 400,\n FULLSCREEN_HEADER_HEIGHT: 50,\n} as const;\n","import type {\n McpUiHostCapabilities,\n McpUiSupportedContentBlockModalities,\n} from \"./ext-apps-bridge.js\";\nimport type { ViewConnection, ViewDisplayMode } from \"./types.js\";\n\n/** Inputs used to derive the capabilities advertised by an MCP App host. */\ntype CapabilityInputs = {\n hasConnection: boolean;\n hasMessageHandler: boolean;\n hasModelContextHandler: boolean;\n hasLogHandler: boolean;\n hasSamplingHandler?: boolean;\n hasDownloadHandler?: boolean;\n messageCapabilities?: McpUiSupportedContentBlockModalities;\n modelContextCapabilities?: McpUiSupportedContentBlockModalities;\n};\n\n/**\n * Builds host capabilities from the callbacks and connections the host exposes.\n *\n * @param inputs - Available host features and supported content modalities.\n * @returns Capabilities suitable for MCP App bridge initialization.\n */\nexport function buildDefaultHostCapabilities({\n hasConnection,\n hasMessageHandler,\n hasModelContextHandler,\n hasLogHandler,\n hasSamplingHandler,\n hasDownloadHandler,\n messageCapabilities,\n modelContextCapabilities,\n}: CapabilityInputs): McpUiHostCapabilities {\n return {\n openLinks: {},\n ...(hasConnection\n ? {\n serverTools: {},\n serverResources: {},\n }\n : {}),\n ...(hasLogHandler ? { logging: {} } : {}),\n ...(hasSamplingHandler ? { sampling: {} } : {}),\n ...(hasDownloadHandler ? { downloadFile: {} } : {}),\n ...(hasModelContextHandler\n ? { updateModelContext: modelContextCapabilities ?? { text: {} } }\n : {}),\n ...(hasMessageHandler\n ? { message: messageCapabilities ?? { text: {} } }\n : {}),\n };\n}\n\n/**\n * Tests whether a tool is visible to the model.\n *\n * Tools without explicit visibility metadata remain model-visible.\n *\n * @param tool - Tool metadata to inspect.\n * @returns `true` when the tool may be presented to the model.\n */\nexport function isToolVisibleToModel(tool: { _meta?: unknown }): boolean {\n if (!tool._meta || typeof tool._meta !== \"object\") return true;\n const ui = (tool._meta as Record<string, unknown>).ui;\n if (!ui || typeof ui !== \"object\") return true;\n const visibility = (ui as Record<string, unknown>).visibility;\n return (\n !Array.isArray(visibility) || visibility.some((value) => value === \"model\")\n );\n}\n\n/**\n * Validates and dispatches an MCP App `ui/message` payload.\n *\n * @param handler - Host callback that accepts message content.\n * @param content - Content blocks supplied by the app.\n * @throws When the host has no message handler or `content` is empty.\n */\nexport async function dispatchUiMessage(\n handler: ((content: unknown[]) => void | Promise<void>) | undefined,\n content: unknown[]\n): Promise<void> {\n if (!handler) {\n throw new Error(\"This host surface does not support ui/message\");\n }\n if (content.length === 0) {\n throw new Error(\"ui/message requires at least one content block\");\n }\n await handler(content);\n}\n\n/**\n * Resolves a display-mode request against host and app availability.\n *\n * @param options - Requested and current modes plus each side's supported modes.\n * @returns The requested mode when both sides support it; otherwise `current`.\n */\nexport function resolveRequestedDisplayMode({\n requested,\n current,\n hostAvailable,\n appAvailable,\n}: {\n requested: ViewDisplayMode;\n current: ViewDisplayMode;\n hostAvailable?: readonly ViewDisplayMode[];\n appAvailable?: readonly ViewDisplayMode[];\n}): ViewDisplayMode {\n const hostModes = hostAvailable ?? [\"inline\"];\n const appModes = appAvailable ?? [\"inline\"];\n return hostModes.includes(requested) && appModes.includes(requested)\n ? requested\n : current;\n}\n\n/**\n * Asserts that an MCP App may call a named server tool.\n *\n * @param tools - Tools available through the live view connection.\n * @param name - Tool name requested by the app.\n * @throws When the tool is unavailable or not visible to apps.\n */\nexport function assertAppCanCallTool(\n tools: ViewConnection[\"tools\"],\n name: string\n): void {\n const tool = tools?.find((candidate) => candidate.name === name);\n if (!tool) {\n throw new Error(`Tool \"${name}\" is not available to this app`);\n }\n\n const visibility = tool._meta?.ui?.visibility;\n if (visibility && !visibility.includes(\"app\")) {\n throw new Error(`Tool \"${name}\" is not available to this app`);\n }\n}\n","import { RESOURCE_MIME_TYPE } from \"./ext-apps-bridge.js\";\n\n/**\n * Reads the MCP App resource URI from tool metadata.\n *\n * @param toolMeta - Tool `_meta` object.\n * @returns The declared view resource URI, or `null` when none is declared.\n */\nexport function getViewResourceUri(\n toolMeta?: Record<string, unknown>\n): string | null {\n const uri = toolMeta?.ui;\n if (\n uri &&\n typeof uri === \"object\" &&\n \"resourceUri\" in uri &&\n typeof (uri as { resourceUri?: unknown }).resourceUri === \"string\"\n ) {\n return (uri as { resourceUri: string }).resourceUri;\n }\n return null;\n}\n\n/**\n * Tests whether tool metadata declares an MCP App resource.\n *\n * @param toolMeta - Tool `_meta` object.\n * @returns `true` when the tool declares a view resource URI.\n */\nexport function isViewTool(toolMeta?: Record<string, unknown>): boolean {\n return getViewResourceUri(toolMeta) !== null;\n}\n\n/**\n * Tests whether a resource uses the MCP App HTML media type.\n *\n * @param mimeType - Resource MIME type.\n * @returns `true` for the MCP App resource media type.\n */\nexport function isViewResource(mimeType?: string): boolean {\n return mimeType === RESOURCE_MIME_TYPE;\n}\n"],"mappings":"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","names":["logger","auth","useCallback","UnauthorizedError","UnauthorizedError","sessionId","response","tracker","tracker","isOAuthClientProvider","session","proxyAddress","useCallback","serverInfo","capabilities","protocolEra","protocolVersion","instructions","extensions","error","auth","parsedUrl","baseUrl","StreamableHTTPClientTransport","StreamableHTTPClientTransport","useCallback","useEffect","useMemo","useRef","useState","useCallback","useEffect","useRef","useState","useMemo","useEffect","useCallback","displayName","useRef","useState","clearRpcLogs","React","useCallback","useEffect","useMemo","useRef","useState","useCallback","useEffect","React","useRef","useState","useMemo","useCallback","useEffect"]}