MCP 2.0: qué cambia y cómo migrar tu servidor
MCP 2.0 llega sin estado: adiós a initialize y a las sesiones. Qué cambia en la spec 2026-07-28 y cómo migrar tu servidor MCP en TypeScript.
MCP 2.0 es como se conoce a la nueva versión de la especificación del Model Context Protocol, publicada el 28 de julio de 2026 (oficialmente, la revisión 2026-07-28).
Si solo usas MCP en Cursor, Claude o ChatGPT, no tienes que hacer nada. Si tienes un servidor MCP, te toca una migración pequeña. Te enseño cuál con el servidor de PokéAPI de cómo crear un MCP.
La idea en una frase
MCP deja de recordar quién eres entre una petición y otra.
Antes, cliente y servidor se "presentaban" al empezar (initialize) y el servidor guardaba una sesión. Ahora cada petición lleva todo lo necesario: qué versión del protocolo usa el cliente y qué sabe hacer.
¿Por qué? Porque las sesiones complican la vida en producción. Si tienes varios servidores detrás de un balanceador, la sesión obliga a que todas tus peticiones vayan siempre a la misma máquina. Sin sesión, cualquier máquina puede responder cualquier petición.
Piénsalo como pasar de una llamada de teléfono (te presentas una vez y hablas) a mensajes de WhatsApp sueltos (cada uno se entiende solo).

¿Me afecta?
Si tú… | Qué tienes que hacer |
|---|---|
Usas MCP en Cursor, Claude Code, VS Code o ChatGPT | Nada. |
Tienes un servidor MCP sencillo (solo tools) | Migración corta: actualizar el SDK y cambiar 2–3 líneas. |
Tu servidor guarda sesiones, o usa sampling / elicitation | Más trabajo: lee la guía oficial. |
Los 3 cambios que importan
1. Sin initialize ni sesiones
Ya no hay saludo inicial ni Mcp-Session-Id. La versión y las capacidades del cliente viajan dentro de cada petición, en un campo _meta.
Si tu servidor necesita recordar algo entre llamadas (por ejemplo, una búsqueda paginada), devuelve un identificador en el resultado y el modelo lo pasa en la siguiente llamada. Es lo que ya hacíamos en cómo crear un MCP con los ids estables.
2. Nuevo server/discover
Como ya no hay saludo inicial, hace falta otra forma de preguntarle al servidor "¿qué versiones y funciones soportas?". Eso es server/discover. Si usas el SDK oficial, no lo escribes tú: lo hace la librería.
3. El servidor ya no "interrumpe" al cliente
Antes, en mitad de una tool, el servidor podía preguntarle algo al cliente: "pídele al usuario su nombre de GitHub", por ejemplo. Eso necesita una conexión abierta, justo lo que MCP 2.0 quiere evitar.
Ahora funciona en dos pasos:
El servidor responde: "me falta tu nombre de GitHub" (
input_required).El cliente se lo pregunta al usuario y repite la petición con la respuesta.

A esto la spec lo llama Multi Round-Trip Requests (MRTR). Si tus tools no piden datos a mitad de camino, no te afecta.
Otras cosas que cambian
Desaparecen
pingylogging/setLevel.Quedan obsoletos Roots, Sampling, Logging y el transporte antiguo HTTP+SSE. Tienes al menos 12 meses antes de que se eliminen.
Las extensiones (como MCP Apps, que usamos en la app de ChatGPT) tienen ahora su sitio propio en el protocolo. Lo nuevo entrará como extensión, sin tocar el núcleo.
La lista completa está en el changelog oficial.
Migrar mi servidor de PokéAPI en 3 pasos
Mi servidor (repo) tiene tres tools y dos formas de arrancar: stdio para Cursor y HTTP para ChatGPT.
Paso 1: actualizar el SDK con el codemod
El SDK de TypeScript para MCP 2.0 es la v2. Hay una herramienta que hace casi toda la migración sola. Lánzala en la raíz del proyecto:
npx @modelcontextprotocol/codemod@latest v1-to-v2 .
npx tsc --noEmit
Necesitas Node 20 o superior y zod 4.
Paso 2: envolver los schemas en z.object
En v2, el inputSchema de cada tool va dentro de z.object(...):
// Antes
inputSchema: {
nameOrId: z.string().min(1),
},
// Después
inputSchema: z.object({
nameOrId: z.string().min(1),
}),
La lógica de las tools no cambia.
Paso 3: cambiar cómo arrancas el servidor (el que todo el mundo se salta)
Actualizar el SDK no basta. Si sigues arrancando el servidor con server.connect(...), solo hablará la versión antigua. Hay que usar las funciones nuevas.
Stdio (src/index.ts):
// Antes
const server = createPokemonMcpServer();
await server.connect(new StdioServerTransport());
// Después
import { serveStdio } from "@modelcontextprotocol/server/stdio";
serveStdio(() => createPokemonMcpServer());
HTTP (src/http.ts):
import { createServer } from "node:http";
import { createMcpHandler } from "@modelcontextprotocol/server";
import { toNodeHandler } from "@modelcontextprotocol/node";
import { createPokemonMcpServer } from "./server.js";
const handler = toNodeHandler(createMcpHandler(() => createPokemonMcpServer()));
createServer((req, res) => void handler(req, res)).listen(8787);
Las dos funciones reciben lo mismo: una función que crea el servidor. Como ya teníamos createPokemonMcpServer(), encaja sin tocar nada más.
En local, la doc del SDK recomienda validar las cabeceras
HostyOriginantes del handler (localhostHostValidationylocalhostOriginValidation, de@modelcontextprotocol/node). Lo dejo fuera para que el ejemplo se lea fácil.
Buena noticia: por defecto, el servidor nuevo sigue funcionando con clientes antiguos. No rompes a nadie que aún no se haya actualizado.
MCP 1.0 vs MCP 2.0
Antes | MCP 2.0 | |
|---|---|---|
Al empezar | Saludo | Nada: cada petición va completa |
Sesión | Sí ( | No |
"¿Qué sabes hacer?" | Respuesta de |
|
El servidor necesita un dato | Le pregunta al cliente a mitad de camino | Responde |
Roots, Sampling, Logging | Activos | Obsoletos (12 meses de margen) |
Preguntas frecuentes
¿Cuándo salió MCP 2.0?
El 28 de julio de 2026. Oficialmente se llama revisión 2026-07-28 de la especificación.
¿Mis servidores antiguos dejan de funcionar?
No de golpe. Los clientes y SDK nuevos siguen hablando con servidores antiguos, y un servidor migrado sigue atendiendo a clientes antiguos.
¿Tengo que reescribir mi servidor?
Si solo tiene tools, no: SDK nuevo, z.object y cambiar cómo lo arrancas. Si usa sesiones, sampling o elicitation, hay más trabajo.