@@ -23,6 +23,7 @@ This library provides a lightweight wrapper that makes [Anthropic Model Context
2323
2424 - Compatible with LangChain.js and LangGraph.js
2525 - Optimized for OpenAI, Anthropic, and Google models
26+ - Supports rich content responses including text, images, and embedded resources
2627
2728- 🛠️ ** Development Features**
2829 - Uses ` debug ` package for debug logging
8788 // Connect to the transport
8889 await client .connect (transport );
8990
90- // Get tools
91- const tools = await loadMcpTools (" math" , client );
91+ // Get tools with custom configuration
92+ const tools = await loadMcpTools (" math" , client , {
93+ // Whether to throw errors if a tool fails to load (optional, default: true)
94+ throwOnLoadError: true ,
95+ // Whether to prefix tool names with the server name (optional, default: false)
96+ prefixToolNameWithServerName: false ,
97+ // Optional additional prefix for tool names (optional, default: "")
98+ additionalToolNamePrefix: " " ,
99+ });
92100
93101 // Create and run the agent
94102 const agent = createReactAgent ({ llm: model , tools });
@@ -117,19 +125,50 @@ import { createReactAgent } from "@langchain/langgraph/prebuilt";
117125
118126// Create client and connect to server
119127const client = new MultiServerMCPClient ({
120- // adds a STDIO connection to a server named "math"
121- math: {
122- transport: " stdio" ,
123- command: " npx" ,
124- args: [" -y" , " @modelcontextprotocol/server-math" ],
125- },
126-
127- // add additional servers by adding more keys to the config
128- // here's a filesystem server
129- filesystem: {
130- transport: " stdio" ,
131- command: " npx" ,
132- args: [" -y" , " @modelcontextprotocol/server-filesystem" ],
128+ // Global tool configuration options
129+ // Whether to throw on errors if a tool fails to load (optional, default: true)
130+ throwOnLoadError: true ,
131+ // Whether to prefix tool names with the server name (optional, default: true)
132+ prefixToolNameWithServerName: true ,
133+ // Optional additional prefix for tool names (optional, default: "mcp")
134+ additionalToolNamePrefix: " mcp" ,
135+
136+ // Server configuration
137+ mcpServers: {
138+ // adds a STDIO connection to a server named "math"
139+ math: {
140+ transport: " stdio" ,
141+ command: " npx" ,
142+ args: [" -y" , " @modelcontextprotocol/server-math" ],
143+ // Restart configuration for stdio transport
144+ restart: {
145+ enabled: true ,
146+ maxAttempts: 3 ,
147+ delayMs: 1000 ,
148+ },
149+ },
150+
151+ // here's a filesystem server
152+ filesystem: {
153+ transport: " stdio" ,
154+ command: " npx" ,
155+ args: [" -y" , " @modelcontextprotocol/server-filesystem" ],
156+ },
157+
158+ // SSE transport example with reconnection configuration
159+ weather: {
160+ transport: " sse" ,
161+ url: " https://example.com/mcp-weather" ,
162+ headers: {
163+ Authorization: " Bearer token123" ,
164+ },
165+ useNodeEventSource: true ,
166+ reconnect: {
167+ enabled: true ,
168+ maxAttempts: 5 ,
169+ delayMs: 2000 ,
170+ },
171+ },
133172 },
134173});
135174
@@ -148,18 +187,176 @@ const agent = createReactAgent({
148187});
149188
150189// Run the agent
151- const mathResponse = await agent .invoke ({
152- messages: [{ role: " user" , content: " what's (3 + 5) x 12?" }],
153- });
154- const weatherResponse = await agent .invoke ({
155- messages: [{ role: " user" , content: " what is the weather in nyc?" }],
156- });
190+ try {
191+ const mathResponse = await agent .invoke ({
192+ messages: [{ role: " user" , content: " what's (3 + 5) x 12?" }],
193+ });
194+ console .log (mathResponse );
195+ } catch (error ) {
196+ console .error (" Error during agent execution:" , error );
197+ // Tools throw ToolException for tool-specific errors
198+ if (error .name === " ToolException" ) {
199+ console .error (" Tool execution failed:" , error .message );
200+ }
201+ }
157202
158203await client .close ();
159204```
160205
161206For more detailed examples, see the [ examples] ( ./examples ) directory.
162207
208+ ## Tool Configuration Options
209+
210+ When loading MCP tools either directly through ` loadMcpTools ` or via ` MultiServerMCPClient ` , you can configure the following options:
211+
212+ | Option | Type | Default | Description |
213+ | ------------------------------ | ------- | ------- | ------------------------------------------------------------------------------------ |
214+ | ` throwOnLoadError ` | boolean | ` true ` | Whether to throw an error if a tool fails to load |
215+ | ` prefixToolNameWithServerName ` | boolean | ` false ` | If true, prefixes all tool names with the server name (e.g., ` serverName__toolName ` ) |
216+ | ` additionalToolNamePrefix ` | string | ` "" ` | Additional prefix to add to tool names (e.g., ` prefix__serverName__toolName ` ) |
217+
218+ ## Response Handling
219+
220+ MCP tools return results in the ` content_and_artifact ` format which can include:
221+
222+ - ** Text content** : Plain text responses
223+ - ** Image content** : Base64-encoded images with MIME type
224+ - ** Embedded resources** : Files, structured data, or other resources
225+
226+ Example for handling different content types:
227+
228+ ``` ts
229+ const tool = tools .find ((t ) => t .name === " mcp__math__calculate" );
230+ const result = await tool .invoke ({ expression: " (3 + 5) * 12" });
231+
232+ // Result format: [content, artifacts]
233+ // - content: string | MessageContentComplex[]
234+ // - artifacts: EmbeddedResource[]
235+
236+ const [textContent, artifacts] = result ;
237+
238+ // Handle text content
239+ if (typeof textContent === " string" ) {
240+ console .log (" Result:" , textContent );
241+ } else {
242+ // Handle complex content (text + images)
243+ textContent .forEach ((item ) => {
244+ if (item .type === " text" ) {
245+ console .log (" Text:" , item .text );
246+ } else if (item .type === " image_url" ) {
247+ console .log (" Image URL:" , item .image_url .url );
248+ }
249+ });
250+ }
251+
252+ // Handle artifacts if needed
253+ if (artifacts .length > 0 ) {
254+ console .log (" Received artifacts:" , artifacts );
255+ }
256+ ```
257+
258+ ## Reconnection Strategies
259+
260+ Both transport types support automatic reconnection:
261+
262+ ### Stdio Transport Restart
263+
264+ ``` ts
265+ {
266+ transport : " stdio" ,
267+ command : " npx" ,
268+ args : [" -y" , " @modelcontextprotocol/server-math" ],
269+ restart : {
270+ enabled : true , // Enable automatic restart
271+ maxAttempts : 3 , // Maximum restart attempts
272+ delayMs : 1000 // Delay between attempts in ms
273+ }
274+ }
275+ ```
276+
277+ ### SSE Transport Reconnect
278+
279+ ``` ts
280+ {
281+ transport : " sse" ,
282+ url : " https://example.com/mcp-server" ,
283+ headers : { " Authorization" : " Bearer token123" },
284+ useNodeEventSource : true ,
285+ reconnect : {
286+ enabled : true , // Enable automatic reconnection
287+ maxAttempts : 5 , // Maximum reconnection attempts
288+ delayMs : 2000 // Delay between attempts in ms
289+ }
290+ }
291+ ```
292+
293+ ## Error Handling
294+
295+ The library provides different error types to help with debugging:
296+
297+ - ** MCPClientError** : For client connection and initialization issues
298+ - ** ToolException** : For errors during tool execution
299+ - ** ZodError** : For configuration validation errors (invalid connection settings, etc.)
300+
301+ Example error handling:
302+
303+ ``` ts
304+ try {
305+ const client = new MultiServerMCPClient ({
306+ math: {
307+ transport: " stdio" ,
308+ command: " npx" ,
309+ args: [" -y" , " @modelcontextprotocol/server-math" ],
310+ },
311+ });
312+
313+ const tools = await client .getTools ();
314+ const result = await tools [0 ].invoke ({ expression: " 1 + 2" });
315+ } catch (error ) {
316+ if (error .name === " MCPClientError" ) {
317+ // Handle connection issues
318+ console .error (` Connection error (${error .serverName }): ` , error .message );
319+ } else if (error .name === " ToolException" ) {
320+ // Handle tool execution errors
321+ console .error (" Tool execution failed:" , error .message );
322+ } else if (error .name === " ZodError" ) {
323+ // Handle configuration validation errors
324+ console .error (" Configuration error:" , error .issues );
325+ // Zod errors contain detailed information about what went wrong
326+ error .issues .forEach ((issue ) => {
327+ console .error (` - Path: ${issue .path .join (" ." )}, Error: ${issue .message } ` );
328+ });
329+ } else {
330+ // Handle other errors
331+ console .error (" Unexpected error:" , error );
332+ }
333+ }
334+ ```
335+
336+ ### Common Zod Validation Errors
337+
338+ The library uses Zod for validating configuration. Here are some common validation errors:
339+
340+ - ** Missing required parameters** : For example, omitting ` command ` for stdio transport or ` url ` for SSE transport
341+ - ** Invalid parameter types** : For example, providing a number where a string is expected
342+ - ** Invalid connection configuration** : For example, using an invalid URL format for SSE transport
343+
344+ Example Zod error for an invalid SSE URL:
345+
346+ ``` json
347+ {
348+ "issues" : [
349+ {
350+ "code" : " invalid_string" ,
351+ "validation" : " url" ,
352+ "path" : [" mcpServers" , " weather" , " url" ],
353+ "message" : " Invalid url"
354+ }
355+ ],
356+ "name" : " ZodError"
357+ }
358+ ```
359+
163360## Browser Environments
164361
165362When using in browsers:
0 commit comments