Cómo integrar LangChain con servidores MCP usando langchain-mcp-adapters

Esta librería ofrece una interfaz ligera para usar herramientas MCP en LangChain. ¡Aprendamos cómo!

Daniel Costa

Daniel Costa

15 April 2025

Cómo integrar LangChain con servidores MCP usando langchain-mcp-adapters

El Protocolo de Contexto del Modelo (MCP) tiene como objetivo estandarizar cómo los modelos de IA interactúan con herramientas y servicios externos. Define una interfaz común, permitiendo que diferentes modelos y proveedores de herramientas se comuniquen eficazmente. Sin embargo, la integración de estas herramientas compatibles con MCP directamente en los frameworks de IA existentes como LangChain requiere adaptación.

Aquí es donde entra en juego la biblioteca langchain-mcp-adapters. Actúa como un puente crucial, traduciendo sin problemas las herramientas MCP a un formato que LangChain y su potente framework de agentes, LangGraph, puedan entender y utilizar. Esta biblioteca proporciona un wrapper ligero, permitiendo a los desarrolladores aprovechar el creciente ecosistema de herramientas MCP dentro de sus aplicaciones LangChain.

Las características clave incluyen:

Este tutorial te guiará a través de la configuración de servidores MCP, la conexión a ellos utilizando la biblioteca adaptadora y la integración de las herramientas cargadas en un agente LangGraph.

💡
¿Quieres una gran herramienta de pruebas de API que genere una hermosa documentación de API?

¿Quieres una plataforma integrada, todo en uno, para que tu equipo de desarrolladores trabaje en conjunto con máxima productividad?

¡Apidog ofrece todas tus demandas y reemplaza a Postman a un precio mucho más asequible!
button

¿Qué es un Servidor MCP? ¿Cómo Funciona?

Comprender algunos conceptos básicos es esencial antes de sumergirse en los ejemplos:

Servidor MCP:

Cliente MCP (langchain-mcp-adapters):

Conversión de Herramientas:

Conversión de Prompts:

Instalar Langchain-mcp-adapter

Primero, instala los paquetes necesarios:

pip install langchain-mcp-adapters langgraph langchain-openai # O tu integración LLM de LangChain preferida

También necesitarás configurar las claves de API para tu proveedor de modelos de lenguaje elegido, normalmente estableciendo variables de entorno:

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

Construye un Servidor MCP Único Rápido con langchain-mcp-adapters

Construyamos un ejemplo simple: un servidor MCP que proporciona funciones matemáticas y un agente LangGraph que utiliza esas funciones.

Paso 1: Crea el Servidor MCP (math_server.py)

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

# Inicializa el servidor MCP con un nombre
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

# Ejemplo de definición de prompt
@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__":
    # Ejecuta el servidor utilizando el transporte stdio
    print("Starting Math MCP server via stdio...")
    mcp.run(transport="stdio")

Guarda este código como math_server.py.

Paso 2: Crea el Cliente y el Agente (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") # O tu modelo preferido

    # Configura los parámetros para ejecutar el script math_server.py
    server_params = StdioServerParameters(
        command="python", # El comando a ejecutar
        args=[math_server_script_path], # Argumentos (la ruta del script)
        # cwd=..., env=... # Directorio de trabajo y variables de entorno opcionales
    )

    print("Connecting to MCP server...")
    # Establece la conexión utilizando el administrador de contexto stdio_client
    async with stdio_client(server_params) as (read, write):
        # Crea una ClientSession utilizando los flujos de lectura/escritura
        async with ClientSession(read, write) as session:
            print("Initializing session...")
            # Handshake con el servidor
            await session.initialize()
            print("Session initialized.")

            print("Loading MCP tools...")
            # Obtén las herramientas MCP y conviértelas en herramientas LangChain
            tools = await load_mcp_tools(session)
            print(f"Loaded tools: {[tool.name for tool in tools]}")

            # Crea un agente LangGraph ReAct utilizando el modelo y las herramientas cargadas
            agent = create_react_agent(model, tools)

            print("Invoking agent...")
            # Ejecuta el agente
            inputs = {"messages": [("human", "what's (3 + 5) * 12?")]}
            async for event in agent.astream_events(inputs, version="v1"):
                 print(event) # Flujo de eventos para la observabilidad

            # O obtén la respuesta final directamente
            # final_response = await agent.ainvoke(inputs)
            # print("Agent response:", final_response['messages'][-1].content)

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

Guarda esto como client_app.py en el mismo directorio que math_server.py.

Para Ejecutar:

Ejecuta el script del cliente:

python client_app.py

El script del cliente iniciará automáticamente math_server.py como un subproceso, se conectará a él, cargará las herramientas add y multiply, y utilizará el agente LangGraph para resolver el problema matemático llamando a esas herramientas a través del servidor MCP. Verás registros tanto del cliente como del servidor.

Conectando a Múltiples Servidores MCP

A menudo, querrás combinar herramientas de diferentes servidores especializados. MultiServerMCPClient hace que esto sea sencillo.

Paso 1: Crea Otro Servidor (weather_server.py)

Creemos un servidor meteorológico que se ejecute utilizando el transporte 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__":
    # Ejecuta el servidor utilizando el transporte SSE (requiere un servidor ASGI como uvicorn)
    # La biblioteca mcp crea implícitamente una aplicación FastAPI para SSE.
    # Por defecto, se ejecuta en el puerto 8000 en el endpoint /sse.
    print("Starting Weather MCP server via SSE on port 8000...")
    # uvicorn.run(mcp.app, host="0.0.0.0", port=8000) # Puedes ejecutar manualmente
    mcp.run(transport="sse", host="0.0.0.0", port=8000) # O utiliza la conveniencia de mcp.run

Guarda esto como weather_server.py.

Paso 2: Actualiza el Cliente para Usar 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 conexiones para múltiples servidores
    server_connections = {
        "math_service": { # Nombre único para esta conexión
            "transport": "stdio",
            "command": "python",
            "args": [math_server_script_path],
            # Añade otros parámetros de StdioConnection si es necesario (env, cwd, etc.)
        },
        "weather_service": { # Nombre único para esta conexión
            "transport": "sse",
            "url": "http://localhost:8000/sse", # URL donde se está ejecutando weather_server
            # Añade otros parámetros de SSEConnection si es necesario (headers, timeout, etc.)
        }
    }

    print("Connecting to multiple MCP servers...")
    # Utiliza el administrador de contexto MultiServerMCPClient
    async with MultiServerMCPClient(server_connections) as client:
        print("Connections established.")

        # Obtén *todas* las herramientas de *todos* los servidores conectados
        all_tools = client.get_tools()
        print(f"Loaded tools: {[tool.name for tool in all_tools]}")

        # Crea un agente con la lista de herramientas combinada
        agent = create_react_agent(model, all_tools)

        # --- Interactúa con el agente ---
        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)

        # --- Ejemplo: Obtener un prompt ---
        # print("\nGetting math server prompt...")
        # prompt_messages = await client.get_prompt(
        #     server_name="math_service", # Utiliza el nombre definido en las conexiones
        #     prompt_name="configure_assistant",
        #     arguments={"skills": "basic arithmetic"}
        # )
        # print("Prompt:", prompt_messages)


