Comment intégrer LangChain avec les serveurs MCP en utilisant langchain-mcp-adapters

Cette librairie enveloppe léger, utilisant les outils MCP dans LangChain. Apprenons à l'utiliser.

Louis Dupont

Louis Dupont

5 June 2025

Comment intégrer LangChain avec les serveurs MCP en utilisant langchain-mcp-adapters

Le protocole Model Context Protocol (MCP) vise à standardiser la façon dont les modèles d'IA interagissent avec les outils et services externes. Il définit une interface commune, permettant à différents modèles et fournisseurs d'outils de communiquer efficacement. Cependant, l'intégration de ces outils conformes à MCP directement dans les frameworks d'IA existants comme LangChain nécessite une adaptation.

C'est là qu'intervient la bibliothèque langchain-mcp-adapters. Elle agit comme un pont crucial, traduisant de manière transparente les outils MCP dans un format que LangChain et son puissant framework d'agent, LangGraph, peuvent comprendre et utiliser. Cette bibliothèque fournit un wrapper léger, permettant aux développeurs de tirer parti de l'écosystème croissant d'outils MCP au sein de leurs applications LangChain.

Les principales fonctionnalités incluent :

Ce tutoriel vous guidera à travers la configuration des serveurs MCP, leur connexion à l'aide de la bibliothèque d'adaptateurs et l'intégration des outils chargés dans un agent LangGraph.

💡
Vous voulez un excellent outil de test d'API qui génère une belle documentation API ?

Vous voulez une plateforme intégrée, tout-en-un, pour que votre équipe de développeurs travaille ensemble avec une productivité maximale ?

Apidog répond à toutes vos demandes et remplace Postman à un prix beaucoup plus abordable !
button

Qu'est-ce qu'un serveur MCP ? Comment ça marche ?

Comprendre quelques concepts de base est essentiel avant de se plonger dans les exemples :

Serveur MCP :

Client MCP (langchain-mcp-adapters) :

Conversion d'outils :

Conversion d'invite :

Installer Langchain-mcp-adapter

Tout d'abord, installez les packages nécessaires :

pip install langchain-mcp-adapters langgraph langchain-openai # Or your preferred LangChain LLM integration

Vous devrez également configurer les clés API pour votre fournisseur de modèle linguistique choisi, généralement en définissant des variables d'environnement :

export OPENAI_API_KEY=<your_openai_api_key>
# or export ANTHROPIC_API_KEY=<...> etc.

Construire un serveur MCP unique rapide avec langchain-mcp-adapters

Construisons un exemple simple : un serveur MCP fournissant des fonctions mathématiques et un agent LangGraph utilisant ces fonctions.

Étape 1 : Créer le serveur MCP (math_server.py)

# math_server.py
from mcp.server.fastmcp import FastMCP

# Initialize the MCP server with a name
mcp = FastMCP("Math")

@mcp.tool()
def add(a: int, b: int) -> int:
    """Add two numbers"""
    print(f"Executing add({a}, {b})") # Server-side log
    return a + b

@mcp.tool()
def multiply(a: int, b: int) -> int:
    """Multiply two numbers"""
    print(f"Executing multiply({a}, {b})") # Server-side log
    return a * b

# Example prompt definition
@mcp.prompt()
def configure_assistant(skills: str) -> list[dict]:
    """Configures the assistant with specified skills."""
    return [
        {
            "role": "assistant", # Corresponds to AIMessage
            "content": f"You are a helpful assistant. You have the following skills: {skills}. Always use only one tool at a time.",
        }
    ]

if __name__ == "__main__":
    # Run the server using stdio transport
    print("Starting Math MCP server via stdio...")
    mcp.run(transport="stdio")

Enregistrez ce code sous le nom math_server.py.

Étape 2 : Créer le client et l'agent (client_app.py)

import asyncio
import os
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI

# --- IMPORTANT: Update this path ---
# Get the absolute path to the math_server.py file
current_dir = os.path.dirname(os.path.abspath(__file__))
math_server_script_path = os.path.join(current_dir, "math_server.py")
# ---

