Tornar al blog
Intel·ligència Artificial

MCP 2026-07-28: el protocol es queda sense estat (i què has de tocar)

MCP 2026-07-28: el protocol sense estat

Per l'equip de Kiwop · Agència Digital especialitzada en Desenvolupament de Programari i Intel·ligència Artificial aplicada · Publicat el 29 de juliol de 2026 · Última actualització: 29 de juliol de 2026

TL;DR — El 28 de juliol de 2026 es va publicar la cinquena revisió d'MCP i és la que més canvia des que va néixer el protocol. Desapareixen les sessions i el handshake `initialize`: cada petició viatja sola, amb la seva versió i capacitats dins de `_meta`. Les peticions que abans iniciava el servidor (sampling, elicitation, roots) passen al patró multi round-trip. Arriben capçaleres obligatòries per encaminar sense obrir el cos, llistes cacheables i una autorització més dura. Si el teu servidor és stdio local, no tens pressa. Si és remot i guarda sessió, el redisseny comença avui. El que queda obsolet aguanta dotze mesos.

MCP 2026-07-28: el protocol sense estat

Hi ha actualitzacions de protocol que es resumeixen en una línia de changelog i n'hi ha d'altres que canvien com es desplega el programari que les parla. La revisió 2026-07-28 de Model Context Protocol és de les segones. No afegeix una funció més a un protocol que ja coneixies: li treu la memòria. I quan un protocol deixa de recordar, el que canvia no és l'API, és l'arquitectura de tot el que corre a sota.

A l'abril vam publicar la comparativa entre MCP, WebMCP i A2A i dèiem que la següent fita rellevant seria la consolidació del transport Streamable HTTP i la retirada del SSE legacy. Les dues coses s'han complert, i de passada ha arribat força més del que esperàvem. Aquest article és la lectura tècnica de què canvia exactament, què es trenca, i què ha de fer un equip que ja té servidors MCP corrent en producció. Amb l'especificació a la mà, no amb el resum de la nota de premsa.

Què es va publicar el 28 de juliol

MCP va néixer el novembre de 2024 com una manera que un model parlés amb eines externes sense que cada integració fos un adaptador a mida. Des del desembre de 2025 no el governa Anthropic en solitari: el protocol viu sota l'Agentic AI Foundation, dins de la Linux Foundation, amb Anthropic, OpenAI, Google, Microsoft, AWS, Block, Cloudflare i Bloomberg entre els seus membres. Aquesta governança compartida explica el to d'aquesta revisió, que s'assembla molt més a un estàndard d'infraestructura que a l'API d'un proveïdor.

La revisió 2026-07-28 és la cinquena de l'especificació i arriba amb dues novetats de procés que importen tant com els canvis tècnics. La primera: existeix per fi una política formal de cicle de vida, amb tres estats (Actiu, Obsolet, Retirat) i una finestra mínima de dotze mesos abans que res desaparegui. La segona: hi ha un registre públic de funcions obsoletes amb la data més primerenca en què cadascuna pot caure. Per a qui manté programari en producció, això val tant com el protocol mateix, perquè converteix la planificació en una cosa que pots posar en un roadmap.

El canvi de fons: de sessió a petició autònoma

Fins a aquesta revisió, parlar MCP era obrir una conversa. El client enviava initialize, el servidor responia amb les seves capacitats, el client confirmava amb notifications/initialized i a partir d'aquí tots dos donaven per sabut el context: quina versió es parlava, què sabia fer cadascú, qui era qui. Sobre HTTP, aquella conversa es materialitzava en una capçalera Mcp-Session-Id que el servidor emetia i el client repetia a cada crida.

Tot això ha desaparegut.

Abans i després: la sessió MCP davant la petició autònoma

Què desapareix

