MCP Events : quand un abonnement devient un identifiant impossible à révoquer
Points clés
- MCP Events ajoute un troisième déclencheur de réveil pour les agents — au-delà des planifications cron et des messages humains, un serveur MCP peut désormais pousser un webhook signé vers ChatGPT lorsque quelque chose change dans une application connectée.
- L'abonnement survit au jeton d'accès qui l'a créé —
ttlMs: nulldemande un abonnement sans expiration, et le tuple qui l'identifie ne contient ni jeton, ni portées, ni expiration. - ChatGPT prend en charge le mode de livraison webhook mais pas l'enveloppe de révocation
terminateddu projet — le seul signal de révocation restant est un refresh en échec renvoyant-32012 Forbidden. - Le propre critère de succès du groupe de travail — un SEP déposé — n'a pas été livré — le tableau de la charte affiche toujours « Ideating », champion « TBD », et une seule entrée de changelog datée du 24 mars 2026.
- WorkOS qualifie l'abonnement d'identifiant — un enregistrement durable, créé sous le jeton d'accès d'un utilisateur, qui autorise votre serveur à pousser les données de cet utilisateur vers un agent bien après l'expiration du jeton.
Jusqu'à présent, un agent IA se réveillait pour l'une de deux raisons : une planification cron se déclenchait, ou un humain tapait un message. Le 29 septembre 2026, à la DevDay, OpenAI a annoncé l'ajout du support de la proposition de spécification MCP Events, afin que les plugins puissent lancer des automatisations quand quelque chose se produit dans une application connectée. La documentation décrit comment un serveur MCP peut pousser des mises à jour vers ChatGPT — un événement message.created filtré par canal, ou un comment.created filtré par document — pour que l'agent agisse quand un rapport de bug arrive ou qu'un commentaire de revue est publié, et non quand vous pensez à demander. Nathan Baschez, qui travaille sur le design produit chez Notion, a publié le 3 octobre qu'il n'avait jamais vu si peu d'enthousiasme à ce sujet : « Les déclencheurs événementiels sont une énorme affaire. »
Cet article cartographie ce que MCP Events implémente réellement, le déficit de durée de vie d'identifiant en son centre, et ce qu'un serveur MCP de production doit stocker et vérifier avant de livrer un webhook. Il s'appuie sur MCP 2026-07-28: What the Stateless Protocol Means for B2B Agent Deployments, qui couvrait le cœur sans état ; ici nous nous concentrons sur l'extension événementielle et sur le problème du cycle de vie d'abonnement que le groupe de travail n'a pas fini de spécifier.
Ce que ChatGPT implémente réellement
La charte du MCP Triggers and Events Working Group ne liste qu'un seul élément de travail actif : « SEP: Events in MCP v1 RFC », statut « Ideating », date cible « End April », champion « TBD ». La charte compte une seule entrée de changelog, datée du 2026-03-24 : « Initial charter ». Le groupe de travail est mené par Clare Liguori (AWS) et Peter Alexander (Anthropic).
Le dépôt d'incubation raconte une autre histoire. Il contient une esquisse de conception marquée « Status: Draft proposal », rédigée par Peter Alexander, datée du 2026-02-19. Le README est sans détour : les contenus sont exploratoires et « ne représentent pas des spécifications ou recommandations officielles de MCP ». Les implémenteurs déposent déjà des retours de terrain. Ce qui n'existe pas, c'est un SEP déposé — le propre critère de succès déclaré de la charte : « un SEP accepté définissant le mécanisme déclencheur/rappel et son cycle de vie d'abonnement. »
ChatGPT implémente une tranche de ce document inachevé. Le guide MCP Events d'OpenAI exige MCP 2.0, la version de protocole 2026-07-28, et prend en charge la livraison webhook et la vérification de rappel du projet. Le polling, le streaming, et les notifications de contrôle gap et terminated du projet ne sont pas pris en charge. Ce dernier point compte.
La mécanique est directe. Un serveur annonce une capacité events dans sa réponse server/discover. L'utilisateur indique à ChatGPT quoi surveiller et comment répondre. ChatGPT appelle events/subscribe avec le nom de l'événement, les arguments de filtre, une URL de rappel et un secret de signature. Le serveur vérifie le rappel avec un défi à usage unique, stocke l'abonnement, et pousse les événements correspondants sous forme de webhooks signés. Trois méthodes — events/list, events/subscribe, events/unsubscribe — s'exécutent sur le même point de terminaison authentifié que les outils.
L'abonnement est un identifiant
La partie qui mérite l'attention est ce que le projet demande à votre serveur de stocker. Comme le cadre l'analyse de WorkOS, un abonnement d'événements est un identifiant : un enregistrement durable, créé sous le jeton d'accès d'un utilisateur, qui autorise votre serveur MCP à pousser les données de cet utilisateur vers un agent bien après que le jeton qui l'a créé a expiré.
Comparez l'abonnement au jeton qui a autorisé l'appel. Selon la spécification d'autorisation 2026-07-28, les serveurs doivent valider que les jetons d'accès ont été émis spécifiquement pour eux, l'autorisation doit figurer dans chaque requête HTTP, et les jetons invalides ou expirés doivent recevoir un 401. Courte durée de vie, portées étroites, revérifiés à chaque requête. L'abonnement n'hérite rien de tout cela. L'esquisse de conception clé un abonnement webhook sur le tuple (principal, delivery.url, name, arguments) — le principal est l'identifiant canonique du sujet authentifié côté serveur. Le tuple ne contient ni le jeton lui-même, ni ses portées, ni son expiration. Et la durée de vie est négociable jusqu'à l'infini : ttlMs: null demande un abonnement sans expiration, et un serveur qui l'accorde renvoie refreshBefore: null.
| Jeton d'accès | Abonnement d'événements | |
|---|---|---|
| Durée de vie | Courte, expiration fixe | Le TTL que vous accordez, jusqu'à sans expiration (ttlMs: null) |
| Lié à | Votre serveur comme audience, plus les portées | (principal, url, name, arguments) — ni jeton, ni portées, ni expiration |
| Vérifié | À chaque requête HTTP, 401 à l'expiration | DOIT à la souscription ; DEVRAIT « périodiquement » ensuite, sans intervalle |
| Se termine quand | Il expire ou le serveur d'autorisation le révoque | Le TTL s'épuise, le client se désabonne, ou votre serveur le termine |
Le jeton d'accès expire. L'abonnement qu'il a créé continue de livrer.
La révocation est asymétrique dans ChatGPT
Le projet est clair sur l'obligation et vague sur la cadence. À la souscription, le principal doit être authentifié et autorisé. À la livraison : « Le serveur DEVRAIT périodiquement revérifier les permissions. Si l'accès de l'utilisateur est révoqué (par exemple retiré d'un canal Slack), » le serveur termine l'abonnement. Le guide d'OpenAI réitère la même obligation : « Revérifiez l'accès de l'utilisateur pendant la durée de vie de l'abonnement et cessez la livraison si l'accès est révoqué. »
« Périodiquement » fait beaucoup de travail dans cette phrase. Pas d'intervalle, pas de DOIT, et aucun test de conformité derrière.
Puis il y a le signal lui-même. Dans le projet, chaque mode de livraison a sa manière de dire « stop ». Pour les webhooks, c'est une enveloppe signée {"type":"terminated"} POSTée vers l'URL de rappel. Après cela, l'abonnement n'existe plus, si bien qu'un refresh ultérieur renvoie -32012 Forbidden si la cause de la terminaison persiste. Cette enveloppe est la manière du protocole de dire à l'agent « ceci s'est arrêté, et voici pourquoi ». C'est aussi l'une des deux notifications de contrôle que l'intégration de ChatGPT ne prend pas en charge.
| Mode de livraison | Comment le projet dit « stop » | Dans ChatGPT |
|---|---|---|
| Poll | Une erreur au prochain sondage | Mode non pris en charge |
| Push stream | notifications/events/terminated |
Mode non pris en charge |
| Webhook | Enveloppe signée terminated POSTée au rappel |
Mode pris en charge, enveloppe non prise en charge |
| Tout mode | Le prochain refresh échoue avec -32012 Forbidden |
Le seul signal restant |
Dans l'intégration de ChatGPT, le seul signal de révocation restant est un refresh en échec. Si l'accès d'un utilisateur est révoqué et que votre serveur cesse la livraison, l'agent ne l'apprend que lorsque le TTL de l'abonnement s'épuise et que le refresh échoue. Si vous avez accordé ttlMs: null, l'agent ne l'apprend jamais.
Ce que votre serveur doit vérifier
Le projet et le guide d'OpenAI spécifient ensemble une véritable surface de sécurité. Les parties non négociables :
- Exigez un principal authentifié.
events/subscribeetevents/unsubscribedoivent être appelés avec un principal authentifié ; les appels qui échouent à l'autorisation reçoivent-32012 Forbidden. - Vérifiez le point de terminaison avant la première livraison réelle. HMAC arrête la falsification, pas l'inondation. Le serveur ne doit pas commencer à livrer vers une URL de rappel avant que l'intention du point de terminaison de recevoir des livraisons soit confirmée — un défi de handshake, une liste d'autorisation, ou une vérification préalable hors bande.
- Exécutez les contrôles SSRF au moment de la livraison. Les URL de rappel doivent utiliser HTTPS. Résolvez et validez l'adresse de destination à chaque connexion, bloquez les plages privées et locales, ne suivez jamais les redirections, et appliquez tout cela aux requêtes de vérification autant qu'aux livraisons.
- Gardez des charges utiles minimales. Les charges utiles d'événements portent le même risque d'injection que les résultats d'outils. Le guide d'OpenAI dit d'envoyer un résumé et d'exposer un outil de lecture pour l'enregistrement complet, de traiter le texte rédigé par les utilisateurs comme des données, et de ne pas ajouter d'instructions dictant au modèle comment se comporter dans la charge utile.
- Rendez les écritures idempotentes. Les événements peuvent arriver désordonnés, donc des appels répétés ne doivent pas dupliquer les changements. Les livraisons plafonnent à 256 KiB, et les réponses 410 et 413 ne sont pas retentées.
- Autorisez au moment de l'action, pas de la réception. La réception d'un événement ne constitue pas une autorisation d'agir. L'appel d'outil que l'agent effectue en réponse passe par vos contrôles habituels — les mêmes qui filtrent les appels d'outils MCP au-delà des portées OAuth.
Tout ce qui précède figure dans les documents. Les deux choses qui n'y figurent pas : à quelle fréquence vous revérifiez l'accès, et comment un utilisateur ou un administrateur voit ce que son compte pousse.
Trois décisions que vous devez prendre vous-même
Le cycle de vie d'abonnement est précisément ce que le groupe de travail s'est charté de spécifier et pour lequel il n'a pas encore livré de SEP. D'ici là, trois décisions sont les vôtres, et les valeurs par défaut les décideront mal.
D'abord, accordez des TTL finis courts et refusez ttlMs: null. Le TTL est l'intervalle auquel un abonnement révoqué devient visible pour le client. Un abonnement sans expiration est une concession OAuth que personne ne peut voir.
Ensuite, revérifiez l'accès sur un calendrier que vous pouvez énoncer en une phrase — pas « périodiquement ». Si vous ne pouvez pas dire « nous revérifions toutes les 15 minutes » et pointer le job qui le fait, vous comptez sur un DEVRAIT sans intervalle ni test de conformité.
Enfin, maintenez un index d'abonnements par utilisateur. Sans lui, départir un utilisateur signifie supposer que ses abonnements sont morts plutôt que le confirmer. Quand un employé part, la question de révocation n'est pas « son jeton a-t-il expiré » — c'est « tous les webhooks qu'il a autorisés se sont-ils arrêtés ».
MCP Events change le modèle de déclencheurs pour les agents, et c'est le véritable changement architectural. Mais le déficit de durée de vie d'identifiant est la partie qui mordra en premier les déploiements de production. Le protocole a rendu le serveur sans état ; l'extension d'événements a rendu le serveur à nouveau avec état — et l'état qu'il détient est un identifiant sans cadence de révocation spécifiée.
Le diagramme ci-dessous cartographie le cycle de vie d'abonnement, le déficit de durée de vie d'identifiant, et la surface de révocation asymétrique :```svg
Related reading
- MCP 2026-07-28: What the Stateless Protocol Means for B2B Agent Deployments — l'article parent : le cœur sans état que MCP Events étend avec une capacité événementielle, et pourquoi le protocole sans état a rendu le serveur sans état uniquement pour que l'extension d'événements le rende à nouveau avec état
- MCP Security Hardening Checklist for Production Deployments — la thèse des modules gouvernés et les contrôles de sécurité applicables aux abonnements d'événements : SSRF, injection de charge utile, rotation des secrets, vérification de rappel
- A2A vs MCP: Choosing the Right Protocol — comment MCP Events change la comparaison des protocoles en ajoutant une capacité événementielle à MCP
Une entreprise SaaS de taille intermédiaire exploite un serveur MCP de support client — de ceux qui connectent ChatGPT à un système de tickets et à une base de connaissances — et souhaite ajouter des déclencheurs événementiels pour qu'un agent rédige une réponse quand un nouveau ticket prioritaire arrive. L'équipe d'ingénierie implémente events/subscribe, stocke l'abonnement et livre la diffusion webhook. Trois semaines plus tard, un agent de support quitte l'entreprise. Son jeton d'accès a expiré en une heure. Son abonnement d'événements, créé sous ce jeton, continue de pousser des webhooks vers ChatGPT parce que personne n'a accordé de TTL fini et que l'index d'abonnements par utilisateur n'existe pas. L'enveloppe terminated qui aurait dit à ChatGPT « ceci s'est arrêté » n'est pas prise en charge dans l'intégration. L'agent continue d'agir sur des tickets que l'employé parti ne peut plus voir dans le système source.
Demandez une réalisation à périmètre défini. Une semaine de discovery. Vous obtenez un inventaire des systèmes, une carte des flux de travail et un périmètre fixe — que vous construisiez avec nous ou non.
Vous voulez cela construit pour vos systèmes ?
Chaque document ici provient d'un travail réel en production. Si vous avez un système cible et un flux en tête, nous pouvons cadrer une construction en une semaine.
Demander un projet cadréDécouverte d'une semaine. Vous obtenez un inventaire des systèmes, une cartographie des flux et un périmètre fixe — que vous construisiez avec nous ou non.