An open API service indexing awesome lists of open source software.

https://github.com/langchain-ai/langchainjs-mcp-adapters

Adapters for integrating Model Context Protocol (MCP) tools with LangChain.js applications, supporting both stdio and SSE transports.
https://github.com/langchain-ai/langchainjs-mcp-adapters

agent-tools ai-tools javascript langchain langchainjs llm-agents llm-integration llm-tools mcp model-context-protocol openai-functions typescript

Last synced: 5 months ago
JSON representation

Adapters for integrating Model Context Protocol (MCP) tools with LangChain.js applications, supporting both stdio and SSE transports.

Awesome Lists containing this project

README

          

# LangChain.js MCP Adapters

[![npm version](https://img.shields.io/npm/v/@langchain/mcp-adapters.svg)](https://www.npmjs.com/package/@langchain/mcp-adapters)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

This library provides a lightweight wrapper that makes [Anthropic Model Context Protocol (MCP)](https://modelcontextprotocol.io/introduction) tools compatible with [LangChain.js](https://github.com/langchain-ai/langchainjs) and [LangGraph.js](https://github.com/langchain-ai/langgraphjs).

## Features

- 🔌 **Transport Options**

- Connect to MCP servers via stdio (local) or Streamable HTTP (remote)
- Streamable HTTP automatically falls back to SSE for compatibility with legacy MCP server implementations
- Support for custom headers in SSE connections for authentication
- Configurable reconnection strategies for both transport types

- 🔄 **Multi-Server Management**

- Connect to multiple MCP servers simultaneously
- Auto-organize tools by server or access them as a flattened collection
- Convenient configuration via JSON file

- 🧩 **Agent Integration**

- Compatible with LangChain.js and LangGraph.js
- Optimized for OpenAI, Anthropic, and Google models
- Supports rich content responses including text, images, and embedded resources

- 🛠️ **Development Features**
- Uses `debug` package for debug logging
- Flexible configuration options
- Robust error handling

## Installation

```bash
npm install @langchain/mcp-adapters
```

### Optional Dependencies

For SSE connections with custom headers in Node.js (does not apply to Streamable HTTP):

```bash
npm install eventsource
```

For enhanced SSE header support (does not apply to Streamable HTTP):

```bash
npm install extended-eventsource
```

# Example: Manage the MCP Client yourself

This example shows how you can manage your own MCP client and use it to get tools that you can pass to a LangGraph prebuilt ReAcT agent.

```bash
npm install @langchain/mcp-adapters @langchain/langgraph @langchain/core @langchain/openai

export OPENAI_API_KEY=
```

## Client

```ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";
import { loadMcpTools } from "@langchain/mcp-adapters";

// Initialize the ChatOpenAI model
const model = new ChatOpenAI({ modelName: "gpt-4" });

// Automatically starts and connects to a MCP reference server
const transport = new StdioClientTransport({
command: "npx",
args: ["-y", "@modelcontextprotocol/server-math"],
});

// Initialize the client
const client = new Client({
name: "math-client",
version: "1.0.0",
});

try {
// Connect to the transport
await client.connect(transport);

// Get tools with custom configuration
const tools = await loadMcpTools("math", client, {
// Whether to throw errors if a tool fails to load (optional, default: true)
throwOnLoadError: true,
// Whether to prefix tool names with the server name (optional, default: false)
prefixToolNameWithServerName: false,
// Optional additional prefix for tool names (optional, default: "")
additionalToolNamePrefix: "",
});

// Create and run the agent
const agent = createReactAgent({ llm: model, tools });
const agentResponse = await agent.invoke({
messages: [{ role: "user", content: "what's (3 + 5) x 12?" }],
});
console.log(agentResponse);
} catch (e) {
console.error(e);
} finally {
// Clean up connection
await client.close();
}
```

# Example: Connect to one or more servers via config

The library also allows you to connect to multiple MCP servers and load tools from them:

## Client

```ts
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { ChatOpenAI } from "@langchain/openai";
import { createReactAgent } from "@langchain/langgraph/prebuilt";

// Create client and connect to server
const client = new MultiServerMCPClient({
// Global tool configuration options
// Whether to throw on errors if a tool fails to load (optional, default: true)
throwOnLoadError: true,
// Whether to prefix tool names with the server name (optional, default: true)
prefixToolNameWithServerName: true,
// Optional additional prefix for tool names (optional, default: "mcp")
additionalToolNamePrefix: "mcp",

// Server configuration
mcpServers: {
// adds a STDIO connection to a server named "math"
math: {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-math"],
// Restart configuration for stdio transport
restart: {
enabled: true,
maxAttempts: 3,
delayMs: 1000,
},
},

// here's a filesystem server
filesystem: {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem"],
},

// Sreamable HTTP transport example, with auth headers and automatic SSE fallback disabled (defaults to enabled)
weather: {
url: "https://example.com/weather/mcp",
headers: {
Authorization: "Bearer token123",
}
automaticSSEFallback: false
},

// how to force SSE, for old servers that are known to only support SSE (streamable HTTP falls back automatically if unsure)
github: {
transport: "sse", // also works with "type" field instead of "transport"
url: "https://example.com/mcp",
reconnect: {
enabled: true,
maxAttempts: 5,
delayMs: 2000,
},
},
},
});

const tools = await client.getTools();

// Create an OpenAI model
const model = new ChatOpenAI({
modelName: "gpt-4o",
temperature: 0,
});

// Create the React agent
const agent = createReactAgent({
llm: model,
tools,
});

// Run the agent
try {
const mathResponse = await agent.invoke({
messages: [{ role: "user", content: "what's (3 + 5) x 12?" }],
});
console.log(mathResponse);
} catch (error) {
console.error("Error during agent execution:", error);
// Tools throw ToolException for tool-specific errors
if (error.name === "ToolException") {
console.error("Tool execution failed:", error.message);
}
}

await client.close();
```

For more detailed examples, see the [examples](./examples) directory.

## Tool Configuration Options

When loading MCP tools either directly through `loadMcpTools` or via `MultiServerMCPClient`, you can configure the following options:

| Option | Type | Default | Description |
| ------------------------------ | ------- | ------- | ------------------------------------------------------------------------------------ |
| `throwOnLoadError` | boolean | `true` | Whether to throw an error if a tool fails to load |
| `prefixToolNameWithServerName` | boolean | `true` | If true, prefixes all tool names with the server name (e.g., `serverName__toolName`) |
| `additionalToolNamePrefix` | string | `mcp` | Additional prefix to add to tool names (e.g., `prefix__serverName__toolName`) |

## Response Handling

MCP tools return results in the `content_and_artifact` format which can include:

- **Text content**: Plain text responses
- **Image content**: Base64-encoded images with MIME type
- **Embedded resources**: Files, structured data, or other resources

Example for handling different content types:

```ts
const tool = tools.find((t) => t.name === "mcp__math__calculate");
const result = await tool.invoke({ expression: "(3 + 5) * 12" });

// Result format: [content, artifacts]
// - content: string | MessageContentComplex[]
// - artifacts: EmbeddedResource[]

const [textContent, artifacts] = result;

// Handle text content
if (typeof textContent === "string") {
console.log("Result:", textContent);
} else {
// Handle complex content (text + images)
textContent.forEach((item) => {
if (item.type === "text") {
console.log("Text:", item.text);
} else if (item.type === "image_url") {
console.log("Image URL:", item.image_url.url);
}
});
}

// Handle artifacts if needed
if (artifacts.length > 0) {
console.log("Received artifacts:", artifacts);
}
```

## Reconnection Strategies

Both transport types support automatic reconnection:

### Stdio Transport Restart

```ts
{
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-math"],
restart: {
enabled: true, // Enable automatic restart
maxAttempts: 3, // Maximum restart attempts
delayMs: 1000 // Delay between attempts in ms
}
}
```

### SSE Transport Reconnect

```ts
{
transport: "sse",
url: "https://example.com/mcp-server",
headers: { "Authorization": "Bearer token123" },
useNodeEventSource: true,
reconnect: {
enabled: true, // Enable automatic reconnection
maxAttempts: 5, // Maximum reconnection attempts
delayMs: 2000 // Delay between attempts in ms
}
}
```

## Error Handling

The library provides different error types to help with debugging:

- **MCPClientError**: For client connection and initialization issues
- **ToolException**: For errors during tool execution
- **ZodError**: For configuration validation errors (invalid connection settings, etc.)

Example error handling:

```ts
try {
const client = new MultiServerMCPClient({
math: {
transport: "stdio",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-math"],
},
});

const tools = await client.getTools();
const result = await tools[0].invoke({ expression: "1 + 2" });
} catch (error) {
if (error.name === "MCPClientError") {
// Handle connection issues
console.error(`Connection error (${error.serverName}):`, error.message);
} else if (error.name === "ToolException") {
// Handle tool execution errors
console.error("Tool execution failed:", error.message);
} else if (error.name === "ZodError") {
// Handle configuration validation errors
console.error("Configuration error:", error.issues);
// Zod errors contain detailed information about what went wrong
error.issues.forEach((issue) => {
console.error(`- Path: ${issue.path.join(".")}, Error: ${issue.message}`);
});
} else {
// Handle other errors
console.error("Unexpected error:", error);
}
}
```

### Common Zod Validation Errors

The library uses Zod for validating configuration. Here are some common validation errors:

- **Missing required parameters**: For example, omitting `command` for stdio transport or `url` for SSE transport
- **Invalid parameter types**: For example, providing a number where a string is expected
- **Invalid connection configuration**: For example, using an invalid URL format for SSE transport

Example Zod error for an invalid SSE URL:

```json
{
"issues": [
{
"code": "invalid_string",
"validation": "url",
"path": ["mcpServers", "weather", "url"],
"message": "Invalid url"
}
],
"name": "ZodError"
}
```

## Browser Environments

When using in browsers:

- EventSource API doesn't support custom headers for SSE
- Consider using a proxy or pass authentication via query parameters to avoid leaking credentials to client
- May require CORS configuration on the server side

## Troubleshooting

### Common Issues

1. **Connection Failures**:

- Verify the MCP server is running
- Check command paths and network connectivity

2. **Tool Execution Errors**:

- Examine server logs for error messages
- Ensure input parameters match the expected schema

3. **Headers Not Applied**:
- Install the recommended `extended-eventsource` package
- Set `useNodeEventSource: true` in SSE connections

### Debug Logging

This package makes use of the [debug](https://www.npmjs.com/package/debug) package for debug logging.

Logging is disabled by default, and can be enabled by setting the `DEBUG` environment variable as per
the instructions in the debug package.

To output all debug logs from this package:

```bash
DEBUG='@langchain/mcp-adapters:*'
```

To output debug logs only from the `client` module:

```bash
DEBUG='@langchain/mcp-adapters:client'
```

To output debug logs only from the `tools` module:

```bash
DEBUG='@langchain/mcp-adapters:tools'
```

## License

MIT

## Acknowledgements

Big thanks to [@vrknetha](https://github.com/vrknetha), [@knacklabs](https://www.knacklabs.ai) for the initial implementation!

## Contributing

Contributions are welcome! Please check out our [contributing guidelines](CONTRIBUTING.md) for more information.