Par l'équipe de Kiwop · Agence Digitale spécialisée en Développement Logiciel et Intelligence Artificielle appliquée · Publié le 29 juillet 2026 · Dernière mise à jour : 29 juillet 2026
TL;DR — La cinquième révision de MCP est sortie le 28 juillet 2026 et c'est celle qui change le plus depuis la naissance du protocole. Les sessions et le handshake `initialize` disparaissent : chaque requête voyage seule, avec sa version et ses capacités dans `_meta`. Les requêtes qu'initiait le serveur (sampling, elicitation, roots) passent au motif multi round-trip. Arrivent des en-têtes obligatoires pour router sans ouvrir le corps, des listes cacheables et une autorisation plus stricte. Si votre serveur est en stdio local, rien ne presse. S'il est distant et garde une session, la refonte commence aujourd'hui. Ce qui est déprécié tient douze mois.

Il y a des mises à jour de protocole qui tiennent en une ligne de changelog, et d'autres qui changent la façon dont se déploie le logiciel qui les parle. La révision 2026-07-28 de Model Context Protocol fait partie des secondes. Elle n'ajoute pas une fonction de plus à un protocole que vous connaissiez : elle lui retire la mémoire. Et quand un protocole cesse de se souvenir, ce qui change n'est pas l'API, c'est l'architecture de tout ce qui tourne en dessous.
En avril nous avons publié notre comparatif entre MCP, WebMCP et A2A en annonçant que le prochain jalon serait la consolidation du transport Streamable HTTP et le retrait du SSE legacy. Les deux se sont réalisés, et il est arrivé au passage bien plus que prévu. Cet article est la lecture technique de ce qui change exactement, de ce qui casse, et de ce que doit faire une équipe qui a déjà des serveurs MCP en production. La spécification en main, pas le résumé du communiqué.
Ce qui est sorti le 28 juillet
MCP est né en novembre 2024 pour qu'un modèle puisse parler à des outils externes sans que chaque intégration devienne un adaptateur sur mesure. Depuis décembre 2025, Anthropic ne le gouverne plus seul : le protocole vit sous l'Agentic AI Foundation, au sein de la Linux Foundation, avec Anthropic, OpenAI, Google, Microsoft, AWS, Block, Cloudflare et Bloomberg parmi ses membres. Cette gouvernance partagée explique le ton de cette révision, qui ressemble bien plus à un standard d'infrastructure qu'à l'API d'un fournisseur.
La révision 2026-07-28 est la cinquième de la spécification et arrive avec deux nouveautés de processus aussi importantes que les changements techniques. La première : il existe enfin une politique formelle de cycle de vie, avec trois états (Actif, Déprécié, Retiré) et une fenêtre minimale de douze mois avant que quoi que ce soit disparaisse. La seconde : il y a un registre public des fonctions dépréciées avec la date la plus précoce à laquelle chacune peut tomber. Pour qui maintient du logiciel en production, cela vaut autant que le protocole lui-même, car cela transforme la planification en quelque chose qui tient dans une roadmap.
Le changement de fond : de la session à la requête autonome
Jusqu'à cette révision, parler MCP revenait à ouvrir une conversation. Le client envoyait initialize, le serveur répondait avec ses capacités, le client confirmait avec notifications/initialized, et à partir de là les deux tenaient le contexte pour acquis : quelle version était parlée, ce que chacun savait faire, qui était qui. Sur HTTP, cette conversation se matérialisait par un en-tête Mcp-Session-Id que le serveur émettait et que le client répétait à chaque appel.
Tout cela a disparu.

