Volver a la Biblioteca
MCP

MCP Events: cuando una suscripción se convierte en una credencial que no puedes revocar

Última actualización: 3 de octubre de 2026

Conclusiones clave

  • MCP Events añade un tercer disparador de despertar para los agentes — además de los esquemas cron y los mensajes humanos, un servidor MCP ahora puede empujar un webhook firmado a ChatGPT cuando algo cambia en una aplicación conectada.
  • La suscripción sobrevive al token de acceso que la creó — ttlMs: null solicita una suscripción sin caducidad, y la tupla que la identifica no contiene token, ámbitos ni expiración.
  • ChatGPT soporta el modo de entrega webhook pero no el sobre de revocación terminated del borrador — la única señal de revocación restante es un refresco fallido que devuelve -32012 Forbidden.
  • El propio criterio de éxito del grupo de trabajo — un SEP presentado — no se ha enviado — la tabla del charter sigue en "Ideating" con champion "TBD" y una única entrada de changelog del 24 de marzo de 2026.
  • WorkOS encuadra la suscripción como una credencial — un registro duradero, creado bajo el token de acceso de un usuario, que autoriza a tu servidor a empujar los datos de ese usuario a un agente mucho después de que el token expire.

Hasta ahora, un agente de IA se despertaba por una de dos razones: se disparaba un esquema cron o un humano escribía un mensaje. El 29 de septiembre de 2026, en DevDay, OpenAI anunció que añade soporte para la propuesta de especificación MCP Events, de modo que los plugins puedan iniciar automatizaciones cuando ocurra algo en una aplicación conectada. La documentación describe cómo un servidor MCP puede empujar actualizaciones a ChatGPT — un evento message.created filtrado por canal, o un comment.created filtrado por documento — para que un agente actúe cuando llega un reporte de error o se publica un comentario de revisión, no cuando te acuerdas de preguntar. Nathan Baschez, que trabaja en diseño de producto en Notion, publicó el 3 de octubre que no había visto apenas emoción al respecto: "Los disparadores dirigidos por eventos son un gran asunto".

Este artículo mapea lo que MCP Events realmente implementa, el hueco de vida de credencial en su centro y lo que un servidor MCP de producción debe almacenar y verificar antes de enviar un webhook. Se basa en MCP 2026-07-28: What the Stateless Protocol Means for B2B Agent Deployments, que cubrió el núcleo sin estado; aquí nos centramos en la extensión dirigida por eventos y en el problema del ciclo de vida de la suscripción que el grupo de trabajo no ha terminado de especificar.

Lo que ChatGPT realmente implementa

El charter del MCP Triggers and Events Working Group lista un único elemento de trabajo activo: "SEP: Events in MCP v1 RFC", estado "Ideating", fecha objetivo "End April", champion "TBD". El charter tiene una única entrada de changelog, fechada 2026-03-24: "Initial charter". El grupo de trabajo está liderado por Clare Liguori (AWS) y Peter Alexander (Anthropic).

El repositorio de incubación cuenta otra historia. Contiene un design sketch marcado "Status: Draft proposal", escrito por Peter Alexander, fechado 2026-02-19. El README es contundente: los contenidos son exploratorios y "no representan especificaciones ni recomendaciones oficiales de MCP". Los implementadores ya están presentando reportes de campo contra él. Lo que no hay es un SEP presentado — el propio criterio de éxito declarado del charter: "An accepted SEP defining the trigger/callback mechanism and its subscription lifecycle."

ChatGPT implementa una porción de ese documento inacabado. La guía de MCP Events de OpenAI requiere MCP 2.0, versión de protocolo 2026-07-28, y soporta la entrega webhook y la verificación de callback del borrador. Polling, streaming y las notificaciones de control gap y terminated del borrador no están soportadas. Esa última importa.

