Inicio / Artículos

MCP para agentes de LangGraph, nivel por nivel: servidores, transportes y el puente adaptador

MCP para agentes de LangGraph, nivel por nivel: roles de host, cliente y servidor, un servidor FastMCP, transportes stdio vs HTTP, langchain-mcp-adapters y problemas comunes.

Editor: REACTAPP.TOP17 min de lectura3867 palabras

Fuentes: MCP for LangGraph Developers: From Basics to Production

Los requisitos previos son sencillos: familiaridad con la estructura de un proyecto LangGraph y con la idea de una función decorada con @tool. El Model Context Protocol es una nueva infraestructura y no una nueva forma de pensar en grafos, por lo que la explicación comienza desde cero sobre el MCP en sí y vuelve a mencionar a LangGraph una vez que el concepto está bien establecido.

El problema de escalabilidad con herramientas simples

Una herramienta en LangGraph suele comenzar de esta manera:

@tool
def search_web(query: str) -> str:
    """Search the web for current information."""
    return f"Search results for: {query}"

Eso está bien hasta que es necesario escalarlo. Supongamos que cinco agentes en cinco proyectos necesitan todos una herramienta de “búsqueda en la base de datos de la empresa”. Con el patrón anterior, la misma herramienta se escribe cinco veces, en cinco bases de código, quizás en cinco lenguajes diferentes. Cualquier cambio en el esquema implica cinco ediciones. Compartirla con un colega que desarrolla un tipo distinto de aplicación de IA, quizás ni siquiera basada en LangGraph, falla por completo, porque esa función @tool pertenece al entorno de Python de LangChain.

El nombre de esta dificultad es el problema de integración N×M. N herramientas (bases de datos, APIs, sistemas de archivos) deben conectarse a M aplicaciones de IA (un agente de LangGraph, un agente personalizado de un colega, Claude Desktop, un asistente de IDE). Sin un estándar compartido, se generan integraciones personalizadas N×M.

El Model Context Protocol (MCP) lo aborda como un estándar abierto y universal para conectar aplicaciones de IA con herramientas y datos. Una herramienta desarrollada una vez como servidor MCP puede ser utilizada por cualquier aplicación compatible con MCP, ya sea un agente LangGraph, Claude Desktop, Cursor o un agente personalizado, sin necesidad de código de integración personalizado. La comparación habitual es con un puerto USB-C: un estándar de conector único, con cualquier dispositivo compatible en cada extremo.

El camino desde “¿qué es MCP?” hasta un servidor de nivel profesional conectado a un agente LangGraph real pasa por cinco niveles, cada uno de los cuales añade una idea adicional.

Nivel 1: qué es MCP

Comience con una imagen antes de cualquier código. Un conserje de hotel no sabe personalmente cómo reservar en un restaurante, llamar a un taxi o comprar boletos de teatro. El conserje mantiene una lista de servicios locales de confianza, cada uno especializado en algo. Cuando un huésped desea hacer una reserva para la cena, el conserje utiliza una línea dedicada al servicio de reservas, realiza la solicitud en un formato que ambas partes entienden y transmite la respuesta de vuelta.

MCP es esa línea estándar y ese formato de solicitud estándar. La aplicación de IA actúa como el conserje. Un servidor MCP es un servicio especializado como un sistema de reservas de restaurantes, una empresa de taxis o una taquilla. MCP en sí mismo es el lenguaje y esquema de conexión común, por lo que cualquier conserje puede comunicarse con cualquier servicio sin necesidad de aprender cómo funciona cada uno de sus sistemas internos.

Las tres funciones