Ce qui disparaît
Disparaissent le handshake initialize et sa notification notifications/initialized. Disparaît l'en-tête Mcp-Session-Id, et avec lui la notion de session au niveau du protocole. Disparaît l'endpoint GET du transport Streamable HTTP, par lequel le serveur ouvrait son canal pour parler de sa propre initiative. Disparaissent resources/subscribe et resources/unsubscribe. Disparaissent ping, logging/setLevel et notifications/roots/list_changed. Et disparaît la reprise des flux SSE : il n'y a plus de Last-Event-ID ni d'identifiants d'événement, de sorte qu'un flux rompu perd la requête en vol et que le client doit la réémettre comme une nouvelle requête, avec un nouvel identifiant.
La liste est longue, et ce n'est pas un hasard. Tout ce qui est parti avait la même propriété : cela présupposait que la connexion signifiait quelque chose.
Ce qui le remplace
Désormais chaque requête s'explique elle-même. L'information qui s'établissait une fois au début voyage dans le champ _meta de chaque appel, sous des clés réservées par la spécification :
protocolVersion et clientCapabilities sont obligatoires sur chaque requête : s'il en manque une, le serveur doit rejeter avec -32602 et, sur HTTP, avec un 400 Bad Request. clientInfo est recommandé sauf raison de ne pas s'identifier. Côté serveur, la recommandation est d'inclure io.modelcontextprotocol/serverInfo dans le _meta de chaque résultat. Lisez attentivement la note de la spécification sur ces deux champs : ils sont auto-déclarés, personne ne les vérifie, et ils ne doivent servir ni à des décisions de sécurité ni à modifier un comportement.
La négociation de version change aussi de nature. Il n'y a plus de moment d'accord : le client déclare à chaque requête quelle version il parle et le serveur accepte ou refuse chacune séparément. S'il ne la prend pas en charge, il répond avec UnsupportedProtocolVersionError (code -32022) et la liste des versions qu'il supporte, pour que le client réessaie avec une version compatible.
Pour les clients qui préfèrent le savoir à l'avance, il y a une nouvelle méthode, server/discover, qui renvoie versions supportées, capacités et identité en un seul appel. Les serveurs doivent l'implémenter. Les clients peuvent l'utiliser ou non : lancer l'appel qui vous intéresse et gérer l'erreur de version si elle survient est parfaitement valide.
Pourquoi c'est une bonne nouvelle
La conséquence pratique est qu'un serveur MCP n'a plus besoin de mémoire entre les appels, et cela change tout au déploiement. Sans session, plus besoin de sticky routing sur le répartiteur, ni de stockage partagé entre instances, ni de processus de longue durée. Un serveur MCP devient ce que toute équipe plateforme sait exploiter depuis des années : un endpoint HTTP sans état qui passe à l'échelle horizontalement, se déploie en serverless ou en edge, et tombe et redémarre sans rien traîner.
La spécification est explicite : même un processus stdio ouvert ne doit pas s'entendre comme une conversation. Le client peut entrelacer des requêtes sans rapport sur le même transport, et le serveur ne peut pas utiliser l'identité du processus comme substitut de continuité. Si votre serveur a besoin d'un état réel entre les appels (une session de travail, un panier, un contexte d'analyse), la voie correcte est désormais explicite : émettez vous-même un identifiant et faites-le passer par le client comme argument normal de l'outil.
Multi Round-Trip Requests : la fin des requêtes du serveur
Le deuxième grand changement est celui qui touchera le plus de code dans les serveurs qui font quelque chose d'intéressant.
Jusqu'ici, quand un serveur avait besoin de quelque chose du client au milieu d'une opération (une réponse de l'utilisateur via elicitation, un appel au modèle via sampling, la liste des répertoires via roots), il ouvrait sa propre requête JSON-RPC en sens inverse. Cela imposait un canal ouvert et, en pratique, que la même instance traite toute l'opération.
Le nouveau motif s'appelle Multi Round-Trip Requests et inverse le flux : le serveur ne demande pas, le serveur termine la requête en demandant. Il renvoie un résultat avec resultType: "input_required" contenant une map inputRequests avec ce dont il a besoin, et éventuellement un requestState opaque. Le client rassemble cette information et réessaie la requête d'origine avec les réponses dans inputResponses et le requestState restitué tel quel.

Trois détails qu'on saute à la lecture rapide et qui coûtent ensuite une après-midi de débogage. L'identifiant JSON-RPC du nouvel essai doit être différent de celui de la requête initiale, car ce sont des requêtes indépendantes. Le requestState est opaque pour le client, qui ne doit ni l'inspecter ni le modifier, mais c'est une entrée contrôlée par l'attaquant du point de vue du serveur : s'il influence l'autorisation ou la logique métier, il faut le protéger avec HMAC ou AEAD, lui donner une expiration courte, le lier au principal authentifié et à la requête d'origine, et rejeter ce qui ne se vérifie pas. Et InputRequiredResult ne peut être renvoyé que sur prompts/get, resources/read et tools/call : nulle part ailleurs.
Effet collatéral : tous les résultats portent désormais un champ resultType obligatoire, avec "complete" pour le cas normal. Si vous parlez à un serveur d'une révision antérieure qui ne l'inclut pas, cela s'interprète comme "complete".
Les autres changements que vous remarquerez
En-têtes obligatoires pour le routage. Toute requête POST sur Streamable HTTP doit porter Mcp-Method avec la méthode, et Mcp-Name avec le nom de l'outil ou l'URI de la ressource sur tools/call, resources/read et prompts/get. Cela sonne administratif jusqu'à ce qu'on pense à qui se trouve devant votre serveur : un répartiteur, une passerelle ou un WAF peut désormais router, mesurer et appliquer des règles sans ouvrir le corps JSON. Le serveur est tenu de valider que l'en-tête et le corps concordent, et de rejeter avec 400 et HeaderMismatch (-32020) sinon. Il existe même un mécanisme pour refléter certains paramètres d'outil dans des en-têtes (x-mcp-header), pensé pour des cas comme le routage par région.
Listes cacheables. Les résultats de tools/list, prompts/list, resources/list, resources/read et resources/templates/list portent maintenant ttlMs et cacheScope (public ou private). Le premier est un indice de fraîcheur pour que le client mette en cache au lieu d'interroger ; le second dit si un intermédiaire partagé peut le stocker. Et il y a une petite recommandation à grand effet : renvoyer les outils de tools/list dans un ordre déterministe, pour que le prompt du modèle ne change pas d'un appel à l'autre et que le cache de prompt du LLM fasse mouche plus souvent.
Abonnements. Ce qui passait par un GET se demande maintenant avec subscriptions/listen, une requête dont la réponse est un flux qui reste ouvert. Le client choisit ce à quoi il s'abonne (toolsListChanged, promptsListChanged, resourcesListChanged, resourceSubscriptions) et le serveur étiquette chaque notification avec io.modelcontextprotocol/subscriptionId. Les notifications de progression et de log continuent de voyager sur le flux de la requête à laquelle elles appartiennent, pas par ici.
Autorisation. Trois tours de vis. Les serveurs d'autorisation devraient inclure le paramètre iss conformément à RFC 9207, et le client doit le valider contre l'issuer enregistré avant d'échanger le code. Les identifiants sont liés à l'issuer qui les a émis : stockés indexés par lui, jamais réutilisés avec un autre, et il faut se réenregistrer si le serveur d'autorisation change. Et l'enregistrement dynamique des clients (DCR, RFC 7591) est déprécié au profit des Client ID Metadata Documents, tout en restant disponible pour les autorisations qui ne supportent pas encore CIMD.
Erreurs. Il existe enfin une politique d'attribution des codes : de -32000 à -32019 reste une zone héritée que personne ne devrait plus utiliser, et de -32020 à -32099 est le territoire exclusif de la spécification. Les trois nouveaux codes sont HeaderMismatch (-32020), MissingRequiredClientCapability (-32021) et UnsupportedProtocolVersion (-32022). De plus, l'erreur de ressource introuvable passe de -32002 à -32602, même si les clients devraient continuer d'accepter l'ancienne venant de serveurs anciens.
Tasks hors du cœur. Les tâches expérimentales sortent du protocole de base et deviennent une extension officielle (io.modelcontextprotocol/tasks), avec polling via tasks/get au lieu du tasks/result bloquant. Dans la même veine, les capacités client et serveur gagnent un champ extensions pour négocier tout ce qui sort du noyau.
Ce qui casse et ce qui ne casse pas
Voici le tableau à avoir sous les yeux avant de toucher à quoi que ce soit. La spécification appelle modernes les versions qui portent les métadonnées sur chaque requête (à partir de 2026-07-28) et legacy celles qui utilisent un handshake (2025-11-25 et antérieures).
L'essentiel est dans les deux lignes qui échouent : un client ancien ne peut pas parler à un serveur uniquement moderne, et il n'y peut rien. C'est pourquoi la spécification demande qu'un serveur uniquement moderne indique, dans l'erreur qu'il renvoie à un initialize, les versions qu'il supporte : ce peut être le seul diagnostic que l'utilisateur de ce client verra jamais.
Un serveur qui veut servir les deux mondes le peut, et il décide selon la façon dont le client ouvre : si la requête porte un _meta moderne, il la sert sans état ; si un initialize arrive, il passe en mode ancien. Un client qui veut la même chose détecte l'ère du serveur par transport : en stdio, en sondant avec server/discover et en retombant sur initialize devant toute erreur qui n'est pas une erreur moderne reconnaissable ; sur HTTP, en lançant une requête moderne et en regardant le corps du 400 avant de décider. Ce résultat se met en cache par serveur, pas par requête.
Ce que vous devez changer, selon votre cas
Si vous utilisez des serveurs MCP en stdio local, ce qui est le cas de la plupart des assistants personnels et de presque tout ce qui tourne dans un IDE, rien ne presse. Votre client et vos serveurs négocient la version que les deux parlent, et la révision précédente reste valide. Ce qu'il faut faire, c'est mettre à jour le SDK quand vous toucherez ce serveur pour une autre raison, pas monter une migration à part. C'est exactement ce que nous ferons avec les serveurs de l'assistant personnel que nous avons construit avec Claude Code.
Si vous avez un serveur distant qui garde une session, il y a là du travail d'architecture, et c'est maintenant. Ce n'est pas changer une bibliothèque : c'est sortir l'état du processus. Inventoriez ce que vous gardez aujourd'hui entre les appels et décidez, pour chaque élément, s'il disparaît (parce que le client l'envoie désormais dans _meta), s'il devient un handle explicite que le client transporte comme argument, ou s'il part dans un stockage externe indexé par ce handle. Tout ce qui dépend de deux appels atterrissant sur la même instance est à considérer comme mort. La récompense est réelle : à l'arrivée, votre serveur tourne en serverless.
Si votre serveur ouvre des requêtes vers le client (sampling, elicitation ou roots), vous devez refaire ce flux avec MRTR. C'est le changement qui déplace le plus de logique, car vous passez d'un modèle conversationnel à un modèle où chaque tentative est autonome et où le contexte voyage dans le requestState que vous signez et vérifiez. Commencez par là, pas par le reste.
Si vous démarrez un nouveau serveur MCP, faites-le directement sur 2026-07-28. Il n'y a aucune raison de construire aujourd'hui sur le modèle à sessions, et il y en a une de ne pas le faire : dans douze mois vous migreriez ce que vous venez d'écrire.
Si vous maintenez un client, le travail est différent et probablement plus lourd : vous devez supporter les deux ères assez longtemps, mettre en cache ce que parle chaque serveur et gérer la dégradation avec discernement. Les quatre SDK de niveau 1 (TypeScript, Python, Go et C#) supportent déjà la nouvelle révision, celui de Rust est en bêta, une bonne partie vous est donc offerte si vous restez à jour.
Le calendrier réel
Le meilleur de la politique de cycle de vie, c'est qu'on peut planifier avec des dates plutôt qu'avec des rumeurs. Voici ce qui est déprécié et jusqu'à quand cela tient :
Attention à la dernière ligne, la seule vraiment pressée. Le transport HTTP+SSE était déprécié depuis mars 2025 et entre maintenant formellement dans la politique, avec une fenêtre de trois mois seulement. S'il vous reste quelque chose qui parle par là, c'est cette migration-là qui est urgente, pas les autres.
Être éligible au retrait ne veut pas dire être retiré ce jour-là : la décision appartient aux mainteneurs à chaque release et peut venir plus tard. Mais c'est la date sur laquelle planifier.
Ce que nous ferions
Trois critères que nous appliquons à ce type de changement, et qui valent particulièrement ici.
Ne migrez pas pour être à jour, migrez pour une raison. Un serveur stdio qui fonctionne n'a pas besoin d'être touché cette semaine. Le coût d'une migration sans motif n'est pas seulement le temps : c'est le risque que vous introduisez dans quelque chose qui allait bien. La fenêtre de douze mois existe pour être utilisée.
Ce qui est urgent, c'est ce qui se conçoit maintenant. Tout nouveau serveur MCP, et toute plateforme qui va ouvrir son API à des agents, se conçoit sans état dès le premier jour. C'est la décision la plus coûteuse à changer ensuite, parce que ce n'est pas une bibliothèque, c'est la façon dont vous répartissez le travail entre instances. Chez nous, cela pèse directement sur la manière dont Nexo exposera ses capacités aux agents de ses clients : la conception se fait contre la nouvelle révision, pas contre celle que nous connaissions.
Prudence avec le produit bâti sur des surfaces expérimentales. Nous l'avons appris avec WebMCP : nous avons construit sur un origin trial de Chrome et un changement côté navigateur a cassé la navigation de notre propre site, avec nos health checks au vert. MCP 2026-07-28 n'est pas expérimental, mais la leçon vaut : quand vous adoptez du tout frais, sachez comment l'éteindre si ça tourne mal, et vérifiez le résultat avec les mains et les yeux, pas seulement avec un code 200.
Questions fréquentes
Est-ce que quelque chose casse aujourd'hui si je ne fais rien ? Non, tant que votre client et vos serveurs parlent la même révision. Ce qui marchait continue de marcher, et la révision précédente reste supportée. Cela casse quand vous mélangez les ères : un client ancien face à un serveur qui ne parle que la nouvelle, ou l'inverse.
Combien de temps ai-je vraiment ? Douze mois minimum pour Roots, Sampling, Logging et l'enregistrement dynamique des clients, comptés depuis le 28 juillet 2026. L'exception est le transport HTTP+SSE, qui peut tomber trois mois après que sa proposition soit finale.
Dois-je implémenter `server/discover` ? Si vous écrivez un serveur, oui : c'est obligatoire. Si vous écrivez un client, non : vous pouvez lancer l'appel dont vous avez besoin et gérer l'erreur de version si elle apparaît. En stdio, c'est aussi la façon recommandée de détecter si le serveur en face est moderne ou ancien.
Que faire de l'état que je gardais dans la session ? Sortez-le du processus. Ce qui était contexte de protocole voyage maintenant dans le _meta de chaque requête. Ce qui est état applicatif devient un identifiant explicite que vous émettez et que le client vous rend comme argument, la donnée réelle allant dans un stockage externe si nécessaire.
Est-ce que cela affecte WebMCP ? Non. WebMCP est la proposition côté navigateur, portée par Chrome et travaillée au W3C, et elle suit son propre chemin. C'est une autre couche : MCP relie l'agent à des outils côté serveur, WebMCP expose les actions du site que l'utilisateur a ouvert.
Et les clients de bureau comme Claude ou ChatGPT ? Les produits adopteront la nouvelle révision à leur rythme, et aucun n'a publié de dates précises. En attendant, ils négocient une version avec chaque serveur : la coexistence est prévue par conception.
Conclusion
La lecture courte de 2026-07-28 : MCP a cessé de se comporter comme une conversation pour se comporter comme une API. Chaque requête s'explique seule, le serveur ne se souvient pas, et tout ce qui avait besoin de mémoire a été repensé ou supprimé. Cela rend le protocole plus ennuyeux à lire et infiniment plus simple à exploiter, ce qui est exactement ce dont a besoin quelque chose qui aspire à devenir une infrastructure.
Pour la plupart des équipes, la réponse pratique de cette semaine est de ne rien faire d'urgent et de bien planifier. Pour celles qui ont des serveurs distants avec session, ou qui s'apprêtent à concevoir l'ouverture de leur plateforme aux agents, c'est l'inverse : le travail commence maintenant, et il commence par sortir l'état du chemin.
Si vous êtes dans le second cas et voulez confronter la conception à quelqu'un qui l'a déjà fait, parlons-en. Nous construisons sur des LLM en production depuis deux ans, nous exploitons des serveurs MCP et nous avons payé la facture d'adopter des choses trop tôt.