MCP 2026-07-28: Cómo la especificación sin estado cambia el diseño de los servidores remotos
La especificación MCP 2026-07-28 pasa a ser sin estado: sin sesiones ni proceso de establecimiento de conexión, además de MRTR, tareas e indicaciones de caché. ¿Qué cambia en los servidores remotos y cómo migrarlos?
Fuentes: MCP Just Changed Its Architecture: Why the 2026 Specification Makes MCP Truly Cloud-Native
Un punto de inflexión para MCP
La revisión del 2026-07-28 del Protocolo de Contexto de Modelo es un evento de mayor importancia que un simple aumento de versión rutinario. Revoluciona una de las suposiciones fundamentales de MCP, a saber, que un servidor remoto está organizado en torno a una sesión de protocolo vinculada a una conexión. MCP ha pasado de un modelo bidireccional con estado a un diseño de solicitudes y respuestas sin estado que funciona como la infraestructura HTTP distribuida habitual. El anuncio del candidato a versión final lo describió como la mayor revisión desde el lanzamiento del protocolo, y la especificación final se publicó el 28 de julio de 2026.
El MCP con estado no era incapaz de funcionar. El problema radicaba en que el estado a nivel de protocolo generaba restricciones operativas que resultaban problemáticas en las plataformas en la nube modernas. Una implementación remota podría tener que recordar un identificador de sesión, vincular esa sesión a un backend específico, coordinar el estado entre las réplicas y mantener activa una infraestructura de comunicación a largo plazo para interacciones que en realidad eran simples solicitudes y respuestas. Eso es manejable a pequeña escala. A gran escala, genera los mismos problemas con los que los sistemas web de sesiones persistentes han luchado durante años.
En el nuevo diseño se elimina la sesión de protocolo y se descarta el intercambio de mensajes initialize y initialized. Cada solicitud incluye los metadatos del cliente que necesita, y los servidores se pueden localizar mediante un proceso de descubrimiento explícito. Las interacciones de servidor a cliente se reorganizan como solicitudes de múltiples viajes, los encabezados HTTP transportan metadatos de enrutamiento, los clientes reciben indicaciones de caché en las respuestas de listas y recursos, el trabajo de larga duración se traslada a la extensión Tasks, se formaliza la gestión del ciclo de vida de las extensiones y se implementa una política de obsolescencia más estricta. El resultado es un núcleo MCP que se integra perfectamente detrás de balanceadores de carga simples, gateways, firewalls de aplicaciones web y despliegues sin servidor o con escalado automático.
Un modelo mental ayuda. El antiguo MCP remoto funcionaba como un protocolo de conexión conversacional distribuido, mientras que la nueva versión actúa como una API HTTP cuyo comportamiento con estado se expresa explícitamente en la capa de aplicación o extensión.
Por qué el MCP basado en sesiones resultó inadecuado
La frase “el MCP con estado dejó de funcionar” debe leerse con cuidado, ya que el MCP con estado no dejó de funcionar de repente. Lo que ocurrió es que el estado gestionado por el protocolo pasó a ser cada vez menos adecuado para la infraestructura en la que se desplegaban los servidores MCP.
En el modelo anterior, un cliente iniciaba la comunicación con una solicitud initialize, y el servidor respondía con un Mcp-Session-Id que toda solicitud posterior debía incluir. Esto vinculaba al cliente lógico a una sesión del lado del servidor. El propio ejemplo de antes y después proporcionado por los mantenedores deja claro el contraste: el flujo heredado requería una solicitud de inicialización seguida de la llamada real a la herramienta, mientras que el protocolo 2026 puede enviar la invocación de la herramienta directamente como una solicitud autónoma.
La consecuencia operativa es más importante que la solicitud HTTP ahorrada. Imagine un servicio MCP con ocho réplicas detrás de un balanceador de carga. Con sesiones, la solicitud uno crea una sesión en la instancia A, y la solicitud dos debe llegar nuevamente a la instancia A a menos que el estado de la sesión se comparta. Eso obliga a elegir entre dos estrategias: enrutamiento pegajoso, para que el mismo cliente siga accediendo a la misma instancia, o un almacén de sesiones compartido al que todas las instancias puedan acceder. Ambas vinculan el comportamiento del protocolo a la topología de despliegue.
El enrutamiento pegajoso reduce la flexibilidad, ya que el balanceador de carga ya no puede enviar cada solicitud a la instancia saludable que tenga capacidad. Un nodo puede quedar sobrecargado mientras otro permanece inactivo debido a que las sesiones están vinculadas a él, y el failover se vuelve más difícil cuando el estado original se encuentra en un nodo que ha desaparecido.
Mantener las sesiones en un almacén compartido resuelve parte del problema, pero introduce uno relacionado con los sistemas distribuidos. Cada sesión se convierte en un registro que debe crearse, replicarse, vencer, eliminarse y permanecer disponible en todo momento. En ese caso, el servidor MCP es una aplicación que incluye un subsistema de estado de sesiones distribuido entre varias máquinas. La versión candidata señala que las sesiones persistentes y los almacenes compartidos son infraestructuras que dejan de ser necesarias en la capa de protocolo una vez que las sesiones desaparecen.
Kubernetes, las plataformas de contenedores de autoescalado, las funciones en la nube y los entornos serverless hacen que el problema sea aún más evidente. Una solicitud puede llegar al pod A; este pod puede desaparecer durante el proceso de escalado, y la siguiente solicitud llega al pod F. Para un servicio HTTP sin estado, esto es completamente normal, pero perjudica a un protocolo cuya corrección presupone que el estado asociado a la conexión permanezca disponible.
El antiguo protocolo presentaba una segunda discrepancia conceptual. Utilizaba un modelo bidireccional en el que los servidores podían enviar solicitudes al cliente. La obtención de datos, el muestreo y la lista de raíces dependían todos de ese patrón, lo cual tenía sentido mientras existía un canal persistente. Los flujos bidireccionales persistentes sobrecargan la infraestructura, ya que los firewalls, proxies, gateways, sistemas de autoescalamiento, entornos serverless y grupos de conexiones tienen cada uno sus propios tiempos de espera y ciclos de vida. Mantener un flujo abierto solo para que el servidor pueda hacer una pregunta más tarde es fundamentalmente diferente del HTTP habitual de solicitud y respuesta.
Un desarrollador que lo probó de forma independiente ofrece un ejemplo concreto de los beneficios. Calificó al nuevo protocolo sin estado como mucho más fácil de implementar tanto en el lado del cliente como en el del servidor, y destacó que las aplicaciones ya no necesitan rastrear identificadores de sesión en el servidor ni redirigir la sesión a una sola máquina. Luego creó un explorador MCP sin estado y lanzó una nueva integración con Datasette MCP.
Por lo tanto, la idea no es que el estado sea algo negativo. El estado oculto del protocolo es costoso, mientras que el estado explícito de la aplicación es manejable.
La sesión y el intercambio de datos han desaparecido
El cambio que la gente nota primero es que ya no existe la sesión del protocolo. En 2026-07-28 desaparece el intercambio de initialize y notifications/initialized, al igual que el encabezado Mcp-Session-Id. Cada solicitud ahora incluye la versión del protocolo y las capacidades del cliente dentro de _meta. Un cliente que quiera conocer información sobre un servidor con antelación puede llamar a server/discover. El registro de cambios final clasifica ambas eliminaciones, la de la sesión y la del proceso de establecimiento de conexión, como cambios importantes.
Anteriormente, el flujo consistía en un proceso de establecimiento de conexión seguido de la llamada real:
Client
|
| initialize
v
MCP Server
|
| Mcp-Session-Id = ABC
v
Client
|
| tools/call + Mcp-Session-Id: ABC
v
Same logical server session
Ahora la llamada puede realizarse directamente:
Client
|
| tools/call
| protocol version
| capabilities
| client metadata
v
Load Balancer
|
+----> MCP Instance A
|
+----> MCP Instance B
|
+----> MCP Instance C
Una solicitud ahora contiene todo el contexto que la capa de protocolo necesita para entenderla. Además, Streamable HTTP copia metadatos clave en los encabezados, como por ejemplo en esta solicitud:
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
El cuerpo del mensaje sigue siendo la fuente de verdad, mientras que el sobre HTTP proporciona metadatos que los intermediarios pueden utilizar. La especificación exige que los intermediarios y los mecanismos de transporte rechacen, cuando sea apropiado, combinaciones incoherentes de encabezados y cuerpo.
Eliminar la sesión no implica que las aplicaciones no puedan tener estado. El estado de la aplicación simplemente se convierte en una parte explícita del modelo de datos. Por ejemplo, un flujo de trabajo de compras podría devolver un identificador para el carrito:
{
"basket_id": "bsk_8f2a..."
}
Y la siguiente llamada a la herramienta devolvería ese mango junto con el artículo:
{
"basket_id": "bsk_8f2a...",
"item_id": "SKU-123"
}
En el lado del servidor, el identificador se busca en Redis, PostgreSQL, DynamoDB, Cosmos DB, un almacén de objetos o cualquier sistema adecuado. El transporte MCP deja de ser responsable de ese estado. Los mantenedores recomiendan identificadores explícitos como basket_id y browser_id como forma de reemplazar el estado del protocolo oculto.
Eso implica una separación arquitectónica, mostrada aquí:
MCP protocol state
|
v
NONEApplication state
|
v
Explicit IDs + external state store
Long-running task state
|
v
Tasks extension + durable task store
Se podría decir que es la idea más importante de toda esta versión.
Metadatos y descubrimiento por solicitud
Si no hay intercambio inicial de información, ¿cómo sabe un servidor qué versión de protocolo y qué capacidades soporta un cliente? La respuesta son los metadatos por solicitud. Los campos reservados _meta se encuentran en el espacio de nombres io.modelcontextprotocol/*, y la versión junto con las capacidades del cliente se incluyen en cada solicitud, sin necesidad de una negociación única que la conexión recuerde en silencio. Cuando un cliente elige identificarse, su identidad también se transmite como metadatos por solicitud, y los servidores pueden incluir los suyos en los metadatos del resultado. Conceptualmente, una solicitud se ve así:
{
"jsonrpc": "2.0",
"id": 42,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"query": "MCP stateless architecture"
},
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {
"extensions": {
"io.modelcontextprotocol/tasks": {}
}
},
"io.modelcontextprotocol/clientInfo": {
"name": "my-agent",
"version": "3.2.0"
}
}
}
}
Cuando es útil contar con información desde el principio, el servidor implementa server/discover. El registro de cambios final lo convierte en un RPC obligatorio para los servidores, de modo que los clientes pueden consultar las versiones de protocolo soportadas, sus capacidades y la identidad del servidor antes de realizar cualquier otra acción. Esto resulta práctico cuando un cliente necesita decidir su comportamiento en función de lo que soporta el servidor.
Existe una distinción sutil aquí: los clientes pueden optar por no llamar a server/discover, pero los servidores deben ofrecerlo. Por lo tanto, MCP ya no necesita este mecanismo de descubrimiento para establecer una sesión, aunque sigue ofreciendo una forma formal de inspeccionar las capacidades de forma proactiva. Su diseño se asemeja a las API HTTP maduras, donde cada solicitud es interpretable de forma independiente y los puntos de extremo de descubrimiento opcionales o los metadatos proporcionan detalles más completos.
Enrutamiento round-robin y escalado a cero
Aquí el diseño resulta más evidente en la arquitectura en la nube. Sin sesiones de protocolo, un endpoint MCP puede funcionar detrás de un balanceador de carga ordinario con un enrutamiento simple por round-robin. El anuncio oficial presenta eso como el objetivo deseado: varias instancias MCP, enrutamiento por round-robin y sin almacén compartido de sesiones de protocolo.
Tomemos tres réplicas detrás de un balanceador de carga:
+------------------+
| Load Balancer |
+---------+--------+
|
+------------+------------+
| | |
v v v
MCP Pod A MCP Pod B MCP Pod C
La solicitud 1 puede ir a A, la solicitud 2 a C y la solicitud 3 a B. Ninguna regla de protocolo exige que las tres lleguen a la misma instancia, que es precisamente la característica que desean los sistemas cloud-native.
Supongamos que un escalador automático de pods horizontales decide que solo se necesita una réplica durante la noche. Dos instancias pueden desaparecer. Cuando llega una solicitud más tarde, se puede iniciar una instancia nueva que la atienda de inmediato, ya que no necesita reconstruir primero una sesión de protocolo. La arquitectura queda así:
El servicio MCP en sí es sin estado, y el estado del negocio permanece duradero fuera de él.
No obstante, hay una advertencia. Un MCP sin estado no hace que todas las aplicaciones MCP se escalen a cero automáticamente. Si una aplicación mantiene una cesta, flujo de trabajo, conversación, transacción o tarea únicamente en la memoria de proceso, simplemente ha recreado el problema del estado oculto en un nivel superior.
Para una escala real hacia cero es necesario que todo aquello que debe sobrevivir al cierre de una instancia se almacene en una infraestructura duradera. Un diseño de producción plausible utiliza Redis para la coordinación a corto plazo, PostgreSQL o una base de datos NoSQL gestionada para el estado permanente de la aplicación, y un almacén de objetos para archivos de gran tamaño. La autenticación también se mantiene fuera del proceso, gestionada por el sistema de autorización OAuth u OIDC en lugar de deducirse de la memoria local.
El compromiso es claro: el protocolo hace posible una infraestructura sin estado, y ahora el diseñador de la aplicación es responsable de decidir qué estado sobrevive, dónde se almacena, cómo se autoriza, cuánto tiempo permanece y cómo se elimina. Eso representa un límite más saludable en el diseño de sistemas.
Gestionar el estado por uno mismo
Los identificadores explícitos podrían ser el resultado de mayor alcance de este modelo. Tomemos como ejemplo un agente de adquisiciones basado en IA al que se le indica ordenar 100 GPUs, obtener la aprobación y enviar el pedido. Un diseño basado en sesiones podría ocultar fácilmente ese flujo de trabajo dentro del estado de la sesión MCP. La nueva arquitectura favorece algo más visible, donde la creación de la solicitud devuelve un identificador:
create_purchase_request()
|
v
purchase_request_id = pr_123
|
v
request_approval(pr_123)
|
v
approval_id = appr_789
|
v
submit_purchase(pr_123, appr_789)
El estado ya no está implícito en una sesión HTTP. Se trata de datos de dominio, y eso es poderoso porque los datos de dominio pueden ser protegidos, auditados, versionados, replicados y consultados de forma independiente. Un registro de estado podría verse conceptualmente de esta manera:
{
"purchase_request_id": "pr_123",
"user_id": "user_42",
"status": "awaiting_approval",
"items": [
{
"sku": "GPU-H100",
"quantity": 100
}
],
"created_at": "2026-08-21T08:00:00Z"
}
El servidor MCP simplemente resuelve el identificador y valida la autorización. La observabilidad también mejora. En lugar de “la sesión ABC hizo algo”, un sistema puede informar que la solicitud de compra pr_123 pasó de draft a approved, lo cual representa un rastro con un significado comercial real.
También resulta más sencillo analizar la seguridad. Un identificador opaco por sí solo nunca constituye una autorización suficiente, y el servidor debe confirmar aún así que la persona autenticada tiene permiso para acceder al estado asociado a ese identificador. La extensión Tasks trata los identificadores de tareas de la misma manera: los servidores deben generar identificadores difíciles de adivinar, y excluir tasks/list es una decisión intencionada en materia de privacidad, ya que nadie puede enumerar los identificadores de tareas de otras personas.
Solicitudes de múltiples idas y venidas
Eliminar las solicitudes persistentes de servidor a cliente genera otro problema básico. Considere una llamada a una herramienta como esta:
delete_customer_data(customer_id=123)
El servidor no puede eliminar nada de forma segura hasta que un usuario lo confirme, mediante un mensaje similar a “¿Eliminar 48 registros?”. El modelo heredado podría mantener un canal abierto y solicitar más información al cliente. Un diseño sin estado no puede depender de una conexión permanentemente abierta, y las solicitudes de múltiples viajes, o MRTR, existen para cubrir esa carencia.
MRTR abarca una única operación lógica que requiere varios intercambios sin una conexión persistente ni una sesión del lado del servidor. Mientras se espera la confirmación, aclaraciones o muestreo, nada mantiene abierta una conexión HTTP ni depende de un estado de conexión persistente. En su lugar, la interacción se convierte en una cadena de solicitudes HTTP separadas unidas por un estado de continuación. El cliente primero solicita una acción, como tools/call para una herramienta de eliminación de datos. El servidor omite iniciar su propio RPC hacia el cliente mientras la operación original permanece suspendida y responde con un resultado intermedio indicando que necesita más datos de entrada:
{
"resultType": "input_required",
"inputRequests": {
"confirm": {
"type": "elicitation",
"message": "Delete 48 records?",
"schema": {
"type": "boolean"
}
}
},
"requestState": "..."
}
El cliente recoge las respuestas y vuelve a enviar la solicitud original con ellas adjuntas:
Client
|
| tools/call
v
Server
|
| input_required
| requestState
v
Client
|
| user confirmation
v
Client
|
| same operation + inputResponses + requestState
v
Any MCP instance
Por lo tanto, la operación se divide en varios viajes de ida y vuelta por HTTP, sin necesidad de mantener la conexión abierta. La versión oficial describe a MRTR como el sustituto de los patrones iniciados por el servidor elicitation/create, sampling/createMessage y roots/list.
El campo clave es requestState. Todo lo que el servidor necesita para reanudar se incluye en él, empaquetado como un token opaco que está firmado, encriptado o protegido de alguna otra forma contra modificaciones. La especificación no almacena todo el estado de la aplicación en un único almacén de sesiones MCP central, y la información necesaria para continuar una interacción simplemente se transmite en la siguiente solicitud. Se asemeja a un token de continuación, y la mayor ventaja es que una interacción lógica prolongada ya no implica una conexión física prolongada.
Encabezados HTTP e indicaciones de caché
Dejar de ser un estado estatal aumentaría por sí solo la escalabilidad, pero el protocolo también se vuelve más fácil de manejar para la infraestructura HTTP. Las solicitudes HTTP streamables llevan encabezados estandarizados como Mcp-Method y Mcp-Name, de modo que las pasarelas y los balanceadores de carga pueden decidir sobre el enrutamiento, la autorización, los límites de velocidad y la telemetría sin tener que abrir los cuerpos JSON-RPC. El cuerpo sigue siendo la fuente de autoridad, y cualquier discrepancia entre un encabezado reflejado y el campo correspondiente en el cuerpo conduce a su rechazo.
Una pasarela podría leer estos dos valores:
Mcp-Method = tools/call
Mcp-Name = search
y aplicar verificaciones de políticas de este tipo:
tools/call + search -> route/search-cluster
tools/call + execute -> route/execution-cluster
resources/read -> route/resource-cluster
Eso permite una separación clara entre la capa de control y la capa de datos, ya que un intermediario puede identificar la categoría operativa de una solicitud sin necesidad de comprender el esquema JSON de la aplicación.
La versión también añade metadatos de caché a través de ttlMs y cacheScope. Una respuesta de lista podría incluirlos de la siguiente manera:
{
"result": {
"tools": [
...
],
"ttlMs": 60000,
"cacheScope": "public"
}
}
La semántica imita intencionadamente a HTTP cache-control. ttlMs indica al cliente cuánto tiempo un resultado se considera actual, mientras que cacheScope indica si es seguro compartir ese resultado. La especificación final separa "public" de "private" y advierte a los implementadores que no consideren el alcance del caché como un sustituto de las verificaciones de autorización. La noción de actualidad funciona de la siguiente manera:
fresh_until = response_received_time + ttlMs
Normalmente, un cliente debería volver a obtener los datos cuando los necesite y estos ya estén obsoletos, en lugar de usar el TTL como intervalo obligatorio de consulta. Para las implementaciones que sí realizan consultas periódicas, la especificación recomienda el uso de variabilidad aleatoria y estrategias de retroceso.
Los catálogos de herramientas hacen evidente este valor. Si un servidor lista 250 herramientas y 500 agentes se conectan, las llamadas constantes a tools/list por parte de cada uno generan un intenso tráfico en el plano de control. Un TTL razonable permite a los clientes reutilizar el catálogo, y un ordenamiento determinista evita cambios innecesarios en el conjunto de herramientas serializadas, lo que puede mantener estables los cachés de prompts de los LLMs. El registro de cambios recomienda el ordenamiento determinista precisamente por esta razón. Otra ventaja es que las conexiones SSE abiertas ya no son la única forma de saber si la lista ha cambiado, por lo que tanto la frescura del caché como las notificaciones de cambios pueden funcionar al mismo tiempo.
Tareas de larga duración
Las API de solicitud y respuesta sin estado aún tienen que manejar tareas que duran minutos u horas. Considere una llamada como esta:
run_ml_training_job()
Puede enviar un trabajo de entrenamiento distribuido, esperar a que estén disponibles las GPUs, ejecutar múltiples etapas, generar puntos de control y cargar los artefactos resultantes. Mantener una conexión HTTP abierta durante todo este proceso es algo frágil. La arquitectura 2026-07-28 lo gestiona a través de la extensión Tasks, identificada como io.modelcontextprotocol/tasks.
Para una tools/call compatible, el servidor puede responder con un identificador de tarea en lugar del resultado final:
{
"resultType": "task",
"task": {
"taskId": "task_7b93...",
"status": "working"
}
}
El cliente puede solicitar luego el estado:
tasks/get(taskId)
Y continúe haciendo consultas hasta que la tarea muestre completed, failed o cancelled. La extensión también ofrece tasks/update para ingresar datos adicionales y tasks/cancel para cancelarla.
Hay una distinción crucial. El protocolo principal es sin estado, mientras que la extensión Tasks representa deliberadamente un estado duradero:
Core MCP
|
+---- Stateless request/response
Tasks extension
|
+---- Durable asynchronous state machine
Eso no es una contradicción. Es una separación de responsabilidades. Una tarea puede asociarse a un sistema de tareas externo, como en este flujo:
MCP tools/call
|
v
Create task
|
v
Queue / workflow engine
|
+--> Kubernetes Job
|
+--> Azure Batch
|
+--> AWS Step Functions
|
+--> Databricks Job
|
+--> CI/CD pipeline
Los clientes utilizan el ID de tarea MCP como identificador duradero para acceder al estado de ese flujo de trabajo externo. Las configuraciones en producción no deben almacenar el estado de las tareas únicamente en un diccionario dentro del proceso. La extensión describe las tareas como máquinas de estado duraderas y recomienda guardar los IDs de tarea de forma persistente, de modo que las consultas continúen tras una caída del cliente o un reinicio del servidor.
Queda una sutileza en la implementación. La extensión Tasks podría seguir necesitando que las solicitudes se dirijan al sistema que almacena el estado de la tarea. La propuesta final permite que Mcp-Name contenga el ID de tarea para las operaciones tasks/get, tasks/update y tasks/cancel, lo que permite a los intermediarios enviar solicitudes de seguimiento al sistema que guarda el estado cuando sea necesario. El intercambio completo entre el cliente, el servidor MCP y el motor de tareas se muestra en este diagrama de secuencia:
Client MCP Server Task DB / Engine
| | |
|--- 1. tools/call ------>| |
| |--- 2. Register Task ----->| (Status: working)
|<-- 3. Return taskId ----| |
| | |
|--- 4. tasks/get ------->| |
| \--- 5. Query state ----->| (Status: working)
|<-- 6. Status: working --/ |
| | |
|--- 7. tasks/get ------->| |
| \--- 8. Query state ----->| (Status: completed)
|<-- 9. Final Result -----/ |
En el patrón típico, un cliente inicia el trabajo con una tools/call, y el servidor escribe una entrada de tarea duradera en un backend compartido como Redis, PostgreSQL o un motor de flujos de trabajo como AWS Step Functions o Kubernetes. Luego devuelve de inmediato un taskId y un estado inicial de working. La primera conexión HTTP se cierra de forma limpia y libera los recursos de red, y el cliente verifica periódicamente el progreso con tasks/get.
Por lo tanto, la afirmación arquitectónica precisa no es que todo en MCP sea sin estado. El núcleo de MCP es sin estado, y el comportamiento con estado se modela explícitamente a través de datos de aplicación y extensiones como Tasks.
Un agente de operaciones de datos y ML en producción
Imagínese una plataforma de IA en producción que expone herramientas MCP a un agente empresarial. El agente cuenta con herramientas como estas:
search_dataset()
inspect_schema()
run_sql()
start_training_job()
get_training_metrics()
deploy_model()
rollback_deployment()
El usuario solicita lo siguiente: encontrar el conjunto de datos más reciente sobre abandono de clientes, analizarlo, entrenar un modelo preliminar, comparar las métricas con el modelo en producción y desplegarlo solo si la mejora es de al menos un 5%.
Bajo la antigua arquitectura con estado, el sistema podía mantener una sesión de protocolo de larga duración que registraba la interacción, lo que vinculaba el flujo de trabajo lógico del usuario a una instancia de servidor específica. Bajo la nueva arquitectura, el proceso puede diseñarse de manera explícita. La primera llamada podría ser una búsqueda:
search_dataset("customer churn latest")
y el servidor devuelve un identificador del conjunto de datos:
{
"dataset_id": "ds_2026_08_20_0042"
}
La siguiente solicitud inspecciona el esquema a través de ese identificador:
inspect_schema("ds_2026_08_20_0042")
El esquema proviene del sistema de metadatos. La siguiente solicitud inicia el entrenamiento:
start_training_job("ds_2026_08_20_0042")
El servidor MCP crea una tarea duradera:
task_id = "task_train_98af..."
El entrenamiento en sí se ejecuta fuera del proceso MCP. El cliente lo consulta periódicamente:
tasks/get("task_train_98af...")
Y la tarea podría pasar por una serie de estados:
QUEUED
|
RUNNING
|
EVALUATING
|
INPUT_REQUIRED
|
RUNNING
|
COMPLETED
En el estado INPUT_REQUIRED el sistema podría solicitar la aprobación para el despliegue, señalando que el candidato es un 7.2% mejor pero aumentaría el gasto en GPU en un 18%. MRTR puede plantear esa pregunta sin mantener abierta la primera conexión. El cliente responde de la siguiente manera:
inputResponses = {
"approve": true
}
Y la solicitud se reanuda.
Ahora imagine que el servidor MCP está ejecutándose en seis réplicas de Kubernetes:
Ingress
|
Load Balancer
|
+------+------+------+------+
| | | | |
MCP1 MCP2 MCP3 MCP4 MCP5
|
v
Task Store
|
+-------+-------+
| |
Redis PostgreSQL
|
v
Workflow Engine
|
+-----+------+
| |
GPU Job Model Registry
Aquí, la primera llamada tools/call llega a MCP2, la siguiente solicitud a MCP5, la consulta de tareas a MCP1 y el intento de aprobación nuevamente a MCP3. Nada falla, ya que el protocolo ya no supone que una sesión esté vinculada a un servidor específico. Si un MCP3 deja de funcionar, es reemplazado por Kubernetes. Si la implementación pasa de seis réplicas a dos durante la noche, el flujo de trabajo sigue funcionando porque el estado de las tareas y las aplicaciones se encuentra fuera del proceso. Allí es donde la especificación demuestra su valor práctico.
Autenticación y refuerzo de la seguridad
Junto con los cambios sin estado, se incluyen mejoras significativas en materia de seguridad. La versión final exige un comportamiento más estricto de OAuth y OIDC: los servidores de autorización deben proporcionar un parámetro iss tal como se describe en RFC 9207, y los clientes MCP deben verificar dicho emisor antes de canjear un código de autorización, lo que evita ataques de confusión entre servidores de autorización. Las credenciales del cliente también están vinculadas al emisor que las creó, por lo que está prohibido reutilizarlas con otro servidor de autorización. El registro dinámico de clientes sigue existiendo por compatibilidad, pero está formalmente obsoleto, siendo reemplazado por los Documentos de Metadatos de ID de Cliente.
El modelo de amenazas cambia de manera útil con la falta de estado, aunque también conlleva responsabilidades. Una implementación en producción debe autenticar cada solicitud y autorizar la operación específica de la herramienta o recurso. Debe verificar los identificadores de estado explícitos en relación con el principal autenticado, evitar que se enumeren los IDs de las tareas y encriptar el estado sensible tanto al almacenarse como al transmitirse. Considere un registro como este:
basket_id = bsk_123
user_id = user_456
Nadie debería concluir de esto que poseer bsk_123 es suficiente para actuar sobre el carrito. Antes que nada, el servidor debería verificar la propiedad, de la siguiente manera:
authenticated_subject == basket.owner
Y luego se aplican permisos específicos para cada herramienta.
También está documentada la propagación del contexto de seguimiento W3C, que se transmite a través de _meta mediante traceparent, tracestate y baggage. El seguimiento a través del host, el cliente MCP, el servidor MCP y los servicios posteriores se vuelve mucho más sencillo, y los mantenedores lo relacionan directamente con los seguimientos compatibles con OpenTelemetry. Por lo tanto, la observabilidad debería formar parte del diseño desde el primer día. Una ruta de solicitud rastreada podría verse así:
User Request
|
v
Agent
|
| traceparent
v
MCP Client
|
| traceparent
v
MCP Gateway
|
v
MCP Server
|
v
Database / Queue / API
La traza resultante puede mostrar toda la cadena causal y no un conjunto de transacciones HTTP no relacionadas.
Las extensiones pasan a ser de primera categoría
Las extensiones también adquieren un estatus formal. Ya existían, pero nada se asemejaba a un ciclo de vida maduro al nivel de un protocolo principal. Ahora cada extensión cuenta con un identificador de DNS inverso, negociación explícita de capacidades, su propio repositorio, control de versiones independiente y un trámite dedicado dentro del proceso SEP.
La razón es que MCP se está expandiendo más rápido de lo que una sola versión de protocolo monolítico puede evolucionar de manera segura. Las tareas de soporte no deberían obligar a todas las implementaciones a ejecutar trabajos distribuidos asíncronos, y un servidor de línea de comandos mínimo no debería verse forzado a adoptar MCP Apps. Los ecosistemas de estándares más grandes siguen el mismo enfoque de mantener el núcleo pequeño y estable, y de trasladar las funciones especializadas a módulos que cambian según su propio calendario.
Dos extensiones son las más destacadas en esta versión. MCP Apps añade una interfaz de usuario interactiva generada por el servidor dentro de un iframe aislado, mientras que Tasks introduce la ejecución asíncrona. La jerarquía resultante se ve así:
MCP
|
+----------+----------+
| |
Core Protocol Extensions
| |
Stateless HTTP +-----+------+
| |
Tasks MCP Apps
Esto brinda a MCP una forma mucho más sostenible de evolucionar.
Desactualizaciones y actualizaciones
La versión introduce intencionadamente un ciclo de vida formal para las funcionalidades. El registro de cambios define los estados Activo, Obsoleto y Eliminado, y establece un período mínimo de desactualización de doce meses, de modo que los desarrolladores de aplicaciones cuenten con un período de migración predecible y no tengan que realizar cambios de emergencia cada vez que el protocolo evoluciona.
Roots, Sampling y Logging se encuentran en la lista de desactualizaciones. Las recomendaciones oficiales para la migración sugieren reemplazar Roots por parámetros de herramienta explícitos, URI de recursos o configuración del servidor; reemplazar Sampling por integraciones directas con proveedores de LLM; y reemplazar Logging por stderr u OpenTelemetry. El transporte HTTP+SSE anterior también está obsoleto, y Streamable HTTP es la opción preferida.
La API experimental Tasks del 2025-11-25 marca otro punto de migración. Ahora se encuentra en la extensión io.modelcontextprotocol/tasks con un ciclo de vida rediseñado basado en tasks/get, tasks/update y tasks/cancel. tasks/list ya no existe porque listar tareas sin una sesión plantea problemas de alcance y privacidad.
Para una organización que migra una flota existente de MCP, el orden más seguro es el siguiente:
- Actualice el SDK y luego busque código que dependa de
Mcp-Session-Id. Examine detenidamente los diccionarios indexados por sesión, los registros de conexión y las reglas de enrutamiento de sesiones persistentes creadas con el modelo antiguo. - Separe el estado del protocolo del estado de la aplicación, asignando a todo lo que represente un estado empresarial real un identificador explícito y trasladándolo a un almacenamiento adecuadamente duradero.
public frente al private tiene consecuencias de seguridad.La documentación actual de migración del SDK de TypeScript también muestra esta realidad transitoria. Las implementaciones pueden soportar el nuevo protocolo manteniendo la compatibilidad con los clientes de la era anterior, de modo que la migración puede ser gradual y no requiere un cambio completo en todo el ecosistema.
Qué significa esto para la arquitectura MCP
La consecuencia más importante es que MCP ahora separa cuatro aspectos que antes estaban mezclados:
- La capa de protocolo es responsable del significado de los mensajes.
- La capa de transporte transmite las solicitudes a través de HTTP o stdio.
- La capa de aplicación almacena el estado, el contexto de autorización, los flujos de trabajo y lo que identifica al objeto de negocio.
- La capa de extensiones proporciona funciones opcionales como tareas asíncronas y aplicaciones MCP.
La estructura en capas se ve así:
+----------------------------+
| MCP Protocol |
| JSON-RPC + request model |
+-------------+--------------+
|
+-------------v--------------+
| Transport |
| stdio / Streamable HTTP |
+-------------+--------------+
|
+-------------v--------------+
| Application Layer |
| explicit IDs + databases |
+-------------+--------------+
|
+-------------v--------------+
| Extensions |
| Tasks / MCP Apps / others |
+----------------------------+
Esto permite una escalabilidad mucho mejor que intentar incluir todo en una sola abstracción de sesión con ámbito de conexión, y alinea a MCP con las prácticas establecidas desde hace tiempo en los sistemas distribuidos: manejo de solicitudes sin estado, estado externo duradero, identificadores explícitos, semántica de caché, reintentos idempotentes, manejadores de tareas asíncronas y trazado distribuido.
Los compromisos
Existen costos. La principal ventaja es la escalabilidad horizontal, pero el precio a pagar es que la gestión del estado pasa a ser responsabilidad de la aplicación. Los desarrolladores deben decidir cómo se crean los manejadores de estado, cuánto tiempo permanecen activos, dónde se almacenan, cómo se autoriza el acceso y cómo se eliminan los que ya no son válidos.
Dado que las capacidades del cliente y los metadatos se transfieren con cada solicitud, las cargas de datos aumentan ligeramente. Los bytes adicionales suelen ser pocos, pero los sistemas de alto rendimiento deben evitar repetir innecesariamente las cargas de datos de capacidades.
MRTR hace posible el HTTP sin estado para intercambios que anteriormente requerían solicitudes iniciadas por el servidor, aunque expone de forma más abierta la máquina de estados de la interacción. El cliente debe reconocer input_required, mantener el estado de la solicitud, recopilar las respuestas y volver a intentarlo adecuadamente.
Las tareas se encargan de la ejecución de larga duración, a costa de un almacén de tareas, que es otro subsistema más duradero. Eso no es un defecto, sino un estado explícito que sustituye al estado oculto del protocolo.
El caché mejora la eficiencia, pero valores incorrectos de cacheScope pueden generar problemas de seguridad. Una respuesta etiquetada erróneamente como "public" podría volverse compartible entre contextos de autorización, y las directrices de caché advierten que el alcance del caché no reemplaza la autorización a nivel primitivo.
El núcleo sin estado no debe interpretarse como una arquitectura inferior. Es mejor describirlo como una responsabilidad distribuida de manera más sensata.
El cambio conceptual
Al preguntarse dónde tiene lugar la interacción lógica, el modelo antiguo indicaba implícitamente que ocurría dentro de la sesión MCP vinculada a la conexión. El nuevo modelo, en cambio, pregunta qué estado realmente necesita la operación, y la respuesta es clara: un identificador de dominio, un identificador de tarea, un contexto de autorización o un token de estado de solicitud necesario para continuar. Esa abstracción permite una escalabilidad mucho mejor.
Las transacciones tienen IDs de transacción, los flujos de trabajo de Kubernetes tienen IDs de tarea, los carritos de compras tienen IDs de carrito, las pipelines de CI tienen IDs de ejecución y los trabajos de entrenamiento tienen IDs de ejecución. Las aplicaciones MCP ahora pueden utilizar el mismo vocabulario.
Qué aporta esta versión
Esta versión va más allá de una simple limpieza del protocolo. Transforma a MCP de una integración de agentes orientada a conexiones hacia sistemas distribuidos nativos de la nube, y los cambios son los siguientes:
- La eliminación de
Mcp-Session-Idpone fin a la afinidad a nivel de protocolo. - Al eliminar el proceso de handshake, cada solicitud se convierte en un intercambio autónomo.
server/discoverpermite el descubrimiento de capacidades sin ninguna semántica de sesión asociada.Mcp-MethodyMcp-Nameexponen el tráfico de MCP a las herramientas HTTP habituales.ttlMsycacheScopebrindan a los clientes y las pasarelas un vocabulario común para gestionar la actualidad y el intercambio de datos.- MRTR abandona la idea de que un servidor que solicita algo al cliente necesite una conexión que nunca se cierre.
- Las tareas representan una abstracción duradera para operaciones que superan la duración de una sola solicitud HTTP.
- Los identificadores explícitos sacan el estado del negocio de los metadatos de transporte ocultos y lo integran en el propio modelo de datos de la aplicación.
- Las extensiones evitan que el núcleo se vuelva excesivamente grande al mismo tiempo que permiten que el ecosistema funcione con rapidez.
- Una autorización más estricta se ajusta al comportamiento real de las implementaciones de OAuth y OIDC.
- Las convenciones de contexto de seguimiento de OpenTelemetry facilitan la observación de los sistemas MCP distribuidos.
- Una política formal de obsolescencia brinda al ecosistema una forma predecible de evolucionar.
El modelo sin estado hace que MCP sea mucho más fácil de implementar, y las herramientas desarrolladas por el desarrollador independiente, como Explorer y Datasette, demuestran que esta simplicidad se convierte en herramientas útiles. Su descripción del protocolo antiguo, que requería inicialización de sesión, y del nuevo, que consiste en una única solicitud autónoma, representa el cambio operativo que buscaban los mantenedores.
La conclusión para los arquitectos es que MCP no eliminó el estado. Lo que sí eliminó fue el estado oculto propiedad del protocolo, reemplazándolo por un estado explícito y componible propiedad de la aplicación. Ese cambio permite que un servidor MCP pase de esta combinación:
sticky sessions
+
shared session store
+
long-lived connections
+
connection affinity
y hacia este:
stateless request handling
+
ordinary load balancing
+
external durable state
+
explicit handles
+
asynchronous task primitives
Para implementaciones empresariales, esto representa una gran ventaja, ya que se adapta mucho mejor a Kubernetes, el escalado automático, la ejecución sin servidores, las pasarelas de API, los despliegues sin interrupciones, el enrutamiento multi-región, el rastreo distribuido y las grandes plataformas multi-inquilino. En pocas palabras, la especificación convierte a MCP de un estándar para cómo los agentes llaman a las herramientas en una infraestructura que encaja perfectamente dentro de los sistemas modernos de IA distribuida.
Leer más
- Cuando un agente de IA tiene 1,000 herramientas MCP: selección, contexto y habilidades — Conectar agentes a muchos servidores MCP genera una explosión de herramientas, un contexto excesivo y selecciones inadecuadas. Por qué el descubrimiento, las habilidades y las pasarelas pueden ser más importantes que el acceso directo.
- 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é proteger y cómo una empresa debe comenzar de forma gradual.
- Los servidores MCP se están convirtiendo en plataformas de capacidades, no en envoltorios de herramientas — Transformación de herramientas, búsqueda, nombres de espacio, visibilidad, proxies, habilidades, tareas, control de versiones y pruebas: patrones que convierten a un servidor MCP en una plataforma de capacidades gestionada.
- Diez servidores MCP que vale la pena instalar primero, en orden de prioridad para desarrolladores — Un conjunto inicial clasificado de servidores MCP para asistentes de programación en IA, desde Context7 y GitHub hasta Postgres y sistemas de memoria, con configuraciones de instalación y advertencias sobre permisos.