Por el equipo de Kiwop · Agencia Digital especializada en Desarrollo de Software e Inteligencia Artificial aplicada · Publicado el 29 de julio de 2026 · Última actualización: 29 de julio de 2026
TL;DR — El 28 de julio de 2026 se publicó la quinta revisión de MCP y es la que más cambia desde que nació el protocolo. Desaparecen las sesiones y el handshake `initialize`: cada petición viaja sola, con su versión y capacidades dentro de `_meta`. Las peticiones que antes iniciaba el servidor (sampling, elicitation, roots) pasan al patrón multi round-trip. Llegan cabeceras obligatorias para enrutar sin abrir el cuerpo, listas cacheables y una autorización más dura. Si tu servidor es stdio local, no te corre prisa. Si es remoto y guarda sesión, el rediseño empieza hoy. Lo deprecado aguanta doce meses.

Hay actualizaciones de protocolo que se resumen en una línea de changelog y hay otras que cambian cómo se despliega el software que las habla. La revisión 2026-07-28 de Model Context Protocol es de las segundas. No añade una función más a un protocolo que ya conocías: le quita la memoria. Y cuando un protocolo deja de recordar, lo que cambia no es la API, es la arquitectura de todo lo que corre debajo.
En abril publicamos la comparativa entre MCP, WebMCP y A2A y dijimos que el siguiente hito relevante sería la consolidación del transporte Streamable HTTP y la retirada del SSE legacy. Las dos cosas se han cumplido, y de paso ha llegado bastante más de lo que esperábamos. Este artículo es la lectura técnica de qué cambia exactamente, qué se rompe, y qué tiene que hacer un equipo que ya tiene servidores MCP corriendo en producción. Con la especificación en la mano, no con el resumen de la nota de prensa.
Qué se publicó el 28 de julio
MCP nació en noviembre de 2024 como una forma de que un modelo hablase con herramientas externas sin que cada integración fuese un adaptador a medida. Desde diciembre de 2025 no lo gobierna Anthropic en solitario: el protocolo vive bajo la Agentic AI Foundation, dentro de la Linux Foundation, con Anthropic, OpenAI, Google, Microsoft, AWS, Block, Cloudflare y Bloomberg entre sus miembros. Esa gobernanza compartida explica el tono de esta revisión, que se parece mucho más a un estándar de infraestructura que a la API de un proveedor.
La revisión 2026-07-28 es la quinta de la especificación y llega con dos novedades de proceso que importan tanto como los cambios técnicos. La primera: existe por fin una política formal de ciclo de vida, con tres estados (Activo, Deprecado, Retirado) y una ventana mínima de doce meses antes de que nada desaparezca. La segunda: hay un registro público de funciones deprecadas con la fecha más temprana en la que cada una puede caer. Para quien mantiene software en producción, eso vale tanto como el protocolo en sí, porque convierte la planificación en algo que se puede meter en un roadmap.
El cambio de fondo: de sesión a petición autónoma
Hasta esta revisión, hablar MCP era abrir una conversación. El cliente mandaba initialize, el servidor respondía con sus capacidades, el cliente confirmaba con notifications/initialized y a partir de ahí ambos daban por sabido el contexto: qué versión se hablaba, qué sabía hacer cada uno, quién era quién. Sobre HTTP, esa conversación se materializaba en una cabecera Mcp-Session-Id que el servidor emitía y el cliente repetía en cada llamada.
Todo eso ha desaparecido.

