Un logotipo con el texto blog.marcnuri.com
English
Inicio»Inteligencia Artificial»Cliente MCP de AI SDK: conecta JavaScript a un servidor MCP

Entradas Recientes

  • ¡Fabric8 Kubernetes Client 8.0 está disponible!
  • ¡Fabric8 Kubernetes Client 7.9 está disponible!
  • ¡Eclipse JKube 1.20 está disponible!
  • Project, Agent, Person: El Eje que Falta en Herramientas de Programación con IA
  • ¡Fabric8 Kubernetes Client 7.8 está disponible!

Categorías

  • Antiguo
  • Cloud Native
  • Desarrollo Backend
  • Desarrollo Frontend
  • Herramientas
  • Ingeniería de calidad
  • Inteligencia Artificial
  • JavaScript
  • Operaciones
  • Personal
  • Proyectos personales
  • Reflexiones sobre Ingeniería

Archivos

  • septiembre 2026
  • julio 2026
  • junio 2026
  • mayo 2026
  • abril 2026
  • marzo 2026
  • febrero 2026
  • enero 2026
  • diciembre 2025
  • octubre 2025
  • septiembre 2025
  • julio 2025
  • mayo 2025
  • abril 2025
  • marzo 2025
  • febrero 2025
  • enero 2025
  • diciembre 2024
  • noviembre 2024
  • agosto 2024
  • junio 2024
  • mayo 2024
  • abril 2024
  • marzo 2024
  • febrero 2024
  • enero 2024
  • diciembre 2023
  • noviembre 2023
  • octubre 2023
  • septiembre 2023
  • agosto 2023
  • julio 2023
  • junio 2023
  • mayo 2023
  • abril 2023
  • marzo 2023
  • febrero 2023
  • enero 2023
  • diciembre 2022
  • noviembre 2022
  • octubre 2022
  • septiembre 2022
  • agosto 2022
  • julio 2022
  • junio 2022
  • mayo 2022
  • marzo 2022
  • febrero 2022
  • enero 2022
  • diciembre 2021
  • noviembre 2021
  • octubre 2021
  • septiembre 2021
  • agosto 2021
  • julio 2021
  • enero 2021
  • diciembre 2020
  • octubre 2020
  • septiembre 2020
  • agosto 2020
  • junio 2020
  • mayo 2020
  • marzo 2020
  • febrero 2020
  • enero 2020
  • noviembre 2019
  • septiembre 2019
  • julio 2019
  • diciembre 2018
  • agosto 2018
  • julio 2018
  • junio 2018
  • mayo 2018
  • marzo 2018
  • febrero 2018
  • noviembre 2017
  • octubre 2017
  • agosto 2017
  • julio 2017
  • enero 2017
  • julio 2016
  • mayo 2016
  • enero 2016
  • diciembre 2015
  • noviembre 2015
  • diciembre 2014
  • noviembre 2014
  • octubre 2014
  • marzo 2014
  • agosto 2012
  • febrero 2011
  • junio 2008
  • mayo 2008
  • abril 2008
  • enero 2008
  • junio 2007
  • mayo 2007
  • abril 2007
  • marzo 2007

Cliente MCP de AI SDK: conecta JavaScript a un servidor MCP

2025-04-11 en Inteligencia Artificial / JavaScript etiquetado JavaScript / LLM / AI Agent / Model Context Protocol (MCP) / AI SDK por Marc Nuri | Última actualización: 2026-10-23
English version

Introducción

⁠

Para conectar una aplicación JavaScript a un servidor Model Context Protocol (MCP) con Vercel AI SDK, creas un cliente MCP con createMCPClient del paquete @ai-sdk/mcp (experimental_createMCPClient en versiones anteriores), pasas las herramientas que devuelve a generateText o streamText, y cierras el cliente cuando terminas. El modelo decide entonces a qué herramientas del servidor llamar, y AI SDK las ejecuta y le devuelve los resultados al modelo.

MCP proporciona una forma estandarizada para que los modelos de inteligencia artificial (IA) interactúen con herramientas y sistemas externos. Echa un vistazo a mi introducción a MCP si el protocolo es nuevo para ti. Vercel AI SDK es un toolkit de TypeScript con una creciente lista de proveedores de modelos compatibles, lo que lo convierte en una excelente alternativa a la librería LangChain.js.

