@h1deya/langchain-mcp-tools 0.1.4 → 0.1.6
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.
- package/README.md +8 -8
- package/dist/langchain-mcp-tools.d.ts +21 -2
- package/dist/langchain-mcp-tools.js +52 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -4,10 +4,10 @@ This package is intended to simplify the use of
|
|
|
4
4
|
[Model Context Protocol (MCP)](https://modelcontextprotocol.io/)
|
|
5
5
|
server tools with LangChain.
|
|
6
6
|
|
|
7
|
-
It contains a utility function `convertMcpToLangchainTools()
|
|
8
|
-
|
|
9
|
-
and
|
|
10
|
-
|
|
7
|
+
It contains a utility function `convertMcpToLangchainTools()`.
|
|
8
|
+
This function handles parallel initialization of specified multiple MCP servers
|
|
9
|
+
and converts their available tools into a list of
|
|
10
|
+
[LangChain-compatible tools](https://js.langchain.com/docs/how_to/tool_calling/).
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
@@ -17,8 +17,8 @@ npm i @h1deya/langchain-mcp-tools
|
|
|
17
17
|
|
|
18
18
|
## Quick Start
|
|
19
19
|
|
|
20
|
-
`convertMcpToLangchainTools()` utility function accepts MCP server
|
|
21
|
-
that
|
|
20
|
+
`convertMcpToLangchainTools()` utility function accepts MCP server configurations
|
|
21
|
+
that follow the same structure as
|
|
22
22
|
[Claude for Desktop](https://modelcontextprotocol.io/quickstart/user),
|
|
23
23
|
but only the contents of the `mcpServers` property,
|
|
24
24
|
and is expressed as a JS Object, e.g.:
|
|
@@ -46,10 +46,10 @@ const { tools, cleanup } = await convertMcpToLangchainTools(mcpServers);
|
|
|
46
46
|
|
|
47
47
|
The utility function initializes all specified MCP servers in parallel,
|
|
48
48
|
and returns LangChain Tools (`tools: DynamicStructuredTool[]`)
|
|
49
|
-
by gathering all
|
|
49
|
+
by gathering all available MCP server tools,
|
|
50
50
|
and by wrapping them into [LangChain Tools](https://js.langchain.com/docs/how_to/tool_calling/).
|
|
51
51
|
It also returns `cleanup` callback function
|
|
52
|
-
|
|
52
|
+
to be invoked to close all MCP server sessions when finished.
|
|
53
53
|
|
|
54
54
|
The returned tools can be used with LangChain, e.g.:
|
|
55
55
|
|
|
@@ -10,11 +10,30 @@ export interface McpServersConfig {
|
|
|
10
10
|
interface LogOptions {
|
|
11
11
|
logLevel?: 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
|
12
12
|
}
|
|
13
|
-
export interface
|
|
13
|
+
export interface McpServerCleanupFn {
|
|
14
14
|
(): Promise<void>;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Initializes multiple MCP (Model Context Protocol) servers and converts them into LangChain tools.
|
|
18
|
+
* This function concurrently sets up all specified servers and aggregates their tools.
|
|
19
|
+
*
|
|
20
|
+
* @param configs - A mapping of server names to their respective configurations
|
|
21
|
+
* @param options - Optional logging configuration
|
|
22
|
+
*
|
|
23
|
+
* @returns A promise that resolves to:
|
|
24
|
+
* - tools: Array of DynamicStructuredTool instances ready for use with LangChain
|
|
25
|
+
* - cleanup: Function to properly terminate all server connections
|
|
26
|
+
*
|
|
27
|
+
* @throws McpInitializationError if any server fails to initialize
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const { tools, cleanup } = await convertMcpToLangchainTools({
|
|
31
|
+
* filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', '.'] },
|
|
32
|
+
* fetch: { command: 'uvx', args: ['mcp-server-fetch'] }
|
|
33
|
+
* });
|
|
34
|
+
*/
|
|
16
35
|
export declare function convertMcpToLangchainTools(configs: McpServersConfig, options?: LogOptions): Promise<{
|
|
17
36
|
tools: DynamicStructuredTool[];
|
|
18
|
-
cleanup:
|
|
37
|
+
cleanup: McpServerCleanupFn;
|
|
19
38
|
}>;
|
|
20
39
|
export {};
|
|
@@ -5,17 +5,35 @@ import { DynamicStructuredTool } from '@langchain/core/tools';
|
|
|
5
5
|
import { jsonSchemaToZod } from '@n8n/json-schema-to-zod';
|
|
6
6
|
import { Logger } from './logger.js';
|
|
7
7
|
// Custom error type for MCP server initialization failures
|
|
8
|
-
class
|
|
8
|
+
class McpInitializationError extends Error {
|
|
9
9
|
serverName;
|
|
10
10
|
details;
|
|
11
11
|
constructor(serverName, message, details) {
|
|
12
12
|
super(message);
|
|
13
13
|
this.serverName = serverName;
|
|
14
14
|
this.details = details;
|
|
15
|
-
this.name = '
|
|
15
|
+
this.name = 'McpInitializationError';
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
|
-
|
|
18
|
+
/**
|
|
19
|
+
* Initializes multiple MCP (Model Context Protocol) servers and converts them into LangChain tools.
|
|
20
|
+
* This function concurrently sets up all specified servers and aggregates their tools.
|
|
21
|
+
*
|
|
22
|
+
* @param configs - A mapping of server names to their respective configurations
|
|
23
|
+
* @param options - Optional logging configuration
|
|
24
|
+
*
|
|
25
|
+
* @returns A promise that resolves to:
|
|
26
|
+
* - tools: Array of DynamicStructuredTool instances ready for use with LangChain
|
|
27
|
+
* - cleanup: Function to properly terminate all server connections
|
|
28
|
+
*
|
|
29
|
+
* @throws McpInitializationError if any server fails to initialize
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* const { tools, cleanup } = await convertMcpToLangchainTools({
|
|
33
|
+
* filesystem: { command: 'npx', args: ['-y', '@modelcontextprotocol/server-filesystem', '.'] },
|
|
34
|
+
* fetch: { command: 'uvx', args: ['mcp-server-fetch'] }
|
|
35
|
+
* });
|
|
36
|
+
*/
|
|
19
37
|
export async function convertMcpToLangchainTools(configs, options) {
|
|
20
38
|
const allTools = [];
|
|
21
39
|
const cleanupCallbacks = [];
|
|
@@ -53,7 +71,24 @@ export async function convertMcpToLangchainTools(configs, options) {
|
|
|
53
71
|
allTools.forEach((tool) => logger.debug(`- ${tool.name}`));
|
|
54
72
|
return { tools: allTools, cleanup };
|
|
55
73
|
}
|
|
56
|
-
|
|
74
|
+
/**
|
|
75
|
+
* Initializes a single MCP server and converts its capabilities into LangChain tools.
|
|
76
|
+
* Sets up a connection to the server, retrieves available tools, and creates corresponding
|
|
77
|
+
* LangChain tool instances.
|
|
78
|
+
*
|
|
79
|
+
* @param serverName - Unique identifier for the server instance
|
|
80
|
+
* @param config - Server configuration including command, arguments, and environment variables
|
|
81
|
+
* @param logger - Logger instance for recording operation details
|
|
82
|
+
*
|
|
83
|
+
* @returns A promise that resolves to:
|
|
84
|
+
* - tools: Array of DynamicStructuredTool instances from this server
|
|
85
|
+
* - cleanup: Function to properly terminate the server connection
|
|
86
|
+
*
|
|
87
|
+
* @throws McpInitializationError if server initialization fails
|
|
88
|
+
* (includes connection errors, tool listing failures)
|
|
89
|
+
*
|
|
90
|
+
* @internal This function is meant to be called by convertMcpToLangchainTools
|
|
91
|
+
*/
|
|
57
92
|
async function convertSingleMcpToLangchainTools(serverName, config, logger) {
|
|
58
93
|
let transport = null;
|
|
59
94
|
let client = null;
|
|
@@ -87,7 +122,7 @@ async function convertSingleMcpToLangchainTools(serverName, config, logger) {
|
|
|
87
122
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
88
123
|
schema: jsonSchemaToZod(tool.inputSchema),
|
|
89
124
|
func: async (input) => {
|
|
90
|
-
logger.info(`MCP
|
|
125
|
+
logger.info(`MCP tool "${serverName}"/"${tool.name}" received input:`, input);
|
|
91
126
|
// Execute tool call
|
|
92
127
|
const result = await client?.request({
|
|
93
128
|
method: "tools/call",
|
|
@@ -96,15 +131,16 @@ async function convertSingleMcpToLangchainTools(serverName, config, logger) {
|
|
|
96
131
|
arguments: input,
|
|
97
132
|
},
|
|
98
133
|
}, CallToolResultSchema);
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
logger.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
//
|
|
134
|
+
const resultStringfied = JSON.stringify(result?.content);
|
|
135
|
+
const roughLength = resultStringfied.length;
|
|
136
|
+
logger.info(`MCP tool "${serverName}"/"${tool.name}" received result (length: ${roughLength})`);
|
|
137
|
+
logger.debug('result:', result?.content);
|
|
138
|
+
return resultStringfied;
|
|
139
|
+
// const filteredResult = result?.content
|
|
140
|
+
// .filter(content => content.type === 'text')
|
|
141
|
+
// .map(content => content.text)
|
|
142
|
+
// .join('\n\n');
|
|
143
|
+
// return filteredResult;
|
|
108
144
|
},
|
|
109
145
|
})));
|
|
110
146
|
logger.info(`MCP server "${serverName}": ${tools.length} tool(s) available:`);
|
|
@@ -112,7 +148,7 @@ async function convertSingleMcpToLangchainTools(serverName, config, logger) {
|
|
|
112
148
|
async function cleanup() {
|
|
113
149
|
if (transport) {
|
|
114
150
|
await transport.close();
|
|
115
|
-
logger.info(`MCP server "${serverName}":
|
|
151
|
+
logger.info(`MCP server "${serverName}": session closed`);
|
|
116
152
|
}
|
|
117
153
|
}
|
|
118
154
|
return { tools, cleanup };
|
|
@@ -128,6 +164,6 @@ async function convertSingleMcpToLangchainTools(serverName, config, logger) {
|
|
|
128
164
|
logger.error(`Failed to cleanup during initialization error: ${cleanupError}`);
|
|
129
165
|
}
|
|
130
166
|
}
|
|
131
|
-
throw new
|
|
167
|
+
throw new McpInitializationError(serverName, `Failed to initialize MCP server: ${error instanceof Error ? error.message : String(error)}`, error);
|
|
132
168
|
}
|
|
133
169
|
}
|