> ## Content Index
> Fetch the complete content index at: https://www.sfeir.dev/llms.txt
> Use this file to discover other available public pages before exploring further.

# MCP 2026-07-28 : serveur stateless, fin de Mcp-Session-Id et passage aux Client ID Metadata Documents (CIMD)
- URL: https://www.sfeir.dev/ia/mcp-2026-07-28-stateless-cimd/
- Published: 2026-10-15T12:33:00.000Z
- Updated: 2026-10-15T12:32:59.000Z
- Description: Révision MCP 2026-07-28 : fin de Mcp-Session-Id, server/discover, DCR déprécié au profit de CIMD. Ce qui change pour vos serveurs.
- Author: Baptiste PIRAULT
- Tags: IA, MCP, Agent IA, Agentic

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#mcp-2026-07-28--serveur-stateless-fin-de-mcp-session-id-et-passage-aux-client-id-metadata-documents-cimd)

La révision `2026-07-28` de la spécification [**Model Context Protocol**](https://www.sfeir.dev/mcp-model-context-protocol-la-cle-pour-connecter-les-ia-au-monde-reel-2/) est la plus structurante depuis l'arrivée de Streamable HTTP. Elle supprime les sessions, remplace le handshake `initialize`, et engage la dépréciation de Dynamic Client Registration au profit des **Client ID Metadata Documents** (CIMD). Ayant migré des serveurs en production à travers cette révision, je détaille ici ce qui change, ce qui ne change pas, et les pièges que j'ai rencontrés.

Un avertissement d'abord : la majorité des tutoriels MCP que renvoie un moteur de recherche décrivent un handshake et un header de session qui n'existent plus. Lisez le [changelog officiel](https://modelcontextprotocol.io/specification/2026-07-28/changelog?ref=sfeir.dev) avant de faire confiance à un article daté d'avant l'été 2026.

## Ce qui disparaît : `Mcp-Session-Id`, `initialize` et le flux GET

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#ce-qui-dispara%C3%AEt--mcp-session-id-initialize-et-le-flux-get)

Sur le transport HTTP, la révision retire :

- le header `Mcp-Session-Id` ;
- le handshake `initialize` ;
- la reprise de flux SSE et l'endpoint `GET` du transport.

La version du protocole et les capacités du client voyagent désormais dans `_meta` à **chaque requête**. Le serveur peut annoncer ses capacités en amont via un nouvel appel `server/discover`. Les headers `Mcp-Method` et `Mcp-Name` deviennent obligatoires sur les POST : ils exposent la méthode appelée aux intermédiaires (proxy, API gateway) sans qu'ils aient à décoder le corps JSON-RPC. Sur ce que JSON-RPC change pour vos APIs et vos gateways, voir [Pourquoi l'IA agentique a ressuscité JSON-RPC et ce que ça change pour vos APIs](https://www.sfeir.dev/ia/pourquoi-lia-agentique-a-ressuscite-json-rpc-et-ce-que-ca-change-pour-vos-apis/).

Conséquence pratique : n'importe quelle requête peut être routée vers n'importe quelle instance derrière un load balancer round-robin, sans rien de partagé entre elles. Un serveur qui a réellement besoin de continuité entre deux appels émet un **handle explicite** et le reçoit en argument de tool. L'état passe sous votre contrôle, dans votre schéma, au lieu de vivre dans un header de transport.

## Migrer un serveur MCP vers la révision 2026-07-28 : qui est concerné ?

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#migrer-un-serveur-mcp-vers-la-r%C3%A9vision-2026-07-28--qui-est-concern%C3%A9-)

- **Un serveur stateful** a un vrai chantier : les sessions sur lesquelles il s'appuyait n'existent plus.
- **Un serveur déjà stateless** (la forme habituelle pour un serveur déployé sur Cloud Run ou un runtime autoscalé) voit son architecture validée. Une montée de version de bibliothèque suffit.

Les clients négocient la version à chaque requête : un ancien serveur continue de répondre aux nouveaux clients pendant la transition. Un serveur qui ne répond pas à `server/discover` est antérieur à la révision, ce qui explique souvent à lui seul le comportement étrange d'un client récent.

## Ce qui ne change pas : votre état OAuth reste stateful

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#ce-qui-ne-change-pas--votre-%C3%A9tat-oauth-reste-stateful)

C'est la confusion que je vois le plus. La spécification a cessé de gérer les **sessions de transport**. Elle n'a jamais géré vos **enregistrements de clients OAuth** ni les tokens amont chiffrés que votre proxy conserve.

Si votre bibliothèque stocke ces enregistrements sur le disque local par défaut, un déploiement autoscalé produit des échecs d'authentification intermittents, différents selon l'instance qui reçoit la requête. "Stateless" ne veut pas dire "sans store partagé" : vos clients OAuth ont toujours besoin d'un stockage externe à l'instance (Firestore, Redis, base SQL).

## Dynamic Client Registration déprécié : passer aux Client ID Metadata Documents (CIMD)

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#dynamic-client-registration-d%C3%A9pr%C3%A9ci%C3%A9--passer-aux-client-id-metadata-documents-cimd)

Jusqu'ici, un client MCP qui découvrait un serveur s'enregistrait dynamiquement (**DCR**, [RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591?ref=sfeir.dev)) et recevait un `client_id` opaque. Avec **CIMD**, le `client_id` est une URL HTTPS qui pointe vers un document JSON décrivant le client :

```json
{
  "client_id": "https://app.example.com/oauth/client.json",
  "client_name": "Mon client MCP",
  "redirect_uris": ["http://127.0.0.1/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "token_endpoint_auth_method": "none"
}
```

Le serveur d'autorisation récupère ce document au moment de l'autorisation, au lieu de maintenir un registre de clients. DCR reste disponible pour les serveurs d'autorisation qui ne supportent pas CIMD, et la fenêtre de dépréciation est de douze mois : rien ne casse ce trimestre.

### Côté serveur d'autorisation

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#c%C3%B4t%C3%A9-serveur-dautorisation)

Récupérer un document à une URL fournie par le client n'est pas anodin. Le [draft IETF](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-client-id-metadata-document-02?ref=sfeir.dev) impose notamment :

- le `client_id` du document doit être **strictement égal** à l'URL d'où il provient ;
- le `redirect_uri` de la requête doit correspondre exactement à l'une des URI du document ;
- **ne pas suivre de redirection** lors de la récupération ;
- refuser les adresses privées ou spéciales (**SSRF**) ;
- limiter la taille du document (de l'ordre de 5 Ko) et ne jamais mettre une erreur en cache ;
- annoncer le support via `client_id_metadata_document_supported` dans les métadonnées.

### Côté client

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#c%C3%B4t%C3%A9-client)

Le document est public par construction. Il ne doit contenir **aucun secret partagé ni clé privée**, et la méthode d'authentification déclarée doit être cohérente avec ce que le client sait réellement faire. Pour vérifier le document de mon propre client, j'utilise `mcp-posture`, un scanner open source que j'ai développé :

```
uvx mcp-posture cimd lint https://app.example.com/oauth/client.json
```

## Trois pièges rencontrés pendant la migration

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#trois-pi%C3%A8ges-rencontr%C3%A9s-pendant-la-migration)

### Le `client_id` n'est plus un token opaque

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#le-client%5Fid-nest-plus-un-token-opaque)

Avec CIMD, le `client_id` est une URL, avec des slashs et un schéma. Un code qui l'utilise comme clé de stockage ou segment de chemin échoue. Je l'ai vécu : le store clé-valeur refusait le caractère `/`, et l'erreur remontait en **500** plutôt qu'en erreur OAuth, car le chemin d'erreur relisait le même client. Ce qui ressemblait à un cas marginal quand deux clients le faisaient devient le cas nominal. Assainissez vos clés.

### `invalid_client_metadata` : `application_type` désormais requis à l'enregistrement

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#invalid%5Fclient%5Fmetadata--application%5Ftype-d%C3%A9sormais-requis-%C3%A0-lenregistrement)

La révision impose aux clients qui utilisent encore DCR d'envoyer `application_type`. Un serveur qui valide strictement les métadonnées d'enregistrement le rejette avec un `invalid_client_metadata` qui ne nomme pas le champ fautif. Acceptez-le explicitement.

### Le cache change de place, pas de nature

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#le-cache-change-de-place-pas-de-nature)

Avec DCR, un client mettait en cache un `client_id` obtenu *avant* votre correctif, et vous pensiez que le correctif ne marchait pas. Avec CIMD, il n'y a plus d'enregistrement à mettre en cache, mais le serveur d'autorisation met en cache le document récupéré, selon ses propres règles. La question à se poser reste la même ; seul l'objet à invalider change.

## Un cycle de vie formel pour les fonctionnalités

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#un-cycle-de-vie-formel-pour-les-fonctionnalit%C3%A9s)

Dernier changement, plus discret mais utile : la spécification a désormais un [cycle de vie formel](https://modelcontextprotocol.io/community/feature-lifecycle?ref=sfeir.dev). Chaque fonctionnalité est *Active*, *Deprecated* ou *Removed*, avec au moins douze mois entre les deux derniers états et un [registre public](https://modelcontextprotocol.io/specification/2026-07-28/deprecated?ref=sfeir.dev) des fonctionnalités dépréciées. **Roots**, **Sampling** et **Logging** sont entrés dans cette fenêtre avec cette révision, tout comme le transport HTTP+SSE historique.

## Checklist de migration

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#checklist-de-migration)

- Le serveur répond à `server/discover` et accepte la version annoncée dans `_meta` (sinon : `UnsupportedProtocolVersionError`).
- Un `405 Method Not Allowed` sur `GET /mcp` est normal : l'endpoint GET n'existe plus.
- Aucune logique ne dépend de `Mcp-Session-Id` ; l'état nécessaire passe par des handles explicites.
- Les headers `Mcp-*` ne sont pas supprimés par un proxy ou un load balancer.
- Les enregistrements OAuth sont dans un store partagé, pas sur le disque de l'instance.
- Les clés de stockage acceptent un `client_id` en forme d'URL.
- L'enregistrement accepte `application_type`.
- Aucune nouvelle fonctionnalité ne repose sur Roots, Sampling ou Logging.

## Conclusion

[](https://github.com/batou9150/writing-workspace/blob/main/blog/drafts/2%5FMCP%202026-07-28%2C%20stateless%20et%20CIMD%20%28FR%29.md?ref=sfeir.dev#conclusion)

Cette révision ne fait que formaliser ce que les serveurs déployés en serverless faisaient déjà : pas d'état de transport. Le vrai travail est ailleurs, dans l'état OAuth que vous gérez vous-même et dans le passage à des `client_id` en forme d'URL. Si vos serveurs étaient stateless, la migration tient en une après-midi. Sinon, c'est le bon moment pour sortir cet état du transport et le mettre dans votre schéma.

[Pourquoi l’IA agentique a ressuscité JSON-RPC et ce que ça change pour vos APIsDécouvrez comment le JSON-RPC, protocole d’action par excellence, devient le pilier du Model Context Protocol (MCP). Entre simplicité architecturale et puissance opérationnelle, explorez pourquoi ce standard surpasse REST pour connecter les agents IA à vos outils d’entreprise.![](https://storage.ghost.io/c/0b/31/0b31478e-a66a-46f1-8c34-d44388e21192/content/images/icon/plume-point-767a8f1d-31e4-4ab1-902e-41c74589edba.png)sfeir.dev - Le média incontournable pour les passionnés de tech et d'intelligence artificielleHamadi JABLOUN![](https://storage.ghost.io/c/0b/31/0b31478e-a66a-46f1-8c34-d44388e21192/content/images/thumbnail/AdobeStock_561694224-64d0d5f5-57ea-4a60-a3ef-48f90f3b0b9c.jpg)](https://www.sfeir.dev/ia/pourquoi-lia-agentique-a-ressuscite-json-rpc-et-ce-que-ca-change-pour-vos-apis/)

[Sécuriser un serveur MCP distant (OAuth) : 7 leçons apprises en production7 failles OAuth rencontrées en production sur des serveurs MCP distants, invisibles aux tests fonctionnels, et comment les démontrer puis les corriger.![](https://storage.ghost.io/c/0b/31/0b31478e-a66a-46f1-8c34-d44388e21192/content/images/icon/plume-point-a7a97b5f-236e-4d8d-8721-3fab5c1055c0.png)sfeir.dev - Le média incontournable pour les passionnés de tech et d'intelligence artificielleBaptiste PIRAULT![](https://storage.ghost.io/c/0b/31/0b31478e-a66a-46f1-8c34-d44388e21192/content/images/thumbnail/mcp_series_01-hero-9412deb0-e18b-4f49-8154-00b198926aa4.png)](https://www.sfeir.dev/ia/securiser-serveur-mcp-oauth/)