La mecánica es directa. Un servidor anuncia una capacidad events en su respuesta server/discover. El usuario le dice a ChatGPT qué monitorizar y cómo responder. ChatGPT llama a events/subscribe con el nombre del evento, los argumentos de filtro, una URL de callback y un secreto de firma. El servidor verifica el callback con un desafío de un solo uso, almacena la suscripción y empuja los eventos coincidentes como webhooks firmados. Tres métodos — events/list, events/subscribe, events/unsubscribe — se ejecutan en el mismo endpoint autenticado que las herramientas.

La suscripción es una credencial

La parte que merece atención es lo que el borrador pide almacenar a tu servidor. Como lo encuadra el análisis de WorkOS, una suscripción de eventos es una credencial: un registro duradero, creado bajo el token de acceso de un usuario, que autoriza a tu servidor MCP a empujar los datos de ese usuario a un agente mucho después de que el token que la creó haya expirado.

Compara la suscripción con el token que autorizó la llamada. Bajo la especificación de autorización 2026-07-28, los servidores deben validar que los tokens de acceso fueron emitidos específicamente para ellos, la autorización debe incluirse en cada petición HTTP, y los tokens inválidos o expirados deben recibir un 401. De vida corta, estrechos en ámbito, re-verificados en cada petición. La suscripción no hereda nada de eso. El design sketch identifica la suscripción webhook por la tupla (principal, delivery.url, name, arguments) — el principal es el identificador canónico del sujeto autenticado en el servidor. La tupla no incluye el token, sus ámbitos ni su expiración. Y la vida es negociable hasta el infinito: ttlMs: null solicita una suscripción sin caducidad, y un servidor que la concede devuelve refreshBefore: null.

Token de acceso Suscripción de eventos
Vida Corta, expiración fija El TTL que concedas, hasta sin caducidad (ttlMs: null)
Ligada a Tu servidor como audiencia, más ámbitos (principal, url, name, arguments) — sin token, ámbitos ni expiración
Verificada En cada petición HTTP, 401 al expirar DEBE en el momento de suscribirse; DEBERÍA "periódicamente" después, sin intervalo
Termina cuando Expira o el servidor de autorización la revoca El TTL vence, el cliente se da de baja, o tu servidor la termina

El token de acceso expira. La suscripción que creó sigue entregando.

La revocación es asimétrica en ChatGPT

El borrador es claro sobre la obligación y vago sobre la cadencia. En el momento de suscribirse, el principal debe estar autenticado y autorizado. En el momento de la entrega: "The server SHOULD periodically re-verify permissions. If the user's access is revoked (e.g., removed from a Slack channel)," el servidor termina la suscripción. La guía de OpenAI reproduce el mismo deber: "Recheck the user's access during the subscription's lifetime and stop delivery if access is revoked."

"Periódicamente" hace mucho trabajo en esa frase. No hay intervalo, no hay DEBE, y no hay prueba de conformidad detrás.

Luego está la señal misma. En el borrador, cada modo de entrega tiene su manera de decir "para". Para webhooks es un sobre firmado {"type":"terminated"} enviado por POST a la URL de callback. Después de eso la suscripción ya no existe, así que un refresco posterior devuelve -32012 Forbidden si la causa de la terminación persiste. Ese sobre es la manera del protocolo de decir al agente "esto se detuvo, y he aquí por qué". Es también una de las dos notificaciones de control que la integración de ChatGPT no soporta.

Modo de entrega Cómo dice "para" el borrador En ChatGPT
Poll Un error en el siguiente sondeo Modo no soportado
Push stream notifications/events/terminated Modo no soportado
Webhook Sobre firmado terminated por POST al callback Modo soportado, sobre no soportado
Cualquier modo El siguiente refresco falla con -32012 Forbidden La única señal restante

En la integración de ChatGPT, la única señal de revocación restante es un refresco fallido. Si el acceso de un usuario es revocado y tu servidor detiene la entrega, el agente solo lo aprende cuando el TTL de la suscripción expira y el refresco falla. Si concediste ttlMs: null, el agente nunca se entera.