Se'n van el handshake initialize i la seva notificació notifications/initialized. Se'n va la capçalera Mcp-Session-Id i amb ella el concepte de sessió a nivell de protocol. Se'n va l'endpoint GET del transport Streamable HTTP, que era per on el servidor obria el seu canal per parlar per iniciativa pròpia. Se'n van resources/subscribe i resources/unsubscribe. Se'n van ping, logging/setLevel i notifications/roots/list_changed. I se'n va la resumabilitat dels streams SSE: ja no existeixen Last-Event-ID ni identificadors d'esdeveniment, de manera que un stream trencat perd la petició en vol i el client l'ha de reemetre com una petició nova, amb un identificador nou.

És una llista llarga, i no és casual. Tot el que se n'ha anat tenia la mateixa propietat: pressuposava que la connexió significava alguna cosa.

Què ho substitueix

Ara cada petició s'explica a si mateixa. La informació que abans s'establia un cop al principi viatja al camp _meta de cada crida, amb claus reservades per l'especificació:

protocolVersion i clientCapabilities són obligatòries a tota petició: si en falta alguna, el servidor ha de rebutjar amb -32602 i, sobre HTTP, amb un 400 Bad Request. clientInfo és recomanable llevat que tinguis una raó per no identificar-te. Del costat del servidor, la recomanació és incloure io.modelcontextprotocol/serverInfo al _meta de cada resultat. Convé llegir bé la nota de l'especificació sobre aquests dos camps: són autodeclarats, ningú no els verifica, i no s'han d'usar per prendre decisions de seguretat ni per canviar comportament.

La negociació de versió també canvia de naturalesa. Ja no hi ha un moment d'acord: el client declara a cada petició quina versió parla i el servidor accepta o rebutja cadascuna per separat. Si no la suporta, respon amb UnsupportedProtocolVersionError (codi -32022) i una llista de les versions que sí que suporta, perquè el client reintenti amb una de compatible.

Per als clients que prefereixen saber-ho per endavant hi ha un mètode nou, server/discover, que retorna versions suportades, capacitats i identitat en una sola crida. Els servidors l'han d'implementar. Els clients poden usar-lo o no: és perfectament vàlid llançar la crida que t'interessi i gestionar l'error de versió si apareix.

Per què això és una bona notícia

La conseqüència pràctica és que un servidor MCP deixa de necessitar memòria entre crides, i això ho canvia tot en el desplegament. Sense sessió no cal sticky routing al balancejador, ni emmagatzematge compartit entre instàncies, ni processos de llarga vida. Un servidor MCP passa a ser el que qualsevol equip de plataforma sap operar des de fa anys: un endpoint HTTP sense estat que escala horitzontalment, es desplega en serverless o a l'edge, i cau i s'aixeca sense arrossegar res.

L'especificació és explícita que ni tan sols un procés stdio obert s'ha d'entendre com una conversa: el client pot intercalar peticions sense relació pel mateix transport, i el servidor no pot fer servir la identitat del procés com a substitut de la continuïtat. Si el teu servidor necessita estat real entre crides (una sessió de treball, un carretó, un context d'anàlisi), la via correcta ara és explícita: emet tu un identificador i fes que el client el passi com a argument normal de l'eina.

Multi Round-Trip Requests: el final de les peticions del servidor

El segon canvi gran és el que més codi tocarà als servidors que fan alguna cosa interessant.