En este artículo, te mostraré cómo conectar tus aplicaciones JavaScript a un servidor MCP utilizando AI SDK. Te explicaré cómo configurar el cliente MCP con stdio y Streamable HTTP, configurar un proveedor de modelos y hacer prompts al modelo utilizando la función generateText. He probado cada paso en octubre de 2026 con AI SDK 7.0.140, @ai-sdk/mcp 2.0.74, Kubernetes MCP Server v0.0.67 y un modelo local pequeño (Qwen3 4B) ejecutándose en Ollama, así que puedes seguirlo sin una API key.

¿Qué import necesitas: experimental_createMCPClient o createMCPClient?

⁠

Vercel añadió un cliente MCP experimental en AI SDK 4.2 (marzo de 2025), y escribí la primera versión de este artículo unas semanas después, en abril de 2025. El cliente se movió a su propio paquete, @ai-sdk/mcp, en octubre de 2025, y AI SDK 6 (diciembre de 2025) lo estabilizó y eliminó el prefijo experimental_, así que el import de los tutoriales más antiguos depende de la versión de AI SDK para la que se escribieron:

Versión de AI SDKImport del cliente MCP
4.2 a 5.0.78experimental_createMCPClient de ai
5.0.79 a 5.xexperimental_createMCPClient de @ai-sdk/mcp (0.x)
6 y 7createMCPClient de @ai-sdk/mcp (1.x y 2.x)

A fecha de octubre de 2026, @ai-sdk/mcp todavía exporta el nombre experimental_createMCPClient como alias, pero el código nuevo debería utilizar createMCPClient. AI SDK 7 (junio de 2026) convirtió todos los paquetes en ESM-only y renombró algunas de las funciones que utilizo en este artículo. Si estás actualizando código de AI SDK 6, estos son los cambios de su guía de migración que afectan a este artículo:

  • stepCountIs ahora es isStepCount (el nombre anterior sigue funcionando como alias).
  • La opción name del cliente está obsoleta en favor de clientName, que las últimas versiones de AI SDK 6 ya aceptan (name sigue funcionando).
  • El transporte HTTP rechaza las redirecciones por defecto; configura redirect: 'follow' si tu servidor depende de ellas.
  • Todos los paquetes son ESM-only y necesitan Node.js 22 o posterior.

Configuración del proyecto

⁠

Los paquetes de AI SDK 7 son ESM-only y necesitan Node.js 22 o posterior (compruébalo con node --version). Crea un proyecto y configúralo para utilizar módulos ES:

npm init -y
npm pkg set type=module

Instala AI SDK, su cliente MCP, el paquete cliente del SDK oficial de MCP para TypeScript (para el transporte stdio) y el proveedor de Ollama:

npm install ai @ai-sdk/mcp @modelcontextprotocol/client ollama-ai-provider-v2

Los ejemplos utilizan un modelo local a través de Ollama. Instala Ollama y descarga un modelo pequeño que soporte tool calling (unos 2,5 GB):

ollama pull qwen3:4b-instruct

Kubernetes MCP Server necesita un clúster con el que comunicarse. Utiliza tu fichero kubeconfig por defecto, así que cualquier clúster sirve; yo utilicé un clúster local de kind, que kind create cluster crea y añade a ese fichero.

Creación de los clientes MCP de AI SDK

⁠

Para interactuar con un servidor MCP, primero necesitamos crear un cliente MCP. AI SDK proporciona una función llamada createMCPClient en el paquete @ai-sdk/mcp que nos permite establecer esta conexión.

La especificación de MCP define dos transportes estándar: stdio y Streamable HTTP. Veamos cómo crear un cliente para cada uno de ellos.

Configuración de un cliente de transporte STDIO

⁠

El método de transporte STDIO nos permite lanzar un proceso local y comunicarnos con él a través de los flujos de entrada y salida estándar. Esto es útil para ejecutar servidores o procesos MCP locales que exponen las capacidades del sistema local.

El siguiente fragmento de código muestra cómo configurar un cliente de transporte STDIO para el servidor MCP de Kubernetes:

stdio-client.js
import {createMCPClient} from '@ai-sdk/mcp';
import {StdioClientTransport} from '@modelcontextprotocol/client/stdio';

const initStdioClient = async () => {
  const transport = new StdioClientTransport({
    command: 'npx',
    args: ['-y', 'kubernetes-mcp-server@latest']
  });
  return createMCPClient({clientName: 'blog.marcnuri.com', transport});
};

En este fragmento, estamos creando un cliente MCP que ejecuta Kubernetes MCP Server utilizando el comando npx.