async def main():
    model = ChatOpenAI(model="gpt-4o") # Or your preferred model

    # Configure parameters to run the math_server.py script
    server_params = StdioServerParameters(
        command="python", # The command to execute
        args=[math_server_script_path], # Arguments (the script path)
        # cwd=..., env=... # Optional working dir and environment vars
    )

    print("Connecting to MCP server...")
    # Establish connection using stdio_client context manager
    async with stdio_client(server_params) as (read, write):
        # Create a ClientSession using the read/write streams
        async with ClientSession(read, write) as session:
            print("Initializing session...")
            # Handshake with the server
            await session.initialize()
            print("Session initialized.")

            print("Loading MCP tools...")
            # Fetch MCP tools and convert them to LangChain tools
            tools = await load_mcp_tools(session)
            print(f"Loaded tools: {[tool.name for tool in tools]}")

            # Create a LangGraph ReAct agent using the model and loaded tools
            agent = create_react_agent(model, tools)

            print("Invoking agent...")
            # Run the agent
            inputs = {"messages": [("human", "what's (3 + 5) * 12?")]}
            async for event in agent.astream_events(inputs, version="v1"):
                 print(event) # Stream events for observability

            # Or get final response directly
            # final_response = await agent.ainvoke(inputs)
            # print("Agent response:", final_response['messages'][-1].content)

if __name__ == "__main__":
    asyncio.run(main())

Enregistrez ceci sous le nom client_app.py dans le même répertoire que math_server.py.

Pour exécuter :

Exécutez le script client :

python client_app.py

Le script client démarrera automatiquement math_server.py en tant que sous-processus, s'y connectera, chargera les outils add et multiply et utilisera l'agent LangGraph pour résoudre le problème mathématique en appelant ces outils via le serveur MCP. Vous verrez les journaux du client et du serveur.

Connexion à plusieurs serveurs MCP

Souvent, vous souhaiterez combiner des outils de différents serveurs spécialisés. MultiServerMCPClient rend cela simple.

Étape 1 : Créer un autre serveur (weather_server.py)

Créons un serveur météo qui s'exécute à l'aide du transport SSE.

# weather_server.py
from mcp.server.fastmcp import FastMCP
import uvicorn # Needs: pip install uvicorn

mcp = FastMCP("Weather")

@mcp.tool()
async def get_weather(location: str) -> str:
    """Get weather for location."""
    print(f"Executing get_weather({location})")
    # In a real scenario, this would call a weather API
    return f"It's always sunny in {location}"

if __name__ == "__main__":
    # Run the server using SSE transport (requires an ASGI server like uvicorn)
    # The mcp library implicitly creates a FastAPI app for SSE.
    # By default, it runs on port 8000 at the /sse endpoint.
    print("Starting Weather MCP server via SSE on port 8000...")
    # uvicorn.run(mcp.app, host="0.0.0.0", port=8000) # You can run manually
    mcp.run(transport="sse", host="0.0.0.0", port=8000) # Or use mcp.run convenience

Enregistrez ceci sous le nom weather_server.py.

Étape 2 : Mettre à jour le client pour utiliser MultiServerMCPClient (multi_client_app.py)

import asyncio
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI

# --- IMPORTANT: Update paths ---
current_dir = os.path.dirname(os.path.abspath(__file__))
math_server_script_path = os.path.join(current_dir, "math_server.py")
# Weather server runs separately, connect via URL
# ---

async def main():
    model = ChatOpenAI(model="gpt-4o")

    # Define connections for multiple servers
    server_connections = {
        "math_service": { # Unique name for this connection
            "transport": "stdio",
            "command": "python",
            "args": [math_server_script_path],
            # Add other StdioConnection params if needed (env, cwd, etc.)
        },
        "weather_service": { # Unique name for this connection
            "transport": "sse",
            "url": "http://localhost:8000/sse", # URL where weather_server is running
            # Add other SSEConnection params if needed (headers, timeout, etc.)
        }
    }

    print("Connecting to multiple MCP servers...")
    # Use MultiServerMCPClient context manager
    async with MultiServerMCPClient(server_connections) as client:
        print("Connections established.")

        # Get *all* tools from *all* connected servers
        all_tools = client.get_tools()
        print(f"Loaded tools: {[tool.name for tool in all_tools]}")

        # Create agent with the combined tool list
        agent = create_react_agent(model, all_tools)

        # --- Interact with the agent ---
        print("\nInvoking agent for math query...")
        math_inputs = {"messages": [("human", "what's (3 + 5) * 12?")]}
        math_response = await agent.ainvoke(math_inputs)
        print("Math Response:", math_response['messages'][-1].content)

        print("\nInvoking agent for weather query...")
        weather_inputs = {"messages": [("human", "what is the weather in nyc?")]}
        weather_response = await agent.ainvoke(weather_inputs)
        print("Weather Response:", weather_response['messages'][-1].content)

        # --- Example: Getting a prompt ---
        # print("\nGetting math server prompt...")
        # prompt_messages = await client.get_prompt(
        #     server_name="math_service", # Use the name defined in connections
        #     prompt_name="configure_assistant",
        #     arguments={"skills": "basic arithmetic"}
        # )
        # print("Prompt:", prompt_messages)


