LangChainLangChain 1.4 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
46 small wins to finish your pathNext lesson →

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

python
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 path

Writing the tool server

Write the tool server. This is the order lookup from the tools lesson, served over MCP by FastMCP.

python
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.

python
if __name__ == "__main__":
    mcp.run()      # talk to the client over standard input and output

Connecting with a Path

Connect with a Path, list the tools, and give them to the agent.

python
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.

Example
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

Example
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 codeA tool over MCP
Where it livesIn your programIn a separate server program
Who can use itThis agentAny MCP-speaking agent
Asked for withThe functionA 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.
Watch out. Passing the server as a plain string makes MCPAdapter treat it as a URL, so a local file raises a URL error. Wrap a local path in Path(...).
Try it yourself
  • Add a second @mcp.tool to the server and print the tool names again.
  • Print tools[0].description and tools[0].args.
  • Ask about B22 through the MCP tool.

Slow is fine. Stopping is the only problem.