Estos son los pasos clave para configurar el cliente de transporte STDIO:

  1. Importar los módulos necesarios de los paquetes @ai-sdk/mcp y @modelcontextprotocol/client.
  2. Crear una nueva instancia de StdioClientTransport, pasando el comando y los argumentos para ejecutar el servidor MCP.
  3. Llamar a createMCPClient con la instancia de transporte para crear el cliente MCP y establecer la conexión. clientName es opcional; es el nombre con el que el cliente se identifica ante el servidor.

Los tutoriales más antiguos, y la documentación de AI SDK a fecha de octubre de 2026, importan el mismo transporte desde @modelcontextprotocol/sdk/client/stdio.js, la versión 1 del SDK de MCP para TypeScript, que sigue funcionando.

Nota

El transporte no pasa todo tu entorno al proceso del servidor: solo unas pocas variables, como HOME, PATH y USER (en Windows, sus equivalentes). Si el servidor necesita alguna otra, como KUBECONFIG o la configuración del proxy para npx, añádela con la opción env del transporte, que se combina con esas variables por defecto, por ejemplo env: {KUBECONFIG: process.env.KUBECONFIG}.

AI SDK también incluye su propio transporte stdio, Experimental_StdioMCPTransport en @ai-sdk/mcp/mcp-stdio. Antes del handshake clásico, consulta al servidor si soporta la nueva revisión stateless del protocolo (2026-07-28) y abandona esa consulta pasado un segundo. En mis pruebas con la v2.0.74, npx -y kubernetes-mcp-server@latest tardaba más que eso en arrancar el servidor, y la conexión fallaba con el error duplicate "initialize" received. La conexión funcionó en cuanto configuré protocolVersionDiscovery: false en createMCPClient, o cuando el servidor arrancaba rápido desde una instalación local. El transporte del SDK de MCP que te he mostrado utiliza el handshake clásico desde el principio, así que prefiero seguir con él.

Configuración de un cliente de transporte Streamable HTTP

⁠

El método de transporte Streamable HTTP nos permite conectarnos a un servidor MCP remoto a través de HTTP. Esto es útil cuando tienes un servidor MCP que ya está ejecutándose como un servicio al que quieres conectarte.

Nota

Antes de la versión 2025-03-26 del protocolo MCP, el transporte SSE (Server-Sent Events) se utilizaba para conexiones remotas. SSE está ahora obsoleto en favor de Streamable HTTP.

Para probarlo en local, guarda la configuración del servidor en un fichero config.toml:

config.toml
port = "8080"
bind_address = "127.0.0.1"

Después, arranca Kubernetes MCP Server en modo HTTP en otro terminal:

npx -y kubernetes-mcp-server@latest --config config.toml

El servidor lee su configuración de este fichero TOML: desde la v0.0.68, rechaza los flags de línea de comandos que usan los tutoriales más antiguos, como --port, con un error unknown flag. Sin bind_address, el servidor escucha en todas las interfaces de red (0.0.0.0) y, por defecto, no autentica a sus clientes, así que cualquiera que pueda llegar al puerto puede utilizar tu clúster con las credenciales de tu kubeconfig.

El siguiente fragmento de código muestra cómo configurar un cliente de transporte Streamable HTTP:

http-client.js
import {createMCPClient} from '@ai-sdk/mcp';

const initHttpClient = async () => {
  return createMCPClient({
    clientName: 'blog.marcnuri.com',
    transport: {
      type: 'http',
      url: 'http://localhost:8080/mcp'
    }
  });
};

En este fragmento, estamos creando un cliente MCP que se conecta a un servidor local que se ejecuta en el puerto 8080 utilizando el protocolo Streamable HTTP. Este enfoque es más adecuado para entornos de producción o cuando tienes un servidor MCP dedicado en ejecución.

Nota

En entornos de producción, la URL debe apuntar a la dirección real de tu servidor MCP (que también debería estar habilitado para HTTPS). El transporte también acepta headers (por ejemplo, una cabecera Authorization) y un authProvider de OAuth. Desde AI SDK 7, rechaza las redirecciones HTTP por defecto; configura redirect: 'follow' si tu servidor depende de ellas.

Estos son los pasos clave para configurar el cliente de transporte Streamable HTTP:

  1. Importar el módulo necesario del paquete @ai-sdk/mcp.
  2. Llamar a createMCPClient con la configuración de transporte, especificando el tipo como http y proporcionando la URL del servidor MCP.
  3. La función devuelve una instancia de cliente MCP que se puede utilizar para interactuar con el servidor remoto.

