ChatGPT MCP Events: crie sua primeira automação de plugin acionada por eventos, passo a passo
Os MCP Events do ChatGPT permitem que o ChatGPT assine mudanças nos seus sistemas e aja sobre elas. Este guia apresenta a construção como um loop Advertise-Subscribe-Verify-Deliver (ASVD). Você anuncia a capacidade e o events/list, torna as assinaturas idempotentes, verifica os callbacks, assina as entregas como Standard Webhooks e testa antes do lançamento. O guia também indica onde a especificação em rascunho e os SDKs ainda estão mudando.
Com os MCP Events, o ChatGPT assina atualizações do seu servidor MCP, e os usuários escolhem o que monitorar e o que o ChatGPT deve fazer quando uma atualização chega. Se a sua equipe já opera um servidor MCP ou uma API SaaS, talvez você perceba que um conector agora pode iniciar uma automação por conta própria, em vez de esperar por um prompt.
Vamos percorrer a construção na ordem em que você vai escrever o código. Chamamos isso de loop Advertise-Subscribe-Verify-Deliver (ASVD), ou seja, anunciar, assinar, verificar e entregar: anuncie os eventos que você emite, torne as assinaturas idempotentes, verifique cada callback antes que ele entre em operação e, então, entregue eventos assinados com novas tentativas que sabem quando parar. Também vamos sinalizar onde a especificação ainda é um rascunho, porque alguns desses detalhes indefinidos acabam no seu código.
O que são os MCP Events e o que o ChatGPT realmente suporta
A documentação para desenvolvedores da OpenAI mantém a descrição curta: o ChatGPT assina atualizações do seu servidor MCP, como novas mensagens, atualizações de conteúdo ou mudanças de status, e o usuário decide o que acontece em seguida. O esboço de design em rascunho tem ambições maiores. Ele quer que um cliente MCP assine eventos em um sistema upstream, como uma mensagem no Slack, um push no GitHub ou um incidente no PagerDuty, para que o agente possa reagir sem que o usuário esteja presente.
O fato de design mais importante é o que o ChatGPT deixa de fora. O ChatGPT suporta a entrega por webhook e a verificação de callback da especificação em rascunho dos MCP Events. Polling, streaming e as notificações de controle gap e terminated do rascunho não são suportados por esta integração.
| Recurso da especificação em rascunho | Suportado pelo ChatGPT | O que construir para o ChatGPT |
|---|---|---|
| Entrega por webhook | Sim | Construa, assine e faça novas tentativas |
| Verificação de callback | Sim | Construa antes de ativar qualquer assinatura |
| Polling | Não | Ignore nesta integração |
| Streaming (modo push) | Não | Ignore nesta integração |
| Notificações de controle gap e terminated | Não | Ignore nesta integração |
A Svix, uma empresa de infraestrutura de webhooks, chama o ChatGPT de o primeiro grande cliente a suportar MCP Events. Ela também observa que o seu servidor entrega eventos ao ChatGPT como Standard Webhooks. Um guia de construção de terceiros na DEV Community afirma que o suporte do ChatGPT começou no OpenAI DevDay, em 29 de setembro de 2026, na versão de protocolo 2026-07-28. Confirme ambos na própria documentação da OpenAI antes de fixar qualquer coisa no código com base neles.
Então, construa para webhooks e nada mais. Caminhos de código para polling e push-stream exigiriam manutenção enquanto existissem, e não fazem nada por esta integração.
Antes de construir: a realidade dos SDKs e o status da especificação
Depois do DevDay, um desenvolvedor na OpenAI Developer Community relatou que o SDK oficial de Python (mcp 2.2.0) ainda não suportava MCP Events, e que o SDK de TypeScript também não. Isso pode ter mudado, então leia as notas de versão atuais. Ainda assim, reservaríamos tempo para escrever parte da infraestrutura à mão.
O Go está em melhor situação. Uma issue aberta no SDK de Go observa que o suporte a métodos personalizados já permite implementar events/list, events/subscribe e events/unsubscribe. O que falta é uma forma de anunciar a capacidade events de nível superior.
A própria especificação ainda está em movimento. O estatuto do grupo de trabalho diz que, atualmente, os clientes ficam sabendo das atualizações do lado do servidor fazendo polling ou mantendo uma conexão SSE aberta, e que o grupo planeja especificar um mecanismo de callback padronizado para que os servidores possam enviar notificações por push. Em 2026-10-16, o grupo foi renomeado para Tasks and Events WG e assumiu o escopo de Tasks do Agents WG. Espere mais revisões.
Nosso conselho é escrever handlers personalizados enxutos agora e mantê-los isolados. Dê aos handlers dos métodos JSON-RPC um módulo próprio e faça o mesmo com o armazenamento de assinaturas e com a assinatura criptográfica e a entrega. Quando o suporte nos SDKs chegar, você troca a camada de protocolo e a sua lógica de negócio continua no lugar.
Etapa 1 do ASVD (Advertise, anunciar): declare a capacidade e defina o events/list
Declare a capacidade events
O seu servidor precisa anunciar a capacidade events de nível superior durante a inicialização. Sugerimos tratar essa declaração como um bloqueador de lançamento, e não como um detalhe a ser resolvido depois. No SDK de Go, essa é exatamente a lacuna descrita na issue aberta, então verifique a situação dela antes de escolher uma solução alternativa.
Projete cada tipo de evento para dois leitores
Sugerimos projetar cada entrada do events/list em torno destas partes:
- Um nome claro que permaneça estável ao longo do tempo.
- Uma descrição que funcione tanto para o usuário quanto para o modelo. O usuário a lê ao escolher o que monitorar; o modelo a lê ao decidir o que fazer.
- Um inputSchema que defina os filtros que um assinante pode configurar.
- Um payloadSchema que descreva exatamente o que você vai enviar.
O exemplo abaixo é ilustrativo. Confira os nomes exatos dos campos na documentação da OpenAI antes de copiá-lo.
{
"name": "ticket.status_changed",
"description": "A support ticket in a project you can access changed status.",
"inputSchema": {
"type": "object",
"properties": {
"project_id": { "type": "string" },
"status": { "type": "string", "enum": ["open", "pending", "closed"] }
},
"required": ["project_id"]
},
"payloadSchema": {
"type": "object",
"properties": {
"ticket_id": { "type": "string" },
"new_status": { "type": "string" },
"summary": { "type": "string" }
}
}
}Mantenha os filtros específicos e significativos para o usuário. Um projeto ou um status de ticket funciona bem, para que as pessoas recebam os eventos que pediram e pouco além disso. Trate o payloadSchema como um contrato público: versione-o, não o quebre e mantenha os payloads enxutos.
Restrinja os eventos ao usuário autenticado
O rascunho afirma que a autorização usa o mesmo principal MCP das suas ferramentas. Na prática, liste apenas os tipos de evento que o usuário autenticado tem permissão para ver e aceite apenas filtros que apontem para recursos que esse usuário pode acessar.
Etapa 2 do ASVD (Subscribe, assinar): events/subscribe e events/unsubscribe idempotentes
Clientes fazem novas tentativas. Redes perdem respostas. Se uma solicitação de subscribe repetida criar uma segunda assinatura, cada evento será enviado duas vezes e a automação de alguém será disparada duas vezes. Projete os dois métodos para que chamá-los novamente não mude nada.
Subscribe
Armazene cada assinatura com seu tipo de evento, filtros normalizados, URL de callback, segredo de assinatura e proprietário. Crie uma chave determinística a partir do proprietário, do tipo de evento, dos filtros normalizados e da URL de callback. Quando um usuário autorizado repete a solicitação, ele recebe de volta a assinatura existente.
authorize(owner_id, event_name, filters) // always first, even on repeats
key = hash(owner_id, event_name, canonical_json(filters), callback_url)
if store.exists(key): return store.get(key)
verify_callback(callback_url) // ASVD Step 3
sub = store.create(key, secret=new_secret(), status="active")
return subA autorização é executada antes da verificação de existência de propósito. Se você inverter a ordem, um usuário cujo acesso foi revogado poderia reenviar uma chamada de subscribe antiga e recuperar a assinatura silenciosamente.
Unsubscribe
O unsubscribe deve ser seguro para chamar duas vezes. Se a assinatura já não existir, retorne sucesso, não um erro. Quem chamou queria removê-la, e ela foi removida.
Persistência e autorização
Mantenha as assinaturas em armazenamento durável. Um mapa em memória perde tudo no próximo deploy, e as entregas param sem nenhum erro visível. Verifique a autorização no momento do subscribe e novamente no momento da entrega, já que o acesso pode ser revogado nesse intervalo.
Você também precisa de um caminho de limpeza. A documentação da OpenAI diz para não repetir uma entrega que retorna 410. Nossa interpretação é que o receptor não quer mais a assinatura, então marque-a como desativada em vez de deixá-la falhar em cada evento futuro.
Etapa 3 do ASVD (Verify, verificar): confirme o callback com o desafio assinado
Antes que qualquer assinatura fique ativa, envie um desafio de verificação assinado para a URL de callback e confirme a resposta esperada. Assim, o seu servidor nunca envia eventos para um endpoint que não comprovou ser o receptor pretendido.
Se a verificação falhar, a documentação da OpenAI diz para retornar o erro JSON-RPC -32015 (CallbackEndpointError) com um data.reason categorizado, como challenge_failed ou timeout.
Fique atento a divergências aqui. O esboço atual do rascunho diz que suas revisões anteriores usavam de -32011 a -32015, uma sub-faixa que a especificação nunca atribui, e que as implementações dessas revisões precisam renumerar. Em termos simples, o código na documentação da OpenAI vem de uma revisão mais antiga do esboço. Siga a documentação da OpenAI por enquanto, porque o ChatGPT é o cliente para o qual você está construindo, e defina o código uma única vez como uma constante nomeada, para que uma mudança futura seja uma edição de uma linha.
Dê à solicitação de desafio um timeout limitado e registre a categoria do motivo em cada falha. Quando um usuário disser que a automação dele nunca começou, essa linha de log é o primeiro lugar para olhar. Se você já instrumenta execuções de agentes, nosso playbook de tracing GenAI com OpenTelemetry é um lugar natural para a telemetria de verificação e entrega.
Etapa 4 do ASVD (Deliver, entregar): assine e envie eventos como Standard Webhooks
As entregas seguem a especificação Standard Webhooks. Segundo a Svix, X-MCP-Subscription-Id é o único cabeçalho específico do MCP, e ele informa ao receptor com qual assinatura, e portanto com qual segredo, verificar a assinatura criptográfica.
Tamanho e formato
A documentação da OpenAI diz para enviar um evento por solicitação, com um corpo de solicitação completo de no máximo 256 KiB (262,144 bytes). O ChatGPT pode agrupar eventos entregues separadamente em uma única execução de tarefa, com base nas configurações de agrupamento da tarefa. Não trate 256 KiB como uma meta. O Standard Webhooks recomenda manter os payloads pequenos, geralmente abaixo de 20 KB. Envie identificadores e um resumo curto, e deixe o ChatGPT chamar suas ferramentas quando precisar do registro completo.
Novas tentativas e condições de parada
A documentação da OpenAI diz para repetir falhas transitórias com backoff exponencial e número limitado de tentativas, preservando o ID do evento e gerando um novo timestamp de assinatura e uma nova assinatura a cada tentativa. Manter o mesmo ID do evento dá ao receptor algo para deduplicar, e o novo timestamp e a nova assinatura evitam que a solicitação seja rejeitada como obsoleta.
A documentação da OpenAI também diz para não repetir entregas que retornam 410 ou 413. Quando uma entrega for recusada dessa forma, sugerimos revisar o estado da assinatura e o design do payload em vez de enviar a solicitação novamente.
| Resultado da entrega | O que o seu servidor deve fazer |
|---|---|
| 2xx | Marcar como entregue |
| Timeout ou 5xx transitório | Repetir com backoff exponencial, mesmo ID do evento, novo timestamp e nova assinatura, tentativas limitadas, conforme a documentação da OpenAI |
| 410 | Não repetir, conforme a documentação da OpenAI; desativar a assinatura é uma resposta razoável |
| 413 | Não repetir, conforme a documentação da OpenAI; trate como um bug de design do payload |
O Standard Webhooks recomenda um timeout de solicitação de 15 a 30 segundos. Escolha o seu valor de forma intencional, em vez de herdar o padrão que vem com a sua biblioteca HTTP.
Use uma biblioteca oficial
Assine com uma biblioteca oficial do Standard Webhooks, como a biblioteca JavaScript do Standard Webhooks ou a oficial para a sua stack, em vez de escrever seu próprio código HMAC. Uma biblioteca construída com base na especificação é a forma mais segura de produzir assinaturas que os receptores conseguem verificar.
Teste antes de lançar: um checklist ASVD pré-lançamento
Percorra esta lista em staging, conectado a uma assinatura real do ChatGPT, antes do lançamento. Cada item exercita uma etapa do loop.
As novas tentativas mantêm o ID do evento, renovam a assinatura e param em 410 e 413.
- [ ] Advertise, filtros: eventos fora dos filtros de uma assinatura nunca são entregues. Teste com eventos que correspondem a alguns filtros, mas não a todos.
- [ ] Subscribe, duplicatas: repetir uma chamada de subscribe retorna a assinatura existente e não cria nada novo.
- [ ] Subscribe, unsubscribe: depois do unsubscribe, nada mais é enviado, incluindo novas tentativas já enfileiradas. Uma segunda chamada de unsubscribe retorna sucesso.
- [ ] Subscribe, reinicializações: depois de uma reinicialização e de um novo deploy, as assinaturas e os segredos persistem e as entregas são retomadas.
- [ ] Subscribe, autorização: revogue o acesso de um usuário a um recurso filtrado. As entregas para ele param, e uma chamada de subscribe repetida é recusada.
- [ ] Verify, desafio de callback: execute um desafio que passa e outro que falha. A falha retorna o código de erro documentado com um data.reason.
- [ ] Deliver, eventos reenviados: reenvie o mesmo ID de evento e anote o que o ChatGPT faz com ele. Não presuma uma deduplicação que você não observou.
- [ ] Deliver, limites de tamanho: payloads logo abaixo e logo acima de 256 KiB são tratados, cada um, da forma que você pretendia.
Erros comuns ao construir servidores de MCP Events
- Construir modos que ninguém chama. Polling, streaming e as notificações gap ou terminated não fazem parte da integração do ChatGPT. Heartbeats entram na mesma categoria. O rascunho diz que um servidor deve enviar um heartbeat pelo menos a cada 30 segundos, mas isso se aplica ao streaming em modo push, que o ChatGPT não suporta.
- Fazer as novas tentativas ao contrário. Um novo ID de evento a cada tentativa tira do receptor a chave de deduplicação. Reutilizar o timestamp e a assinatura antigos abre caminho para uma rejeição por obsolescência.
- Repetir becos sem saída. A documentação da OpenAI diz para não repetir entregas que retornam 410 ou 413. O mesmo corpo vai ser recusado de novo.
- Enviar registros inteiros. Documentos completos aproximam os payloads de 256 KiB, quando o Standard Webhooks sugere ficar abaixo de 20 KB.
- Manter assinaturas em memória. Elas desaparecem na reinicialização, e nada avisa você.
- Confiar no texto do payload. Quando um evento carrega texto gerado por usuários, uma mensagem de cliente, por exemplo, esse texto pode conter instruções direcionadas ao modelo. Trate os payloads como entrada não confiável, da mesma forma que você trata resultados de ferramentas, e remova ou delimite claramente esse texto.
Ressalvas: divergências na especificação e limites operacionais
A especificação é um rascunho. O código de erro da OpenAI e a renumeração do esboço atual já divergem, e o grupo de trabalho ainda está ajustando seu escopo. Construa com base na documentação da OpenAI e releia-a regularmente.
O seu código personalizado é temporário. O suporte nos SDKs é desigual. Planeje substituir os handlers assim que o suporte oficial for lançado.
Automação sem supervisão precisa de proteções. Antes que uma tarefa acionada por evento toque sistemas de produção, decida quais ações ela pode executar sem a aprovação de uma pessoa. Adicione logs de auditoria e limites de taxa, e dê a cada assinatura seu próprio botão de desligamento. Para saber mais sobre como restringir o que uma tarefa acionada pode alcançar, veja nossa nota sobre como conter o alcance de um agente comprometido. Se o trabalho acionado crescer para tarefas de várias etapas, nosso checklist de seleção de runtime para agentes de IA duráveis pode ajudar você a decidir onde esse estado deve ficar.
Confirme detalhes de segunda mão. A data de lançamento e a versão do protocolo mencionadas acima vêm em parte de guias de terceiros. Confira-as na documentação da OpenAI.
Pontos principais
- 1Construa seguindo o loop Advertise-Subscribe-Verify-Deliver (ASVD): anuncie eventos, assine de forma idempotente, verifique callbacks e depois entregue eventos assinados.
- 2O ChatGPT suporta apenas a entrega por webhook e a verificação de callback da especificação em rascunho dos MCP Events, então ignore polling, streaming e as notificações gap e terminated.
- 3Execute a autorização antes de retornar uma assinatura existente, torne subscribe e unsubscribe idempotentes e mantenha as assinaturas em armazenamento durável.
- 4Verifique cada URL de callback com um desafio assinado antes da ativação. Mantenha o código de erro de falha em uma única constante, já que o rascunho o renumerou.
- 5A documentação da OpenAI limita o corpo de cada solicitação de evento único a 256 KiB, mas o Standard Webhooks recomenda payloads abaixo de 20 KB.
- 6A documentação da OpenAI diz para não repetir um 410 ou 413 e para repetir falhas transitórias com o mesmo ID de evento e uma nova assinatura.
- 7Os SDKs oficiais de Python e TypeScript não tinham suporte a MCP Events no lançamento e o SDK de Go ainda não consegue anunciar a capacidade, então isole os handlers personalizados.
Conclusão
A Svix chama o ChatGPT de o primeiro grande cliente a suportar MCP Events. Para equipes que já operam um servidor MCP ou uma API SaaS, isso torna este um momento razoável para deixar que mudanças nos seus próprios sistemas iniciem trabalho no ChatGPT, em vez de esperar por prompts digitados. A maior parte da construção é engenharia de webhooks que você provavelmente já fez antes, organizada como o loop ASVD.
As partes complicadas são as que ainda estão em movimento. Os códigos de erro do rascunho já mudaram uma vez, e o suporte nos SDKs é irregular. Há também uma questão de segurança que merece reflexão séria: o que uma tarefa sem supervisão deve poder fazer com um texto de payload que ela não escreveu?
O caminho que sugerimos é modesto. Lance um único tipo de evento, específico e bem filtrado. Passe-o pelo checklist pré-lançamento e, depois, acompanhe-o em produção com logs e um botão de desligamento à mão. Mantenha o código de protocolo personalizado enxuto e separado da lógica de negócio, para que uma futura mudança na especificação custe uma pequena edição, e não uma reescrita. Adicione mais tipos de evento quando o primeiro tiver funcionado de forma confiável por um tempo.
Perguntas frequentes
O que são os MCP Events do ChatGPT?
Os MCP Events permitem que o ChatGPT assine atualizações do seu servidor MCP, como novas mensagens, atualizações de conteúdo ou mudanças de status. A documentação da OpenAI diz que o ChatGPT suporta a entrega por webhook e a verificação de callback da especificação em rascunho dos MCP Events. Os usuários escolhem o que monitorar e o que o ChatGPT deve fazer quando uma atualização chega, para que um conector possa iniciar uma automação sem esperar por um prompt.
O ChatGPT suporta polling ou streaming para MCP Events, ou apenas webhooks?
Apenas webhooks. A documentação da OpenAI diz que o ChatGPT suporta a entrega por webhook e a verificação de callback da especificação em rascunho dos MCP Events. Polling, streaming e as notificações de controle gap e terminated do rascunho não são suportados por esta integração, então você pode deixar esses caminhos de código de fora.
Qual é o tamanho máximo de payload de evento que o ChatGPT aceita, e qual deveria ser o tamanho real dos payloads?
A documentação da OpenAI diz que o ChatGPT aceita um evento por solicitação, com um corpo completo de no máximo 256 KiB (262,144 bytes). Trate isso como um teto. A especificação Standard Webhooks recomenda manter os payloads pequenos, geralmente abaixo de 20 KB. Na prática, envie identificadores e resumos curtos e deixe o ChatGPT buscar os registros completos por meio das suas ferramentas.
Como as novas tentativas devem funcionar, e quais respostas HTTP indicam que devo parar de tentar?
A documentação da OpenAI diz para não repetir entregas que retornam 410 ou 413. Sugerimos tratar qualquer uma dessas respostas como um sinal para mudar algo do seu lado, como o status da assinatura ou o design do payload, em vez de tentar de novo. A documentação da OpenAI também diz para repetir falhas transitórias com backoff exponencial e número limitado de tentativas, preservando o ID do evento e gerando um novo timestamp de assinatura e uma nova assinatura a cada tentativa.
Qual erro o meu servidor deve retornar quando a verificação de callback falha, e por que o código pode mudar?
A documentação da OpenAI diz para retornar o erro JSON-RPC -32015 (CallbackEndpointError) com um data.reason categorizado, como challenge_failed ou timeout. O esboço atual do rascunho, no entanto, diz que revisões anteriores usavam de -32011 a -32015 e que as implementações precisam renumerar. Siga a documentação da OpenAI para o ChatGPT, mantenha o código em uma única constante e consulte a documentação regularmente.
Posso usar os SDKs oficiais de MCP para Python, TypeScript ou Go para construir MCP Events hoje?
Em parte. Um desenvolvedor da comunidade relatou que o SDK oficial de Python (mcp 2.2.0) e o SDK de TypeScript não suportavam MCP Events no lançamento. No SDK de Go, você pode implementar events/list, events/subscribe e events/unsubscribe como métodos personalizados, mas ainda falta a possibilidade de anunciar a capacidade events de nível superior. Verifique as versões atuais e mantenha os handlers personalizados isolados para poder substituí-los depois.
Fontes
- https://developers.openai.com/plugins/build/mcp-events
- https://github.com/modelcontextprotocol/experimental-ext-triggers-events/blob/main/docs/design-sketch-proposal.md
- https://modelcontextprotocol.io/community/working-groups/tasks-events
- https://github.com/standard-webhooks/standard-webhooks/blob/main/spec/standard-webhooks.md
- https://github.com/standard-webhooks/standard-webhooks/tree/main/libraries/javascript
- https://www.svix.com/blog/mcp-events/
- https://dev.to/hassann/mcp-events-explained-build-and-test-a-webhook-emitting-mcp-server-chatgpt-can-subscribe-to-4od8
- https://community.openai.com/t/mcp-events-for-the-official-python-mcp-sdk-tested-end-to-end-with-chatgpt/1402999
- https://github.com/modelcontextprotocol/go-sdk/issues/1325
- https://community.openai.com/t/devday-2026-announcements-and-developer-resources/1402006
Escrito por
Hamza DiazHamza Diaz é o fundador da Optijara, onde cria agentes de IA práticos, sistemas de automação e fluxos de trabalho do Copilot para empresas de serviços. Ele escreve sobre operações de IA, estratégia de agentes e implementação no mundo real para equipes que querem sistemas úteis em vez de exagero.
