The
langchain.mcp namespace requires langchain[mcp]>=1.4.0 and is in beta. The API may change.MCPAdapter opens an MCP connection, discovers tools, and returns LangChain tools your agent can call. How you pass servers in, and how long you keep the adapter open, depends on the shape of your app. The connection itself is FastMCP’s; this page covers the LangChain patterns and links out to FastMCP for transport and client details.
Prefer the default lifecycle unless you are connecting to several servers or deploying many concurrent runs. For what a single target can be (URL, script path, in-process server), see Transports.
Choose a pattern
Pick one row from each table. Server shape and connection lifetime are independent; any shape works with any lifetime. Server shape
Connection lifetime
Connection lifecycle
MCPAdapter is an async context manager. Entering it connects the underlying client; exiting it releases the connection. Discovery happens inside the context, but the tools it returns hold the client, so they stay callable after the context exits.
To discover tools and build an agent (the default pattern):
One session per invocation
The toolsMCPAdapter returns are reentrant: each time a tool is invoked, it opens the client, runs the MCP call, and releases it, whether or not a connection is already held elsewhere. A single agent run therefore opens one session per tool call and closes it when the call returns, rather than holding a session open across the whole run. This keeps a long-running agent from pinning an idle connection between tool calls, and it is why the tools stay callable after the discovery context exits.
If you want a session held open across several calls, keep the adapter’s context open when you call the agent. The reentrant client reuses the existing connection rather than opening a second one.
Multiple servers
To give one agent tools from several servers, chooseMCPConfig when a single aggregate connection is enough, or ClientGroup when each server needs its own connection (different protocol eras, per-server authentication, or a shared pool configured per client).
One aggregate connection with MCPConfig
Give the adapter an MCPConfig dict to connect to several servers behind one aggregate endpoint. FastMCP prefixes every tool with its config key, so two servers exposing the same tool name stay distinguishable in the list handed to a model:
MCPConfig fleet shares a single negotiated protocol era across every backend, though: add a legacy-only server and the whole fleet drops to the legacy era.
Independent connections with ClientGroup
To keep each server on its own connection, pass a ClientGroup. Each member keeps its own negotiated protocol era, authentication, and handlers, and the group routes each call back to the client that advertised the tool. This is what lets a legacy and a modern server run side by side, and it namespaces tools the same way so identical tool names across servers never collide:
Scale a deployment
A deployment that serves many runs should discover per run but reuse its connections underneath, rather than reconnecting on every request. Build the agent inside alanggraph dev graph factory so each run picks up the current tool catalog, and let a shared connection pool and response cache absorb the cost:
In a
langgraph dev graph factory, the annotated parameter types and the return type must be importable at runtime, not only under TYPE_CHECKING. langgraph-api classifies the factory with typing.get_type_hints(); if an annotation cannot resolve, it injects a config dict instead of the runtime.Shared connection pool
By default each FastMCP client manages its own HTTP connections. Across a fleet of servers, or many concurrent runs, that means many independent pools. To share one pool, pass anhttpx_client_factory that draws from a single transport, and lend it out without letting any one client close it:
_POOL, the deployment opens one set of HTTP connections for the whole fleet rather than one per server.
Caching
FastMCP can cache the result oflist_tools so repeated discovery avoids a network round trip. Caching is opt-in and honors the server’s own cache hints, so it only takes effect against modern-era servers that advertise them.
list_tools() accepts a cache_mode that selects how discovery reads a configured cache:
use(the default): serve a cached tool list when one is present and still within the server’s TTL hint, otherwise fetch and store.refresh: fetch a fresh list from the server and repopulate the cache.bypass: skip the cache entirely.
Client(cache=...). For a shared store across a fleet of replicas, or partitioning cached responses per user, see Response caching in the FastMCP documentation.
Protocol eras
MCP changed how a client and server agree on what each supports. The legacy era begins every connection with aninitialize handshake; the modern era (protocol version 2026-07-28 and later) discovers support by probing the server’s server/discover endpoint. FastMCP negotiates the era per connection, so nothing on the LangChain side has to know which a given server speaks.
To hold tools from servers on different eras in one agent, give each its own connection so it keeps the best era its server supports, either through a ClientGroup or one adapter per server. A prebuilt fastmcp.Client selects the era with its mode parameter:
MCPConfig fleet instead would negotiate one era for everything the fleet holds, dropping every server to the oldest era any member requires.
For the full negotiation rules, see Protocol negotiation in the FastMCP documentation.
See also
- Authentication — bearer, OAuth, and per-user credentials
- Deploy a LangGraph server — graph factories for long-lived deployments
- FastMCP connection lifecycle
- MCP configuration format
Connect these docs to Claude, VSCode, and more via MCP for real-time answers.

