主题
从 langchain-mcp-adapters 迁移
从独立的 langchain-mcp-adapters 包迁移到内置的 langchain.mcp 命名空间。
MCP 支持现在随 LangChain 一起提供,位于 langchain.mcp 命名空间中,基于 FastMCP 构建。它取代了独立的 langchain-mcp-adapters 包,后者的 MultiServerMCPClient 被合并为单个 MCPAdapter 类。
有关完整的功能文档,请参阅 Model Context Protocol (MCP)。
将此代码库从独立的 langchain-mcp-adapters 包迁移到内置的 langchain.mcp 命名空间。
第 1 步:阅读指南
获取并遵循 https://www.bytesrouter.com/langchain/oss/python/migrate/langchain-mcp-adapters 作为包变更、导入路径、客户端 API、连接配置、回调、拦截器、身份认证以及尚未封装功能的权威来源。迁移后的当前功能文档,请在需要时也获取 https://www.bytesrouter.com/langchain/oss/python/langchain/mcp 及其链接页面。
步骤 2:升级包
卸载 langchain-mcp-adapters,并使用此项目中已使用的包管理器(uv 或 pip)安装 >=1.4.0 的 langchain[mcp]。当项目已经固定版本时,优先固定当前稳定版本。
步骤 3:应用迁移
找出所有从 langchain_mcp_adapters 导入或使用 MultiServerMCPClient 的调用点,然后应用指南中的前后更改,包括:
- 将
MultiServerMCPClient替换为MCPAdapter(异步上下文管理器;使用list_tools())。 - 将服务器配置移至标准的
MCPConfig结构(mcpServers),并在指南说明传输方式为推断时,删除每个条目中的transport键。 - 将导入路径、重命名的辅助函数(例如将
convert_mcp_tool_to_langchain_tool改为as_langchain_tool)、构造函数参数、回调、工具拦截器和身份认证更新为页面上的映射。 - 保留指南标记为保留的行为(例如
MCPToolArtifact和多模态内容)。
步骤 4:显式处理缺口
如果代码库使用了提示词、资源、采样、roots、SSE/WebSocket 传输、to_fastmcp,或指南标记为不支持或协议已弃用的任何 API,请停下来询问用户如何继续。不要自行发明替代方案。
规则
- 将范围限定在此次迁移内。不要重写无关的智能体代码。
- 优先使用指南中的
langchain.mcpAPI,而不是保留langchain-mcp-adapters。 - 当某调用点或参数未在指南中涵盖时,请询问而不是猜测。
NOTE
langchain.mcp 命名空间需要 langchain[mcp]>=1.4.0,且处于 beta 阶段。从其中导入会引发 LangChainBetaWarning。该 API 可能会发生变化。
安装
用 mcp 附加项替换独立的包,它会引入 FastMCP:
bash
pip uninstall langchain-mcp-adapters
pip install "langchain[mcp]"bash
uv remove langchain-mcp-adapters
uv add "langchain[mcp]"导入路径
langchain-mcp-adapters | langchain.mcp |
|---|---|
from langchain_mcp_adapters.client import MultiServerMCPClient | from langchain.mcp import MCPAdapter |
from langchain_mcp_adapters.tools import load_mcp_tools | from langchain.mcp import MCPAdapter(使用 MCPAdapter(...).list_tools()) |
from langchain_mcp_adapters.tools import convert_mcp_tool_to_langchain_tool | from langchain.mcp import as_langchain_tool(重命名) |
from langchain_mcp_adapters.tools import MCPToolArtifact | from langchain.mcp import MCPToolArtifact |
客户端
MultiServerMCPClient 接收一个服务器配置字典并暴露了若干方法。MCPAdapter 是一个异步上下文管理器,它从其目标推断传输方式并暴露 list_tools()。
之前:
python
from langchain_mcp_adapters.client import MultiServerMCPClient
client = MultiServerMCPClient(
{
"math": {"transport": "stdio", "command": "python", "args": ["/path/to/math_server.py"]},
"weather": {"transport": "http", "url": "http://localhost:8000/mcp"},
}
)
tools = await client.get_tools()之后:
python
from langchain.mcp import MCPAdapter
config = {
"mcpServers": {
"math": {"command": "python", "args": ["/path/to/math_server.py"]},
"weather": {"url": "http://localhost:8000/mcp"},
}
}
async with MCPAdapter(config) as adapter:
tools = await adapter.list_tools()该配置使用标准的 MCPConfig 结构(mcpServers),传输方式从每个条目推断,而不是用 transport 键指定。对于单个服务器,直接传入其 URL、脚本路径或进程内服务器。请参阅 连接。
客户端方法
MultiServerMCPClient 方法 | langchain.mcp |
|---|---|
get_tools(server_name=...) | MCPAdapter(...).list_tools()。将适配器指向某一个服务器,即可限定到该服务器。 |
get_prompt(server_name, prompt_name, arguments=...) | 不支持。 请参阅 提示词和资源。 |
get_resources(server_name, uris=...) | 不支持。 请参阅 提示词和资源。 |
session(server_name, auto_initialize=...) | 未暴露。list_tools() 管理会话;每个返回的工具在每次调用时都会打开自己的会话。请参阅 连接生命周期。 |
构造函数参数
MultiServerMCPClient(...) 参数 | langchain.mcp |
|---|---|
connections(连接配置字典) | 适配器的 target:URL、Path、进程内服务器、MCPConfig 字典、预构建的 fastmcp.Client 或 ClientGroup。 |
tool_name_prefix | 对于多服务器 MCPConfig 或 ClientGroup,会自动添加前缀({server}_{tool})。请参阅 多个服务器。 |
handle_tool_errors | 该标志已移除。 行为现在固定为:isError=True 变为 ToolMessage(status="error");传输失败会抛出异常。请参阅 工具。 |
callbacks(Callbacks) | 在 fastmcp.Client 上设置相应的处理程序。请参阅 回调。 |
tool_interceptors(ToolCallInterceptor) | 使用 LangChain @wrap_tool_call middleware。 |
连接配置
langchain-mcp-adapters 使用了类型化的连接类。MCPAdapter 会推断传输方式,或者你可以传入 fastmcp 传输以实现完全控制。
langchain-mcp-adapters | langchain.mcp |
|---|---|
StdioConnection | 一个 Path 目标,或一个带有 command/args 的 MCPConfig 条目。 |
StreamableHttpConnection | 一个 http/https URL 目标,或一个带有 url 的 MCPConfig 条目。 |
SSEConnection | Client(SSETransport(url)),传给 MCPAdapter。受支持,但该传输已被弃用。请参阅 已弃用的传输。 |
WebsocketConnection | 没有 FastMCP 传输。将服务器迁移到 Streamable HTTP。请参阅 已弃用的传输。 |
httpx_client_factory | 在 fastmcp 传输上设置。请参阅 共享连接池。 |
auth(每个连接) | 在 fastmcp.Client 上设置 auth。请参阅 身份认证。 |
headers(每个连接) | 在 fastmcp 传输上设置(StreamableHttpTransport(url, headers=...))。 |
已弃用的传输
MCP 规范 弃用了 HTTP+SSE 传输(协议版本 2024-11-05),转而使用 Streamable HTTP。FastMCP 仍然提供了一个 SSETransport 用于向后兼容,因此 SSE 服务器仍可通过 MCPAdapter(Client(SSETransport(url))) 工作,但更建议将服务器迁移到 Streamable HTTP。WebSocket 没有 FastMCP 传输。
引出(elicitation)
引出从客户端上注册的回调迁移为 LangGraph interrupt,并且现在默认开启。MCPAdapter 会将其构建的每个客户端武装起来以声明该能力,并驱动中断循环;当运行暂停时回答服务器的请求,使用 Command(resume={"responses": {key: answer}}) 恢复。
langchain-mcp-adapters | langchain.mcp |
|---|---|
Callbacks(on_elicitation=...) | 自动进行。MCPAdapter(target) 无需选择加入即可启用引出。若预构建客户端自带引出处理程序,则优先使用它。 |
请参阅 引出(elicitation)。
采样和 roots
langchain.mcp 通过中断来应答 引出(elicitation) 请求,但不包括 sampling(服务器要求客户端运行一次 LLM 补全)或 roots(服务器询问客户端可以访问哪些本地路径)。返回其中任一种的工具调用都会引发 NotImplementedError。
这遵循了协议。现代 MCP 时代是无会话的,没有可供服务器在请求中途回调的实时反向通道,因此推送形式的 sampling 和 roots 仅存在于遗留的握手时代。正因如此,FastMCP 4 从所有时代中移除了 ctx.sample() 和 ctx.list_roots()。如果你需要通过 LangChain 应答服务器的 sampling 或 roots 请求,请提交 issue。
回调
langchain-mcp-adapters 的 Callbacks 对象已移除,但底层的处理程序并没有:FastMCP 直接在其 Client 上接收它们。构建带有你所需处理程序的 fastmcp.Client,并将其传给 MCPAdapter。
Callbacks 字段 | langchain.mcp |
|---|---|
on_elicitation | 作为中断自动处理;无需处理程序。若预构建客户端自带 elicitation_handler,则优先使用它。请参阅 引出(elicitation)。 |
on_progress | Client(transport, progress_handler=...)。 |
on_logging_message | Client(transport, log_handler=...)。 |
python
from fastmcp.client import Client
from langchain.mcp import MCPAdapter
client = Client("https://example.com/mcp", progress_handler=on_progress, log_handler=on_log)
async with MCPAdapter(client) as adapter:
tools = await adapter.list_tools()请参阅 FastMCP 文档中的 回调处理程序。
工具拦截器
langchain-mcp-adapters 的拦截器类型(tool_interceptors、ToolCallInterceptor、MCPToolCallRequest、MCPToolCallResult)已移除。使用 LangChain @wrap_tool_call middleware 在智能体侧拦截工具调用,它会包装 create_agent 运行的每个工具,而不仅是 MCP 工具。MCP 来源信息可在工具元数据的 metadata["mcp"] 下获取,因此拦截器仍可据此进行分支:
python
from collections.abc import Callable
from langchain.agents import create_agent
from langchain.agents.middleware import wrap_tool_call
from langchain.mcp import MCPAdapter
from langchain.messages import ToolMessage
from langchain.tools.tool_node import ToolCallRequest
@wrap_tool_call
def log_mcp_calls(
request: ToolCallRequest,
handler: Callable[[ToolCallRequest], ToolMessage],
) -> ToolMessage:
"""Intercept every tool call, MCP or otherwise, before and after it runs."""
# Inspect or rewrite the request here; MCP provenance is on the tool's
# metadata under `request.tool.metadata["mcp"]`.
print(f"calling {request.tool_call['name']}")
result = handler(request)
print(f"-> {request.tool_call['name']} done")
return result
async def agent_with_interception(target):
async with MCPAdapter(target) as adapter:
tools = await adapter.list_tools()
return create_agent("claude-sonnet-5", tools, middleware=[log_mcp_calls])错误处理
handle_tool_errors 标志已移除。行为现在固定为:报告 isError=True 的 MCP 工具会以带有 status="error" 的 ToolMessage 形式到达模型,并携带服务器的消息,而传输失败会抛出异常。请参阅 工具。
身份认证
身份认证已移至 fastmcp.Client 上。不再在连接配置上设置 auth 和 headers,而是构建一个客户端,将 auth 设置为 bearer token、字面量 "oauth" 或任意 httpx.Auth,然后将该客户端传给 MCPAdapter。同时支持按服务器和按用户进行身份认证。请参阅 身份认证。
工具结果
工具结果处理得到保留并扩展。
langchain-mcp-adapters | langchain.mcp |
|---|---|
MCPToolArtifact(结构化内容) | 保留。 从 langchain.mcp 导出。请参阅 结构化内容。 |
| 多模态内容块 | 保留。 请参阅 多模态内容。 |
| 工具元数据 | 扩展。 归组在工具元数据的 mcp 命名空间下,附带注解和服务器标识。请参阅 工具元数据。 |
convert_mcp_tool_to_langchain_tool | 重命名为 as_langchain_tool,且现在是一个协程:await as_langchain_tool(tool, client)。 |
to_fastmcp(LangChain 工具 → FastMCP 工具) | 尚无 langchain.mcp 对应项。如果你将 LangChain 工具转换为 MCP 工具,请提交 issue —— 我们很想了解该用例。 |
提示词和资源
langchain.mcp 专注于工具,尚未封装 MCP 提示词 或 资源。这些 langchain-mcp-adapters 辅助函数目前没有 langchain.mcp 对应项:
langchain-mcp-adapters | langchain.mcp |
|---|---|
load_mcp_prompt, get_prompt, convert_mcp_prompt_message_to_langchain_message | 尚无封装 |
load_mcp_resources, get_resources, get_mcp_resource, convert_mcp_resource_to_langchain_blob | 尚无封装 |
我们尚未看到足够的需求来优先提供一等封装。如果你有用例,请提交 issue —— 我们真心希望了解它,这有助于我们确定优先级。与此同时,你可以直接通过 FastMCP 客户端读取提示词和资源:client.get_prompt(...) 和 client.read_resource(...)。请参阅 FastMCP 文档中的 读取资源 和 获取提示词。
MCP 协议中已弃用的内容
某些 langchain-mcp-adapters 功能没有替代方案,是因为 MCP 协议本身弃用或移除了它们所依赖的机制,而不是因为 langchain.mcp 选择将其舍弃。langchain.mcp 通过 FastMCP 4 面向现代、无会话的协议时代。
| 机制 | 协议状态 | 对迁移的影响 |
|---|---|---|
| HTTP+SSE 传输 | 因改用 Streamable HTTP 而弃用(协议 2024-11-05) | SSE 仍可通过 FastMCP 的 SSETransport 工作,但更建议将服务器迁移到 Streamable HTTP。WebSocket 没有 FastMCP 传输。 |
| 服务器推送的 sampling 和 roots | 已从现代时代中移除;无会话协议没有实时反向通道。FastMCP 4 从所有时代移除了 ctx.sample() 和 ctx.list_roots() | langchain.mcp 不应答。请参阅 采样和 roots。 |
| 服务器推送的 elicitation | 现代时代以需要输入的轮次取代推送请求 | 通过中断而非回调来应答。请参阅 引出(elicitation)。 |
| JSON-RPC 批处理 | 已移除(协议 2025-06-18) | 不适用;请求会逐个发送。 |