Cada sistema MCP cuenta exactamente con tres participantes, y todo lo demás se basa en ellos.

  • Anfitrión. La aplicación de IA que utiliza realmente el usuario final: aquí un agente de LangGraph, en otros casos Claude Desktop, Cursor o VS Code con un copiloto. Es el que gestiona la conversación, decide cuándo se necesita una herramienta y muestra los resultados.
  • Cliente. Se encuentra dentro del anfitrión, y cada cliente mantiene una conexión uno-a-uno dedicada con exactamente un servidor. Un anfitrión conectado a tres servidores ejecuta internamente tres clientes. Esta relación uno-a-uno constituye una barrera de seguridad intencionada, de modo que un cliente del servidor de sistema de archivos no pueda filtrar accidentalmente datos al servidor de base de datos.
  • Servidor. Un programa pequeño y especializado que expone capacidades específicas. Puede encapsular una base de datos, un sistema de archivos, una API de búsqueda web o un CRM interno. Cabe destacar que no sabe ni le importa qué host lo llama, por lo que el mismo servidor puede servir a un agente de LangGraph hoy y a otra aplicación mañana sin necesidad de cambios.
  • El formato de comunicación: JSON-RPC 2.0

    Los mensajes entre el cliente y el servidor utilizan JSON-RPC 2.0, un formato simple y ampliamente adoptado que cuenta con tres tipos de mensajes.

    Una solicitud pide que se realice alguna acción e incluye un id único para poder asociarla a la respuesta correspondiente:

    {"jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": {"name": "search_db", "arguments": {"query": "Q3 revenue"}}}
    

    Una respuesta responde a una solicitud. Contiene ya sea un resultado en caso de éxito o un error en caso de fracaso, con el mismo id que la solicitud:

    {"jsonrpc": "2.0", "id": 1, "result": {"content": [{"type": "text", "text": "Q3 revenue was $4.2M"}]}}
    

    Una notificación es un mensaje unidireccional que no espera respuesta, por ejemplo, para anunciar que la lista de herramientas disponibles ha cambiado.

    El JSON-RPC en su forma bruta rara vez se escribe a mano, ya que los SDKs se encargan de ello. Sin embargo, conocer su estructura básica ayuda a comprender mejor lo que sigue, al igual que conocer HTTP hace que una persona sea un mejor desarrollador REST incluso si nunca escribe HTTP en su forma bruta.

    Nivel 2: las tres primitivas

    Un servidor ofrece sus capacidades a través de exactamente tres tipos de primitivas, y casi toda decisión de diseño al crear uno implica elegir entre ellas.

    Herramientas son acciones que el modelo puede realizar. Una herramienta es una función que el LLM puede decidir llamar mientras razona, al igual que una función decorada en LangGraph tradicional. La diferencia radica en dónde se encuentra: dentro de un servidor MCP y no en el códigobase de LangGraph, siendo descubiertas y llamadas a través del protocolo. Se recurre a una herramienta cada vez que es necesario realizar algo: un cálculo, una consulta a una base de datos, un correo electrónico o una edición de archivo.

    Recursos proporcionan contexto de solo lectura. La aplicación puede obtener un recurso para entregar al modelo material de referencia, sin que el modelo tenga que decidir llamarlo como lo haría con una herramienta. Los recursos se identifican mediante URI, de forma similar a como una página web se identifica mediante URL. Úsalos para material de solo lectura como archivos de configuración, documentos o listas de fuentes de datos que el modelo pueda querer conocer antes de decidir qué buscar.

    Prompts son plantillas reutilizables. Un prompt es una estructura ya escrita que inicia un flujo de trabajo específico para un usuario o el anfitrión. A diferencia de las herramientas, los prompts suelen ser invocados por el usuario y no por el modelo, por lo que se asemejan a comandos con barra diagonal. Son adecuados para tareas comunes y repetibles como “resumir este documento” o “revisar este código en busca de problemas de seguridad”, donde instrucciones consistentes y bien diseñadas son mejores que dejar que el usuario elija las palabras.

    Cuando no esté seguro de cuál usar, pregúntese si esa acción modifica algo o solo proporciona información. Si crea, actualiza, elimina, envía o ejecuta, se trata de una herramienta. Si se trata de datos de solo lectura que el modelo pueda necesitar como contexto, es un recurso. Si es una plantilla de instrucciones que el usuario activa explícitamente, es un prompt.

    Nivel 3: un primer servidor con FastMCP

    FastMCP es el framework de Python dominante para crear servidores MCP. Convierte la compleja estructura del protocolo (manejo de solicitudes, generación de esquemas, ciclo de vida) en unos pocos decoradores, siguiendo el mismo enfoque que @tool para las funciones de LangChain. Instalación:

    pip install fastmcp
    

    Un servidor completo con una sola herramienta cabe en un archivo breve:

    # ── math_server.py ───────────────────────────────────────────
    from fastmcp import FastMCP
    
    # Create the server - this object is the container for everything below
    mcp = FastMCP(name="Math Server")
    @mcp.tool
    def add(a: int, b: int) -> int:
        """Add two numbers together."""
        return a + b
    @mcp.tool
    def multiply(a: int, b: int) -> int:
        """Multiply two numbers together."""
        return a * b
    if __name__ == "__main__":
        mcp.run()  # Defaults to stdio transport
    

    Ese es un servidor MCP válido y funcional. FastMCP lee las indicaciones de tipo de la función para generar el esquema de entrada y lee la documentación para crear la descripción que ve el LLM. Se aplica la misma regla que para las herramientas ordinarias, solo que con consecuencias más graves: una documentación vaga hace que el modelo no sepa cuándo llamar a la herramienta, y ahora esa vaguedad afecta a todas las aplicaciones que se conectan, no solo a un agente.

    Para agregar un recurso se necesita un decorador con un URI a elección:

    # ── Adding to math_server.py ─────────────────────────────────
    
    @mcp.resource("config://server-info")
    def server_info() -> dict:
        """Provides metadata about this server's capabilities."""
        return {"version": "1.0", "operations": ["add", "multiply"]}
    

    Cuando un cliente solicita config://server-info, FastMCP llama a la función y devuelve el resultado. Solo se ejecuta a petición, lo que constituye una evaluación perezosa, por lo que no se calcula nada que el modelo nunca utilice.

    A veces un recurso debería depender de un argumento, como un registro específico y no de un bloque fijo de configuración:

    @mcp.resource("history://{operation_id}")
    def get_calculation(operation_id: str) -> dict:
        """Retrieve a past calculation by its ID."""
        # In a real server, this would look up a database record
        return {"id": operation_id, "result": "..."}
    

    El marcador de posición {operation_id} en la URI convierte esto en una plantilla de recurso. Una solicitud a history://abc123 hace que FastMCP extraiga abc123 y lo pase automáticamente a la función.

    Una instrucción se define de la misma manera:

    @mcp.prompt
    def explain_calculation(operation: str, result: str) -> str:
        """Generate a request to explain a calculation in plain English."""
        return f"Explain how the operation '{operation}' produced the result '{result}', in simple terms a beginner could follow."
    

    Para ejecutar el servidor:

    python math_server.py
    

    Antes de conectar una aplicación de IA real, verifíquela con el MCP Inspector, una herramienta de depuración basada en navegador que viene incluida en el ecosistema. Esta lista las herramientas, las llama manualmente e inspecciona los recursos sin la participación de un LLM:

    fastmcp dev math_server.py
    

    Eso abre una interfaz web local, generalmente en http://127.0.0.1:6274, para navegar por las herramientas, ingresar argumentos de prueba y observar los mensajes JSON-RPC que se envían de un lado a otro. Pruebe aquí primero. Es mucho más difícil depurar una herramienta defectuosa a través del comportamiento de llamada a herramientas de un LLM que directamente en el Inspector.

    Nivel 4: transportes

    Hasta ahora el servidor funcionó con el transporte predeterminado. La elección es importante porque determina cómo se conectará un agente de LangGraph.

    Considere el transporte como el cable físico y JSON-RPC como el lenguaje que se transmite a través de él. El inglés funciona tanto por teléfono como por radio: un mismo lenguaje, dos medios de transmisión. Los servidores MCP utilizan siempre JSON-RPC 2.0, independientemente del transporte, pero los bytes se transmiten de manera diferente.

    stdio, para herramientas locales

    Es el valor predeterminado, y es lo que hace mcp.run() cuando se llama sin argumentos:

    if __name__ == "__main__":
        mcp.run()  # stdio is the default
    

    Con stdio (entrada y salida estándar), el host inicia el servidor como un subproceso y se comunica con él escribiendo en su stdin y leyendo su stdout. No se necesita red: se trata de una comunicación de proceso a proceso dentro de la misma máquina. Es adecuado para servidores que ejecutan junto al host, como herramientas de sistema de archivos, ejecutores de scripts locales o utilidades personales, y representa la configuración más simple y la más común para el desarrollo.

    Hay una restricción muy importante. Bajo stdio, el stdout del servidor está reservado exclusivamente para mensajes de protocolo, por lo que una línea de depuración con print() accidental corrompe el flujo de datos. El registro de información debe realizarse en stderr.

    HTTP flujo, para herramientas remotas

    Para un servidor en red, se debe especificar explícitamente el transporte:

    if __name__ == "__main__":
        mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)
    

    Aquí el servidor funciona como un servicio web independiente. Los clientes se conectan a través de la red mediante solicitudes HTTP POST, con eventos enviados por el servidor de forma opcional para transmitir las respuestas en tiempo real. Eso hace que el servidor sea verdaderamente remoto: puede estar en otra máquina, en la nube o detrás de un balanceador de carga, y servir varias aplicaciones al mismo tiempo. Úselo cuando sea necesario compartir un servidor entre un equipo, desplegarlo de forma centralizada o acceder a él desde máquinas distintas, incluyendo un agente LangGraph que funciona en un servidor y se comunica con un servidor MCP de acceso a bases de datos en otro lugar.

    La regla general: stdio para herramientas locales, con un único usuario y una configuración sencilla, típica del desarrollo y uso personal; Streamable HTTP para herramientas compartidas, con muchos usuarios o aplicaciones, despliegues en producción y necesidades de autenticación. Esta es exactamente la opción que se debe declarar para cada servidor en la configuración de LangGraph a continuación.

    Nivel 5: conexión a LangGraph

    El puente es un paquete llamado langchain-mcp-adapters, mantenido por el equipo de LangChain para hacer que las herramientas MCP sean utilizables dentro de los agentes de LangGraph. Hace por MCP lo que el decorador @tool hacía con las funciones normales: convierte una herramienta MCP externa en un objeto BaseTool que se integra directamente en un ToolNode de LangGraph sin necesidad de tratamientos especiales en el grafo. Después de la conversión, el agente ni sabe ni le importa si una herramienta proviene de un servidor MCP o fue desarrollada localmente.

    Instálalo con:

    pip install langchain-mcp-adapters langgraph "langchain[openai]"
    

    El objeto central es MultiServerMCPClient, el cual puede conectarse a varios servidores MCP al mismo tiempo y combinar transportes libremente:

    # ── MODULE 1 (extended): MCP CLIENT CONFIGURATION ───────────
    from langchain_mcp_adapters.client import MultiServerMCPClient
    
    client = MultiServerMCPClient({
        # A local server, launched as a subprocess via stdio
        "math": {
            "command": "python",
            "args": ["/absolute/path/to/math_server.py"],
            "transport": "stdio",
        },
        # A remote server, already running, connected over HTTP
        "company_data": {
            "url": "http://localhost:8000/mcp",
            "transport": "http",
        },
    })
    

    Cada entrada del diccionario corresponde a un servidor. La clave ("math" o "company_data") es solo una etiqueta que permite organizar internamente las herramientas de diferentes servidores. La entrada refleja la decisión de transporte: los servidores stdio reciben un command y args, mientras que los servidores HTTP reciben una url.

    La carga de las herramientas requiere una sola llamada:

    # This single call discovers every tool, on every configured server,
    # and converts each one into a LangChain-compatible BaseTool
    tools = await client.get_tools()
    
    print([t.name for t in tools])
    # ['add', 'multiply', 'search_company_db', ...]
    

    Esa es toda la integración. client.get_tools() envía la solicitud MCP tools/list a cada servidor configurado, toma los esquemas devueltos y los envuelve en un objeto de herramienta que, desde la vista del grafo, es indistinguible de una función @tool escrita a mano.

    El resto de la configuración es similar a la de cualquier agente LangGraph. MCP cambia la fuente de las herramientas pero no modifica la forma en que se construye el grafo. Un plantilla completa:

    # ============================================================
    # LANGGRAPH + MCP AGENT — COMPLETE TEMPLATE
    # Extends: Part 1 (core structure)
    # ============================================================
    
    # ── MODULE 1: IMPORTS & CONFIGURATION ───────────────────────
    import asyncio
    from langchain_mcp_adapters.client import MultiServerMCPClient
    from langchain.chat_models import init_chat_model
    from langchain_core.messages import HumanMessage
    from langgraph.graph import StateGraph, MessagesState, START, END
    from langgraph.prebuilt import ToolNode, tools_condition
    from langgraph.checkpoint.memory import MemorySaver
    llm = init_chat_model("openai:gpt-4o")
    client = MultiServerMCPClient({
        "math": {
            "command": "python",
            "args": ["./math_server.py"],
            "transport": "stdio",
        },
        "company_data": {
            "url": "http://localhost:8000/mcp",
            "transport": "http",
        },
    })
    
    # ── MODULE 2: STATE ──────────────────────────────────────────
    class State(MessagesState):
        pass
    
    # ── MODULE 4: NODES ──────────────────────────────────────────
    # (Module 3, Tools, is now sourced from MCP rather than defined here)
    def make_agent_node(llm_with_tools):
        """Factory pattern: tools are loaded asynchronously, so the node
        closure is built after the async tool-loading step completes."""
        def agent_node(state: State) -> dict:
            response = llm_with_tools.invoke(state["messages"])
            return {"messages": [response]}
        return agent_node
    
    # ── MODULE 6: GRAPH ASSEMBLY (inside an async function) ──────
    async def build_graph():
        tools = await client.get_tools()
        llm_with_tools = llm.bind_tools(tools)
    
        graph_builder = StateGraph(State)
        graph_builder.add_node("agent", make_agent_node(llm_with_tools))
        graph_builder.add_node("tools", ToolNode(tools))
    
        graph_builder.add_edge(START, "agent")
        graph_builder.add_conditional_edges("agent", tools_condition)
        graph_builder.add_edge("tools", "agent")
    
        return graph_builder.compile(checkpointer=MemorySaver())
    
    # ── MODULE 7: ENTRYPOINT ──────────────────────────────────────
    async def main():
        graph = await build_graph()
        config = {"configurable": {"thread_id": "session-001"}}
    
        response = await graph.ainvoke(
            {"messages": [HumanMessage(content="What's (3 + 5) times 12?")]},
            config=config
        )
        print(response["messages"][-1].content)
    if __name__ == "__main__":
        asyncio.run(main())
    

    Todo se vuelve asíncrono

    MCP introduce un único ajuste real. La comunicación es inherentemente asíncrona, ya que cada llamada a una herramienta implica un viaje de ida y vuelta por la red o un subproceso, incluso a través de stdio. Por lo tanto, client.get_tools() debe esperarse, la construcción del grafo normalmente se encuentra dentro de un async def, y el grafo compilado se invoca con ainvoke y no con invoke. Todo lo demás, StateGraph, MessagesState, tools_condition y MemorySaver, permanece igual que antes.

    El enrutador preconstruido de nuevo

    El enrutamiento prácticamente desaparece en esta plantilla. En lugar de un enrutador personalizado, utiliza tools_condition, el ya preparado: si el último mensaje contiene llamadas a herramientas, se dirige a "tools"; de lo contrario, finaliza. El enrutador no puede distinguir entre las herramientas MCP y las escritas a mano, ya que ambas se convierten en objetos BaseTool para cuando el grafo las procesa.

    Nivel 6: consideraciones de producción

    Hay varios aspectos que separan una demostración funcional de un sistema listo para desplegar, y estos son los que surgen con mayor frecuencia en configuraciones reales de MCP y LangGraph.

    Mantenga la conexión con el cliente activa. MultiServerMCPClient es sin estado por defecto: cada llamada a la herramienta abre una conexión nueva, la ejecuta y la cierra. Eso está bien para una sola solicitud. Pero en una aplicación que atiende a muchas solicitudes, abrir un subproceso o una conexión HTTP en cada llamada genera una latencia real. En entornos de producción, abra el cliente una sola vez al iniciar el proceso y réutilícelo durante toda la vida útil de la aplicación:

    # Hold the connection open across the application's lifetime,
    # rather than opening/closing per request
    async with MultiServerMCPClient({...}) as client:
        tools = await client.get_tools()
        graph = await build_graph_with(tools)
        # ... serve many requests using this same graph ...
    

    Evite usar stdio en un servidor web. Stdio fue diseñado para casos locales, de un solo usuario y en la misma máquina, como una aplicación de escritorio que inicia una herramienta auxiliar. Cuando un agente de LangGraph se despliega como servicio web para muchos usuarios, los servidores stdio se convierten en un problema: se generan subprocesos por cada solicitud, sin una forma natural de compartir estado ni de escalar. Para cualquier despliegue del lado del servidor, prefiera Streamable HTTP y pregúntese honestamente si realmente se necesita un proceso MCP separado. Hay casos en los que una función simple @tool que llama directamente a una biblioteca interna es mejor, tanto por su simplicidad como por su velocidad, que pasar por el protocolo adicional.

    Agregue aprobación humana para herramientas sensibles. Las herramientas MCP se convierten en herramientas ordinarias una vez que llegan al grafo, por lo que se aplican todos los patrones existentes. Si un servidor expone algo sensible, como enviar correos electrónicos, modificar una base de datos o gastar dinero, envuélvalo con el mismo paso de revisión interrupt() que se utiliza para cualquier otra llamada a herramientas. MCP proporciona descubrimiento y estandarización, pero no ofrece seguridad de forma predeterminada. Esa tarea sigue siendo responsabilidad del desarrollador.

    Los servidores no pueden ver el estado del grafo. Los servidores MCP se ejecutan como procesos separados. No pueden acceder al state de LangGraph, al checkpointer ni a ningún objeto de Python en memoria. Cuando una llamada necesita personalización, por ejemplo con una preferencia del usuario almacenada, el valor debe pasarse explícitamente como argumento de la herramienta, o proporcionarse a través de interceptores, un mecanismo avanzado ofrecido por langchain-mcp-adapters que permite inspeccionar y modificar una llamada antes de que sea enviada, utilizando el contexto de ejecución del grafo. Pasar valores como argumentos es suficiente para la mayoría de los agentes y es mucho más sencillo.

    Nivel 7: MCP en un sistema multiagente

    MCP se combina con el patrón supervisor. Varios agentes especializados obtienen sus herramientas de su propio servidor dedicado:

    # ── Specialist agents, each pulling tools from a DIFFERENT MCP server ──
    
    async def build_multi_agent_system():
        client = MultiServerMCPClient({
            "research": {"url": "http://localhost:8001/mcp", "transport": "http"},
            "code":     {"url": "http://localhost:8002/mcp", "transport": "http"},
        })
    
        research_tools = await client.get_tools(server_name="research")
        code_tools     = await client.get_tools(server_name="code")
    
        researcher_llm = llm.bind_tools(research_tools)
        coder_llm      = llm.bind_tools(code_tools)
    
        # From here, wire researcher_node, coder_node, and a supervisor_node
        # exactly as shown in Part 4 - the rest of the supervisor pattern
        # is completely unchanged.
        ...
    

    MCP no introduce aquí una arquitectura rival. Un especialista respaldado por un servidor MCP es estructuralmente idéntico a uno respaldado por herramientas manuales: el supervisor dirige las comunicaciones de la misma manera y los especialistas envían sus informes de la misma forma. MCP solo modifica el lugar donde se almacenan las definiciones de las herramientas y cuántas aplicaciones pueden reutilizarlas.

    Referencia rápida

    • Arquitectura. Host es la aplicación de IA con la que interactúa el usuario (en este caso, el agente LangGraph). Client se encuentra dentro del host, uno por cada servidor conectado, y gestiona una sesión uno a uno. Server es el programa independiente que expone herramientas, recursos y comandos, sin saber qué host se conecta. JSON-RPC 2.0 es el formato de mensajes utilizado en todos los intercambios: solicitudes, respuestas y notificaciones.
    • Primitivas. Tool es una acción ejecutable que el modelo elige llamar, creada con @mcp.tool. Resource son datos de solo lectura a los que se accede mediante un URI, controlados por la aplicación o el usuario, creados con @mcp.resource("uri://..."). Prompt es un modelo de instrucción reutilizable que invoca el usuario, creado con @mcp.prompt.
    • FastMCP. FastMCP(name="...") crea el servidor, que es el contenedor de todo. @mcp.tool expone una función que lee las indicaciones de tipo del esquema y la documentación para su descripción. @mcp.resource("scheme://{param}") declara datos de solo lectura, siendo {param} el encargado de generar un template. @mcp.prompt sirve para declarar un template. mcp.run() inicia el servidor, por defecto en stdio, o con transport="streamable-http" para su uso en red. fastmcp dev server.py abre el Inspector para pruebas sin necesidad de un LLM.
    • Transportes. stdio funciona mediante subprocesos y de forma local, con el host iniciando el servidor, y la salida de depuración nunca debe dirigirse a stdout. streamable-http es de red, soporta varios hosts concurrentes y es la opción predeterminada en entornos de producción para servidores compartidos.
    • Integración con LangGraph. MultiServerMCPClient({...}), proveniente de langchain_mcp_adapters.client, se conecta a uno o más servidores con diferentes transportes en un único diccionario. await client.get_tools() descubre todas las herramientas y las convierte en BaseTool. tools_condition es el enrutador preconstruido y funciona de manera idéntica tanto para herramientas escritas a mano como para aquellas provenientes de MCP. Todo es asíncrono: get_tools(), la creación del grafo y ainvoke requieren todos await.

    ¿Se necesita MCP aquí?

    • Una herramienta, un agente, una base de código única. No se necesita MCP. Una función sencilla @tool es más simple y no implica sobrecarga de protocolo.
    • Una herramienta que se reutiliza en varios agentes o proyectos, o que se comparte con colegas de otros frameworks. Cómprala como un servidor MCP. Ese es su valor principal.
    • Deseo contar con cientos de servidores comunitarios existentes (GitHub, Slack, Postgres, Google Drive, Stripe y más) en lugar de código de integración escrito a mano. Conéctese a través de MultiServerMCPClient y evite escribir la integración, lo que suele ser el mayor ahorro de tiempo que ofrece MCP.
    • Una herramienta en una máquina distinta al agente, o compartida por varios hosts al mismo tiempo. Utilice Streamable HTTP como servicio independiente.
  • Una herramienta que solo funciona localmente junto a un agente para desarrollo o uso personal. stdio es suficiente y es más fácil de configurar.
  • Un estándar, no un reemplazo

    Aprender un nuevo protocolo genera la preocupación de que reemplace lo que ya se conoce. MCP no lo hace. Deja intactas las herramientas, nodos y grafos de LangGraph. Lo que cambia es el origen de las herramientas y la cantidad de aplicaciones que pueden compartirlas. Una vez que una herramienta MCP llega al ToolNode, se comporta como cualquier herramienta escrita a mano, es aprobada por los mismos patrones interrupt() y se adapta a las mismas arquitecturas de supervisión.

    La progresión siguió un patrón en escalones: conceptos y roles, las tres primitivas, un servidor operativo, la elección del transporte, el puente LangGraph, el endurecimiento para producción y la composición con sistemas multiagente. Cada nivel añadía una idea a una base estable. Combinado con la estructura de gráfico canónica, la gestión de memoria, la seguridad mediante intervención humana, la orquestación y recuperación multiagente, esto abarca la mayor parte de lo que necesita una aplicación LangGraph seria para producción, y MCP es lo que permite que las herramientas se escalen parcialmente más allá de una única base de código.

    Leer más

  • LangGraph Human-in-the-Loop: interrupt(), ediciones de estado y viaje en el tiempo — Cuatro patrones de LangGraph para supervisión humana: aprobación de llamadas a herramientas mediante interrupt(), sistemas de retroalimentación, ediciones manuales de estado y viaje en el tiempo, con las palabras clave que necesita.
  • Notas prácticas: Codificación agente diseñada para minimizar costos: creación de una solución de nivel profesional — Guía paso a paso de las Notas prácticas: Codificación agente diseñada para minimizar costos: creación de una solución de nivel profesional: contratos, verificaciones y bloques de código listos para usar para los equipos que implementan este patrón.
  • Cómo MCP cambia la forma en que los agentes de IA se conectan a los software empresariales — Cómo el Protocolo de Contexto de Modelo conecta a los agentes con CRM, ERP y APIs internas, qué es necesario proteger y cómo una empresa debe comenzar de forma gradual.
  • LlamaIndex Plus LangGraph: Un patrón claro para agentes RAG — Cómo crear una base de conocimientos con LlamaIndex y exponerla a un agente LangGraph como herramienta, explicando la persistencia, Chroma y el modo exclusivo de recuperación.
  • Conectar agentes de IA a GeoServer 2.28 mediante la extensión MCP — Instale el archivo JAR de la extensión MCP de GeoServer, verifique que se haya cargado, llame al endpoint con curl, conecte Claude Desktop o LangChain, y restrinja el acceso así como los herramientas de escritura.