Skip to content
/

LangChain MCP Adapters

langchain-mcp-adapters · langchain-ai/langchain-mcp-adapters · ★ 3.5k · last commit 2026-05-26

Primitive shape
No installable primitives
00

Summary

LangChain MCP Adapters — Summary

LangChain MCP Adapters is a lightweight Python library (v0.2.2) that bridges the Anthropic Model Context Protocol with LangChain/LangGraph tooling, converting any MCP tool into a fully typed BaseTool subclass that LangGraph agents can call natively. It ships MultiServerMCPClient, a connection manager that multiplexes stdio, SSE, HTTP, and WebSocket transports to any number of MCP servers simultaneously, handling session lifecycle so calling code does not need to. The library also adapts MCP prompts and resources (via load_mcp_prompt, load_mcp_resources) and provides a ToolCallInterceptor protocol for request/response mutation before and after every tool call. Content conversion is bidirectional: MCP TextContent, ImageContent, AudioContent, and EmbeddedResource all round-trip to the corresponding LangChain content-block types, with optional LangGraph Command passthrough. A companion TypeScript/JavaScript implementation exists in the langchainjs monorepo, making the adapter pattern available in both ecosystems. Compared to the seeds, this is narrowest-scope of the catalog: unlike taskmaster-ai (an MCP-anchored toolserver with its own memory and task graph), this is a pure protocol-translation shim — no skills, no hooks, no memory, no orchestration — solely the typed glue layer that lets LangGraph consume any MCP server.

01

Overview

LangChain MCP Adapters — Overview

Origin

Maintained by Vadym Barda at LangChain AI. First published around mid-2024 when the MCP specification stabilized; the library tracks mcp>=1.9.2 and langchain-core>=1.0.0. The repo sits inside the langchain-ai GitHub org alongside LangGraph, not inside the main langchain monorepo, signaling it is a protocol-integration layer rather than a framework feature.

Philosophy

The README states: "This library provides a lightweight wrapper that makes Anthropic Model Context Protocol (MCP) tools compatible with LangChain and LangGraph." That one-liner is the entire philosophy: protocol translation, nothing else. The design explicitly avoids owning agent logic, state, or workflows — those live in LangGraph.

Design manifesto (inferred from architecture)

  • Zero config: instantiate MultiServerMCPClient(dict_of_connections), call await client.get_tools(), feed the list to create_agent(). No YAML, no project scaffold, no setup wizard.
  • Typed at every seam: StdioConnection, SSEConnection, StreamableHttpConnection, WebsocketConnection are TypedDict subtypes; load_mcp_tools returns list[BaseTool]; ToolCallInterceptor is a generic protocol parameterized on request/result types.
  • Interceptors, not monkeypatching: MCPToolCallRequest / MCPToolCallResult are immutable dataclass pairs passed through a middleware chain, allowing mutation without subclassing.
  • Session-per-call by default, explicit session for efficiency: the default MultiServerMCPClient.get_tools() opens a fresh session per tool invocation; explicit async with client.session("name") as s keeps it open for batch calls.

Key quotes

From the README migration note (v0.1.0 breaking change):

"As of langchain-mcp-adapters 0.1.0, MultiServerMCPClient cannot be used as a context manager (e.g., async with MultiServerMCPClient(...)). Instead, you can do one of the following: 1. client = MultiServerMCPClient(...) \n tools = await client.get_tools()"

This breaking-change text reveals the philosophy: the team is willing to change the API contract sharply to get session management semantics correct.

Ecosystem position

  • Consumes: any MCP server (stdio, SSE, HTTP, WebSocket, RPC)
  • Produces: list[BaseTool] (LangChain), MCP prompts as list[BaseMessage], resources as list[Blob]
  • Used by: any LangGraph agent that wants MCP tools without manual session plumbing
02

Architecture

LangChain MCP Adapters — Architecture

Distribution

  • Type: pip-package
  • PyPI name: langchain-mcp-adapters
  • Version analyzed: 0.2.2
  • Install: pip install langchain-mcp-adapters
  • Build system: pdm-backend
  • Required runtime: Python ≥ 3.10

Dependencies