Fíjate en que el transporte HTTP es mucho más sencillo de configurar que el transporte STDIO: AI SDK lo incluye, así que no necesitas el SDK de MCP.

Configuración del proveedor y el modelo de AI SDK

⁠

Una vez que tenemos el cliente MCP configurado, necesitamos configurar el proveedor de AI SDK y el modelo que utilizará las herramientas del servidor MCP. AI SDK tiene una larga lista de proveedores compatibles; en este caso, utilizaremos el proveedor de Ollama de la comunidad para ejecutar un modelo en local.

El siguiente fragmento de código muestra cómo configurar el proveedor de Ollama con el modelo Qwen3 4B:

ollama.js
import {ollama} from 'ollama-ai-provider-v2';

const model = ollama('qwen3:4b-instruct');

En este fragmento, estamos utilizando la instancia por defecto del proveedor de Ollama y especificando el modelo que queremos utilizar:

  • La instancia ollama por defecto se conecta a un servidor local de Ollama en http://127.0.0.1:11434/api. Si el tuyo se ejecuta en otro sitio, crea tu propia instancia con createOllama({baseURL: '...'}).
  • La función ollama se llama con el nombre del modelo para crear una instancia del modelo que se puede utilizar para generar texto.

El modelo debe soportar tool calling, y los modelos pequeños varían mucho en lo bien que lo hacen. Escribí sobre esto en Otorgando Superpoderes a Small Language Models con MCP.

Consejo

Cambiar a un modelo alojado en la nube solo afecta a estas dos líneas. Por ejemplo, con el proveedor de Google (@ai-sdk/google), importarías google y crearías el modelo con google('<model-id>'), que lee la API key de la variable de entorno GOOGLE_GENERATIVE_AI_API_KEY. En AI SDK 7, la función createGoogleGenerativeAI del proveedor de Google ahora se llama createGoogle.

Hacer prompts al modelo con generateText

⁠

Ahora que tenemos todos los componentes configurados, podemos juntar las piezas para hacer prompts al modelo y dejar que interactúe con las herramientas del servidor MCP.

En este ejemplo, vamos a generar texto pidiendo al modelo que liste todos los pods de Kubernetes en formato de tabla Markdown.

El siguiente fragmento de código muestra las partes relevantes del pipeline:

assistant.js
import {generateText, isStepCount} from 'ai';
import {ollama} from 'ollama-ai-provider-v2';

const assistant = async () => {
  const mcpClient = await initStdioClient();
  try {
    const tools = await mcpClient.tools();
    const model = ollama('qwen3:4b-instruct');
    const result = await generateText({
      model,
      tools,
      stopWhen: isStepCount(10),
      messages: [{
        role: 'user',
        content: 'List all pods in my cluster and output their name and namespace as a Markdown table'
      }]
    });
    console.log(result.text);
  } finally {
    await mcpClient.close();
  }
};

assistant().catch(err => {
  console.error('Error:', err);
});

En este fragmento, estamos creando un asistente que conecta el modelo Qwen3 4B a las herramientas del servidor MCP de Kubernetes y le hace un prompt sencillo.

Estos son los componentes clave de este ejemplo:

  • Primero inicializamos el cliente STDIO y obtenemos las herramientas disponibles llamando a mcpClient.tools(). Esto lista todas las herramientas que ofrece el servidor (20 con los toolsets por defecto de Kubernetes MCP Server) y las convierte en herramientas de AI SDK.
  • Luego llamamos a la función generateText con los siguientes parámetros:
    • model: La instancia del modelo que creamos anteriormente.
    • tools: Las herramientas disponibles desde el cliente del servidor MCP.
    • stopWhen: Una condición que determina cuándo detener el bucle de generación. Usamos isStepCount(10) para limitar el modelo a un máximo de 10 pasos.
      Por defecto, generateText ejecuta un único paso: AI SDK ejecutaría la herramienta que pide el modelo, pero el modelo no tendría otro paso para convertir el resultado en una respuesta, así que result.text quedaría vacío. Un valor mayor que 1 garantiza que el modelo pueda procesar el prompt inicial y los prompts posteriores con los resultados de la ejecución de las herramientas.
    • messages: Un array de mensajes que representan el historial de la conversación. En este caso, proporcionamos un solo mensaje del usuario pidiendo al modelo que liste todos los pods en el clúster y formatee la salida como una tabla Markdown.
  • Por último, mostramos el texto generado en la consola y cerramos el cliente en un bloque finally, para que el proceso del servidor se detenga aunque la generación falle.

El resultado del ejemplo será similar a esto:

| NAMESPACE | NAME |
|----------|------|
| default | nginx-6f5fc479d9-j25wp |
| default | nginx-6f5fc479d9-vq4r9 |
| kube-system | coredns-668d6bf9bc-2q9pp |
| kube-system | coredns-668d6bf9bc-r2jg2 |
| kube-system | etcd-ai-sdk-refresh-control-plane |
| kube-system | kindnet-zncdz |
| kube-system | kube-apiserver-ai-sdk-refresh-control-plane |
| kube-system | kube-controller-manager-ai-sdk-refresh-control-plane |
| kube-system | kube-proxy-rpsdh |
| kube-system | kube-scheduler-ai-sdk-refresh-control-plane |
| local-path-storage | local-path-provisioner-7dc846544d-8xlh6 |

result.text solo contiene la respuesta final del modelo. result.steps contiene cada paso del bucle, incluidas las llamadas a herramientas y sus resultados, que es donde puedes comprobar lo que el modelo hizo realmente.

Esa comprobación es importante con un modelo pequeño. En mis pruebas, Qwen3 4B siempre llamó a la herramienta pods_list, pero cada vez que le pedí columnas concretas, añadió un field selector status.phase=Running que no le había pedido, lo que habría ocultado cualquier pod pendiente o con errores. Cuando, en cambio, le pedí todas las columnas, llamó a la herramienta sin filtros, pero copió mal la IP de un pod al reescribir la tabla de 13 columnas. En mi portátil, cada ejecución tardó entre 25 y 40 segundos.

Limitar las herramientas que puede usar el modelo

⁠

mcpClient.tools() le entrega al modelo todas las herramientas que expone el servidor, incluidas las destructivas como pods_delete y resources_delete. La forma más sencilla de mantener al modelo alejado de ellas está en el lado del servidor: la opción read_only de Kubernetes MCP Server expone solo las herramientas anotadas como de solo lectura. El modo de solo lectura impide cambios, no lecturas: herramientas como resources_get pueden seguir devolviendo Secrets, que llegan al modelo (y a su proveedor, si usas uno alojado); la opción denied_resources del servidor puede bloquearlos.

Actívala en un fichero TOML y pásale el fichero al servidor con --config:

read-only.toml
read_only = true
args: ['-y', 'kubernetes-mcp-server@latest', '--config', 'read-only.toml']

Con esta opción, el cliente recibe 14 herramientas en lugar de 20. En el lado del cliente, AI SDK expone las anotaciones de herramientas MCP de cada herramienta en sus metadatos, y su opción toolApproval te permite exigir la aprobación del usuario para las herramientas que no están marcadas como de solo lectura. Eso sí, las anotaciones son pistas que da el servidor: fíate de ellas solo con servidores en los que confíes, ya que un servidor puede marcar una herramienta destructiva como de solo lectura y saltarse la aprobación.

Conclusión

⁠

En este artículo, te he mostrado cómo conectarte a un servidor MCP desde JavaScript utilizando Vercel AI SDK. Hemos visto cómo configurar tanto clientes de transporte STDIO como Streamable HTTP, configurar un modelo local con el proveedor de Ollama y hacer prompts al modelo utilizando la función generateText para generar resultados útiles.

Esta arquitectura modular ilustra la flexibilidad del SDK: cambiar el transporte o el proveedor de modelos solo afecta a unas pocas líneas, y el resto del código sigue igual. Al seguir estos pasos, puedes integrar tus aplicaciones JavaScript con un servidor MCP y permitir que los LLMs interactúen con herramientas y sistemas externos.

A medida que el ecosistema MCP madura, los mismos servidores MCP funcionan desde AI SDK, desde LangChain.js o desde cualquier otro cliente MCP.

Puedes encontrar el código fuente de este artículo en GitHub.

Te Puede Interesar

⁠
  • Introducción a Model Context Protocol (MCP): El Futuro de la Integración de IA
  • MCP con LangChain.js: conecta agentes a servidores MCP
  • Cliente MCP de LangChain4j: conecta Java a un servidor MCP
  • Otorgando Superpoderes a Small Language Models con Model Context Protocol (MCP)
  • MCP Tool Annotations: cada hint y su valor por defecto
Icono de TwitterIcono de FacebookIcono de LinkedInIcono de PinterestIcono de correo electrónico

Navegador de artículos
MCP con LangChain.js: conecta agentes a servidores MCP¡Fabric8 Kubernetes Client 7.2.0 está disponible!
© 2007 - 2026 Marc Nuri