Lo que tu servidor debe verificar

El borrador y la guía de OpenAI especifican entre ambos una superficie de seguridad real. Las partes que no son negociables:

  • Exige un principal autenticado. events/subscribe y events/unsubscribe deben llamarse con un principal autenticado; las llamadas que fallan la autorización reciben -32012 Forbidden.
  • Verifica el endpoint antes de la primera entrega real. HMAC detiene la falsificación, no la inundación. El servidor no debe empezar a entregar a una URL de callback hasta que la intención del endpoint de recibir entregas esté confirmada — un desafío de handshake, una lista de permitidos o una verificación previa fuera de banda.
  • Ejecuta comprobaciones SSRF en el momento de la entrega. Las URLs de callback deben usar HTTPS. Resuelve y valida la dirección de destino en cada conexión, bloquea los rangos privados y locales, no sigas nunca redirecciones, y aplica todo ello también a las peticiones de verificación además de a las entregas.
  • Mantén los payloads mínimos. Los payloads de eventos conllevan el mismo riesgo de inyección que los resultados de herramientas. La guía de OpenAI dice enviar un resumen y exponer una herramienta de lectura para el registro completo, tratar el texto escrito por usuarios como datos, y no añadir instrucciones que digan al modelo cómo comportarse dentro del payload.
  • Haz las escrituras idempotentes. Los eventos pueden llegar desordenados, así que llamadas repetidas no deben duplicar cambios. Las entregas se limitan a 256 KiB, y las respuestas 410 y 413 no se reintentan.
  • Autoriza en el momento de la acción, no en el de la recepción. La recepción de un evento no constituye autorización para actuar. La llamada a herramienta que el agente haga en respuesta pasa por tus comprobaciones normales — las mismas que filtran las llamadas a herramientas MCP más allá de los ámbitos OAuth.

Todo lo anterior está en los documentos. Las dos cosas que no están: con qué frecuencia re-verificas el acceso, y cómo un usuario o un administrador ve lo que su cuenta está empujando.

Tres decisiones que debes tomar tú mismo

El ciclo de vida de la suscripción es exactamente lo que el grupo de trabajo se chartó a sí mismo especificar y para lo que aún no ha presentado un SEP. Hasta entonces, tres decisiones son tuyas, y los valores por defecto las decidirán mal.

Primero, concede TTLs finitos cortos y rechaza ttlMs: null. El TTL es el intervalo al que una suscripción revocada se hace visible para el cliente. Una suscripción sin caducidad es una concesión OAuth que nadie puede ver.

Segundo, re-verifica el acceso en una agenda que puedas declarar en una frase — no "periódicamente". Si no puedes decir "re-verificamos cada 15 minutos" y señalar el trabajo que lo hace, estás confiando en un DEBERÍA sin intervalo ni prueba de conformidad.

Tercero, mantén un índice de suscripciones por usuario. Sin él, despedir a un usuario significa asumir que sus suscripciones murieron en lugar de confirmarlo. Cuando un empleado se va, la pregunta de revocación no es "¿expiró su token?" — es "¿dejaron de dispararse todos los webhooks que autorizó?".

MCP Events cambia el modelo de disparadores para los agentes, y ese es el verdadero cambio arquitectónico. Pero el hueco de vida de credencial es la parte que morderá primero a los despliegues de producción. El protocolo hizo el servidor sin estado; la extensión de eventos hizo el servidor con estado otra vez — y el estado que retiene es una credencial sin cadencia de revocación especificada.

El diagrama siguiente mapea el ciclo de vida de la suscripción, el hueco de vida de credencial y la superficie de revocación asimétrica:

MCP Events: ciclo de vida de la suscripción y el hueco de credencial La primera primitiva de transporte MCP nueva desde la especificación sin estado de 2026-07-28 1 Suscribir — events/subscribe ChatGPT llama a tu servidor con nombre del evento, argumentos de filtro, URL de callback, secreto de firma (HMAC) El servidor verifica el callback (desafío de handshake), almacena la suscripción con propietario, filtros, URL, secreto, expiración Requiere MCP 2.0, versión de protocolo 2026-07-28 · Disponible para 1.200M usuarios semanales de ChatGPT 2 El hueco de credencial — la suscripción sobrevive al token Token de acceso: corto, ámbitos verificados en cada petición, 401 al expirar Suscripción: identificada por (principal, url, name, arguments) — sin token, ámbitos ni expiración en la clave ttlMs: null solicita sin caducidad · refreshBefore: null concedido · WorkOS: "una credencial que nadie puede ver" Token: TTL de ~1 hora Verificado en cada petición Suscripción: hasta para siempre DEBERÍA "periódicamente" — sin intervalo 3 Entregar — webhook firmado a la URL de callback Standard Webhooks: webhook-id, webhook-timestamp, webhook-signature · tope de 256 KiB · un evento por petición Comprobaciones SSRF en la entrega: solo HTTPS, bloquear rangos privados, sin redirecciones · El payload = superficie de inyección Escrituras idempotentes (los eventos llegan desordenados) · Recibo del evento ≠ autorización para actuar 4 Revocar — asimétrico en ChatGPT Borrador: sobre firmado {"type":"terminated"} por POST al callback → el agente sabe "esto se detuvo, y por qué" ChatGPT: modo webhook soportado, sobre terminated NO soportado Camino de revocación del borrador sobre terminated → agente notificado de inmediato Camino de revocación de ChatGPT TTL expira → refresco falla → -32012 Forbidden (única señal restante) ttlMs: null Sin caducidad → refresco nunca se dispara → el agente nunca se entera 5 Grupo de trabajo — SEP no presentado Líderes: Clare Liguori (AWS) + Peter Alexander (Anthropic) · Changelog del charter: una entrada, 2026-03-24 Elemento activo: "SEP: Events in MCP v1 RFC" — Estado: Ideating · Objetivo: End April · Champion: TBD Design sketch existe (2026-02-19, Borrador) · Implementadores presentan reportes de campo · Sin SEP presentado = sin pruebas de conformidad El ciclo de vida de la suscripción está explícitamente en alcance y explícitamente inacabado Tres decisiones que debes tomar antes de enviar a producción 1. Concede TTLs finitos cortos — rechaza ttlMs: null 2. Re-verifica el acceso en una agenda que puedas declarar en una frase 3. Mantén un índice de suscripciones por usuario — confirma, no asumas, en el offboarding

Related reading


Una empresa SaaS de mercado medio que opera un servidor MCP de soporte al cliente — del tipo que conecta ChatGPT con un sistema de tickets y una base de conocimiento — quiere añadir disparadores dirigidos por eventos para que un agente redacte una respuesta cuando llegue un ticket nuevo de prioridad alta. El equipo de ingeniería implementa events/subscribe, almacena la suscripción y envía la entrega webhook. Tres semanas después, un agente de soporte deja la empresa. Su token de acceso expiró en una hora. Su suscripción de eventos, creada bajo ese token, sigue disparando webhooks a ChatGPT porque nadie concedió un TTL finito y el índice de suscripciones por usuario no existe. El sobre terminated que habría dicho a ChatGPT "esto se detuvo" no está soportado en la integración. El agente sigue actuando sobre tickets que el empleado que se fue ya no puede ver en el sistema de origen.

Solicita una implementación acotada. Un descubrimiento de una semana. Recibirás un inventario de sistemas, un mapa de flujos de trabajo y un alcance fijo, construyas o no con nosotros.

¿Quieres esto construido para tus sistemas?

Cada documento aquí viene de trabajo real de producción. Si tienes un sistema objetivo y un flujo en mente, podemos definir un proyecto en una semana.

Solicitar un proyecto

Descubrimiento de una semana. Obtienes un inventario de sistemas, mapa de flujos y alcance fijo — decidas o no construir con nosotros.