if __name__ == "__main__":
    # Start the weather server first in a separate terminal:
    # python weather_server.py
    # Then run this client script:
    asyncio.run(main())

Enregistrez ceci sous le nom multi_client_app.py.

Pour exécuter :

  1. Démarrez le serveur météo dans un terminal : python weather_server.py
  2. Exécutez l'application multi-client dans un autre terminal : python multi_client_app.py

Le MultiServerMCPClient démarrera le sous-processus math_server.py (stdio) et se connectera au weather_server.py en cours d'exécution (sse). Il agrège les outils (add, multiply, get_weather) qui sont ensuite disponibles pour l'agent LangGraph.

Intégration avec le serveur API LangGraph

Vous pouvez déployer un agent LangGraph utilisant des outils MCP en tant que service API persistant en utilisant langgraph deploy. La clé est de gérer correctement le cycle de vie du MultiServerMCPClient dans le contexte de l'application LangGraph.

Créez un fichier graph.py :

# graph.py
from contextlib import asynccontextmanager
import os
from langchain_mcp_adapters.client import MultiServerMCPClient
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI # Or Anthropic, etc.

# --- IMPORTANT: Update paths ---
# Assuming servers are relative to where the LangGraph server runs
math_server_script_path = os.path.abspath("math_server.py")
# ---

# Define connections (ensure paths/URLs are correct for the server environment)
server_connections = {
    "math_service": {
        "transport": "stdio",
        "command": "python",
        "args": [math_server_script_path],
    },
    "weather_service": {
        "transport": "sse",
        "url": "http://localhost:8000/sse", # Weather server must be running independently
    }
}

model = ChatOpenAI(model="gpt-4o")

# Use an async context manager to handle client setup/teardown
@asynccontextmanager
async def lifespan(_app): # LangGraph expects this structure for lifespan management
    async with MultiServerMCPClient(server_connections) as client:
        print("MCP Client initialized within lifespan.")
        # Create the agent *inside* the context where the client is active
        agent = create_react_agent(model, client.get_tools())
        yield {"agent": agent} # Make the agent available

# No need for a separate main graph definition if lifespan yields it

Configurez votre langgraph.json (ou pyproject.toml sous [tool.langgraph]) pour utiliser cette définition de graphique avec le gestionnaire de durée de vie :

// langgraph.json (example)
{
  "dependencies": ["."], // Or specify required packages
  "graphs": {
    "my_mcp_agent": {
      "entrypoint": "graph:agent", // Refers to the key yielded by lifespan
      "lifespan": "graph:lifespan"
    }
  }
}

Maintenant, lorsque vous exécutez langgraph up, la fonction lifespan s'exécutera, en démarrant le MultiServerMCPClient (et le serveur math stdio). L'agent créé dans ce contexte sera servi par LangGraph. N'oubliez pas que le serveur météo SSE doit toujours être exécuté séparément.

Transports de serveur (stdio vs. SSE)

stdio :

sse (Server-Sent Events) :

Choisissez le transport en fonction de vos besoins de déploiement.

Configuration client avancée pour la configuration langchain-mcp-adapters

Les dictionnaires StdioConnection et SSEConnection dans MultiServerMCPClient acceptent des paramètres optionnels supplémentaires pour un contrôle plus fin :

Reportez-vous à la définition MultiServerMCPClient dans langchain_mcp_adapters/client.py pour plus de détails.

Conclusion (100 mots)

La bibliothèque langchain-mcp-adapters comble efficacement le fossé entre le Model Context Protocol standardisé et l'écosystème flexible LangChain. En fournissant le MultiServerMCPClient et la conversion automatique des outils, elle permet aux développeurs d'incorporer facilement divers outils conformes à MCP dans leurs agents LangChain et leurs applications LangGraph.

Le flux de travail de base implique :

  1. Définir des outils (et éventuellement des invites) dans un serveur MCP en utilisant @mcp.tool().
  2. Configurer le MultiServerMCPClient avec les détails de connexion (stdio ou sse) pour chaque serveur.
  3. Utiliser le gestionnaire de contexte client (async with ...) pour se connecter et récupérer les outils via client.get_tools().
  4. Passer les outils compatibles LangChain récupérés à votre agent (create_react_agent ou agents personnalisés).

Cela permet de créer des applications d'IA puissantes et modulaires qui tirent parti d'outils externes spécialisés via un protocole standardisé. Explorez les exemples et les tests dans le référentiel pour plus d'informations.

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API