@h1deya/langchain-mcp-tools
Version:
MCP To LangChain Tools Conversion Utility
195 lines (194 loc) • 7.26 kB
TypeScript
import { IOType } from "node:child_process";
import { Stream } from "node:stream";
import { StructuredTool } from "@langchain/core/tools";
import { StreamableHTTPReconnectionOptions } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { OAuthClientProvider } from "@modelcontextprotocol/sdk/client/auth.js";
/**
* Configuration for a command-line based MCP server.
* This is used for local MCP servers that are spawned as child processes.
*
* @remarks
* The `transport` and `type` fields are optional for command-based configs.
* They can be useful for explicitly specifying "stdio" transport or for
* compatibility with VSCode-style configurations.
*
* @public
*/
export interface CommandBasedConfig {
url?: never;
transport?: string;
type?: string;
headers?: never;
command: string;
args?: string[];
env?: Record<string, string>;
stderr?: IOType | Stream | number;
cwd?: string;
}
/**
* Configuration for a URL-based MCP server.
* This is used for remote MCP servers that are accessed via HTTP/HTTPS (SSE) or WebSocket.
*
* @remarks
* The `headers` field provides a simple way to add authorization headers.
* However, it will be overridden if transport-specific options (streamableHTTPOptions or sseOptions)
* specify their own headers in requestInit.
*
* @public
*/
export interface UrlBasedConfig {
url: string;
transport?: string;
type?: string;
headers?: Record<string, string>;
command?: never;
args?: never;
env?: never;
stderr?: never;
cwd?: never;
streamableHTTPOptions?: {
authProvider?: OAuthClientProvider;
requestInit?: RequestInit;
reconnectionOptions?: StreamableHTTPReconnectionOptions;
sessionId?: string;
};
sseOptions?: {
authProvider?: OAuthClientProvider;
eventSourceInit?: EventSourceInit;
requestInit?: RequestInit;
};
}
/**
* Configuration for an MCP server.
* Can be either a command-line based server or a URL-based server.
*
* @public
*/
export type SingleMcpServerConfig = CommandBasedConfig | UrlBasedConfig;
/**
* A registry mapping server names to their respective configurations.
* This is used as the main parameter to convertMcpToLangchainTools().
*
* @example
* const serverRegistry: McpServersConfig = {
* "filesystem": { command: "npx", args: ["@modelcontextprotocol/server-filesystem", "."] },
* "fetch": { command: "uvx", args: ["mcp-server-fetch"] }
* };
*
* @public
*/
export interface McpServersConfig {
[key: string]: SingleMcpServerConfig;
}
/**
* Logger interface for MCP tools operations.
* Provides structured logging capabilities for debugging and monitoring
* MCP server connections and tool executions.
*
* @public
*/
export interface McpToolsLogger {
debug(...args: unknown[]): void;
info(...args: unknown[]): void;
warn(...args: unknown[]): void;
error(...args: unknown[]): void;
}
/**
* Options for configuring logging behavior.
* Controls the verbosity level of logging output during MCP operations.
*
* @public
*/
export interface LogOptions {
/** Log verbosity level. Higher levels include all lower levels (e.g., "debug" includes "info", "warn", "error", "fatal") */
logLevel?: "fatal" | "error" | "warn" | "info" | "debug" | "trace";
}
/**
* Supported LLM providers for schema transformations.
* Each provider has specific JSON schema requirements that may conflict with MCP tool schemas.
*
* @public
*/
export type LlmProvider = "openai" | "google_gemini" | "google_genai" | "anthropic" | "xai" | "none";
/**
* Configuration options for converting MCP servers to LangChain tools.
* Extends LogOptions to include provider-specific schema transformations and custom logging.
*
* @public
*/
export interface ConvertMcpToLangchainOptions extends LogOptions {
/** Custom logger implementation. If not provided, uses default Logger with specified logLevel */
logger?: McpToolsLogger;
/** LLM provider for schema compatibility transformations. Performs provider-specific JSON schema modifications to prevent compatibility issues */
llmProvider?: LlmProvider;
}
/**
* Cleanup function returned by convertMcpToLangchainTools.
* Properly terminates all MCP server connections and cleans up resources.
*
* @public
*/
export interface McpServerCleanupFn {
(): Promise<void>;
}
/**
* Error interface for MCP-related errors.
* Extends the standard Error interface with MCP-specific properties.
*
* @public
*/
export interface McpError extends Error {
serverName: string;
details?: unknown;
}
/**
* Error thrown when an MCP server initialization fails.
* Contains details about the server that failed to initialize.
*
* @public
*/
export declare class McpInitializationError extends Error implements McpError {
serverName: string;
details?: unknown | undefined;
constructor(serverName: string, message: string, details?: unknown | undefined);
}
/**
* Initializes multiple MCP (Model Context Protocol) servers and converts them into LangChain tools.
* This function concurrently sets up all specified servers and aggregates their tools.
*
* @param configs - A mapping of server names to their respective configurations
* @param options - Optional configuration settings
* @param options.logLevel - Log verbosity level ("fatal" | "error" | "warn" | "info" | "debug" | "trace")
* @param options.logger - Custom logger implementation that follows the McpToolsLogger interface.
* If provided, overrides the default Logger instance.
* @param options.llmProvider - LLM provider for schema compatibility transformations.
* Performs provider-specific JSON schema modifications to prevent compatibility issues.
* Set to "openai" for OpenAI models, "google_gemini"/"google_genai" for Google models,
* "anthropic" for Claude models, or "none" for no transformation.
*
* @returns A promise that resolves to:
* - tools: Array of StructuredTool instances ready for use with LangChain
* - cleanup: Function to properly terminate all server connections
*
* @throws McpInitializationError if any server fails to initialize
* (includes connection errors, tool listing failures, configuration validation errors)
*
* @remarks
* - Servers are initialized concurrently for better performance
* - Configuration is validated and will throw errors for conflicts (e.g., both url and command specified)
* - Schema transformations are applied based on llmProvider to ensure compatibility
* - The cleanup function continues with remaining servers even if some cleanup operations fail
*
* @example
* const { tools, cleanup } = await convertMcpToLangchainTools({
* filesystem: { command: "npx", args: ["-y", "@modelcontextprotocol/server-filesystem", "."] },
* fetch: { command: "uvx", args: ["mcp-server-fetch"] }
* }, {
* llmProvider: "openai",
* logLevel: "debug"
* });
*/
export declare function convertMcpToLangchainTools(configs: McpServersConfig, options?: ConvertMcpToLangchainOptions): Promise<{
tools: StructuredTool[];
cleanup: McpServerCleanupFn;
}>;