Arquitectura MCP sin estado: novedades de MCP 2026

  1. Inicio
  2. Blog
  3. Inteligencia artificial

Inteligencia artificial

Arquitectura MCP sin estado: novedades de MCP 2026

La especificación MCP de 2026 elimina el handshake y el ID de sesión. Ahora cada solicitud es independiente. Esto es lo que significa para el escalado, la seguridad y tu código.

Por Stack QuoraActualizado el 29 oct 202611 min de lectura
Diagrama de la arquitectura MCP sin estado: una solicitud de cliente llega a uno de tres servidores a través de un balanceador de carga

Ideas clave

  • La especificación MCP 2026-07-28 hace que el protocolo sea sin estado en su núcleo.
  • Se eliminan el handshake initialize y la cabecera Mcp-Session-Id.
  • Cualquier instancia del servidor puede responder a cualquier solicitud, así que escalar es mucho más sencillo.
  • Las preguntas a mitad de una llamada usan ahora Multi Round-Trip Requests (MRTR).
  • Tu aplicación aún puede mantener estado. Solo que lo mantienes de forma explícita, no dentro del transporte.

Imagina un servidor MCP funcionando en tres máquinas detrás de un balanceador de carga. Un cliente saluda a la máquina dos. Su siguiente solicitud llega a la máquina uno. La máquina uno nunca ha visto a ese cliente, así que la llamada falla. Para quien ejecutaba MCP a escala, era un dolor de cabeza habitual.

La revisión de 2026 del Model Context Protocol (MCP) lo arregla de raíz. Esta guía explica el cambio con palabras sencillas y muestra cómo migrar tu propio servidor. Los datos de aquí siguen la especificación oficial y las notas de la versión, así que consúltalas para conocer las reglas exactas de cada campo.

El problema anterior: las sesiones

MCP es un estándar abierto que permite a las aplicaciones de IA usar herramientas y datos externos de una forma común. Los servidores ofrecen herramientas, recursos y prompts. Los clientes, como los asistentes de IA, los llaman. Para ver un ejemplo práctico, consulta nuestra guía de Playwright MCP.

En las versiones anteriores, una conexión empezaba con un pequeño ritual:

  1. El cliente enviaba una solicitud initialize.
  2. El servidor respondía y, por HTTP, podía añadir una cabecera Mcp-Session-Id.
  3. El cliente enviaba una notificación initialized.
  4. Cada solicitud posterior tenía que llevar el mismo ID de sesión.

En una sola máquina funciona bien. El servidor guarda la sesión en memoria. Con varias máquinas, la segunda solicitud puede llegar a una instancia que no sabe nada de la sesión. Los equipos tenían dos salidas: las sesiones pegajosas (fijar cada cliente a una instancia) o un almacén de sesiones compartido como Redis. Ambas añaden coste y puntos de fallo. Si una instancia muere, sus sesiones mueren con ella.

Qué cambió en MCP 2026

La especificación 2026-07-28 convierte MCP de un protocolo con estado y bidireccional en uno sin estado de solicitud y respuesta. Los responsables lo describen como el cambio principal. Los cuatro SDK de nivel 1 (TypeScript, Python, Go y C#) ya lo admiten.

  • Sin sesiones: Mcp-Session-Id se elimina de Streamable HTTP.
  • Sin handshake: initialize e initialized desaparecen.
  • Enrutamiento por cabeceras: las solicitudes llevan las cabeceras Mcp-Method y Mcp-Name.
  • MRTR: los servidores pueden pedir más datos a mitad de una llamada sin un flujo abierto.
  • Listas cacheables: los resultados de listas incluyen ttlMs y cacheScope.
  • Reglas de autorización más estrictas.
  • Marco de extensiones (Tasks pasó a ser una extensión) y una política de obsolescencia con al menos doce meses de aviso.

Un efecto secundario útil: los endpoints de listas como tools/list ya no difieren por conexión. Todos los clientes ven el mismo catálogo, lo que facilita el almacenamiento en caché y las pruebas.

Cómo es una solicitud sin estado

Esta es una llamada simplificada con Streamable HTTP:

POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search_docs

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_docs",
    "arguments": { "query": "refund policy" },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {},
      "io.modelcontextprotocol/clientInfo": { "name": "support-bot", "version": "1.2.0" }
    }
  }
}

No hay ID de sesión y no hace falta ninguna llamada previa. Ahora viajan tres cosas con cada solicitud:

  • Versión del protocolo: si el servidor no puede gestionarla, devuelve un error UnsupportedProtocolVersion.
  • Capacidades del cliente: lo que admite el cliente, en _meta.
  • Identidad del cliente: quién llama.

