ALLER AU CONTENU
AGENTS IA7 minAgents en production / Ép. 11 · Niveau 11-1

MCP sans session : où va ce que gardait votre serveur ?

Votre serveur MCP range ses données dans une table indexée par identifiant de session. Avec la version 2026-07-28, cet identifiant disparaît : où vont ces données ?

XIN
Scène nocturne en pixel art : une rangée d’armoires de serveurs identiques, sans bagage à côté. Chaque enveloppe lumineuse qui arrive sur un tapis roulant porte son propre petit sac à dos, et une clé de coffre turquoise pend à l’une des enveloppes.

EN 30 SECONDES

MCP sans état, c’est le changement de la version 2026-07-28 de la spécification qui retire les sessions. Chaque requête porte ce dont le serveur a besoin pour y répondre. Ce que votre serveur gardait par session doit donc trouver une autre place.

À RETENIR · 3

  • La version 2026-07-28 supprime les sessions MCP. Chaque requête porte sa version de protocole et les capacités du client dans un champ _meta.
  • Dans ma règle de tri, le protocole va dans chaque requête, l’identité dans le jeton d’accès, un appel en attente dans un état scellé, le travail de longue durée derrière un handle.
  • clientInfo est autodéclaré : il ne prouve jamais qui appelle.
Sur cette page

Le problème : plus de session sur laquelle s’appuyer

EN BREF Un moyen rapide de casser un serveur sur la nouvelle version, c’est une table indexée par identifiant de session : cet identifiant n’existe plus.

Par transparence : je construis des outils pour agents, 200+ agents sur environ 21 plugins Claude Code. Ce que je présente comme une proposition est mon avis, pas le standard. Les citations anglaises de la spécification sont traduites librement.

LES MOTS À CONNAÎTRE

MCP
Model Context Protocol : le standard ouvert par lequel une application d’IA (le client) appelle les outils d’un programme (le serveur).
Session
Un contexte que le serveur gardait d’une requête à l’autre pour un même client.
Sans état
Le protocole ne garde aucune mémoire entre deux requêtes. Votre application, elle, peut toujours stocker des données.
Répartiteur de charge
Le composant (load balancer) qui distribue les requêtes entre plusieurs instances du même serveur.

EN CLAIR

Jusqu’ici, un client MCP Model Context Protocol : le standard ouvert par lequel une application d’IA (le client) appelle les outils d’un programme (le serveur). Voir le glossaire ouvrait une Session Un contexte que le serveur gardait d’une requête à l’autre pour un même client. Voir le glossaire une fois, et le serveur pouvait y accrocher des données.

La version 2026-07-28 de la spécification supprime les sessions : le protocole devient Sans état Le protocole ne garde aucune mémoire entre deux requêtes. Votre application, elle, peut toujours stocker des données. Voir le glossaire. Chaque requête doit se suffire à elle-même. Un Répartiteur de charge Le composant (load balancer) qui distribue les requêtes entre plusieurs instances du même serveur. Voir le glossaire peut envoyer deux requêtes d’un même client sur deux instances différentes.

L’article paraît le jour où se termine AGNTCon + MCPCon North America à San Jose (22 et 23 octobre). Je m’attends à ce que beaucoup de ces migrations s’y discutent.

Ce qui change pour les serveurs avec MCP 2026-07-28

EN BREF Une bonne part de ce que portait la session voyage désormais avec chaque requête : la version, les capacités du client, le niveau de log.

Le changelog s’ouvre sur deux lignes. La première supprime « les sessions au niveau du protocole et l’en-tête Mcp-Session-Id du transport Streamable HTTP ». La deuxième vise à « rendre MCP sans état » en supprimant la poignée de main initialize/notifications/initialized.

LE MÊME APPEL, AVANT ET APRÈS

Jusqu’à 2025-11-25

  • Le client se présente une fois (la poignée de main initialize) et peut recevoir un identifiant de session.
  • Le serveur garde une table qui associe cet identifiant aux données dont il a besoin.

À partir de 2026-07-28

  • Plus de présentation, plus d’identifiant de session.
  • Chaque requête porte ce qu’il lui faut : n’importe quelle instance peut y répondre.
Version simplifiée, d’après le changelog de la spécification.

Ces informations voyagent dans un champ appelé _meta. La version du protocole et les capacités du client sont obligatoires ; le nom du client, le niveau de log et le contexte de trace sont facultatifs. En HTTP, une requête sans champ obligatoire reçoit en réponse l’erreur -32602 et un statut HTTP 400.

ADAM explique : Pensez à un vestiaire : n’importe quel préposé vous sert, si vous montrez votre ticket. La limite : dans ma conception, le serveur vérifie aussi que le ticket est bien le vôtre.

Un serveur qui ne parle que la nouvelle version devrait ignorer un Mcp-Session-Id résiduel, ne jamais en émettre ni en renvoyer, et répondre 405 à GET ou DELETE.

Coming up next: Et le reste de vos données de session, où va-t-il ?

Où va chaque donnée de session

EN BREF Le protocole est sans état, votre serveur n’a pas à l’être : son état ne peut simplement plus se trouver dans la connexion.

