This lesson uses MultiServerMCPClient to connect to a local server and a time server at the same time, then gives the tools, resources and prompt exposed by MCP to a LangChain Agent.
The core value of MCP (Model Context Protocol) is to expose external system capabilities to model applications in a consistent way. For a LangChain Agent, an MCP server can provide three kinds of things:tools、resources and prompts。
| Type | Meaning in this lesson | How the Agent uses it |
|---|---|---|
| Tools | Callable actions, such as checking the time or querying an external system | As create_agent(..., tools=tools) tool list |
| Resources | Readable materials, such as text, files or configuration provided by the server | Read them first, then place them into the prompt or context |
| Prompts | Prompt templates maintained by the server | Use after fetching as system_prompt |
MCP does not let the model access arbitrary systems directly. The server explicitly exposes the available capabilities, and the Agent only sees the registered tools, resources and prompts.
The notebook first loads environment variables, then handles the event-loop and stderr issues that can appear when starting stdio subprocesses under Windows + Jupyter.
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 servers of this type rely on subprocess communication. Jupyter on Windows has unusual event-loop and stderr behavior, so the notebook handles compatibility first.
MultiServerMCPClient can manage multiple MCP servers at the same time. This lesson connects to two servers: a local Python server and another time server started through uvx .
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"],
},
}
)The local script exposes course-specific tools, resources and prompt.
The third-party MCP server exposes time-query tools.
Fetch the capabilities together and give them to the Agent.
After connecting, the client can read the tools, resources and prompt exposed by the MCP server. The prompt here becomes the Agent system prompt.
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() By default it aggregates tools from all servers managed by the client; resources and prompts usually require a server name.
After obtaining the MCP tools and prompt, creating the Agent is almost the same as using ordinary LangChain tools. The difference is that MCP tools often involve process or network I/O, so the notebook uses 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)After the user question enters the Agent, the model decides whether to call an MCP tool based on tool descriptions. After the MCP server returns a result, the model composes the final natural-language answer.
The MCP server defines tools, resources and prompt. It can be a local script or a remote service.
MultiServerMCPClient Bring the capabilities from multiple servers into the current program.
create_agent It receives tools and a system prompt, and at runtime the model decides which tool to call.
When tools come from external processes, third-party services, internal company systems, or need cross-language reuse, MCP is easier to standardize than writing Python tools directly.