Conectarse a un servidor MCP con JavaScript y LangChain.js
Introducción
Model Context Protocol (MCP) es una forma estandarizada de exponer datos y funcionalidades a aplicaciones de Modelos de Lenguaje Grandes (LLMs) de manera segura y consistente. Desarrollado inicialmente por Anthropic, MCP ha ganado una tracción significativa en el ecosistema de inteligencia artificial (IA), con cientos de servidores publicados hasta el momento. El protocolo permite a los LLMs interactuar con sistemas externos a través de interfaces bien definidas, lo que les permite acceder a datos en tiempo real, realizar cálculos y tomar acciones en respuesta a consultas de los usuarios.
En marzo de 2025, la comunidad de LangChain lanzó MCP adapters para LangChain.js, una librería JavaScript para crear aplicaciones potenciadas por LLMs. Los adapters convierten las herramientas MCP en herramientas compatibles con LangChain.js y LangGraph.js, permitiendo a los desarrolladores incorporarlas sin problemas en sus flujos de trabajo de agentes ya existentes.
En este artículo, te mostraré cómo conectar tus aplicaciones JavaScript a un servidor MCP utilizando LangChain.js y LangGraph.js. Cubriré tanto el transporte STDIO como el SSE, y proporcionaré un ejemplo sencillo para crear un agente que interactúe con un clúster de Kubernetes.
Configuración de clientes MCP
Antes de poder usar las herramientas MCP con LangChain.js, necesitamos configurar clientes MCP que puedan comunicarse con los servidores MCP. La librería TypeScript SDK para Model Context Protocol proporciona implementaciones de clientes para diferentes métodos de transporte. Veamos cómo configurar clientes para los transportes STDIO y SSE.
Configuración de un cliente de transporte STDIO
El transporte STDIO es ideal para herramientas de línea de comandos e integraciones directas. Permite la comunicación con un servidor MCP que se ejecuta como un subproceso de tu aplicación. Este enfoque es particularmente útil para la ejecución local, lo que resulta conveniente para agentes que realizan tareas en la misma máquina donde se está ejecutando el servidor.
El siguiente fragmento de código muestra cómo configurar un cliente de transporte STDIO:
import {Client} from '@modelcontextprotocol/sdk/client/index.js';
import {StdioClientTransport} from '@modelcontextprotocol/sdk/client/stdio.js';
const initStdioClient = async () => {
const stdioClient = new Client({
name: 'blog.marcnuri.com'
});
const transport = new StdioClientTransport({
command: 'npx',
args: ['-y', 'kubernetes-mcp-server@latest']
});
await stdioClient.connect(transport);
return stdioClient;
};
En este ejemplo, estamos creando un nuevo cliente MCP con un identificador de nombre y conectándolo a un transporte que ejecuta el paquete kubernetes-mcp-server
usando npx.
El transporte STDIO genera un subproceso y se comunica con él a través de las entradas y salidas estándar.
Estos son los componentes clave de la configuración del cliente de transporte STDIO:
- Creamos una nueva instancia de
Client
con un identificador de nombre opcional. Este nombre se utiliza para identificar al cliente con el servidor. - Creamos una nueva instancia de
StdioClientTransport
con el comando para ejecutar el servidor MCP.command
: El comando para ejecutar el servidor MCP.args
: La lista de argumentos a pasar al comando.
- Llamamos al método
connect
en la instancia del cliente, pasando la instancia de transporte para establecer la conexión.
Configuración de un cliente de transporte SSE
El transporte Server-Sent Events (SSE) es más adecuado para servidores MCP que se ejecutan en un entorno remoto. Establece una conexión persistente con el servidor MCP a través de HTTP utilizando SSE para la comunicación en tiempo real.
El siguiente fragmento de código muestra cómo configurar un cliente de transporte SSE:
import {Client} from '@modelcontextprotocol/sdk/client/index.js';
import {SSEClientTransport} from '@modelcontextprotocol/sdk/client/sse.js';
const initSseClient = async () => {
const sseClient = new Client({
name: 'blog.marcnuri.com'
});
const transport = new SSEClientTransport('https://localhost:8080/sse');
await sseClient.connect(transport);
return sseClient;
};
En este ejemplo, estamos creando un nuevo cliente MCP y conectándolo a un transporte SSE que apunta a un servidor local en el puerto 8080. Esto asume que tienes un servidor MCP ejecutándose en esa URL con un endpoint SSE. Cuando el cliente se conecta, establece una conexión de larga duración con el servidor utilizando el protocolo Server-Sent Events, lo que permite al servidor enviar mensajes al cliente en tiempo real.
Estos son los componentes clave de la configuración del cliente de transporte SSE:
- Creamos una nueva instancia de
Client
con un identificador de nombre opcional. Este nombre se utiliza para identificar al cliente con el servidor. - Creamos una nueva instancia de
SSEClientTransport
con la URL del servidor MCP. - Llamamos al método
connect
en la instancia del cliente, pasando la instancia de transporte para establecer la conexión.
Configuración de LangChain.js MCP adapters
Ahora que tenemos nuestros clientes MCP configurados, podemos usar los MCP adapters de LangChain.js para integrar herramientas MCP con LangChain.js.
El paquete @langchain/mcp-adapters
proporciona una forma sencilla de cargar herramientas MCP y usarlas con agentes LangChain.js.
Los MCP adapters proporcionan una función loadMcpTools
que envuelve las herramientas MCP y las hace compatibles con LangChain.js.
El siguiente fragmento de código demuestra cómo cargar las herramientas MCP:
import {loadMcpTools} from '@langchain/mcp-adapters';
// Assuming you've already set up an MCP client as shown above
const stdioClient = await initStdioClient();
const tools = await loadMcpTools('kubernetes-mcp-server', stdioClient);
La función loadMcpTools
toma dos argumentos:
- Un nombre para las herramientas (esto puede ser cualquier cadena que elijas).
- La instancia del cliente MCP.
Devuelve una lista de herramientas compatibles con LangChain que puedes usar con agentes LangChain.js. Por debajo, esta función descubre las herramientas disponibles del servidor MCP y crea objetos de herramienta correspondientes a LangChain para cada una.
El adaptador se encarga de todos los detalles específicos del protocolo, lo que te permite concentrarte en construir la lógica de tu aplicación.
Además, proporciona características como:
- 🔌 Múltiples opciones de transporte con estrategias de reconexión.
- 🔄 Conexión a múltiples servidores MCP simultáneamente.
- 🧩 Integración sin problemas con agentes LangChain.
- 🛠️ Manejo de errores elegante cuando los servidores no están disponibles.
Cómo usar LangGraph.js para crear un agente
Ahora que tenemos todas las piezas, podemos crear un agente utilizando LangGraph.js que pueda aprovechar las herramientas MCP. LangGraph.js proporciona una forma sencilla de crear flujos de trabajo de agentes complejos. Además, incluye agentes predefinidos que hacen que sea aún más fácil comenzar.
Aquí hay un ejemplo completo que muestra cómo crear un agente que puede interactuar con un clúster de Kubernetes usando el kubernetes-mcp-server:
import {createReactAgent} from '@langchain/langgraph/prebuilt';
import {ChatOpenAI} from '@langchain/openai';
import {loadMcpTools} from '@langchain/mcp-adapters';
const assistant = async () => {
const model = new ChatOpenAI({
configuration: {
apiKey: process.env['GITHUB_TOKEN'],
baseURL: 'https://models.inference.ai.azure.com'
},
model: 'gpt-4o-mini'
});
const stdioClient = await initStdioClient();
const tools = await loadMcpTools('kubernetes-mcp-server', stdioClient);
const agent = createReactAgent({
llm: model,
tools
});
const listPods = await agent.invoke({
messages:[{
role: 'user',
content: 'List all pods in my cluster and output as markdown table'
}]
});
console.log(listPods.messages.slice(-1)[0].content);
await stdioClient.close();
};
assistant()
.then(() => {
console.log('done');
})
.catch(err => {
console.error('Error:', err);
});
En este ejemplo, creamos un asistente muy sencillo que conecta la herramienta kubernetes-mcp-server
con el modelo de lenguaje gpt-4o-mini
proporcionado por GitHub.
Como puedes ver, el ecosistema LangChain hace que sea fácil crear agentes que puedan interactuar con servidores MCP.
Estos son los componentes clave del ejemplo del agente:
ChatOpenAI
:
Creamos una nueva instancia de ChatOpenAI configurada para usar el modelogpt-4o-mini
de Azure AI/GitHub Marketplace.configuration
: El objeto de configuración para la API de OpenAI, incluyendo la clave API y la URL base.model
: El nombre del modelo de lenguaje a usar.
loadMcpTools
:
Carga las herramientas MCP del cliente STDIO como se describió en la sección anterior.createReactAgent
:
Crea un agente ReAct (Razonamiento y Acción) de LangGraph.js utilizando los modelos y herramientas que cargamos.invoke
:
Invoca el agente con una solicitud de usuario para listar todos los pods en el clúster de Kubernetes. El agente utilizará las herramientas para realizar la acción y devolver el resultado.listPods.messages
:
La respuesta del agente se almacena en la variablelistPods
. Imprimimos el último mensaje de la respuesta, que contiene el resultado de la acción.
El agente emplea ReAct un patrón de razonamiento y acción que alterna entre razonar sobre qué hacer a continuación y tomar acción utilizando las herramientas disponibles. En este caso, el agente puede usar las herramientas proporcionadas por el servidor MCP de Kubernetes para interactuar con tu clúster de Kubernetes.
El resultado del ejemplo será similar a esto:
Here is the list of pods in your cluster presented as a markdown table:
```markdown
| Name | Namespace | Status | Container Image | Pod IP |
|--------------------------|-----------|---------|-----------------------|-------------|
| kubernetes-mcp-run-nxvvq | default | Running | marcnuri/chuck-norris | 10.133.7.0 |
| kubernetes-mcp-run-rhqzb | default | Running | marcnuri/chuck-norris | 10.133.7.0 |
```
You can copy and paste this markdown into any markdown viewer to see it formatted correctly.
No obstante, la variable listPods.messages
contendrá la lista completa de mensajes intercambiados entre el agente y el LLM.
En este caso particular, la invocación involucró dos mensajes.
Lo interesante de este enfoque es que el agente puede decidir qué herramientas usar en función del prompt del usuario. Por ejemplo, si el usuario pide listar pods, el agente identificará que necesita usar la herramienta de Kubernetes adecuada para obtener información sobre los pods y luego formatear el resultado como una tabla Markdown.
Conclusión
En este artículo, hemos explorado cómo conectar aplicaciones JavaScript a un servidor MCP utilizando LangChain.js y LangGraph.js. Hemos cubierto cómo configurar tanto clientes de transporte STDIO como SSE, cómo usar los MCP adapters para cargar herramientas desde el servidor y cómo unir todo utilizando LangGraph.js para crear un agente. La combinación de MCP, LangChain.js y LangGraph.js proporciona una plataforma muy potente para construir aplicaciones potenciadas por LLMs que interactúan con varias herramientas y recursos. Con los MCP adapters, puedes integrar sin problemas el creciente ecosistema de servidores de herramientas MCP en tus agentes LangChain y LangGraph.
Puedes encontrar el código fuente de este artículo en GitHub.