Major Changes
-
#11767
56a7f0bThanks @byhow! - This release moves to MCP SDK 2, supports modern and legacy MCP servers in the same adapter, and lets servers ask users for input through LangGraph interrupts. It also changes tool names, configuration, and tool results. If you are upgrading from 1.x, review the changes below before updating.See the migration guide for more information on migrating.
Update your client code
Use
MCPAdapterfor new code:1.x API Recommended API MultiServerMCPClientMCPAdaptermcpServersor a flat server map{ servers: { ... } }getTools(...)listTools(...)initializeConnections()listToolsets()ClientConfigMCPAdapterConfigThese older APIs still work but are deprecated.
listTools()returns a flat list of executable LangChain tools;listToolsets()groups them by server. Read configuration fromadapter.config.servers; the returned snapshot no longer hasmcpServers, and changing it does not reconfigure the adapter.The adapter requires
@langchain/core ^1.2.6and@langchain/langgraph ^1.4.13. It includes the MCP SDK client. If you create an SDK client yourself forloadMcpTools, switch your client imports from@modelcontextprotocol/sdkto@modelcontextprotocol/client(or@modelcontextprotocol/client/stdiofor the stdio transport).getClient()now returns an SDK 2 client. An SDK 2Clientnegotiates only the legacy protocol by default; passversionNegotiation: { mode: "auto" }when you construct it to reach modern servers.Tool names and configuration
- Tool names now include the server name by default, including with the deprecated
MultiServerMCPClientand with one server:searchon a server nameddocsbecomesdocs__search. Update code, prompts, and saved examples that refer to tool names, or setprefixToolNameWithServerName: falseto keep unprefixed names. UpdateinterruptOnapproval rules to the prefixed names; a rule fordelete_repono longer matchesgithub__delete_repo. Server names aren't validated, so choose names your model provider accepts in tool names. The standaloneloadMcpTools()helper keeps its previous default offalse. - Duplicate tool names throw. With
prefixToolNameWithServerName: false,listTools()andgetTools()throwMCPClientErrorwhen two servers expose the same tool name, or when one server lists a name twice. Keep the prefix, or pick tools per server fromlistToolsets(). - Configuration is validated with Zod 4. Unknown adapter and server options, options that don't apply to a server's mode or transport, conflicting transport settings, empty server maps, and setting both
serversandmcpServersnow throw, andloadMcpToolsvalidates its options the same way. RemoveuseStandardContentBlocks,onRootsListChanged,onCancelled, and stdioencoding. - Move notification and progress callbacks into each server's configuration:
onMessage,onProgress,onInitialized,onPromptsListChanged,
onResourcesListChanged,onResourcesUpdated, andonToolsListChanged.
beforeToolCall,afterToolCall, andonConnectionErrorremain top-levelMCPAdapteroptions.
Connections and authentication
Each server negotiates its protocol independently. Omit
modeto use"auto", setmode: "modern"to require the modern protocol, or setmode: "legacy"to skip probing a known legacy server.- Legacy connection options need
mode: "legacy". This applies toonInitialized,onElicitation,automaticSSEFallback, and HTTP/SSEreconnect. HTTP connections in"auto"or"modern"mode no longer resume a dropped response stream. Use legacy mode if you depend on that behavior. - Some client methods are legacy-only. On a server that negotiates the modern protocol,
setLoggingLevel()throws; set the server'slogLevelinstead. Modern servers rejectresources/subscribe; list the URIs to watch in the server'sresourceSubscriptionsoption and handleonResourcesUpdated. - SSE remains a legacy transport. It rejects
mode: "modern",elicitation, andlogLevel. TheSSEConnectiontype now describes SSE only; useStreamableHTTPConnectionfor HTTP orConnectionfor any transport. Automatic HTTP-to-SSE fallback in"auto"mode is limited to HTTP 404 and 405. authProvideraccepts token providers as well as OAuth providers. Use{ token, onUnauthorized? }for tokens your app manages. Once a provider has a token, it takes precedence over a configuredAuthorizationheader; until then, the configured header is sent. Complete OAuth redirects through the SDK'stransport.finishAuth(params)using the same provider storage.- Authentication failures can recover. Discovery retries an authentication failure on the next call, including with
onConnectionError: "ignore". Walk the error'scausechain forUnauthorizedError(now exported) or an HTTP 401 error: discovery wraps it inMCPClientError, twice when legacy mode falls back to SSE, and tool calls wrap it inToolException. - Tool catalogs are kept separate for different headers and provider objects. Recreate the adapter if you switch accounts behind the same provider object. A method-level
authProviderreplaces the configured one, and method-levelheadersare added to each server's headers, where a configured header with the same name wins. Both apply to all of the adapter's HTTP/SSE servers, even when you select tools from just one server.
See the connections guide and authentication guide.
Servers can pause a run to ask for input
Modern MCP elicitation is enabled by default. When a tool asks the user to fill in a form or visit a URL, the adapter pauses the run with a LangGraph interrupt. Use a checkpointer and resume with
createMCPElicitationResume(interrupt, responses)inside a LangGraphCommand. A tool needs a checkpointer only if it asks for input; otherwise direct invocation still works. Setelicitation: falseon a server to opt out. Legacy servers can use the new per-serveronElicitationcallback withmode: "legacy".Resuming runs the tool again from the beginning, including
beforeToolCall. Make sure repeating that work will not duplicate side effects. Answers must cover every request in the interrupt and match the requested form schema. Sampling and roots requests are not answered through these interrupts; they fail the tool call with aToolException, even alongside an elicitation.Tool results and errors
- Multimodal content uses standard LangChain blocks. Images and audio expose
dataandmimeType; resource links becomefileblocks withurl,mimeType, and resource metadata. Update consumers ofimage_url,mime_type, orsource_type. Blocks routed to the artifact keep their MCP format, including when passed toafterToolCall. - Structured output and protocol metadata stay in the artifact. Read
structuredContentfrom themcp_structured_contententry and_metafrommcp_meta. A single text block now becomes plain string content even when those fields are present, so they are no longer included in what the model sees. Original resource blocks and content metadata are retained inmcp_contententries when conversion would otherwise lose them. - Resource conversion no longer fetches URIs. Call
readResource()explicitly when you need to fetch a resource. When routed to model content, embedded text resources become text blocks; embedded binary resources become image, audio, or file blocks according to their MIME type.readResource()preserves SDK metadata; narrow its results with"text" in contentor"blob" in content. - Server-reported failures return an error message. When an MCP server returns a tool result with
isError, the adapter returns aToolMessagewithstatus: "error"for an agent's tool call. Direct invocation with plain arguments still throwsToolException, with the MCP response inerror.result. - Connection and validation failures still throw from the tool. Invoked directly, the tool raises the exception; in a
createAgentagent, the default tool error handling turns it into aToolMessagewithstatus: "error". Read the exception'smessagefor details;causeis not always set. - Hooks preserve
ToolMessageand LangGraphCommandresults. They are no longer flattened or rejected. Hookstateis now typedunknown; narrow it before use, and return an object when overriding arguments. The merged arguments are validated against the tool's input schema before the call is sent.afterToolCallreceives successful results only. - Tool input schemas are no longer simplified. They reach the model as the server declares them. 1.x inlined
$refdefinitions, mergedallOf, flattenedanyOfandoneOf, and removedif/then/else,not,$schema, andunevaluatedProperties.
Discovery, cleanup, and diagnostics
listTools([], { cacheMode: "refresh" })refreshes discovery;cacheMode: "bypass"skips the cache. A failed refresh keeps previously returned tools usable.- Keep the adapter open while using its tools, then await
close(). Closing stops active discovery and pending reconnects and clears connections and caches. You can reuse the adapter by discovering fresh tools afterwards. listResources()andlistResourceTemplates()now surface server errors; 1.x returned[]for a failing server and logged the error only underDEBUG. A server that does not implement resource-template listing still contributes[].DEBUG=@langchain/mcp-adapters:*no longer emits logs; useonConnectionErrorand the per-server notification callbacks.- Exhausted background stdio restart attempts report through an
onConnectionErrorcallback. Errors thrown or rejected by anonProgresscallback are now ignored.
- Tool names now include the server name by default, including with the deprecated