langchain-core>=1.0.0,<2.0.0
mcp>=1.9.2
typing-extensions>=4.14.0

Optional (integration extras):

langchain>=1.0.8  # for create_agent helper

Source layout

langchain_mcp_adapters/
  __init__.py
  callbacks.py        # CallbackContext, Callbacks, _MCPCallbacks
  client.py           # MultiServerMCPClient
  interceptors.py     # MCPToolCallRequest, MCPToolCallResult, ToolCallInterceptor
  prompts.py          # load_mcp_prompt
  resources.py        # load_mcp_resources
  sessions.py         # Connection types: Stdio, SSE, StreamableHttp, Websocket
  tools.py            # load_mcp_tools, MCPToolArtifact, content converters
  py.typed

Connection types (from sessions.py)

Type Transport Config keys
StdioConnection subprocess stdin/stdout command, args, env
SSEConnection Server-Sent Events url, headers
StreamableHttpConnection HTTP streaming url, headers
WebsocketConnection WebSocket url

Content type mapping

MCP type LangChain type
TextContent TextContentBlock
ImageContent ImageContentBlock
AudioContent raises NotImplementedError
EmbeddedResource (text) TextContentBlock
EmbeddedResource (blob) FileContentBlock
ResourceLink TextContentBlock (URL)

Target AI tools

  • Primary: LangGraph (via BaseTool list)
  • Secondary: any LangChain agent that accepts list[BaseTool]
  • LangGraph passthrough: when LangGraph is installed, Command objects from tool results are forwarded as-is

CLI binary

None. The library is import-only; no bin/ entry, no pyproject.toml scripts section.

No local UI

Pure Python library; no web dashboard, no TUI.

03

Components

LangChain MCP Adapters — Components

Public API surface (all in langchain_mcp_adapters/)

Core functions

Name Module Purpose
load_mcp_tools tools.py Convert all tools from an MCP ClientSession into list[BaseTool]
load_mcp_prompt prompts.py Fetch an MCP prompt and convert arguments to list[BaseMessage]
load_mcp_resources resources.py List and read MCP resources, returning list[Blob]

Classes

Name Module Purpose
MultiServerMCPClient client.py Connection manager for N MCP servers; provides get_tools(), get_prompts(), session()
ToolCallInterceptor interceptors.py Protocol class for pre/post-call mutation of tool requests and results
MCPToolCallRequest interceptors.py Immutable dataclass representing an outgoing tool call (tool_name, arguments)
MCPToolCallResult interceptors.py Immutable dataclass representing an incoming tool result
MCPToolArtifact tools.py TypedDict wrapping structuredContent from MCP CallToolResult
CallbackContext callbacks.py Typed wrapper threading LangChain callbacks through MCP calls

Connection TypedDicts (from sessions.py)

Name Transport
StdioConnection subprocess
SSEConnection Server-Sent Events
StreamableHttpConnection HTTP streaming
WebsocketConnection WebSocket
Connection Union of all four

No commands, skills, agents, hooks, or MCP servers

This library consumes MCP servers; it does not ship any. No slash-commands, no skills, no hooks, no subagents — it is a translation layer only.

Template / example count

  • examples/ directory contains integration notebooks; no named templates.
  • Tests in tests/ cover all transport types.
05

Prompts

LangChain MCP Adapters — Prompts

This library contains no LLM prompt files. Its job is to convert MCP tool schemas into LangChain BaseTool objects — the prompts come from the MCP servers being adapted, not from this library.

Verbatim: tool docstring convention (from tools.py)

class MCPToolArtifact(TypedDict):
    """Artifact returned from MCP tool calls.

    This TypedDict wraps the structured content from MCP tool calls,
    allowing for future extension if MCP adds more fields to tool results.

    Attributes:
        structured_content: The structured content returned by the MCP tool,
            corresponding to the structuredContent field in CallToolResult.
    """
    structured_content: dict[str, Any]

Technique: Standard Python docstring as API documentation; no prompt engineering involved.

Verbatim: error message used as LLM context (from client.py)