Una nueva llamada server/discover permite al cliente preguntar qué admite un servidor. Los servidores deben implementarla, pero los clientes pueden omitirla. El flujo antiguo necesitaba cinco pasos para una llamada a una herramienta. El nuevo necesita dos.

¿Dónde va el estado ahora?

El protocolo olvida, pero tu aplicación no tiene por qué hacerlo. Si tus herramientas necesitan memoria, como un carrito de compra, usa un identificador explícito: una herramienta crea el carrito, devuelve un ID de carrito y el modelo devuelve ese ID como un argumento normal.

// Ilustración simplificada, no es código real de un SDK
async function createCart(userId: string) {
  const cartId = crypto.randomUUID();
  await db.carts.insert({ cartId, userId, items: [] });
  return { cartId };
}

async function addItem(userId: string, cartId: string, sku: string) {
  const cart = await db.carts.find({ cartId, userId }); // comprobar la propiedad
  if (!cart) throw new Error("Cart not found");
  await db.carts.addItem(cartId, sku);
}

Aquí importan dos puntos. El estado vive en una base de datos, no en la memoria del servidor. Y la consulta comprueba tanto cartId como userId, de modo que un ID adivinado no pueda abrir el carrito de otra persona. Los responsables señalan que esto es mejor que un estado oculto en el transporte, porque el modelo puede ver el identificador y llevarlo entre herramientas. Si TypeScript es nuevo para ti, lee nuestro tutorial de TypeScript, y para modelar datos consulta el tutorial de SQL.

MCP con estado vs sin estado

Punto Con estado (antiguo) Sin estado (2026)
Inicio Primero el handshake Envía la solicitud real de inmediato
ID de sesión Mcp-Session-Id Ninguno
Enrutamiento A menudo sesiones pegajosas Funciona el round-robin simple
Almacén compartido Puede hacer falta para las sesiones No hace falta para el protocolo
Preguntas del servidor Solicitudes iniciadas por el servidor en flujos abiertos MRTR
Si una instancia muere Se pierden sus sesiones Reintenta en otra instancia

Ventajas de MCP sin estado

  • Balanceo de carga simple: cualquier balanceador normal puede repartir las solicitudes. Las pasarelas pueden enrutar y limitar la frecuencia usando las cabeceras Mcp-Method y Mcp-Name sin leer el cuerpo.
  • Escalado horizontal fácil: añade instancias y no hay nada que sincronizar.
  • Menos infraestructura: puedes prescindir del almacén de sesiones para MCP. Conserva cualquier almacén que necesites para los datos de tu propia aplicación, como carritos o trabajos.
  • Encaje con la nube y serverless: cada llamada es autocontenida, así que las funciones pueden arrancar, responder y terminar. Empaquetar servidores en contenedores también se simplifica; consulta nuestro tutorial de Docker.

Ten cuidado con las afirmaciones de rendimiento. MCP sin estado mejora la escalabilidad y la fiabilidad y reduce los viajes de ida y vuelta, pero no hace más rápido el código de tus herramientas, y cada solicitud lleva algo más de datos.

Cambios en Streamable HTTP

Enrutamiento basado en cabeceras

Las solicitudes POST deben incluir Mcp-Method y Mcp-Name. El servidor también las comprueba con el cuerpo y rechaza cualquier discrepancia. Esto impide que un cliente etiquete una llamada arriesgada como inofensiva.

Multi Round-Trip Requests (MRTR)

A veces una herramienta debe preguntar algo al usuario a mitad de camino, como “¿Eliminar este proyecto?”. Un servidor sin estado no puede mantener un flujo abierto para eso. Así que MRTR funciona así:

  1. El cliente llama a una herramienta.
  2. El servidor responde con resultType: "input_required" y sus preguntas.
  3. El cliente obtiene las respuestas, a menudo del usuario.
  4. El cliente reintenta la llamada con inputResponses.
  5. El servidor termina con resultType: "complete".

Si el servidor necesita enlazar los reintentos, puede usar requestState. MRTR sustituye a las antiguas solicitudes de elicitation, sampling y roots iniciadas por el servidor.

Otros cambios

  • Se elimina la reanudación de flujos SSE con Last-Event-ID. Si un flujo se corta, el cliente reenvía la solicitud con un ID nuevo, así que haz que las herramientas con efectos secundarios sean seguras de reintentar.
  • Los resultados de listas y lecturas incluyen ttlMs y cacheScope (público o privado), para que los clientes puedan almacenarlos en caché.