if __name__ == "__main__":
    # Inicia el servidor meteorológico primero en una terminal separada:
    # python weather_server.py
    # Luego ejecuta este script del cliente:
    asyncio.run(main())

Guarda esto como multi_client_app.py.

Para Ejecutar:

  1. Inicia el servidor meteorológico en una terminal: python weather_server.py
  2. Ejecuta la aplicación multi-cliente en otra terminal: python multi_client_app.py

El MultiServerMCPClient iniciará el subproceso math_server.py (stdio) y se conectará al weather_server.py en ejecución (sse). Agrega herramientas (add, multiply, get_weather) que luego están disponibles para el agente LangGraph.

Integración con el Servidor de API de LangGraph

Puedes implementar un agente LangGraph utilizando herramientas MCP como un servicio de API persistente utilizando langgraph deploy. La clave es gestionar el ciclo de vida de MultiServerMCPClient correctamente dentro del contexto de la aplicación LangGraph.

Crea un archivo 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

Configura tu langgraph.json (o pyproject.toml bajo [tool.langgraph]) para usar esta definición de gráfico con el administrador de ciclo de vida:

// langgraph.json (ejemplo)
{
  "dependencies": ["."], // O especifica los paquetes requeridos
  "graphs": {
    "my_mcp_agent": {
      "entrypoint": "graph:agent", // Se refiere a la clave producida por el ciclo de vida
      "lifespan": "graph:lifespan"
    }
  }
}

Ahora, cuando ejecutes langgraph up, la función lifespan se ejecutará, iniciando el MultiServerMCPClient (y el servidor matemático stdio). El agente creado dentro de este contexto será servido por LangGraph. Recuerda que el servidor meteorológico SSE aún debe ejecutarse por separado.

Transportes del Servidor (stdio vs. SSE)

stdio:

sse (Eventos Enviados por el Servidor):

Elige el transporte en función de tus necesidades de implementación.

Configuración Avanzada del Cliente para la Configuración de langchain-mcp-adapters

Los diccionarios StdioConnection y SSEConnection dentro de MultiServerMCPClient aceptan parámetros opcionales adicionales para un control más preciso:

Consulta la definición de MultiServerMCPClient en langchain_mcp_adapters/client.py para obtener más detalles.

Conclusión (100 palabras)

La biblioteca langchain-mcp-adapters cierra eficazmente la brecha entre el Protocolo de Contexto del Modelo estandarizado y el ecosistema flexible de LangChain. Al proporcionar el MultiServerMCPClient y la conversión automática de herramientas, permite a los desarrolladores incorporar fácilmente diversas herramientas compatibles con MCP en sus agentes LangChain y aplicaciones LangGraph.

El flujo de trabajo principal implica:

  1. Definir herramientas (y opcionalmente prompts) en un servidor MCP utilizando @mcp.tool().
  2. Configurar el MultiServerMCPClient con detalles de conexión (stdio o sse) para cada servidor.
  3. Utilizar el administrador de contexto del cliente (async with ...) para conectarse y obtener herramientas a través de client.get_tools().
  4. Pasar las herramientas compatibles con LangChain recuperadas a tu agente (create_react_agent o agentes personalizados).

Esto permite construir aplicaciones de IA potentes y modulares que aprovechan herramientas externas especializadas a través de un protocolo estandarizado. Explora los ejemplos y las pruebas dentro del repositorio para obtener más información.

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs