LangChain MCP adapters for connecting MCP servers with LangChain applications.
Interrupt-driven elicitation has its own types — the interrupt payload, the
answers a run resumes with, and the discriminator to recognize them by. Import
those from langchain.mcp.elicitation.
langchain.mcp is actively being worked on and its API may change. Importing
from it raises a LangChainBetaWarning once per process. Silence it with
warnings.filterwarnings("ignore", category=LangChainBetaWarning), or scope
the suppression with langchain_core._api.suppress_langchain_beta_warning().
Adapt an MCP target into LangChain tools.
MCPAdapter uses FastMCP for protocol negotiation and connection management,
then converts discovered MCP tools into asynchronous LangChain tools. The
resulting tools can be passed directly to create_agent.
Transport inference is delegated to fastmcp.Client, so a target may be a URL,
a local script path (launched over stdio), an in-process server, or an already
constructed client.
fastmcp.Client resolves a string by testing it as a filesystem path
before testing it as a URL, so a string naming an existing .py or .js
file launches that file as a subprocess. Because strings are the form a
target most often arrives in from configuration or from a model,
MCPAdapter rejects one that is not an http or https URL rather than
let it select local execution. Reach a local server through Path, a
fastmcp transport, or an MCPConfig, all of which say so explicitly.
A server that needs input mid-call is answered with a LangGraph
interrupt(), so a human answers and the run resumes — see
langchain.mcp.elicitation. This is the default: the adapter arms every
client it builds to advertise the elicitation capability and drives the
interrupt loop on each call. A server that never asks for input is
unaffected, since the loop only runs when the server returns a request.
A pre-built client (or ClientGroup) that already carries its own
elicitation handler is honored rather than overridden: its handler keeps
answering, and the adapter leaves the client as the caller built it. Only a
client with no handler is armed, and it is cloned first so the caller's own
object is never mutated.
Artifact attached to the ToolMessage produced by an MCP tool call.
Wrapping the structured content in a TypedDict leaves room for further
MCP result fields without changing the artifact's shape.
Answer MCP elicitation requests with a LangGraph interrupt.
A server needing input mid-call returns an InputRequiredResult and expects the
tools/call to be retried with answers. This module drives that loop, sourcing
each answer from interrupt() so the human reviewing the agent answers too.
We drive the loop here rather than via the SDK's run_input_required_driver
because that driver answers from callbacks run concurrently in a task group:
LangGraph matches resume values to interrupt() calls by order, so concurrent
firing scrambles the matching, and FastMCP would swallow the GraphInterrupt as
an MCP error. Calling interrupt() from this frame keeps one per round.
Only elicitation is answered. Sampling, roots, and continuation rounds are refused rather than half-served.
Convert MCP tools and tool results into LangChain-native values.
Tool results follow langchain-mcp-adapters, so a call made through
langchain.mcp reaches a model in the same shape as one loaded by that
package. Tool metadata is richer here: it is grouped under a single mcp
namespace with the tool's annotations and _meta under mcp.tool and the
serving server's identity under mcp.server.
Adapt MCP tools into LangChain tools suitable for create_agent.