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.
- Host: GitHub
- URL: https://github.com/langchain-ai/langchainjs-mcp-adapters
- Owner: langchain-ai
- License: mit
- Created: 2025-03-03T19:52:24.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2025-05-12T15:49:34.000Z (5 months ago)
- Last Synced: 2025-05-12T16:31:30.916Z (5 months ago)
- Topics: agent-tools, ai-tools, javascript, langchain, langchainjs, llm-agents, llm-integration, llm-tools, mcp, model-context-protocol, openai-functions, typescript
- Language: TypeScript
- Homepage:
- Size: 2.22 MB
- Stars: 215
- Watchers: 3
- Forks: 30
- Open Issues: 13
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# LangChain.js MCP Adapters
[](https://www.npmjs.com/package/@langchain/mcp-adapters)
[](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/openaiexport 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 resourcesExample 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 transportExample 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 connectivity2. **Tool Execution Errors**:
- Examine server logs for error messages
- Ensure input parameters match the expected schema3. **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.