La section Statelessness le dit : les serveurs « ne doivent pas (MUST NOT) s’appuyer sur les requêtes précédentes d’une même connexion pour établir le contexte ». L’état qui couvre plusieurs requêtes a sa propre règle :

« doit (MUST) être désigné par un identifiant explicite que le client transmet à chaque requête ».

Spécification MCP 2026-07-28, section Statelessness

Cela vaut aussi pour Le transport local : le client lance le serveur comme un processus et lui parle via l’entrée et la sortie standard. : une connexion ouverte « n’est ni une conversation ni une session ».

OÙ ÇA VA

Décision : Ce champ se trouvait dans la session. Où va-t-il désormais ?Arbre de décision : Ce champ se trouvait dans la session. Où va-t-il désormais ? Si Il décrit le protocole de l’appelant : version, capacités, niveau de log, trace, alors Lisez-le dans chaque requête. Si C’est l’identité de l’appelant, alors Tirez-la du jeton d’accès. Si C’est un appel en pause, en attente d’une saisie, alors Scellez-le dans un état que le client renvoie. Si Il doit survivre à l’appel : un import, un brouillon, une tâche, alors Un handle adossé à votre stockage.DÉCISIONCe champ se trouvait dans lasession. Où va-t-il désormais?Si il décrit le protocolede l’appelant : version,capacités, niveau de log,traceLisez-le dans chaquerequêteSi c’est l’identité del’appelantTirez-la du jetond’accèsJamais du nom que le clientdéclare lui-mêmeSi c’est un appel en pause,en attente d’une saisieScellez-le dans unétat que le clientrenvoieExpiration courte, lié àl’appelant et à la requêteSi il doit survivre àl’appel : un import, unbrouillon, une tâcheUn handle adossé àvotre stockage
Les clés de _meta : io.modelcontextprotocol/protocolVersion et io.modelcontextprotocol/clientCapabilities (obligatoires), io.modelcontextprotocol/clientInfo et io.modelcontextprotocol/logLevel (facultatives), plus traceparent. La spécification appelle cet état facultatif requestState.

Étape 1. La question. Prenez un champ que votre serveur gardait par session.

Choisissez une étape pour la voir bouger
  1. La question Prenez un champ que votre serveur gardait par session.
  2. Le protocole Lisez-les dans _meta à chaque requête, jamais dans une requête précédente.
  3. L’identité Elle vient du jeton d’accès, à chaque fois. clientInfo est autodéclaré et ne devrait pas (SHOULD NOT) servir aux décisions de sécurité.
  4. Un appel en attente Il est rangé dans un état scellé, que le client renvoie quand il relance l’appel. Le lier à l’appelant, à une expiration et à la requête limite le rejeu, sans le rendre à usage unique.
  5. Le travail durable Il reste dans votre stockage, derrière un handle : un identifiant émis par le serveur.
Ma règle de tri, construite sur les exigences de la spécification : quatre types de données de session, quatre nouvelles places.

Une réserve : pour la spécification, l’autorisation est facultative (OPTIONAL). Tirer l’identité du jeton suppose un serveur HTTP qui vérifie chaque appel. Je voudrais ce contrôle sur tout serveur qui touche des données réelles.

OBJET OBTENU

Chaque donnée trouve sa place

Chaque donnée trouve une nouvelle place : la requête, le jeton, un état scellé ou un handle.

Sources : release 2026-07-28, changelog, protocole de base, Streamable HTTP, toutes lues le 7 octobre 2026.

FAQ

Les serveurs doivent (MUST) implémenter server/discover, qui liste leurs versions et capacités. Les réponses des appels de liste, comme tools/list, portent deux champs obligatoires, ttlMs et cacheScope, et « ne dépendent plus de la connexion ». ping disparaît, et chaque résultat porte un resultType.

NIVEAU TERMINÉ

Ce que vous savez maintenant

  • Pourquoi une table indexée par session casse : l’identifiant n’existe plus, et l’appel suivant peut arriver ailleurs.
  • Où va désormais chaque type de donnée de session, et pourquoi l’identité vient du jeton.

Vérifiez par vous-même

Touchez ou cliquez une question pour voir la réponse.

En HTTP, une deuxième requête sur la même connexion n’a pas les capacités du client dans son _meta. Le serveur peut-il reprendre celles de la première ?

Non. Elles sont obligatoires dans chaque requête : celle-ci reçoit -32602 et HTTP 400.

Niveau suivant :Comment un serveur sans session demande-t-il une information à l’utilisateur en plein appel ?7 min
Adam Boudjemaa
Adam Boudjemaa

Ancien CTO d’Integra. Auteur nommé (1 sur 5) d’ERC-3643, premier auteur d’ERC-6960, co-auteur d’ERC-7410 et co-auteur d’ERC-8203, encore à l’état de brouillon. Conçoit des systèmes d’IA en production et des systèmes Web3 régulés.

Un projet à livrer ou un poste à pourvoir ?

Parlons de votre besoin
Suivre les notes techniques

Recevez les nouveaux articles sur l’IA en production et les smart contracts par email.