ASYNC_CONTEXT_MANAGER_ERROR = (
    "As of langchain-mcp-adapters 0.1.0, MultiServerMCPClient cannot be used as a "
    "context manager (e.g., async with MultiServerMCPClient(...)). "
    "Instead, you can do one of the following:\n"
    "1. client = MultiServerMCPClient(...)\n"
    "   tools = await client.get_tools()\n"
    "2. client = MultiServerMCPClient(...)\n"
    "   async with client.session(server_name) as session:\n"
    "       tools = await load_mcp_tools(session)"
)

Technique: Instructional error message designed to guide both human developers and AI coding assistants reading stack traces.

MCP prompt passthrough

load_mcp_prompt(session, name, arguments) fetches the prompt text from the MCP server, converts PromptMessage objects to HumanMessage/AIMessage, and returns them as list[BaseMessage]. The prompt content itself is opaque to this library — it passes through verbatim.

09

Uniqueness

LangChain MCP Adapters — Uniqueness

Differs from seeds

The closest seed is ccmemory — both are MCP-anchored libraries — but ccmemory ships an MCP server that stores memory in Neo4j, while langchain-mcp-adapters consumes arbitrary MCP servers and translates them for LangGraph. The next closest seed is claude-flow which also involves MCP servers, but claude-flow ships 305 bundled MCP tools with its own SQLite memory and orchestration; langchain-mcp-adapters has zero bundled tools and zero memory. The most analogous pattern is Archetype 3 (MCP-anchored toolserver) run in reverse: where other frameworks add MCP capabilities to an agent, this library adds LangChain capability to any MCP ecosystem.

Positioning

Single-purpose glue layer maintained by the LangChain organization to ensure any MCP server is immediately usable in LangGraph without boilerplate. It occupies the gap between the MCP Python SDK (mcp>=1.9.2) and LangChain's BaseTool interface. No competing framework in this batch does this specific job.

Observable failure modes

  1. Session leak on exception: if get_tools() is called inside a try/except that swallows errors, the background MCP server subprocess may not be cleaned up.
  2. No reconnect: if the MCP server process dies mid-conversation, the next tool call raises McpError; there is no automatic reconnect.
  3. AudioContent: explicitly raises NotImplementedError — MCP servers that return audio will break agent runs.
  4. Tool name collisions: with tool_name_prefix=False (default), two servers with a tool named search will silently shadow each other.
  5. No streaming: tool results are buffered completely before returning to LangGraph; large binary responses (e.g., file reads) load entirely into memory.

What it deliberately does not do

  • No agent logic, no memory, no state machine
  • No model selection or routing
  • No hooks, no skills, no commands
  • Does not wrap Claude Code, Claude CLI, or any IDE
04

Workflow

LangChain MCP Adapters — Workflow

Usage pattern (single server)

Phase Artifact
1. Instantiate MultiServerMCPClient with connection dict Client object in memory
2. await client.get_tools() → list[BaseTool] LangChain-compatible tool list
3. Pass tools to create_agent(model, tools) LangGraph CompiledGraph
4. await agent.ainvoke({"messages": prompt}) Final agent response

Usage pattern (explicit session for batching)

async with client.session("server_name") as session:
    tools = await load_mcp_tools(session)
    # use tools in multiple calls within this block

Approval gates

None. The library is a protocol adapter — no approval gates, no spec phases, no human-in-the-loop primitives.

Multi-server pattern

  1. Define a dict[server_name, Connection] with mixed transports
  2. tools = await client.get_tools() — loads and namespaces all tools
  3. Optional tool_name_prefix=True to avoid name collisions (e.g., "weather_search" instead of "search")

Interceptor pattern (advanced)

class LoggingInterceptor(ToolCallInterceptor):
    async def intercept(self, request, next_handler):
        print(f"Calling: {request.tool_name}")
        result = await next_handler(request)
        print(f"Result: {result}")
        return result

client = MultiServerMCPClient(..., tool_interceptors=[LoggingInterceptor()])

Error handling

  • mcp.McpError from the session propagates as ToolException into LangChain's standard error-handling path
  • Re-prompt: LangGraph re-prompts the LLM with tool errors by default

No spec format, no state files, no git automation

06

Memory Context

LangChain MCP Adapters — Memory & Context

Memory

None. The library is stateless between calls. No files written, no database, no cache.

