MCPAdapter: tools from another program
MCP is a standard way for one program to offer tools to any agent, and MCPAdapter is the object that connects to an MCP server, lists its tools, and hands them to create_agent as LangChain tools.
Last updated: 27 Sep, 2026 · LangChain 1.4
The Model Context Protocol lets one team write a tool server and any agent framework use it. MCP support is an extra of the langchain package, built on the FastMCP library, and marked beta: importing it prints a warning that the API may change.
pip install "langchain[mcp]==1.4.2"Loading tools with MCPAdapter
from pathlib import Path
from langchain.mcp import MCPAdapter
async with MCPAdapter(Path("server.py")) as adapter: # a local server over stdio
tools = await adapter.list_tools() # -> LangChain tools
# a bare string would be read as a URL, not a file pathWriting the tool server
Write the tool server. This is the order lookup from the tools lesson, served over MCP by FastMCP.
from fastmcp import FastMCP
mcp = FastMCP("shop")
ORDERS = {"A17": "shipped on 3 March", "C40": "waiting for stock"}
@mcp.tool
def lookup_order(order_id: str) -> str:
"""Look up an order's shipping status by its id, such as A17."""
status = ORDERS.get(order_id)
return f"{order_id} {status}." if status else f"{order_id} is not an order we have."Running the server over stdio
Run as a script, it talks to its client over standard input and output.
if __name__ == "__main__":
mcp.run() # talk to the client over standard input and outputConnecting with a Path
Connect with a Path, list the tools, and give them to the agent.
from pathlib import Path
from langchain.mcp import MCPAdapter
# a Path asks for a local server explicitly; a bare string would be read as a URL
async with MCPAdapter(Path("shop_server.py")) as adapter:
tools = await adapter.list_tools() # the server's tools as LangChain tools
print([tool.name for tool in tools])The URL rule
Pass the server as a plain string and it is read as a URL, so the import raises before anything runs. This is the error to see before the fix.
from langchain.mcp import MCPAdapter
MCPAdapter("shop_server.py")A plain string is always read as a URL, so that a string can never start a program by accident. A local server has to be asked for explicitly, with a Path.
Running the agent on the server's tools
import asyncio
from pathlib import Path
from langchain.agents import create_agent
from langchain.mcp import MCPAdapter
from shop_model import ShopModel
async def main():
async with MCPAdapter(Path("shop_server.py")) as adapter:
tools = await adapter.list_tools()
print([tool.name for tool in tools])
agent = create_agent(ShopModel(), tools)
result = await agent.ainvoke({"messages": [{"role": "user", "content": "Where is A17?"}]})
print(result["messages"][-1].text)
asyncio.run(main())MCPAdapter started the server, and list_tools turned its tool into a LangChain tool with the same name and description. The agent is the same one as lesson 7. It ran after the async with block closed, because each tool call opens its own connection to the server.
How the adapter loads the tools
- A bare string is read as a URL, so passing a filename raises before anything runs; a local server has to be asked for with a Path.
- MCPAdapter started the server and list_tools turned its tool into a LangChain tool with the same name and description.
- The agent is the same one as the create_agent lesson; the tool reaching it over MCP changes nothing about how it calls it.
- Each tool call opens its own connection, so the run finished after the async with block closed.
A local tool vs an MCP tool
| A @tool in your code | A tool over MCP | |
|---|---|---|
| Where it lives | In your program | In a separate server program |
| Who can use it | This agent | Any MCP-speaking agent |
| Asked for with | The function | A Path or URL to the server |
When to reach for MCP tools
- Using a tool server another team wrote, from any agent framework.
- Sharing one set of tools across several agents without copying the code.
Path(...).Related
- Previous: Retrieval as a tool
- Next: Subagents as tools
- Reference: MCP
- Add a second
@mcp.toolto the server and print the tool names again. - Print
tools[0].descriptionandtools[0].args. - Ask about B22 through the MCP tool.
Slow is fine. Stopping is the only problem.