UNPKG

@langchain/mcp-adapters

Version:
627 lines (626 loc) 21.4 kB
/// <reference types="node" resolution-mode="require"/> import { Client } from "@modelcontextprotocol/sdk/client/index.js"; import type { StructuredToolInterface } from "@langchain/core/tools"; import { z } from "zod"; import Stream from "node:stream"; /** * Create schema for stdio transport restart configuration */ export declare function createStdioRestartSchema(): z.ZodObject<{ /** * Whether to automatically restart the process if it exits */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of restart attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between restart attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>; /** * Create schema for stdio transport connection */ export declare function createStdioConnectionSchema(): z.ZodObject<{ transport: z.ZodOptional<z.ZodLiteral<"stdio">>; type: z.ZodOptional<z.ZodLiteral<"stdio">>; command: z.ZodString; args: z.ZodArray<z.ZodString, "many">; env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; encoding: z.ZodOptional<z.ZodString>; stderr: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"overlapped">, z.ZodLiteral<"pipe">, z.ZodLiteral<"ignore">, z.ZodLiteral<"inherit">, z.ZodType<Stream, z.ZodTypeDef, Stream>]>>; cwd: z.ZodOptional<z.ZodString>; /** * Additional restart settings */ restart: z.ZodOptional<z.ZodObject<{ /** * Whether to automatically restart the process if it exits */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of restart attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between restart attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>>; }, "strip", z.ZodTypeAny, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }>; /** * Create schema for SSE transport reconnection configuration */ export declare function createSseReconnectSchema(): z.ZodObject<{ /** * Whether to automatically reconnect if the connection is lost */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of reconnection attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between reconnection attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>; /** * Create schema for SSE transport connection */ export declare function createSseConnectionSchema(): z.ZodIntersection<z.ZodObject<{ url: z.ZodString; headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; useNodeEventSource: z.ZodOptional<z.ZodBoolean>; /** * Additional reconnection settings */ reconnect: z.ZodOptional<z.ZodObject<{ /** * Whether to automatically reconnect if the connection is lost */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of reconnection attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between reconnection attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>>; }, "strip", z.ZodTypeAny, { url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }, { url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }>, z.ZodUnion<[z.ZodObject<{ transport: z.ZodLiteral<"sse">; }, "strip", z.ZodTypeAny, { transport: "sse"; }, { transport: "sse"; }>, z.ZodObject<{ type: z.ZodLiteral<"sse">; }, "strip", z.ZodTypeAny, { type: "sse"; }, { type: "sse"; }>]>>; /** * Create combined schema for all transport connection types */ export declare function createConnectionSchema(): z.ZodUnion<[z.ZodObject<{ transport: z.ZodOptional<z.ZodLiteral<"stdio">>; type: z.ZodOptional<z.ZodLiteral<"stdio">>; command: z.ZodString; args: z.ZodArray<z.ZodString, "many">; env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; encoding: z.ZodOptional<z.ZodString>; stderr: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"overlapped">, z.ZodLiteral<"pipe">, z.ZodLiteral<"ignore">, z.ZodLiteral<"inherit">, z.ZodType<Stream, z.ZodTypeDef, Stream>]>>; cwd: z.ZodOptional<z.ZodString>; /** * Additional restart settings */ restart: z.ZodOptional<z.ZodObject<{ /** * Whether to automatically restart the process if it exits */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of restart attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between restart attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>>; }, "strip", z.ZodTypeAny, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }>, z.ZodIntersection<z.ZodObject<{ url: z.ZodString; headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; useNodeEventSource: z.ZodOptional<z.ZodBoolean>; /** * Additional reconnection settings */ reconnect: z.ZodOptional<z.ZodObject<{ /** * Whether to automatically reconnect if the connection is lost */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of reconnection attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between reconnection attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>>; }, "strip", z.ZodTypeAny, { url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }, { url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }>, z.ZodUnion<[z.ZodObject<{ transport: z.ZodLiteral<"sse">; }, "strip", z.ZodTypeAny, { transport: "sse"; }, { transport: "sse"; }>, z.ZodObject<{ type: z.ZodLiteral<"sse">; }, "strip", z.ZodTypeAny, { type: "sse"; }, { type: "sse"; }>]>>]>; /** * Create schema for {@link MultiServerMCPClient} configuration */ export declare function createClientConfigSchema(): z.ZodObject<{ mcpServers: z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodObject<{ transport: z.ZodOptional<z.ZodLiteral<"stdio">>; type: z.ZodOptional<z.ZodLiteral<"stdio">>; command: z.ZodString; args: z.ZodArray<z.ZodString, "many">; env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; encoding: z.ZodOptional<z.ZodString>; stderr: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"overlapped">, z.ZodLiteral<"pipe">, z.ZodLiteral<"ignore">, z.ZodLiteral<"inherit">, z.ZodType<Stream, z.ZodTypeDef, Stream>]>>; cwd: z.ZodOptional<z.ZodString>; /** * Additional restart settings */ restart: z.ZodOptional<z.ZodObject<{ /** * Whether to automatically restart the process if it exits */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of restart attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between restart attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>>; }, "strip", z.ZodTypeAny, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }>, z.ZodIntersection<z.ZodObject<{ url: z.ZodString; headers: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; useNodeEventSource: z.ZodOptional<z.ZodBoolean>; /** * Additional reconnection settings */ reconnect: z.ZodOptional<z.ZodObject<{ /** * Whether to automatically reconnect if the connection is lost */ enabled: z.ZodOptional<z.ZodBoolean>; /** * Maximum number of reconnection attempts */ maxAttempts: z.ZodOptional<z.ZodNumber>; /** * Delay in milliseconds between reconnection attempts */ delayMs: z.ZodOptional<z.ZodNumber>; }, "strip", z.ZodTypeAny, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }, { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; }>>; }, "strip", z.ZodTypeAny, { url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }, { url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; }>, z.ZodUnion<[z.ZodObject<{ transport: z.ZodLiteral<"sse">; }, "strip", z.ZodTypeAny, { transport: "sse"; }, { transport: "sse"; }>, z.ZodObject<{ type: z.ZodLiteral<"sse">; }, "strip", z.ZodTypeAny, { type: "sse"; }, { type: "sse"; }>]>>]>>; throwOnLoadError: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>; prefixToolNameWithServerName: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>; additionalToolNamePrefix: z.ZodDefault<z.ZodOptional<z.ZodString>>; }, "strip", z.ZodTypeAny, { throwOnLoadError: boolean; prefixToolNameWithServerName: boolean; additionalToolNamePrefix: string; mcpServers: Record<string, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; } | ({ url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; } & ({ transport: "sse"; } | { type: "sse"; }))>; }, { mcpServers: Record<string, { command: string; args: string[]; type?: "stdio" | undefined; transport?: "stdio" | undefined; env?: Record<string, string> | undefined; encoding?: string | undefined; stderr?: Stream | "overlapped" | "pipe" | "ignore" | "inherit" | undefined; cwd?: string | undefined; restart?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; } | ({ url: string; headers?: Record<string, string> | undefined; useNodeEventSource?: boolean | undefined; reconnect?: { enabled?: boolean | undefined; maxAttempts?: number | undefined; delayMs?: number | undefined; } | undefined; } & ({ transport: "sse"; } | { type: "sse"; }))>; throwOnLoadError?: boolean | undefined; prefixToolNameWithServerName?: boolean | undefined; additionalToolNamePrefix?: string | undefined; }>; /** * Configuration for stdio transport connection */ export type StdioConnection = z.infer<ReturnType<typeof createStdioConnectionSchema>>; /** * Configuration for SSE transport connection */ export type SSEConnection = z.infer<ReturnType<typeof createSseConnectionSchema>>; /** * Union type for all transport connection types */ export type Connection = z.infer<ReturnType<typeof createConnectionSchema>>; /** * Type for {@link MultiServerMCPClient} configuration */ export type ClientConfig = z.infer<ReturnType<typeof createClientConfigSchema>>; /** * Error class for MCP client operations */ export declare class MCPClientError extends Error { readonly serverName?: string | undefined; constructor(message: string, serverName?: string | undefined); } /** * Client for connecting to multiple MCP servers and loading LangChain-compatible tools. */ export declare class MultiServerMCPClient { private _clients; private _serverNameToTools; private _connections?; private _loadToolsOptions; private _cleanupFunctions; private _transportInstances; /** * Create a new MultiServerMCPClient. * * @param connections - Optional connections to initialize */ constructor(config: ClientConfig | Record<string, Connection>); /** * Proactively initialize connections to all servers. This will be called automatically when * methods requiring an active connection (like {@link getTools} or {@link getClient}) are called, * but you can call it directly to ensure all connections are established before using the tools. * * @returns A map of server names to arrays of tools * @throws {MCPClientError} If initialization fails */ initializeConnections(): Promise<Record<string, StructuredToolInterface[]>>; /** * Get tools from specified servers as a flattened array. * * @param servers - Optional array of server names to filter tools by. * If not provided, returns tools from all servers. * @returns A flattened array of tools from the specified servers (or all servers) */ getTools(...servers: string[]): Promise<StructuredToolInterface[]>; /** * Get a the MCP client for a specific server. Useful for fetching prompts or resources from that server. * * @param serverName - The name of the server * @returns The client for the server, or undefined if the server is not connected */ getClient(serverName: string): Promise<Client | undefined>; /** * Close all connections. */ close(): Promise<void>; /** * Initialize a stdio connection */ private _initializeStdioConnection; /** * Set up stdio restart handling */ private _setupStdioRestart; /** * Initialize an SSE connection */ private _initializeSSEConnection; /** * Create an SSE transport with appropriate EventSource implementation */ private _createSSETransport; /** * Create an EventSource transport for Node.js environments */ private _createNodeEventSourceTransport; /** * Set up SSE reconnect handling */ private _setupSSEReconnect; /** * Load tools for a specific server */ private _loadToolsForServer; /** * Attempt to reconnect to a server after a connection failure. * * @param serverName - The name of the server to reconnect to * @param connection - The connection configuration * @param maxAttempts - Maximum number of reconnection attempts * @param delayMs - Delay in milliseconds between reconnection attempts * @private */ private _attemptReconnect; /** * Clean up resources for a specific server */ private _cleanupServerResources; /** * Get all tools from all servers as a flat array. * * @returns A flattened array of all tools */ private _getAllToolsAsFlatArray; /** * Get tools from specific servers as a flat array. * * @param serverNames - Names of servers to get tools from * @returns A flattened array of tools from the specified servers */ private _getToolsFromServers; }