本节用 MultiServerMCPClient 同时连接本地 server 和时间 server,把 MCP 暴露的工具、资源和 prompt 交给 LangChain Agent 使用。
MCP(Model Context Protocol)的核心价值,是把外部系统的能力统一暴露给模型应用。对 LangChain Agent 来说,MCP server 可以提供三类东西:tools、resources 和 prompts。
| 类型 | 在本课中的含义 | Agent 如何使用 |
|---|---|---|
| Tools | 可调用动作,例如查时间、查外部系统 | 作为 create_agent(..., tools=tools) 的工具列表 |
| Resources | 可读取资料,例如 server 提供的文本、文件或配置 | 先读出来,再放入 prompt 或上下文 |
| Prompts | server 维护的提示模板 | 取出后作为 system_prompt |
MCP 不是让模型直接访问任意系统,而是通过 server 明确暴露可用能力。Agent 只看到被注册出来的工具、资源和 prompt。
Notebook 先加载环境变量,再处理 Windows + Jupyter 下启动 stdio 子进程时可能遇到的事件循环和 stderr 问题。
from dotenv import load_dotenv
load_dotenv()
import os
import sys
import asyncio
from langchain.agents import create_agent
from langchain.messages import HumanMessage
from langchain_mcp_adapters.client import MultiServerMCPClient
if sys.platform == "win32":
if not isinstance(asyncio.get_event_loop_policy(), asyncio.WindowsProactorEventLoopPolicy):
asyncio.set_event_loop_policy(asyncio.WindowsProactorEventLoopPolicy())
if "ipykernel" in sys.modules:
sys.stderr = sys.__stderr__stdio 类型的 MCP server 依赖子进程通信。Jupyter 在 Windows 上的事件循环和标准错误流比较特殊,所以 notebook 先做兼容处理。
MultiServerMCPClient 可以同时管理多个 MCP server。本课连接两个 server:一个本地 Python server,另一个通过 uvx 启动的时间 server。
client = MultiServerMCPClient(
{
"local_server": {
"transport": "stdio",
"command": "python",
"args": ["resources/2.1_mcp_server.py"],
},
"time": {
"transport": "stdio",
"command": "uvx",
"args": ["mcp-server-time", "--local-timezone=Australia/Melbourne"],
},
}
)本地脚本暴露课程自定义的 tools、resources 和 prompt。
第三方 MCP server 暴露时间查询工具。
统一拉取能力,并交给 Agent 使用。
连接完成后,client 可以分别读取 MCP server 暴露的工具、资源和 prompt。这里的 prompt 会作为 Agent 的系统提示词。
tools = await client.get_tools()
resources = await client.get_resources("local_server")
prompt = await client.get_prompt("local_server", "prompt")
prompt = prompt[0].contentget_tools() 默认会聚合 client 管理的所有 server 工具;而 resources 和 prompts 通常需要指定 server 名称。
拿到 MCP 工具和 prompt 后,Agent 的创建方式和普通 LangChain tool 几乎一样。区别在于 MCP 工具往往涉及进程或网络 I/O,所以 notebook 使用 await agent.ainvoke(...)。
agent = create_agent(
model=deepseek_model(),
tools=tools,
system_prompt=prompt,
)
question = HumanMessage(content="What time is it?")
response = await agent.ainvoke({"messages": [question]})
print(response["messages"][-1].content)用户问题进入 Agent 后,模型会根据工具描述决定是否调用 MCP tool;MCP server 返回结果后,模型再组织最终自然语言回答。
MCP server 负责定义工具、资源和 prompt。它可以是本地脚本,也可以是远程服务。
MultiServerMCPClient 把多个 server 的能力统一拿到当前程序里。
create_agent 接收 tools 和 system prompt,运行时由模型决定调用哪个工具。
当工具来自外部进程、第三方服务、公司内部系统,或者需要跨语言复用时,MCP 比直接写 Python tool 更容易标准化。