Skip to main content
Model Context Protocol (MCP) is an open protocol that standardizes how applications provide tools and context to LLMs. LangChain agents can use tools defined on MCP servers using the langchain-mcp-adapters library.

Quickstart

Install the langchain-mcp-adapters library:
langchain-mcp-adapters enables agents to use tools defined across one or more MCP servers.
MultiServerMCPClient is stateless by default. Each tool invocation creates a fresh MCP ClientSession, executes the tool, and then cleans up. See the stateful sessions section for more details.
Accessing multiple MCP servers
Trace MCP tool calls alongside your agent’s reasoning steps with LangSmith. Follow the tracing quickstart to get set up.

Custom servers

To create a custom MCP server, use the FastMCP library:
To test your agent with MCP tool servers, use the following examples:

Transports

MCP supports different transport mechanisms for client-server communication.

HTTP

The http transport (also referred to as streamable-http) uses HTTP requests for client-server communication. See the MCP HTTP transport specification for more details.

Passing headers

When connecting to MCP servers over HTTP, you can include custom headers (e.g., for authentication or tracing) using the headers field in the connection configuration. This is supported for sse (deprecated by MCP spec) and streamable_http transports.
Passing headers with MultiServerMCPClient

Authentication

The langchain-mcp-adapters library uses the official MCP SDK under the hood, which allows you to provide a custom authentication mechanism by implementing the httpx.Auth interface.

stdio

Client launches server as a subprocess and communicates via standard input/output. Best for local tools and simple setups.
Unlike HTTP transports, stdio connections are inherently stateful: the subprocess persists for the lifetime of the client connection. However, when using MultiServerMCPClient without explicit session management, each tool call still creates a new session. See stateful sessions for managing persistent connections.

Stateful sessions

By default, MultiServerMCPClient is stateless: each tool invocation creates a fresh MCP session, executes the tool, and then cleans up. If you need to control the lifecycle of an MCP session (for example, when working with a stateful server that maintains context across tool calls), you can create a persistent ClientSession using client.session().
Using MCP ClientSession for stateful tool usage

Core features

Tools

Tools allow MCP servers to expose executable functions that LLMs can invoke to perform actions—such as querying databases, calling APIs, or interacting with external systems. LangChain converts MCP tools into LangChain tools, making them directly usable in any LangChain agent or workflow.

Loading tools

Use client.get_tools() to retrieve tools from MCP servers and pass them to your agent:
By default, when an MCP tool fails, the error is passed back to the model as a tool message with status="error" instead of raising an exception. This lets the agent read the error and try again. To raise an exception instead, set handle_tool_errors=False on MultiServerMCPClient or load_mcp_tools. This applies only to tool execution errors (CallToolResult(isError=True)). Transport, session, and content-conversion failures always raise.
Returning MCP tool errors as failed tool messages requires langchain-mcp-adapters>=0.3.0. Earlier versions raise a ToolException.

Structured content

MCP tools can return structured content alongside the human-readable text response. This is useful when a tool needs to return machine-parseable data (like JSON) in addition to text that gets shown to the model. When an MCP tool returns structuredContent, the adapter wraps it in an MCPToolArtifact and returns it as the tool’s artifact. You can access this using the artifact field on the ToolMessage. You can also use interceptors to process or transform structured content automatically. Extracting structured content from artifact After invoking your agent, you can access the structured content from tool messages in the response:
Appending structured content via interceptor If you want structured content to be visible in the conversation history (visible to the model), you can use an interceptor to automatically append structured content to the tool result:

Multimodal tool content

MCP tools can return multimodal content (images, text, etc.) in their responses. When an MCP server returns content with multiple parts (e.g., text and images), the adapter converts them to LangChain’s standard content blocks. You can access the standardized representation via the content_blocks property on the ToolMessage:
This allows you to handle multimodal tool responses in a provider-agnostic way, regardless of how the underlying MCP server formats its content.

Resources

Resources allow MCP servers to expose data—such as files, database records, or API responses—that can be read by clients. LangChain converts MCP resources into Blob objects, which provide a unified interface for handling both text and binary content.

Loading resources

Use client.get_resources() to load resources from an MCP server:
You can also use load_mcp_resources directly with a session for more control:

Prompts

Prompts allow MCP servers to expose reusable prompt templates that can be retrieved and used by clients. LangChain converts MCP prompts into messages, making them easy to integrate into chat-based workflows.

Loading prompts

Use client.get_prompt() to load a prompt from an MCP server:
You can also use load_mcp_prompt directly with a session for more control:

Advanced features

Tool interceptors

MCP servers run as separate processes—they can’t access LangGraph runtime information like the store, context, or agent state. Interceptors bridge this gap by giving you access to this runtime context during MCP tool execution. Interceptors also provide middleware-like control over tool calls: you can modify requests, implement retries, add headers dynamically, or short-circuit execution entirely.

Accessing runtime context

When MCP tools are used within a LangChain agent (via create_agent), interceptors receive access to the ToolRuntime context. This provides access to the tool call ID, state, config, and store—enabling powerful patterns for accessing user data, persisting information, and controlling agent behavior.
Access user-specific configuration like user IDs, API keys, or permissions that are passed at invocation time:
Inject user context into MCP tool calls
For more context engineering patterns, see Context engineering and Tools.

State updates and commands

Interceptors can return Command objects to update agent state or control graph execution flow. This is useful for tracking task progress, switching between agents, or ending execution early.
Mark task complete and switch agents
Use Command with goto="__end__" to end execution early:
End agent run on completion

Custom interceptors

Interceptors are async functions that wrap tool execution, enabling request/response modification, retry logic, and other cross-cutting concerns. They follow an “onion” pattern where the first interceptor in the list is the outermost layer. Basic pattern An interceptor is an async function that receives a request and a handler. You can modify the request before calling the handler, modify the response after, or skip the handler entirely.
Basic interceptor pattern
Modifying requests Use request.override() to create a modified request. This follows an immutable pattern, leaving the original request unchanged.
Modifying tool arguments
Modifying headers at runtime Interceptors can modify HTTP headers dynamically based on the request context:
Dynamic header modification
Composing interceptors Multiple interceptors compose in “onion” order—the first interceptor in the list is the outermost layer:
Composing multiple interceptors
Error handling Use interceptors to catch exceptions from tool execution, such as transport or runtime failures, and add retry logic. Tool execution errors (CallToolResult(isError=True)) do not raise by default, so exception-catching interceptors never trigger on them. To catch those as exceptions here, set handle_tool_errors=False.
Retry on error
You can also catch specific error types and return fallback values:
Error handling with fallback

Progress notifications

Subscribe to progress updates for long-running tool executions:
Progress callback
The CallbackContext provides:
  • server_name: Name of the MCP server
  • tool_name: Name of the tool being executed (available during tool calls)

Logging

The MCP protocol supports logging notifications from servers. Use the Callbacks class to subscribe to these events.
Logging callback

Elicitation

Elicitation allows MCP servers to request additional input from users during tool execution. Instead of requiring all inputs upfront, servers can interactively ask for information as needed.

Server setup

Define a tool that uses ctx.elicit() to request user input with a schema:
MCP server with elicitation

Client setup

Handle elicitation requests by providing a callback to MultiServerMCPClient:
Handling elicitation requests

Response actions

The elicitation callback can return one of three actions:
Response action examples

Additional resources