Cambios incompatibles que debes conocer

Área Qué cambió
Sesiones No hay sesiones de protocolo; se elimina Mcp-Session-Id
Handshake Se eliminan initialize e initialized; la versión, las capacidades y la información del cliente van en _meta
Resultados Cada resultado lleva un resultType obligatorio
Llamadas eliminadas ping, logging/setLevel y algunas notificaciones; el nivel de registro ahora es por solicitud
Errores Recurso no encontrado usa -32602
Tasks Movido a la extensión io.modelcontextprotocol/tasks
Obsoleto Roots, Sampling y Logging (siguen funcionando al menos 12 meses); el antiguo transporte HTTP+SSE

Seguridad en un mundo sin estado

Sin sesión, cada solicitud debe demostrarse a sí misma. Comprueba la versión del protocolo, comprueba que las cabeceras coinciden con el cuerpo, comprueba el token y valida los argumentos. Ya no existe el “ya comprobamos a este cliente antes”.

  • Registro de clientes: se prefieren los Client ID Metadata Documents (CIMD). El Dynamic Client Registration (DCR) está obsoleto, aún funciona por ahora y se eliminará en una versión futura.
  • Comprobación del emisor: los clientes deben validar el parámetro iss (RFC 9207) antes de canjear un código de autorización. Esto bloquea los ataques de “confusión”.
  • Credenciales vinculadas: las credenciales de cliente guardadas quedan ligadas al servidor que las emitió.
  • Los identificadores no son inicios de sesión: vincula siempre los datos al usuario autenticado y nunca trates la información de cliente de _meta como prueba de identidad.

¿Debes actualizar y cómo?

Actualiza pronto si ejecutas servidores en varias instancias o en la nube, usas sesiones pegajosas o un almacén de sesiones solo para MCP, despliegas en serverless, o los clientes de tus usuarios se están pasando a 2026-07-28. Un único servidor local para ti tiene menos urgencia, pero planifica el cambio.

  1. Busca en tu código initialize, initialized y Mcp-Session-Id.
  2. Enumera para qué se usaba cada valor de sesión. Todo lo que vaya más allá de la versión y la información del cliente necesita un nuevo responsable.
  3. Actualiza primero tu SDK. Gestiona gran parte del trabajo de cabeceras y _meta.
  4. Implementa server/discover, añade resultType a los resultados y añade ttlMs y cacheScope a las respuestas de listas.
  5. Sustituye las preguntas iniciadas por el servidor por MRTR.
  6. Trabaja en una rama de Git aparte. Nuestro tutorial de Git explica cómo.
  7. Prueba las rutas antigua y nueva en CI. Consulta GitHub Actions y prueba una solicitud suelta a mano con Postman.

Este es un cambio incompatible. Los clientes antiguos siguen funcionando solo si tu servidor también mantiene la ruta de sesión antigua, así que muchos equipos admitirán ambas durante un tiempo. Lecturas relacionadas: cómo descubren herramientas los agentes y WebMCP.

Preguntas frecuentes

¿Qué es MCP sin estado?

Significa que cada solicitud es autocontenida. El servidor no necesita memoria a nivel de protocolo de las solicitudes anteriores, y cada solicitud lleva su propia versión, información de cliente y capacidades.

¿Es MCP ahora completamente sin estado?

El protocolo sí, pero tu aplicación no tiene por qué serlo. Usa identificadores explícitos, como un ID de carrito, y guarda los datos en tu propia base de datos.

¿Qué pasó con Mcp-Session-Id?

Se eliminó de Streamable HTTP en la especificación 2026-07-28. Los servidores ya no lo emiten y los clientes ya no lo envían.

¿Es MCP 2026 retrocompatible?

No automáticamente. Los clientes antiguos siguen funcionando solo si tu servidor también admite la ruta de sesión antigua.

¿Sigo necesitando Redis para MCP?

No para las sesiones de MCP, ya que dejaron de existir. Puede que aún necesites almacenamiento para los datos de tu propia aplicación, así que revisa para qué se usa cada valor guardado antes de eliminar nada.

Sigue aprendiendo

Trabaja con Stack Quora

¿Necesitas ayuda con testing, WordPress o SEO?

Ayudamos a los equipos a lanzar mejor software y a hacer crecer sus sitios. Cuéntanos en qué trabajas y te sugeriremos un siguiente paso claro.