@langchain/mcp-adapters
Version:
LangChain.js adapters for Model Context Protocol (MCP)
627 lines (626 loc) • 21.4 kB
TypeScript
/// <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;
}