Qué desaparece
Se van el handshake initialize y su notificación notifications/initialized. Se va la cabecera Mcp-Session-Id y con ella el concepto de sesión a nivel de protocolo. Se va el endpoint GET del transporte Streamable HTTP, que era por donde el servidor abría su canal para hablar por iniciativa propia. Se van resources/subscribe y resources/unsubscribe. Se van ping, logging/setLevel y notifications/roots/list_changed. Y se va la resumabilidad de los streams SSE: ya no existen Last-Event-ID ni identificadores de evento, de modo que un stream roto pierde la petición en vuelo y el cliente tiene que reemitirla como una petición nueva, con un identificador nuevo.
Es una lista larga, y no es casual. Todo lo que se ha ido tenía la misma propiedad: presuponía que la conexión significaba algo.
Qué lo sustituye
Ahora cada petición se explica a sí misma. La información que antes se establecía una vez al principio viaja en el campo _meta de cada llamada, con claves reservadas por la especificación:
protocolVersion y clientCapabilities son obligatorias en toda petición: si falta alguna, el servidor debe rechazar con -32602 y, sobre HTTP, con un 400 Bad Request. clientInfo es recomendable salvo que tengas una razón para no identificarte. Del lado del servidor, la recomendación es incluir io.modelcontextprotocol/serverInfo en el _meta de cada resultado. Conviene leer bien la nota de la especificación sobre estos dos campos: son autodeclarados, nadie los verifica, y no deben usarse para tomar decisiones de seguridad ni para cambiar comportamiento.
La negociación de versión también cambia de naturaleza. Ya no hay un momento de acuerdo: el cliente declara en cada petición qué versión habla y el servidor acepta o rechaza cada una por separado. Si no la soporta, responde con UnsupportedProtocolVersionError (código -32022) y una lista de las versiones que sí soporta, para que el cliente reintente con una compatible.
Para los clientes que prefieren saberlo de antemano hay un método nuevo, server/discover, que devuelve versiones soportadas, capacidades e identidad en una sola llamada. Los servidores tienen que implementarlo. Los clientes pueden usarlo o no: es perfectamente válido lanzar la llamada que te interese y gestionar el error de versión si aparece.
Por qué esto es una buena noticia
La consecuencia práctica es que un servidor MCP deja de necesitar memoria entre llamadas, y eso lo cambia todo en el despliegue. Sin sesión no hace falta sticky routing en el balanceador, ni almacenamiento compartido entre instancias, ni procesos de larga vida. Un servidor MCP pasa a ser lo que cualquier equipo de plataforma sabe operar desde hace años: un endpoint HTTP sin estado que escala horizontalmente, se despliega en serverless o en el edge, y se cae y se levanta sin arrastrar nada.
La especificación es explícita en que ni siquiera un proceso stdio abierto debe entenderse como una conversación: el cliente puede intercalar peticiones sin relación por el mismo transporte, y el servidor no puede usar la identidad del proceso como sustituto de la continuidad. Si tu servidor necesita estado real entre llamadas (una sesión de trabajo, un carrito, un contexto de análisis), la vía correcta ahora es explícita: emite tú un identificador y haz que el cliente lo pase como argumento normal de la herramienta.
Multi Round-Trip Requests: el fin de las peticiones del servidor
El segundo cambio grande es el que más código va a tocar en los servidores que hacen algo interesante.
Hasta ahora, cuando un servidor necesitaba algo del cliente a mitad de una operación (una respuesta del usuario vía elicitation, una llamada al modelo vía sampling, la lista de directorios vía roots) abría su propia petición JSON-RPC en dirección contraria. Eso obligaba a mantener un canal abierto y, en la práctica, a que la misma instancia atendiese toda la operación.
El patrón nuevo se llama Multi Round-Trip Requests y le da la vuelta al flujo: el servidor no pregunta, el servidor termina la petición pidiendo. Devuelve un resultado con resultType: "input_required" que contiene un mapa inputRequests con lo que necesita, y opcionalmente un requestState opaco. El cliente reúne esa información, y reintenta la petición original con las respuestas en inputResponses y el requestState devuelto tal cual.

