{"version":3,"file":"client.cjs","names":["getDebugLog","#config","clientConfigSchema","z","connectionSchema","_resolveAndApplyOverrideHandlingOverrides","#loadToolsOptions","#mcpServers","#clientConnections","ConnectionManager","#onConnectionError","#failedServers","#serverNameToTools","loadMcpTools","#cleanupServerResources"],"sources":["../src/client.ts"],"sourcesContent":["import { StdioClientTransport } from \"@modelcontextprotocol/sdk/client/stdio.js\";\nimport {\n  SSEClientTransport,\n  type SseError,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport {\n  StreamableHTTPClientTransport,\n  type StreamableHTTPError,\n} from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\nimport type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type { DynamicStructuredTool } from \"@langchain/core/tools\";\nimport type { LoggingLevel } from \"@modelcontextprotocol/sdk/types.js\";\n\nimport { z } from \"zod/v3\";\nimport { loadMcpTools } from \"./tools.js\";\nimport { ConnectionManager, type Client } from \"./connection.js\";\nimport { getDebugLog } from \"./logging.js\";\nimport {\n  type ClientConfig,\n  type Connection,\n  type ResolvedClientConfig,\n  type ResolvedConnection,\n  type ResolvedStdioConnection,\n  type ResolvedStreamableHTTPConnection,\n  type CustomHTTPTransportOptions,\n  type MCPResource,\n  type MCPResourceTemplate,\n  type MCPResourceContent,\n  type ConnectionErrorHandler,\n  clientConfigSchema,\n  connectionSchema,\n  type LoadMcpToolsOptions,\n  _resolveAndApplyOverrideHandlingOverrides,\n} from \"./types.js\";\n\nconst debugLog = getDebugLog();\n\n/**\n * Error class for MCP client operations\n */\nexport class MCPClientError extends Error {\n  constructor(\n    message: string,\n    public readonly serverName?: string\n  ) {\n    super(message);\n    this.name = \"MCPClientError\";\n  }\n}\n\n/**\n * Checks if the connection configuration is for a stdio transport\n * @param connection - The connection configuration\n * @returns True if the connection configuration is for a stdio transport\n */\nfunction isResolvedStdioConnection(\n  connection: unknown\n): connection is ResolvedStdioConnection {\n  if (\n    typeof connection !== \"object\" ||\n    connection === null ||\n    Array.isArray(connection)\n  ) {\n    return false;\n  }\n\n  if (\"transport\" in connection && connection.transport === \"stdio\") {\n    return true;\n  }\n\n  if (\"type\" in connection && connection.type === \"stdio\") {\n    return true;\n  }\n\n  if (\"command\" in connection && typeof connection.command === \"string\") {\n    return true;\n  }\n\n  return false;\n}\n\n/**\n * Checks if the connection configuration is for a streamable HTTP transport\n * @param connection - The connection configuration\n * @returns True if the connection configuration is for a streamable HTTP transport\n */\nfunction isResolvedStreamableHTTPConnection(\n  connection: unknown\n): connection is ResolvedStreamableHTTPConnection {\n  if (\n    typeof connection !== \"object\" ||\n    connection === null ||\n    Array.isArray(connection)\n  ) {\n    return false;\n  }\n\n  if (\n    (\"transport\" in connection &&\n      typeof connection.transport === \"string\" &&\n      [\"http\", \"sse\"].includes(connection.transport)) ||\n    (\"type\" in connection &&\n      typeof connection.type === \"string\" &&\n      [\"http\", \"sse\"].includes(connection.type))\n  ) {\n    return true;\n  }\n\n  if (\"url\" in connection && typeof connection.url === \"string\") {\n    try {\n      new URL(connection.url);\n      return true;\n    } catch {\n      return false;\n    }\n  }\n\n  return false;\n}\n\n/**\n * Client for connecting to multiple MCP servers and loading LangChain-compatible tools.\n */\nexport class MultiServerMCPClient {\n  /**\n   * Cached map of server names to tools\n   */\n  #serverNameToTools: Record<string, DynamicStructuredTool[]> = {};\n\n  /**\n   * Configured MCP servers\n   */\n  #mcpServers?: Record<string, ResolvedConnection>;\n\n  /**\n   * Cached map of server names to load tools options\n   */\n  #loadToolsOptions: Record<string, LoadMcpToolsOptions> = {};\n\n  /**\n   * Connection manager\n   */\n  #clientConnections: ConnectionManager;\n\n  /**\n   * Resolved client config\n   */\n  #config: ResolvedClientConfig;\n\n  /**\n   * Behavior when a server fails to connect\n   */\n  #onConnectionError: \"throw\" | \"ignore\" | ConnectionErrorHandler;\n\n  /**\n   * Set of server names that have failed to connect (when onConnectionError is \"ignore\")\n   */\n  #failedServers: Set<string> = new Set();\n\n  /**\n   * Returns clone of server config for inspection purposes.\n   *\n   * Client does not support config modifications.\n   */\n  get config(): ClientConfig {\n    // clone config so it can't be mutated\n    return JSON.parse(JSON.stringify(this.#config));\n  }\n\n  /**\n   * Create a new MultiServerMCPClient.\n   *\n   * @param config - Configuration object\n   */\n  constructor(config: ClientConfig | Record<string, Connection>) {\n    let parsedServerConfig: ResolvedClientConfig;\n\n    const configSchema = clientConfigSchema;\n\n    if (\"mcpServers\" in config) {\n      parsedServerConfig = configSchema.parse(config);\n    } else {\n      // two step parse so parse errors are referencing the correct object paths\n      const parsedMcpServers = z.record(connectionSchema).parse(config);\n\n      parsedServerConfig = configSchema.parse({ mcpServers: parsedMcpServers });\n    }\n\n    if (Object.keys(parsedServerConfig.mcpServers).length === 0) {\n      throw new MCPClientError(\"No MCP servers provided\");\n    }\n\n    for (const [serverName, serverConfig] of Object.entries(\n      parsedServerConfig.mcpServers\n    )) {\n      const outputHandling = _resolveAndApplyOverrideHandlingOverrides(\n        parsedServerConfig.outputHandling,\n        serverConfig.outputHandling\n      );\n      const defaultToolTimeout =\n        parsedServerConfig.defaultToolTimeout ??\n        serverConfig.defaultToolTimeout;\n\n      this.#loadToolsOptions[serverName] = {\n        throwOnLoadError: parsedServerConfig.throwOnLoadError,\n        prefixToolNameWithServerName:\n          parsedServerConfig.prefixToolNameWithServerName,\n        additionalToolNamePrefix: parsedServerConfig.additionalToolNamePrefix,\n        useStandardContentBlocks: parsedServerConfig.useStandardContentBlocks,\n        ...(Object.keys(outputHandling).length > 0 ? { outputHandling } : {}),\n        ...(defaultToolTimeout ? { defaultToolTimeout } : {}),\n        onProgress: parsedServerConfig.onProgress,\n        /**\n         * make sure to place global hooks (e.g. parsedServerConfig) first before\n         * server-specific hooks (e.g. serverConfig) so they can override tool call\n         * configuration.\n         */\n        beforeToolCall: parsedServerConfig.beforeToolCall,\n        afterToolCall: parsedServerConfig.afterToolCall,\n      };\n    }\n\n    this.#config = parsedServerConfig;\n    this.#mcpServers = parsedServerConfig.mcpServers;\n    this.#clientConnections = new ConnectionManager(parsedServerConfig);\n    this.#onConnectionError = parsedServerConfig.onConnectionError;\n  }\n\n  /**\n   * Proactively initialize connections to all servers. This will be called automatically when\n   * methods requiring an active connection (like {@link getTools} or {@link getClient}) are called,\n   * but you can call it directly to ensure all connections are established before using the tools.\n   *\n   * When a server fails to connect, the client will throw an error if `onConnectionError` is \"throw\",\n   * otherwise it will skip the server and continue with the remaining servers.\n   *\n   * @returns A map of server names to arrays of tools\n   * @throws {MCPClientError} If initialization fails and `onConnectionError` is \"throw\" (default)\n   */\n  async initializeConnections(\n    customTransportOptions?: CustomHTTPTransportOptions\n  ): Promise<Record<string, DynamicStructuredTool[]>> {\n    if (!this.#mcpServers || Object.keys(this.#mcpServers).length === 0) {\n      throw new MCPClientError(\"No connections to initialize\");\n    }\n\n    for (const [serverName, connection] of Object.entries(this.#mcpServers)) {\n      // Skip servers that have already failed (when onConnectionError is \"ignore\")\n      if (\n        (this.#onConnectionError === \"ignore\" ||\n          typeof this.#onConnectionError === \"function\") &&\n        this.#failedServers.has(serverName)\n      ) {\n        continue;\n      }\n\n      try {\n        await this._initializeConnection(\n          serverName,\n          connection,\n          customTransportOptions\n        );\n        // If we successfully initialized, remove from failed set (in case it was there before)\n        this.#failedServers.delete(serverName);\n      } catch (error) {\n        if (this.#onConnectionError === \"throw\") {\n          throw error;\n        }\n\n        // Handle custom error handler function\n        if (typeof this.#onConnectionError === \"function\") {\n          this.#onConnectionError({ serverName, error });\n          // If we get here, the handler didn't throw, so treat as ignored\n          this.#failedServers.add(serverName);\n          debugLog(\n            `WARN: Failed to initialize connection to server \"${serverName}\": ${String(error)}`\n          );\n          continue;\n        }\n\n        // Default \"ignore\" behavior\n        // Mark this server as failed so we don't try again\n        this.#failedServers.add(serverName);\n        debugLog(\n          `WARN: Failed to initialize connection to server \"${serverName}\": ${String(error)}`\n        );\n        continue;\n      }\n    }\n\n    // Warn if no servers successfully connected when using \"ignore\" mode\n    if (\n      this.#onConnectionError === \"ignore\" &&\n      Object.keys(this.#serverNameToTools).length === 0\n    ) {\n      debugLog(\n        `WARN: No servers successfully connected. All connection attempts failed.`\n      );\n    }\n\n    return this.#serverNameToTools;\n  }\n\n  /**\n   * Get tools from specified servers as a flattened array.\n   *\n   * @param servers - Optional array of server names to filter tools by.\n   *                 If not provided, returns tools from all servers.\n   * @param options - Optional connection options for the tool calls, e.g. custom auth provider or headers.\n   * @returns A flattened array of tools from the specified servers (or all servers)\n   *\n   * @example\n   * ```ts\n   * // Get tools from all servers\n   * const tools = await client.getTools();\n   * ```\n   *\n   * @example\n   * ```ts\n   * // Get tools from specific servers\n   * const tools = await client.getTools(\"server1\", \"server2\");\n   * ```\n   *\n   * @example\n   * ```ts\n   * // Get tools from specific servers with custom connection options\n   * const tools = await client.getTools([\"server1\", \"server2\"], {\n   *   authProvider: new OAuthClientProvider(),\n   *   headers: { \"X-Custom-Header\": \"value\" },\n   * });\n   * ```\n   */\n  async getTools(...servers: string[]): Promise<DynamicStructuredTool[]>;\n  async getTools(\n    servers: string[],\n    options?: CustomHTTPTransportOptions\n  ): Promise<DynamicStructuredTool[]>;\n  async getTools(...args: unknown[]): Promise<DynamicStructuredTool[]> {\n    if (args.length === 0 || args.every((arg) => typeof arg === \"string\")) {\n      await this.initializeConnections();\n\n      const servers = args as string[];\n      return servers.length === 0\n        ? this._getAllToolsAsFlatArray()\n        : this._getToolsFromServers(servers);\n    }\n\n    const [servers, options] = args as [\n      string[],\n      CustomHTTPTransportOptions | undefined,\n    ];\n    await this.initializeConnections(options);\n    return servers.length === 0\n      ? this._getAllToolsAsFlatArray()\n      : this._getToolsFromServers(servers);\n  }\n\n  /**\n   * Set the logging level for all servers\n   * @param level - The logging level\n   *\n   * @example\n   * ```ts\n   * await client.setLoggingLevel(\"debug\");\n   * ```\n   */\n  async setLoggingLevel(level: LoggingLevel): Promise<void>;\n  /**\n   * Set the logging level for a specific server\n   * @param serverName - The name of the server\n   * @param level - The logging level\n   *\n   * @example\n   * ```ts\n   * await client.setLoggingLevel(\"server1\", \"debug\");\n   * ```\n   */\n  async setLoggingLevel(serverName: string, level: LoggingLevel): Promise<void>;\n  async setLoggingLevel(...args: unknown[]): Promise<void> {\n    if (args.length === 1 && typeof args[0] === \"string\") {\n      const level = args[0] as LoggingLevel;\n      await Promise.all(\n        this.#clientConnections\n          .getAllClients()\n          .map((client) => client.setLoggingLevel(level))\n      );\n      return;\n    }\n\n    const [serverName, level] = args as [string, LoggingLevel];\n    await this.#clientConnections.get(serverName)?.setLoggingLevel(level);\n  }\n\n  /**\n   * Get a the MCP client for a specific server. Useful for fetching prompts or resources from that server.\n   *\n   * @param serverName - The name of the server\n   * @returns The client for the server, or undefined if the server is not connected\n   */\n  async getClient(\n    serverName: string,\n    options?: CustomHTTPTransportOptions\n  ): Promise<Client | undefined> {\n    await this.initializeConnections(options);\n    return this.#clientConnections.get({\n      serverName,\n      headers: options?.headers,\n      authProvider: options?.authProvider,\n    });\n  }\n\n  /**\n   * List resources from specified servers.\n   *\n   * @param servers - Optional array of server names to filter resources by.\n   *                 If not provided, returns resources from all servers.\n   * @param options - Optional connection options for the resource listing, e.g. custom auth provider or headers.\n   * @returns A map of server names to their resources\n   *\n   * @example\n   * ```ts\n   * // List resources from all servers\n   * const resources = await client.listResources();\n   * ```\n   *\n   * @example\n   * ```ts\n   * // List resources from specific servers\n   * const resources = await client.listResources(\"server1\", \"server2\");\n   * ```\n   */\n  async listResources(\n    ...servers: string[]\n  ): Promise<Record<string, MCPResource[]>>;\n  async listResources(\n    servers: string[],\n    options?: CustomHTTPTransportOptions\n  ): Promise<Record<string, MCPResource[]>>;\n  async listResources(\n    ...args: unknown[]\n  ): Promise<Record<string, MCPResource[]>> {\n    let servers: string[];\n    let options: CustomHTTPTransportOptions | undefined;\n\n    if (args.length === 0 || args.every((arg) => typeof arg === \"string\")) {\n      servers = args as string[];\n      await this.initializeConnections();\n    } else {\n      [servers, options] = args as [\n        string[],\n        CustomHTTPTransportOptions | undefined,\n      ];\n      await this.initializeConnections(options);\n    }\n\n    const targetServers =\n      servers.length > 0 ? servers : Object.keys(this.#config.mcpServers);\n\n    const result: Record<string, MCPResource[]> = {};\n\n    for (const serverName of targetServers) {\n      const client = await this.getClient(serverName, options);\n      if (!client) {\n        debugLog(`WARN: Server \"${serverName}\" not found or not connected`);\n        continue;\n      }\n\n      try {\n        const resourcesList = await client.listResources();\n        result[serverName] = resourcesList.resources.map((resource) => ({\n          uri: resource.uri,\n          name: resource.title ?? resource.name,\n          description: resource.description,\n          mimeType: resource.mimeType,\n        }));\n        debugLog(\n          `INFO: Listed ${result[serverName].length} resources from server \"${serverName}\"`\n        );\n      } catch (error) {\n        debugLog(\n          `ERROR: Failed to list resources from server \"${serverName}\": ${error}`\n        );\n        result[serverName] = [];\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * List resource templates from specified servers.\n   *\n   * Resource templates are used for dynamic resources with parameterized URIs.\n   *\n   * @param servers - Optional array of server names to filter resource templates by.\n   *                 If not provided, returns resource templates from all servers.\n   * @param options - Optional connection options for the resource template listing, e.g. custom auth provider or headers.\n   * @returns A map of server names to their resource templates\n   *\n   * @example\n   * ```ts\n   * // List resource templates from all servers\n   * const templates = await client.listResourceTemplates();\n   * ```\n   *\n   * @example\n   * ```ts\n   * // List resource templates from specific servers\n   * const templates = await client.listResourceTemplates(\"server1\", \"server2\");\n   * ```\n   */\n  async listResourceTemplates(\n    ...servers: string[]\n  ): Promise<Record<string, MCPResourceTemplate[]>>;\n  async listResourceTemplates(\n    servers: string[],\n    options?: CustomHTTPTransportOptions\n  ): Promise<Record<string, MCPResourceTemplate[]>>;\n  async listResourceTemplates(\n    ...args: unknown[]\n  ): Promise<Record<string, MCPResourceTemplate[]>> {\n    let servers: string[];\n    let options: CustomHTTPTransportOptions | undefined;\n\n    if (args.length === 0 || args.every((arg) => typeof arg === \"string\")) {\n      servers = args as string[];\n      await this.initializeConnections();\n    } else {\n      [servers, options] = args as [\n        string[],\n        CustomHTTPTransportOptions | undefined,\n      ];\n      await this.initializeConnections(options);\n    }\n\n    const targetServers =\n      servers.length > 0 ? servers : Object.keys(this.#config.mcpServers);\n\n    const result: Record<string, MCPResourceTemplate[]> = {};\n\n    for (const serverName of targetServers) {\n      const client = await this.getClient(serverName, options);\n      if (!client) {\n        debugLog(`WARN: Server \"${serverName}\" not found or not connected`);\n        continue;\n      }\n\n      try {\n        const templatesList = await client.listResourceTemplates();\n        result[serverName] = templatesList.resourceTemplates.map(\n          (template) => ({\n            uriTemplate: template.uriTemplate,\n            name: template.title ?? template.name,\n            description: template.description,\n            mimeType: template.mimeType,\n          })\n        );\n        debugLog(\n          `INFO: Listed ${result[serverName].length} resource templates from server \"${serverName}\"`\n        );\n      } catch (error) {\n        debugLog(\n          `ERROR: Failed to list resource templates from server \"${serverName}\": ${error}`\n        );\n        result[serverName] = [];\n      }\n    }\n\n    return result;\n  }\n\n  /**\n   * Read a resource from a specific server.\n   *\n   * @param serverName - The name of the server to read the resource from\n   * @param uri - The URI of the resource to read\n   * @param options - Optional connection options for reading the resource, e.g. custom auth provider or headers.\n   * @returns The resource contents\n   *\n   * @example\n   * ```ts\n   * const content = await client.readResource(\"server1\", \"file://path/to/resource\");\n   * ```\n   */\n  async readResource(\n    serverName: string,\n    uri: string,\n    options?: CustomHTTPTransportOptions\n  ): Promise<MCPResourceContent[]> {\n    await this.initializeConnections(options);\n\n    const client = await this.getClient(serverName, options);\n    if (!client) {\n      throw new MCPClientError(\n        `Server \"${serverName}\" not found or not connected`,\n        serverName\n      );\n    }\n\n    try {\n      debugLog(`INFO: Reading resource \"${uri}\" from server \"${serverName}\"`);\n      const result = await client.readResource({ uri });\n      return result.contents.map((content) => ({\n        uri: content.uri,\n        mimeType: content.mimeType,\n        text: \"text\" in content ? content.text : undefined,\n        blob: \"blob\" in content ? content.blob : undefined,\n      }));\n    } catch (error) {\n      throw new MCPClientError(\n        `Failed to read resource \"${uri}\" from server \"${serverName}\": ${error}`,\n        serverName\n      );\n    }\n  }\n\n  /**\n   * Close all connections.\n   */\n  async close(): Promise<void> {\n    debugLog(`INFO: Closing all MCP connections...`);\n    this.#serverNameToTools = {};\n    this.#failedServers.clear();\n    await this.#clientConnections.delete();\n    debugLog(`INFO: All MCP connections closed`);\n  }\n\n  /**\n   * Initialize a connection to a specific server\n   */\n  private async _initializeConnection(\n    serverName: string,\n    connection: ResolvedConnection,\n    customTransportOptions?: CustomHTTPTransportOptions\n  ): Promise<void> {\n    if (isResolvedStdioConnection(connection)) {\n      debugLog(\n        `INFO: Initializing stdio connection to server \"${serverName}\"...`\n      );\n\n      /**\n       * check if we already initialized this stdio connection\n       */\n      if (this.#clientConnections.has(serverName)) {\n        return;\n      }\n\n      await this._initializeStdioConnection(serverName, connection);\n    } else if (isResolvedStreamableHTTPConnection(connection)) {\n      /**\n       * Users may want to use different connection options for tool calls or tool discovery.\n       */\n      const { authProvider, headers } = customTransportOptions ?? {};\n      const updatedConnection = {\n        ...connection,\n        authProvider: authProvider ?? connection.authProvider,\n        headers: { ...headers, ...connection.headers },\n      };\n\n      /**\n       * check if we already initialized this streamable HTTP connection\n       */\n      const key = {\n        serverName,\n        headers: updatedConnection.headers,\n        authProvider: updatedConnection.authProvider,\n      };\n      if (this.#clientConnections.has(key)) {\n        return;\n      }\n\n      if (connection.type === \"sse\" || connection.transport === \"sse\") {\n        await this._initializeSSEConnection(serverName, updatedConnection);\n      } else {\n        await this._initializeStreamableHTTPConnection(\n          serverName,\n          updatedConnection\n        );\n      }\n    } else {\n      // This should never happen due to the validation in the constructor\n      throw new MCPClientError(\n        `Unsupported transport type for server \"${serverName}\"`,\n        serverName\n      );\n    }\n  }\n\n  /**\n   * Initialize a stdio connection\n   */\n  private async _initializeStdioConnection(\n    serverName: string,\n    connection: ResolvedStdioConnection\n  ): Promise<void> {\n    const { command, args, restart } = connection;\n\n    debugLog(\n      `DEBUG: Creating stdio transport for server \"${serverName}\" with command: ${command} ${args.join(\n        \" \"\n      )}`\n    );\n\n    try {\n      const client = await this.#clientConnections.createClient(\n        \"stdio\",\n        serverName,\n        connection\n      );\n      const transport = this.#clientConnections.getTransport({\n        serverName,\n      }) as StdioClientTransport;\n\n      // Set up auto-restart if configured\n      if (restart?.enabled) {\n        this._setupStdioRestart(serverName, transport, connection, restart);\n      }\n\n      // Load tools for this server\n      await this._loadToolsForServer(serverName, client);\n    } catch (error) {\n      throw new MCPClientError(\n        `Failed to connect to stdio server \"${serverName}\": ${error}`,\n        serverName\n      );\n    }\n  }\n\n  /**\n   * Set up stdio restart handling\n   */\n  private _setupStdioRestart(\n    serverName: string,\n    transport: StdioClientTransport,\n    connection: ResolvedStdioConnection,\n    restart: NonNullable<ResolvedStdioConnection[\"restart\"]>\n  ): void {\n    const originalOnClose = transport.onclose;\n    // oxlint-disable-next-line @typescript-eslint/no-misused-promises\n    transport.onclose = async () => {\n      if (originalOnClose) {\n        await originalOnClose();\n      }\n\n      // Only attempt restart if we haven't cleaned up\n      if (this.#clientConnections.get(serverName)) {\n        debugLog(\n          `INFO: Process for server \"${serverName}\" exited, attempting to restart...`\n        );\n        await this._attemptReconnect(\n          serverName,\n          connection,\n          restart.maxAttempts,\n          restart.delayMs\n        );\n      }\n    };\n  }\n\n  private _getHttpErrorCode(error: unknown): number | undefined {\n    const streamableError = error as StreamableHTTPError | SseError;\n    let { code } = streamableError;\n    // try parsing from error message if code is not set\n    if (code == null) {\n      const m = streamableError.message.match(/\\(HTTP (\\d\\d\\d)\\)/);\n      if (m && m.length > 1) {\n        code = parseInt(m[1], 10);\n      }\n    }\n    return code;\n  }\n\n  private _createAuthenticationErrorMessage(\n    serverName: string,\n    url: string,\n    transport: \"HTTP\" | \"SSE\",\n    originalError: string\n  ): string {\n    return (\n      `Authentication failed for ${transport} server \"${serverName}\" at ${url}. ` +\n      `Please check your credentials, authorization headers, or OAuth configuration. ` +\n      `Original error: ${originalError}`\n    );\n  }\n\n  private _toSSEConnectionURL(url: string): string {\n    const urlObj = new URL(url);\n    const pathnameParts = urlObj.pathname.split(\"/\");\n    const lastPart = pathnameParts.at(-1);\n    if (lastPart && lastPart === \"mcp\") {\n      pathnameParts[pathnameParts.length - 1] = \"sse\";\n    }\n    urlObj.pathname = pathnameParts.join(\"/\");\n    return urlObj.toString();\n  }\n\n  /**\n   * Initialize a streamable HTTP connection\n   */\n  private async _initializeStreamableHTTPConnection(\n    serverName: string,\n    connection: ResolvedStreamableHTTPConnection\n  ): Promise<void> {\n    const { url, type: typeField, transport: transportField } = connection;\n    const automaticSSEFallback = connection.automaticSSEFallback ?? true;\n    const transportType = typeField || transportField;\n\n    debugLog(\n      `DEBUG: Creating Streamable HTTP transport for server \"${serverName}\" with URL: ${url}`\n    );\n\n    if (transportType === \"http\" || transportType == null) {\n      try {\n        const client = await this.#clientConnections.createClient(\n          \"http\",\n          serverName,\n          connection\n        );\n\n        await this._loadToolsForServer(serverName, client);\n      } catch (error) {\n        const code = this._getHttpErrorCode(error);\n        if (automaticSSEFallback && code != null && code >= 400 && code < 500) {\n          // Streamable HTTP error is a 4xx, so fall back to SSE\n          try {\n            await this._initializeSSEConnection(serverName, connection);\n          } catch (firstSSEError) {\n            // try one more time, but modify the URL to end with `/sse`\n            const sseUrl = this._toSSEConnectionURL(url);\n\n            if (sseUrl !== url) {\n              try {\n                await this._initializeSSEConnection(serverName, {\n                  ...connection,\n                  url: sseUrl,\n                });\n              } catch (secondSSEError) {\n                // Provide specific error message for authentication failures\n                if (code === 401) {\n                  throw new MCPClientError(\n                    this._createAuthenticationErrorMessage(\n                      serverName,\n                      url,\n                      \"HTTP\",\n                      `${error}. Also tried SSE fallback at ${url} and ${sseUrl}, but both failed with authentication errors.`\n                    ),\n                    serverName\n                  );\n                }\n                throw new MCPClientError(\n                  `Failed to connect to streamable HTTP server \"${serverName}, url: ${url}\": ${error}. Additionally, tried falling back to SSE at ${url} and ${sseUrl}, but this also failed: ${secondSSEError}`,\n                  serverName\n                );\n              }\n            } else {\n              // Provide specific error message for authentication failures\n              if (code === 401) {\n                throw new MCPClientError(\n                  this._createAuthenticationErrorMessage(\n                    serverName,\n                    url,\n                    \"HTTP\",\n                    `${error}. Also tried SSE fallback at ${url}, but it failed with authentication error: ${firstSSEError}`\n                  ),\n                  serverName\n                );\n              }\n              throw new MCPClientError(\n                `Failed to connect to streamable HTTP server after trying to fall back to SSE: \"${serverName}, url: ${url}\": ${error} (SSE fallback failed with error ${firstSSEError})`,\n                serverName\n              );\n            }\n          }\n        } else {\n          // Provide specific error message for authentication failures\n          if (code === 401) {\n            throw new MCPClientError(\n              this._createAuthenticationErrorMessage(\n                serverName,\n                url,\n                \"HTTP\",\n                `${error}`\n              ),\n              serverName\n            );\n          }\n          throw new MCPClientError(\n            `Failed to connect to streamable HTTP server \"${serverName}, url: ${url}\": ${error}`,\n            serverName\n          );\n        }\n      }\n    }\n  }\n\n  /**\n   * Initialize an SSE connection\n   *\n   * Don't call this directly unless SSE transport is explicitly requested. Otherwise,\n   * use _initializeStreamableHTTPConnection and it'll fall back to SSE if needed for\n   * backwards compatibility.\n   *\n   * @param serverName - The name of the server\n   * @param connection - The connection configuration\n   */\n  private async _initializeSSEConnection(\n    serverName: string,\n    connection: ResolvedStreamableHTTPConnection // used for both SSE and streamable HTTP\n  ): Promise<void> {\n    const { url, headers, reconnect, authProvider } = connection;\n\n    try {\n      const client = await this.#clientConnections.createClient(\n        \"sse\",\n        serverName,\n        connection\n      );\n      const transport = this.#clientConnections.getTransport({\n        serverName,\n        headers,\n        authProvider,\n      }) as SSEClientTransport;\n\n      // Set up auto-reconnect if configured\n      if (reconnect?.enabled) {\n        this._setupSSEReconnect(serverName, transport, connection, reconnect);\n      }\n\n      // Load tools for this server\n      await this._loadToolsForServer(serverName, client);\n    } catch (error) {\n      // Check if this is already a wrapped error that should be re-thrown\n      if (error && (error as Error).name === \"MCPClientError\") {\n        throw error;\n      }\n\n      // Check if this is an authentication error that needs better messaging\n      const isAuthError = error && this._getHttpErrorCode(error) === 401;\n\n      if (isAuthError) {\n        throw new MCPClientError(\n          this._createAuthenticationErrorMessage(\n            serverName,\n            url,\n            \"SSE\",\n            `${error}`\n          ),\n          serverName\n        );\n      }\n\n      throw new MCPClientError(\n        `Failed to create SSE transport for server \"${serverName}, url: ${url}\": ${error}`,\n        serverName\n      );\n    }\n  }\n\n  /**\n   * Set up reconnect handling for SSE (Streamable HTTP reconnects are more complex and are handled internally by the SDK)\n   */\n  private _setupSSEReconnect(\n    serverName: string,\n    transport: SSEClientTransport | StreamableHTTPClientTransport,\n    connection: ResolvedStreamableHTTPConnection,\n    reconnect: NonNullable<ResolvedStreamableHTTPConnection[\"reconnect\"]>\n  ): void {\n    const originalOnClose = transport.onclose;\n    // oxlint-disable-next-line @typescript-eslint/no-misused-promises\n    transport.onclose = async () => {\n      if (originalOnClose) {\n        await originalOnClose();\n      }\n\n      // Only attempt reconnect if we haven't cleaned up\n      if (\n        this.#clientConnections.get({\n          serverName,\n          headers: connection.headers,\n          authProvider: connection.authProvider,\n        })\n      ) {\n        debugLog(\n          `INFO: HTTP connection for server \"${serverName}\" closed, attempting to reconnect...`\n        );\n        await this._attemptReconnect(\n          serverName,\n          connection,\n          reconnect.maxAttempts,\n          reconnect.delayMs\n        );\n      }\n    };\n  }\n\n  /**\n   * Load tools for a specific server\n   */\n  private async _loadToolsForServer(\n    serverName: string,\n    client: Client\n  ): Promise<void> {\n    try {\n      debugLog(`DEBUG: Loading tools for server \"${serverName}\"...`);\n      const tools = await loadMcpTools(\n        serverName,\n        client,\n        this.#loadToolsOptions[serverName]\n      );\n      this.#serverNameToTools[serverName] = tools;\n      debugLog(\n        `INFO: Successfully loaded ${tools.length} tools from server \"${serverName}\"`\n      );\n    } catch (error) {\n      throw new MCPClientError(\n        `Failed to load tools from server \"${serverName}\": ${error}`\n      );\n    }\n  }\n\n  /**\n   * Attempt to reconnect to a server after a connection failure.\n   *\n   * @param serverName - The name of the server to reconnect to\n   * @param connection - The connection configuration\n   * @param maxAttempts - Maximum number of reconnection attempts\n   * @param delayMs - Delay in milliseconds between reconnection attempts\n   * @private\n   */\n  private async _attemptReconnect(\n    serverName: string,\n    connection: ResolvedConnection,\n    maxAttempts = 3,\n    delayMs = 1000\n  ): Promise<void> {\n    let connected = false;\n    let attempts = 0;\n\n    // Clean up previous connection resources\n    if (\"headers\" in connection || \"authProvider\" in connection) {\n      const { headers, authProvider } = connection;\n      await this.#cleanupServerResources({ serverName, authProvider, headers });\n    } else {\n      await this.#cleanupServerResources({ serverName });\n    }\n\n    while (\n      !connected &&\n      (maxAttempts === undefined || attempts < maxAttempts)\n    ) {\n      attempts += 1;\n      debugLog(\n        `INFO: Reconnection attempt ${attempts}${\n          maxAttempts ? `/${maxAttempts}` : \"\"\n        } for server \"${serverName}\"`\n      );\n\n      try {\n        // Wait before attempting to reconnect\n        if (delayMs) {\n          await new Promise((resolve) => {\n            setTimeout(resolve, delayMs);\n          });\n        }\n\n        // Initialize just this connection based on its type\n        if (isResolvedStdioConnection(connection)) {\n          await this._initializeStdioConnection(serverName, connection);\n        } else if (isResolvedStreamableHTTPConnection(connection)) {\n          if (connection.type === \"sse\" || connection.transport === \"sse\") {\n            await this._initializeSSEConnection(serverName, connection);\n          } else {\n            await this._initializeStreamableHTTPConnection(\n              serverName,\n              connection\n            );\n          }\n        }\n\n        // Check if connected\n        const key =\n          \"headers\" in connection\n            ? {\n                serverName,\n                headers: connection.headers,\n                authProvider: connection.authProvider,\n              }\n            : { serverName };\n        if (this.#clientConnections.has(key)) {\n          connected = true;\n          debugLog(`INFO: Successfully reconnected to server \"${serverName}\"`);\n        }\n      } catch (error) {\n        debugLog(\n          `ERROR: Failed to reconnect to server \"${serverName}\" (attempt ${attempts}): ${error}`\n        );\n      }\n    }\n\n    if (!connected) {\n      debugLog(\n        `ERROR: Failed to reconnect to server \"${serverName}\" after ${attempts} attempts`\n      );\n    }\n  }\n\n  /**\n   * Clean up resources for a specific server\n   */\n  async #cleanupServerResources(transportOptions: {\n    serverName: string;\n    authProvider?: OAuthClientProvider;\n    headers?: Record<string, string>;\n  }): Promise<void> {\n    const { serverName, authProvider, headers } = transportOptions;\n    delete this.#serverNameToTools[serverName];\n    await this.#clientConnections.delete({ serverName, authProvider, headers });\n  }\n\n  /**\n   * Get all tools from all servers as a flat array.\n   *\n   * @returns A flattened array of all tools\n   */\n  private _getAllToolsAsFlatArray(): DynamicStructuredTool[] {\n    const allTools: DynamicStructuredTool[] = [];\n    for (const tools of Object.values(this.#serverNameToTools)) {\n      allTools.push(...tools);\n    }\n    return allTools;\n  }\n\n  /**\n   * Get tools from specific servers as a flat array.\n   *\n   * @param serverNames - Names of servers to get tools from\n   * @returns A flattened array of tools from the specified servers\n   */\n  private _getToolsFromServers(serverNames: string[]): DynamicStructuredTool[] {\n    const allTools: DynamicStructuredTool[] = [];\n    for (const serverName of serverNames) {\n      const tools = this.#serverNameToTools[serverName];\n      if (tools) {\n        allTools.push(...tools);\n      }\n    }\n    return allTools;\n  }\n}\n"],"mappings":"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"}