Session management (ephemeral)

MultiServerMCPClient manages MCP ClientSession lifetimes:

  • Default mode (get_tools()): a new session is opened per tool invocation and closed immediately after
  • Explicit mode (async with client.session("name")): one session per with block; calling code controls lifetime

Session objects are held in asyncio coroutines; when the coroutine exits, the session closes. No persistence across process restarts.

Context passed to tools

Tool arguments come from the LLM's structured output (JSON schema validated against mcp.types.Tool.inputSchema). The library does not inject any additional context (no user-id, no conversation history) beyond what the LLM outputs.

State files

None. No .cache, no .langchain-mcp, no project-level artifacts.

Cross-session handoff

Not applicable — no state to hand off.

07

Orchestration

LangChain MCP Adapters — Orchestration

Multi-agent

No. The library is a single-layer adapter with no orchestration primitives. Multi-agent behavior lives in LangGraph (the consumer), not here.

Orchestration pattern

None. MultiServerMCPClient multiplexes connections to multiple MCP servers, but does not orchestrate agents.

Isolation mechanism

None — no sandboxing, no containers, no worktrees. Tool calls execute inside the MCP server process (managed externally).

Multi-model

No. Model selection is entirely up to the LangGraph caller; this library is model-agnostic.

Execution mode

Library (imported into a running process). No daemon, no scheduler, no event loop of its own.

Concurrent tool calls

MultiServerMCPClient.get_tools() opens sessions concurrently using asyncio.gather. Tool calls themselves follow LangGraph's concurrency model (parallel tool calling when the LLM emits multiple tool calls in one turn).

Consensus

None.

Prompt chaining

Indirect: load_mcp_prompt can fetch a prompt template from an MCP server and return it as LangChain messages, which a LangGraph node then injects as context. The chaining logic is in LangGraph, not here.

Cross-tool portability

Medium — works with any LangChain/LangGraph consumer; does not work with non-LangChain agent frameworks directly (though the mcp Python SDK provides lower-level access that other frameworks use).

08

Ui Cli Surface

LangChain MCP Adapters — UI & CLI Surface

CLI binary

None. No bin/ entry in pyproject.toml, no scripts section. This is a pure Python library.

Local UI / dashboard

None.

IDE integration

Indirectly — any IDE that understands LangChain (Cursor, VSCode with Pylance) gets full type hints from py.typed marker + typed stubs. The MultiServerMCPClient constructor and load_mcp_tools are fully annotated.

Observability

  • No built-in tracing
  • LangChain's standard Callbacks system is threaded through tool calls via CallbackContext — so LangSmith, LangFuse, or any BaseCallbackHandler implementation will receive tool call events
  • ToolCallInterceptor protocol provides a framework-level interception point for custom logging/metrics

TypeScript companion

A JavaScript/TypeScript version exists at langchainjs/libs/langchain-mcp-adapters/. The APIs mirror the Python version; MultiServerMCPClient and load_mcp_tools are available in both ecosystems.

Notes

The library is intentionally minimal in surface area — the UI/CLI layer is delegated to LangGraph's ecosystem (LangSmith dashboard, LangGraph Studio, etc.).

Related frameworks

same archetype · same primary tool · same memory type

Claude-Flow / Ruflo ★ 55k

Eliminates single-agent context limits and sequential bottlenecks by orchestrating fault-tolerant swarms of specialized AI agents…

Hermes Agent (NousResearch) ★ 168k

Self-improving personal AI agent with closed learning loop, 7 terminal backends, and messaging gateway — not tied to any AI…

OpenCode ★ 165k

Terminal-first AI coding agent with multi-model routing, native desktop app, and a typed .opencode/ configuration system for…

OpenHands ★ 75k

Open-source AI software development platform (open-source Devin alternative) with Docker sandbox isolation, 77.6% SWE-bench…

DeerFlow ★ 70k

Long-horizon superagent that researches, codes, and creates by orchestrating parallel sub-agents with isolated contexts in Docker…

oh-my-openagent (omo) ★ 60k

Multi-provider AI agent orchestration for OpenCode: escape vendor lock-in by routing Sisyphus (Claude/Kimi/GLM) and Hephaestus…