Tres detalles que se pasan por alto al leerlo rápido y que luego cuestan una tarde de depuración. El identificador JSON-RPC del reintento tiene que ser distinto del de la petición inicial, porque son peticiones independientes. El requestState es opaco para el cliente, que no puede inspeccionarlo ni modificarlo, pero es entrada controlada por el atacante desde el punto de vista del servidor: si influye en autorización o en lógica de negocio, hay que protegerlo con HMAC o AEAD, meterle caducidad corta, atarlo al principal autenticado y a la petición de origen, y rechazar lo que no verifique. Y InputRequiredResult solo puede devolverse en prompts/get, resources/read y tools/call: en ningún otro sitio.
Como efecto colateral, todos los resultados llevan ahora un campo resultType obligatorio, con "complete" para lo normal. Si hablas con un servidor de una revisión anterior que no lo incluye, se interpreta como "complete".
El resto de cambios que sí vas a notar
Cabeceras obligatorias para enrutar. Toda petición POST sobre Streamable HTTP tiene que llevar Mcp-Method con el método, y Mcp-Name con el nombre de la herramienta o el URI del recurso en tools/call, resources/read y prompts/get. Suena a burocracia hasta que piensas quién está delante de tu servidor: ahora un balanceador, un gateway o un WAF puede enrutar, medir y aplicar políticas sin abrir el cuerpo JSON. El servidor está obligado a validar que cabecera y cuerpo coinciden, y a rechazar con 400 y HeaderMismatch (-32020) si no. Hay incluso un mecanismo para llevar parámetros concretos de una herramienta a cabeceras (x-mcp-header), pensado para cosas como enrutar por región.
Listas cacheables. Los resultados de tools/list, prompts/list, resources/list, resources/read y resources/templates/list llevan ahora ttlMs y cacheScope (public o private). El primero es una pista de frescura para que el cliente cachee en vez de preguntar; el segundo dice si un intermediario compartido puede guardarlo. Y hay una recomendación pequeña con efecto grande: devolver las herramientas en tools/list en orden determinista, porque así el prompt del modelo no cambia entre llamadas y el caché de prompt del LLM acierta más.
Suscripciones. Lo que antes se hacía abriendo un GET ahora se pide con subscriptions/listen, una petición cuya respuesta es un stream que se queda abierto. El cliente elige a qué se suscribe (toolsListChanged, promptsListChanged, resourcesListChanged, resourceSubscriptions) y el servidor etiqueta cada notificación con io.modelcontextprotocol/subscriptionId. Las notificaciones de progreso y de log siguen viajando por el stream de la petición a la que pertenecen, no por aquí.
Autorización. Tres apretones de tuerca. Los servidores de autorización deberían incluir el parámetro iss según RFC 9207, y el cliente tiene que validarlo contra el issuer registrado antes de canjear el código. Las credenciales quedan atadas al issuer que las emitió: se guardan indexadas por él, no se reutilizan con otro, y si el servidor de autorización cambia hay que registrarse de nuevo. Y el registro dinámico de clientes (DCR, RFC 7591) queda deprecado en favor de los Client ID Metadata Documents, aunque sigue disponible para autorizaciones que no soporten CIMD todavía.
Errores. Hay por fin una política de asignación de códigos: de -32000 a -32019 queda como zona heredada que nadie nuevo debería usar, y de -32020 a -32099 es territorio exclusivo de la especificación. Los tres códigos nuevos son HeaderMismatch (-32020), MissingRequiredClientCapability (-32021) y UnsupportedProtocolVersion (-32022). Además, el error de recurso no encontrado pasa de -32002 a -32602, aunque los clientes deberían seguir aceptando el viejo de servidores antiguos.
Tasks fuera del core. Las tareas experimentales salen del protocolo base y pasan a ser una extensión oficial (io.modelcontextprotocol/tasks), con polling vía tasks/get en lugar del tasks/result bloqueante. En la misma línea, capacidades de cliente y servidor incorporan un campo extensions para negociar todo lo que quede fuera del núcleo.
Qué se rompe y qué no
Esta es la tabla que conviene tener delante antes de tocar nada. La especificación llama modernas a las versiones que llevan los metadatos en cada petición (de 2026-07-28 en adelante) y legacy a las que usan handshake (2025-11-25 y anteriores).
La lectura importante está en las dos filas que fallan: un cliente antiguo no puede hablar con un servidor solo-moderno, y no hay nada que pueda hacer al respecto. Por eso la especificación pide que un servidor que solo hable moderno incluya, en el error con que responda a un initialize, las versiones que sí soporta: puede ser el único diagnóstico que llegue a ver el usuario de ese cliente.
Un servidor que quiera atender a los dos mundos puede hacerlo, y decide por cómo abre el cliente: si la petición trae _meta moderno, la sirve sin estado; si llega un initialize, entra en modo antiguo. Un cliente que quiera lo mismo detecta la era del servidor por transporte: en stdio, sondeando con server/discover y cayendo a initialize ante cualquier error que no sea un error moderno reconocible; sobre HTTP, lanzando una petición moderna y mirando el cuerpo del 400 antes de decidir. Ese resultado se cachea por servidor, no por petición.
Qué tienes que tocar, según tu caso
Si usas servidores MCP por stdio en local, que es el caso de la mayoría de asistentes personales y de casi todo lo que corre dentro de un IDE, no te corre prisa. Tu cliente y tus servidores negocian la versión que ambos hablen, y la revisión anterior sigue siendo válida. Lo que toca es actualizar el SDK cuando vayas a tocar ese servidor por cualquier otro motivo, no montar una migración por su cuenta. Es exactamente lo que vamos a hacer nosotros con los servidores del asistente personal que construimos con Claude Code.
Si tienes un servidor remoto que guarda sesión, aquí sí hay trabajo de arquitectura, y es ahora. No es cambiar una librería: es sacar el estado del proceso. Inventaría qué guardas hoy entre llamadas y decide para cada cosa si desaparece (porque el cliente ya la manda en _meta), si pasa a ser un handle explícito que el cliente lleva como argumento, o si se va a un almacén externo indexado por ese handle. Todo lo que dependa de que dos llamadas caigan en la misma instancia hay que darlo por muerto. La recompensa es real: al terminar, tu servidor corre en serverless.
Si tu servidor abre peticiones al cliente (sampling, elicitation o roots), tienes que rehacer ese flujo con MRTR. Es el cambio que más lógica mueve, porque pasas de un modelo conversacional a uno donde cada intento es autónomo y el contexto viaja en el requestState que tú firmas y verificas. Empieza por ahí, no por lo demás.
Si vas a empezar un servidor MCP nuevo, hazlo directamente sobre 2026-07-28. No hay ninguna razón para construir hoy sobre el modelo con sesiones, y sí una para no hacerlo: en doce meses estarías migrando lo que acabas de escribir.
Si mantienes un cliente, el trabajo es distinto y probablemente mayor: tienes que soportar las dos eras durante bastante tiempo, cachear qué habla cada servidor y manejar la degradación con criterio. Los cuatro SDK de nivel 1 (TypeScript, Python, Go y C#) ya llevan soporte de la revisión nueva, y el de Rust va en beta, así que buena parte de esto te lo dan hecho si vas al día.
El calendario real
Lo mejor de la política de ciclo de vida es que se puede planificar con fechas, no con rumores. Esto es lo que está deprecado y hasta cuándo aguanta:
Ojo con la última fila, que es la que va con prisa de verdad. El transporte HTTP+SSE llevaba deprecado desde marzo de 2025 y ahora entra formalmente en la política, con una ventana de solo tres meses. Si te queda algo hablando por ahí, esa es la migración urgente, no las otras.
Que algo sea elegible para retirada no significa que se retire ese día: la decisión la toman los mantenedores en cada release y puede llegar más tarde. Pero es la fecha con la que planificar.
Qué haríamos nosotros
Tres criterios que aplicamos a esta clase de cambios, y que aquí valen especialmente.
No migres por estar al día, migra por una razón. Un servidor stdio que funciona no necesita tocarse esta semana. El coste de migrar sin motivo no es solo el rato: es que introduces riesgo en algo que ya iba bien. La ventana de doce meses existe para usarla.
Lo que sí es urgente es lo que se diseña ahora. Cualquier servidor MCP nuevo, y cualquier plataforma que vaya a abrir su API a agentes, se diseña sin estado desde el primer día. Es la decisión que más caro sale cambiar después, porque no es una librería, es cómo repartes el trabajo entre instancias. En nuestro caso, esto afecta directamente a cómo Nexo va a exponer sus capacidades a los agentes de sus clientes: el diseño se hace contra la revisión nueva, no contra la que ya conocíamos.
Cuidado con construir producto sobre superficies experimentales. Lo aprendimos con WebMCP: montamos sobre un origin trial de Chrome y un cambio del lado del navegador nos rompió la navegación del sitio, con nuestros propios health checks en verde. MCP 2026-07-28 no es experimental, pero la lección aplica igual: cuando adoptes algo recién publicado, ten claro cómo lo apagas si sale mal, y comprueba el resultado con manos y ojos, no solo con un código 200.
Preguntas frecuentes
¿Se me rompe algo hoy si no hago nada? No, si tu cliente y tus servidores hablan la misma revisión. Lo que ya funcionaba sigue funcionando, y la revisión anterior mantiene soporte. Se rompe cuando mezclas eras: un cliente antiguo contra un servidor que solo habla la nueva, o al revés.
¿Cuánto tiempo tengo de verdad? Doce meses como mínimo para Roots, Sampling, Logging y el registro dinámico de clientes, contados desde el 28 de julio de 2026. La excepción es el transporte HTTP+SSE, que puede caer tres meses después de que su propuesta sea final.
¿Tengo que implementar `server/discover`? Si escribes un servidor, sí: es obligatorio. Si escribes un cliente, no: puedes lanzar la llamada que necesites y gestionar el error de versión si aparece. En stdio es además la forma recomendada de detectar si el servidor de enfrente es moderno o antiguo.
¿Qué hago con el estado que guardaba en la sesión? Sácalo del proceso. Lo que era contexto de protocolo ya viaja en _meta de cada petición. Lo que es estado de aplicación pasa a ser un identificador explícito que tú emites y el cliente te devuelve como argumento, con el dato real en un almacén externo si hace falta.
¿Esto afecta a WebMCP? No. WebMCP es la propuesta del navegador, impulsada por Chrome y trabajada en el W3C, y sigue su propio camino. Es otra capa: MCP conecta al agente con herramientas de servidor, WebMCP expone acciones desde la web que el usuario tiene abierta.
¿Y a los clientes de escritorio tipo Claude o ChatGPT? Los productos van a ir incorporando la revisión nueva a su ritmo, y ninguno ha publicado fechas concretas. Mientras tanto negocian versión con cada servidor, así que la convivencia está prevista por diseño.
Conclusión
La lectura corta de 2026-07-28 es que MCP ha dejado de comportarse como una conversación para comportarse como una API. Cada petición se explica sola, el servidor no recuerda, y todo lo que necesitaba memoria se ha rediseñado o se ha ido. Eso hace el protocolo más aburrido de leer y muchísimo más fácil de operar, que es exactamente lo que necesita algo que aspira a ser infraestructura.
Para la mayoría de equipos la respuesta práctica de esta semana es no hacer nada urgente y planificar bien. Para quien tenga servidores remotos con sesión, o esté a punto de diseñar cómo abre su plataforma a agentes, la respuesta es la contraria: el trabajo empieza ahora, y empieza por sacar el estado de en medio.
Si estás en el segundo caso y quieres contrastar el diseño con alguien que ya lo ha hecho, hablamos. Llevamos dos años construyendo sobre LLM en producción, tenemos servidores MCP corriendo y hemos pagado la factura de adoptar cosas antes de tiempo.