Fins ara, quan un servidor necessitava alguna cosa del client a mitja operació (una resposta de l'usuari via elicitation, una crida al model via sampling, la llista de directoris via roots) obria la seva pròpia petició JSON-RPC en direcció contrària. Això obligava a mantenir un canal obert i, a la pràctica, que la mateixa instància atengués tota l'operació.

El patró nou es diu Multi Round-Trip Requests i li dona la volta al flux: el servidor no pregunta, el servidor acaba la petició demanant. Retorna un resultat amb resultType: "input_required" que conté un mapa inputRequests amb el que necessita, i opcionalment un requestState opac. El client reuneix aquesta informació i reintenta la petició original amb les respostes a inputResponses i el requestState retornat tal qual.

Multi Round-Trip Requests: el servidor acaba demanant, el client reintenta

Tres detalls que es passen per alt en llegir-ho ràpid i que després costen una tarda de depuració. L'identificador JSON-RPC del reintent ha de ser diferent del de la petició inicial, perquè són peticions independents. El requestState és opac per al client, que no el pot inspeccionar ni modificar, però és entrada controlada per l'atacant des del punt de vista del servidor: si influeix en autorització o en lògica de negoci, cal protegir-lo amb HMAC o AEAD, posar-li caducitat curta, lligar-lo al principal autenticat i a la petició d'origen, i rebutjar el que no verifiqui. I InputRequiredResult només es pot retornar a prompts/get, resources/read i tools/call: enlloc més.

Com a efecte col·lateral, tots els resultats porten ara un camp resultType obligatori, amb "complete" per al cas normal. Si parles amb un servidor d'una revisió anterior que no l'inclou, s'interpreta com "complete".

La resta de canvis que sí que notaràs

Capçaleres obligatòries per encaminar. Tota petició POST sobre Streamable HTTP ha de portar Mcp-Method amb el mètode, i Mcp-Name amb el nom de l'eina o l'URI del recurs a tools/call, resources/read i prompts/get. Sona a burocràcia fins que penses qui hi ha davant del teu servidor: ara un balancejador, un gateway o un WAF pot encaminar, mesurar i aplicar polítiques sense obrir el cos JSON. El servidor està obligat a validar que capçalera i cos coincideixen, i a rebutjar amb 400 i HeaderMismatch (-32020) si no. Fins i tot hi ha un mecanisme per portar paràmetres concrets d'una eina a capçaleres (x-mcp-header), pensat per a coses com encaminar per regió.

Llistes cacheables. Els resultats de tools/list, prompts/list, resources/list, resources/read i resources/templates/list porten ara ttlMs i cacheScope (public o private). El primer és una pista de frescor perquè el client cachegi en comptes de preguntar; el segon diu si un intermediari compartit el pot guardar. I hi ha una recomanació petita amb efecte gran: retornar les eines a tools/list en ordre determinista, perquè així el prompt del model no canvia entre crides i el cau de prompt de l'LLM encerta més.

Subscripcions. El que abans es feia obrint un GET ara es demana amb subscriptions/listen, una petició la resposta de la qual és un stream que es queda obert. El client tria a què se subscriu (toolsListChanged, promptsListChanged, resourcesListChanged, resourceSubscriptions) i el servidor etiqueta cada notificació amb io.modelcontextprotocol/subscriptionId. Les notificacions de progrés i de log continuen viatjant pel stream de la petició a la qual pertanyen, no per aquí.

Autorització. Tres estrenyements de rosca. Els servidors d'autorització haurien d'incloure el paràmetre iss segons RFC 9207, i el client ha de validar-lo contra l'issuer registrat abans de bescanviar el codi. Les credencials queden lligades a l'issuer que les va emetre: es guarden indexades per ell, no es reutilitzen amb un altre, i si el servidor d'autorització canvia cal registrar-se de nou. I el registre dinàmic de clients (DCR, RFC 7591) queda obsolet en favor dels Client ID Metadata Documents, tot i que continua disponible per a autoritzacions que encara no suportin CIMD.

Errors. Hi ha per fi una política d'assignació de codis: de -32000 a -32019 queda com a zona heretada que ningú nou hauria d'usar, i de -32020 a -32099 és territori exclusiu de l'especificació. Els tres codis nous són HeaderMismatch (-32020), MissingRequiredClientCapability (-32021) i UnsupportedProtocolVersion (-32022). A més, l'error de recurs no trobat passa de -32002 a -32602, tot i que els clients haurien de continuar acceptant el vell de servidors antics.

Tasks fora del core. Les tasques experimentals surten del protocol base i passen a ser una extensió oficial (io.modelcontextprotocol/tasks), amb polling via tasks/get en lloc del tasks/result bloquejant. En la mateixa línia, capacitats de client i servidor incorporen un camp extensions per negociar tot el que quedi fora del nucli.

Què es trenca i què no

Aquesta és la taula que convé tenir davant abans de tocar res. L'especificació anomena modernes les versions que porten les metadades a cada petició (de 2026-07-28 endavant) i legacy les que fan servir handshake (2025-11-25 i anteriors).

La lectura important és a les dues files que fallen: un client antic no pot parlar amb un servidor només-modern, i no hi pot fer res. Per això l'especificació demana que un servidor que només parli modern inclogui, a l'error amb què respongui a un initialize, les versions que sí que suporta: pot ser l'únic diagnòstic que arribi a veure l'usuari d'aquell client.

Un servidor que vulgui atendre els dos mons ho pot fer, i decideix per com obre el client: si la petició porta _meta modern, la serveix sense estat; si arriba un initialize, entra en mode antic. Un client que vulgui el mateix detecta l'era del servidor per transport: en stdio, sondejant amb server/discover i caient a initialize davant de qualsevol error que no sigui un error modern reconeixible; sobre HTTP, llançant una petició moderna i mirant el cos del 400 abans de decidir. Aquest resultat es cacheja per servidor, no per petició.

Què has de tocar, segons el teu cas

Si fas servir servidors MCP per stdio en local, que és el cas de la majoria d'assistents personals i de gairebé tot el que corre dins d'un IDE, no tens pressa. El teu client i els teus servidors negocien la versió que tots dos parlin, i la revisió anterior continua sent vàlida. El que toca és actualitzar l'SDK quan vagis a tocar aquell servidor per qualsevol altre motiu, no muntar una migració pel seu compte. És exactament el que farem nosaltres amb els servidors de l'assistent personal que vam construir amb Claude Code.

Si tens un servidor remot que guarda sessió, aquí sí que hi ha feina d'arquitectura, i és ara. No és canviar una llibreria: és treure l'estat del procés. Inventaria què guardes avui entre crides i decideix per a cada cosa si desapareix (perquè el client ja l'envia a _meta), si passa a ser un handle explícit que el client porta com a argument, o si se'n va a un magatzem extern indexat per aquell handle. Tot el que depengui que dues crides caiguin a la mateixa instància cal donar-ho per mort. La recompensa és real: en acabar, el teu servidor corre en serverless.

Si el teu servidor obre peticions al client (sampling, elicitation o roots), has de refer aquell flux amb MRTR. És el canvi que més lògica mou, perquè passes d'un model conversacional a un on cada intent és autònom i el context viatja al requestState que tu signes i verifiques. Comença per aquí, no per la resta.

Si vas a començar un servidor MCP nou, fes-ho directament sobre 2026-07-28. No hi ha cap raó per construir avui sobre el model amb sessions, i sí una per no fer-ho: en dotze mesos estaries migrant el que acabes d'escriure.

Si mantens un client, la feina és diferent i probablement més gran: has de suportar les dues eres durant força temps, cachejar què parla cada servidor i gestionar la degradació amb criteri. Els quatre SDK de nivell 1 (TypeScript, Python, Go i C#) ja porten suport de la revisió nova, i el de Rust va en beta, així que bona part d'això t'ho donen fet si vas al dia.

El calendari real

El millor de la política de cicle de vida és que es pot planificar amb dates, no amb rumors. Això és el que està obsolet i fins quan aguanta:

Compte amb l'última fila, que és la que va amb pressa de debò. El transport HTTP+SSE feia temps que estava obsolet, des del març de 2025, i ara entra formalment a la política amb una finestra de només tres mesos. Si et queda res parlant per aquí, aquella és la migració urgent, no les altres.

Que una cosa sigui elegible per a retirada no vol dir que es retiri aquell dia: la decisió la prenen els mantenidors a cada release i pot arribar més tard. Però és la data amb què planificar.

Què faríem nosaltres

Tres criteris que apliquem a aquesta mena de canvis, i que aquí valen especialment.

No migris per estar al dia, migra per una raó. Un servidor stdio que funciona no cal tocar-lo aquesta setmana. El cost de migrar sense motiu no és només l'estona: és que introdueixes risc en una cosa que ja anava bé. La finestra de dotze mesos existeix per fer-la servir.

El que sí que és urgent és el que es dissenya ara. Qualsevol servidor MCP nou, i qualsevol plataforma que vagi a obrir la seva API a agents, es dissenya sense estat des del primer dia. És la decisió que més cara surt de canviar després, perquè no és una llibreria, és com reparteixes la feina entre instàncies. En el nostre cas, això afecta directament com Nexo exposarà les seves capacitats als agents dels seus clients: el disseny es fa contra la revisió nova, no contra la que ja coneixíem.

Compte amb construir producte sobre superfícies experimentals. Ho vam aprendre amb WebMCP: vam muntar sobre un origin trial de Chrome i un canvi del costat del navegador ens va trencar la navegació del lloc, amb els nostres health checks en verd. MCP 2026-07-28 no és experimental, però la lliçó s'hi aplica igual: quan adoptis una cosa acabada de publicar, tingues clar com l'apagues si surt malament, i comprova el resultat amb mans i ulls, no només amb un codi 200.

Preguntes freqüents

Se'm trenca res avui si no faig res? No, si el teu client i els teus servidors parlen la mateixa revisió. El que ja funcionava continua funcionant, i la revisió anterior manté suport. Es trenca quan barreges eres: un client antic contra un servidor que només parla la nova, o a l'inrevés.

Quant temps tinc de debò? Dotze mesos com a mínim per a Roots, Sampling, Logging i el registre dinàmic de clients, comptats des del 28 de juliol de 2026. L'excepció és el transport HTTP+SSE, que pot caure tres mesos després que la seva proposta sigui final.

He d'implementar `server/discover`? Si escrius un servidor, sí: és obligatori. Si escrius un client, no: pots llançar la crida que necessitis i gestionar l'error de versió si apareix. En stdio és a més la manera recomanada de detectar si el servidor del davant és modern o antic.

Què faig amb l'estat que guardava a la sessió? Treu-lo del procés. El que era context de protocol ja viatja al _meta de cada petició. El que és estat d'aplicació passa a ser un identificador explícit que tu emets i el client et retorna com a argument, amb la dada real en un magatzem extern si cal.

Això afecta WebMCP? No. WebMCP és la proposta del navegador, impulsada per Chrome i treballada al W3C, i segueix el seu propi camí. És una altra capa: MCP connecta l'agent amb eines de servidor, WebMCP exposa accions des del web que l'usuari té obert.

I els clients d'escriptori tipus Claude o ChatGPT? Els productes aniran incorporant la revisió nova al seu ritme, i cap no ha publicat dates concretes. Mentrestant negocien versió amb cada servidor, així que la convivència està prevista per disseny.

Conclusió

La lectura curta de 2026-07-28 és que MCP ha deixat de comportar-se com una conversa per comportar-se com una API. Cada petició s'explica sola, el servidor no recorda, i tot el que necessitava memòria s'ha redissenyat o se n'ha anat. Això fa el protocol més avorrit de llegir i moltíssim més fàcil d'operar, que és exactament el que necessita una cosa que aspira a ser infraestructura.

Per a la majoria d'equips la resposta pràctica d'aquesta setmana és no fer res urgent i planificar bé. Per a qui tingui servidors remots amb sessió, o estigui a punt de dissenyar com obre la seva plataforma a agents, la resposta és la contrària: la feina comença ara, i comença traient l'estat del mig.

Si estàs en el segon cas i vols contrastar el disseny amb algú que ja ho ha fet, en parlem. Portem dos anys construint sobre LLM en producció, tenim servidors MCP corrent i hem pagat la factura d'adoptar coses abans d'hora.

Consulta
tècnica inicial.

IA, seguretat i rendiment. Diagnòstic i proposta tancada per fases.

NDA disponible
Resposta <24h
Proposta per fases

La teva primera reunió és amb un Arquitecte de Solucions, no amb un comercial.

Sol·licitar diagnòstic