What Is MCP Events?
MCP Events is a draft extension to the Model Context Protocol (MCP) that lets an AI agent subscribe to events from an MCP server. When something happens, such as a GitHub Actions build failing, the event can reach the agent and wake it to investigate, without anyone prompting it.
It was proposed on October 5, 2026, in SEP-3415, a Specification Enhancement Proposal from MCP's Triggers & Events Working Group. The SEP grew out of the working group's earlier design sketch, which several early implementations follow instead. This guide explains how MCP Events works, who supports it so far, and how to publish and receive events reliably, with an interactive diagram for each part.
Your agent waits to be asked
Most of the time, an agent waits for a prompt: someone types a message, and the agent gets to work. With MCP Events, the agent also subscribes to events from other systems, and an event can wake the same session. A CI build fails, the failure becomes an event, and the event reaches the agent's existing session, where the agent starts investigating.
SEP-3415 leaves what happens next to the MCP client. For example, the client might add the event to the conversation, wake the agent, or queue the event for later. The client also decides whether to invoke the model at all.
An idle agent session that a chat message wakes, and then, in the same session, a failed-build event from GitHub.
- Most of the time, an agent waits for a prompt.
- With MCP Events, an event from another system can wake the same session.
MCP has no standard way to say what happened
MCP is request-driven: the client asks, and the server answers. So how does your agent find out that a build failed? The client can poll, asking the MCP server for the latest build status again and again. Or you write a background script, outside MCP, that watches CI and prompts your agent. Either way, the MCP server has no standard way to tell your agent that the build failed.
MCP does have notifications, but they don't fill the gap. A change notification says only that a resource (data the server exposes) or a list changed. It carries no payload, so the client has to read the resource again to find out what happened.
Notifications also need a live connection. If one is sent while the client is disconnected, the client never gets it. Nothing tells the client that it missed one.
A client asks an MCP server for news again and again; a notification carries only a resource's URI; and a notification sent while the client is disconnected is lost.
- MCP is request-driven: the client asks, and the server answers.
- Without events, the client polls, or a script outside MCP prompts the agent.
- A notification only says that a resource or a list changed, not what happened.
- They also need a live connection. A disconnected client never gets them.
Where MCP Events fits
An event starts in a service. In this guide's example, a pushed commit triggers a GitHub Actions build, and the build fails.
Say you use an MCP server for GitHub. How that MCP server hears about the failure is outside the spec: GitHub sends it a workflow_run webhook. MCP Events is the next hop, from the MCP server to the MCP client. The MCP client runs inside the host application, the app your agent runs in, such as ChatGPT.
A pushed commit starts a GitHub Actions build that fails. GitHub's webhook to the MCP server is outside the spec; MCP Events carries the event from the MCP server to the MCP client in the host application.
- An event starts in a service: a pushed commit triggers a build, and the build fails.
- An MCP server for GitHub receives it as a webhook. That hop is outside the spec.
- MCP Events is the next hop: from the MCP server to the MCP client in the host.
MCP Events use cases
Any MCP server that wraps a system where things happen could offer events. Some examples:
- Code and CI/CD: a push, a new pull request or a failed CI run reaches a coding agent, which reads the failure, investigates it and opens a draft fix. It's the trigger GitHub webhooks have long provided, aimed at an agent.
- Team chat and feedback: a new message in a channel such as
#product-feedbackreaches an agent, which triages it, files an issue or drafts a pull request. OpenAI's MCP Events guide uses this scenario, with amessage.createdevent filtered bychannel_id. - Documents and review: a new comment on a document reaches an agent, which applies the requested edit. A subscription argument, such as a
document_id, keeps the agent on one document. - Incidents and on-call: a new incident reaches an agent, which gathers logs, checks recent deploys and posts a first summary before a person picks it up. Subscription arguments can narrow this to a severity or a service.
- Email and inbox triage: an email from a given sender reaches an agent, which summarizes it or drafts a reply.
- Long-running work: a job in another system, such as a data export or a deployment, finishes, and the event tells the agent instead of the agent checking back.
In every case, the pattern is the one webhooks made familiar: something happens in one system, and a notification carries it to another. The difference is the receiver: an agent that decides what to do, rather than code that runs the same handler every time.
An agent subscribes to event types
A client calls events/list to see the event types an MCP server offers. Each event type has a name, an inputSchema for the arguments a subscription takes (which repository to watch, for example), a payloadSchema for the event data, and a delivery field listing the delivery modes it supports.
The client then subscribes to an event type, passing its arguments, in one of those delivery modes. How the subscription starts depends on the mode: with the first events/poll request, with an events/stream request, or with events/subscribe for webhooks. To unsubscribe, the client stops polling, cancels its stream, or calls events/unsubscribe.
Every event has the same fields, whichever delivery mode the client uses: an ID (eventId), the event type (name), a timestamp and the data. A cursor marks the client's position in the sequence of events: push and webhook mode send it with each event, and poll mode with each response. If the event type supports replay, a client that disconnects can resume from its last cursor and get the events it missed. Replay is optional for each event type.
Here's an example event, as push or webhook mode delivers it. The server's payloadSchema defines what goes in data:
{
"eventId": "evt_2f81c0",
"name": "build.failed",
"timestamp": "2026-10-14T09:12:03Z",
"data": {
"repository": "acme/webapp",
"workflow": "CI",
"conclusion": "failure"
},
"cursor": "c_000412"
}
A client lists an MCP server's event types and subscribes to one with a repository argument. Each event has an ID, an event type, a timestamp and data, and the client keeps a cursor.
- The server lists its event types. The client subscribes to one, with arguments.
- Every event has the same fields. The client keeps a cursor per subscription.
Three delivery modes
An event type can offer any combination of three delivery modes, and none is required. In the SEP's words, "No mode subsumes another": each one suits a different place where MCP servers and clients run.
- Poll (
events/poll): the client calls the server on a timer, passing its cursor, and gets back any new events. Every request goes from the client to the server, so poll works almost anywhere, even with a serverless MCP server or a client behind NAT. It costs latency, up to one polling interval, and a request each time, even when nothing has happened. Those requests use no tokens: the client's SDK runs the polling loop, not the model. - Push (
events/stream): the client opens a request and holds it open, and the server sends events down it as they happen. Push suits a client that can hold a connection open, such as a coding agent on a laptop. The server also sends heartbeats carrying the latest cursor, so if the stream drops, a client can reconnect and resume from that cursor, for event types that support replay. The cost falls on the server: one open connection for every subscription. - Webhook (
events/subscribe): the server sends each event as an HTTP POST to a URL the client gave it, so nobody holds a connection open. Webhook mode suits a client hosted in the cloud with a public URL, such as ChatGPT. The cost is setup: the client needs an address the server can reach, and the server has to verify it before sending anything.
SEP-3415's guidance for SDKs, which isn't binding, has the client's MCP SDK pick the mode. It compares the modes an event type lists with the ones the client is set up to use, and prefers webhook, then push, then poll, unless the caller chooses a mode for the subscription. No official SDK implements this yet.
The three delivery modes, poll, push and webhook, with where each fits and what it costs, then an event type's delivery field listing the modes it supports.
- Three delivery modes, each suited to a different place MCP servers and clients run.
- Poll: the client asks on a timer. Works almost anywhere; costs latency, not tokens.
- Push: the client holds a stream open. Heartbeats carry the cursor.
- Webhook: the client subscribes with a URL, and the server POSTs each event to it.
- events/list says which modes each event type supports. The client picks one.
Who supports MCP Events
No official MCP SDK has shipped support yet, and several early implementations follow the working group's earlier design sketch, not SEP-3415. Here's what we found, checked on October 26, 2026:
| Name | Side | What it is | Delivery modes | Status | Based on |
|---|---|---|---|---|---|
| ChatGPT | Client | OpenAI's agent host | Webhook | Shipping, in Work chats | Predates SEP-3415 |
| Vercel AI SDK | Client | @ai-sdk/mcp, the AI SDK's MCP client | Webhook | Experimental | The design sketch |
| Mastra | Client and server | @mastra/mcp, the Mastra framework's MCP package; its client can deliver events to agent threads | Client: poll and webhook. Server: poll and push | Experimental, since 2.5.0 (October 21) | SEP-3415 |
| TanStack AI | Client | @tanstack/ai-mcp, TanStack AI's MCP package | Webhook | Experimental, since 1.0.0 (October 22) | SEP-3415 |
| Hermes Agent | Client | Nous Research's open-source agent | Webhook | Experimental, since v0.22.5 (October 23) | The design sketch |
| Inline | Server | The hosted MCP server of Inline, an open-source team chat app | Webhook | In its code since October 3; production use not verified | Predates SEP-3415 |
| mcp-handler | Server | Vercel Labs' adapter for running MCP servers in Next.js and similar frameworks | Webhook | Released in v2.3.0 | The design sketch |
| Skybridge | Server | Alpic's framework for building ChatGPT apps | Webhook | Released in v2.1.0 (October 23) | The design sketch and OpenAI's guide |
"Predates SEP-3415" means it shipped before the SEP was proposed on October 5.
Claude doesn't support MCP Events yet. Claude Code has an open feature request for it.
Most support only webhook mode. Skybridge, the one that gives a reason, says it's because ChatGPT only supports webhooks. OpenAI's guide sets out ChatGPT's limits: it needs MCP 2.0 (protocol version 2026-07-28), takes one event per request with a body of at most 256 KiB, and works in Work chats on the web and in the desktop app with Cloud selected. ChatGPT also leaves out the gap and terminated notices. They tell a client that events were skipped, or that a subscription has ended.
We left smaller projects out of this table, and there may be implementations we didn't find.
Webhook mode, step by step
Most of the implementations above use webhook mode. It works in five steps:
- Subscribe. The client calls
events/subscribewith a callback URL and a secret it generates itself:whsec_followed by 24 to 64 bytes, base64-encoded. The server returns a subscription ID. Webhook mode needs an authenticated principal (the user, app or service account the server has authenticated), so a server without authentication can offer poll and push, but not webhooks. - Verify. Before the server sends any events, it confirms the endpoint wants them. Usually that's a handshake: the server POSTs a signed challenge to the URL, and the endpoint echoes it back. The SEP also accepts an allowlist, verification out of band, or a
/.well-known/mcp-webhook-receiver.jsonfile on the endpoint's host. Without verification, a subscriber could point a subscription at someone else's URL and flood it with events. - Deliver. Each event arrives as an HTTP POST with Standard Webhooks headers. Standard Webhooks is an open specification for webhook signatures: the headers carry an ID for the delivered message, a timestamp, and an HMAC signature made with the client's secret. MCP Events adds one header,
X-MCP-Subscription-Id, so an endpoint with several subscriptions can pick the right secret. - Renew. A subscription usually has a lifetime, and the client renews it by subscribing again before it expires. A server can also grant one that doesn't expire.
- Unsubscribe. When the client no longer wants the events, it calls
events/unsubscribe.
A delivery looks like this:
POST /mcp-events HTTP/1.1
Host: agent.example.com
Content-Type: application/json
webhook-id: msg_2KWPBgLlAfxdpx2AI54pPJ85f4W
webhook-timestamp: 1791969123
webhook-signature: v1,<HMAC-SHA256 signature, base64-encoded>
X-MCP-Subscription-Id: sub_7d2e9a
{"eventId":"evt_2f81c0","name":"build.failed","timestamp":"2026-10-14T09:12:03Z","data":{...},"cursor":"c_000412"}
The endpoint verifies the signature against the raw request body before it trusts anything. Off-the-shelf Standard Webhooks libraries can do that.
In SEP-3415, webhook-id and eventId are different. Since its October 23 revision, the server generates a webhook-id for each delivered message, one event on one subscription, and reuses it on that message's retries. The body's eventId identifies the upstream event, so the same eventId can arrive on two subscriptions. Today's clients still expect the two to match. OpenAI's guide for ChatGPT says webhook-id is the same value as eventId, and the Vercel AI SDK and TanStack AI reject a delivery where they differ, TanStack AI even though it otherwise follows SEP-3415. So for now, servers send the eventId as webhook-id.
Webhook mode: the client subscribes with a callback URL and a secret, the server verifies the endpoint with a signed challenge, then each event arrives signed and the endpoint checks it.
- Webhook mode, the one with traction: subscribe, verify the endpoint, then signed delivery.
- The client subscribes with a callback URL and its own secret, and gets a subscription ID.
- The server POSTs a signed challenge to the URL, and the endpoint echoes it back.
- Each event arrives as a signed HTTP POST, with Standard Webhooks headers.
- The endpoint checks the signature against the raw body before it trusts anything.
MCP Events vs. webhooks
In webhook mode, each MCP event is delivered as a webhook: a signed HTTP POST from one system to another when something happens. What MCP Events adds is a standard way for an agent to find, subscribe to and manage those deliveries at runtime, across MCP servers, without a developer setting each one up by hand.
| Webhooks | MCP Events | |
|---|---|---|
| Who subscribes | A developer, through the provider's dashboard or API | The MCP client, at runtime |
| How events are discovered | Reading each provider's documentation | events/list, with a JSON Schema for the arguments and another for the payload |
| Delivery | HTTP POST | Webhook (POST), push (a stream the client holds open) or poll |
| Subscription lifetime | Usually until someone deletes the endpoint | A webhook subscription expires unless the client renews it, though a server can grant one that doesn't |
| Signing | Varies by provider | Standard Webhooks headers and signatures, in webhook mode |
| Endpoint verification | Varies by provider | Required before the first webhook delivery |
| Filtering | Usually by event type | Arguments the server defines, such as a repository |
| Resuming after downtime | Varies by provider | A cursor, where the event type supports replay |
| Payload | Often the full object, though some providers now send thin events | Kept small; the agent fetches details with tools |
| Who reacts | Code you wrote for that event | The MCP client decides; it can wake an agent |
Why not just send a webhook to your agent?
You can already trigger an agent from a webhook: a handler receives the event, verifies it, and starts an agent run with the payload in its prompt. That works well for fixed automations.
MCP Events changes who sets this up, and where the event lands:
- The agent subscribes itself. It discovers the event types offered by an MCP server it already uses, and subscribes at runtime. There's no handler to write, host or wire up for each source.
- An event can reach the session that subscribed. Instead of a fresh run for every event, the client can wake the existing session, along with the context of what the agent was doing. An agent fixing a flaky test can then relate a new failed build to the ones it has already looked at. SEP-3415 leaves this choice to the client.
- One session can listen to several sources, such as GitHub, your CI service and your issue tracker, through the MCP servers it's connected to.
There are two caveats. A webhook subscription usually expires unless the client keeps renewing it, which suits an agent watching for something it's working on now more than an always-on pipeline. And client support is still early. For always-on automations, a webhook that starts an agent run may stay the simpler choice.
What stays the same
The reliability problems of webhooks carry over. The same event can arrive more than once, and webhook deliveries can arrive out of order. So you still need idempotent processing, signature verification, and a plan for bursts and downtime. An agent raises the cost of getting these wrong: a duplicate event might mean a duplicate pull request.
Do MCP Events replace webhooks?
No. In the SEP's worked example, the MCP server receives GitHub's own webhooks, and that hop is outside the spec. Webhooks stay the plumbing between services, and MCP Events brings what flows through that plumbing to agents.
Publishing events reliably
These practices are for adding events to your own MCP server, when every event needs to reach its subscribers.
Plan for what each delivery mode asks of your server
Before you offer a delivery mode, check what it will ask of your server. Poll needs a history of recent events, kept by your server or by the upstream service, to answer each client's next poll. Push holds a connection open for every subscription.
Webhook mode needs neither. The server stores each subscription's URL and secret, and sends each event as it happens. Any web stack can receive a signed HTTP POST, and off-the-shelf libraries can verify one.
What webhook mode asks instead is delivery to endpoints you don't control. Some will be down when your server sends an event. And because each client chooses its own callback URL, some could point at addresses inside your own network. The next three sections deal with both.
What each delivery mode asks of the server, then one event delivered to many webhook endpoints, one of them down.
- Poll keeps recent events. Push holds a connection per subscription.
- Webhook needs neither: a URL and secret, and a signed POST per event.
- The hard part: endpoints it doesn't control. One is down; one is internal.
Retry with backoff, up to a cap
Deliver webhooks from a delivery layer that retries. A delivery layer is a durable queue that your MCP server adds each event to, plus a separate process that makes the delivery attempts. Your MCP server never waits for a slow or failing endpoint to answer.
Without one, your server sends each event in a single HTTP request. If the subscriber's endpoint is mid-deploy at that moment, the request fails and the event is lost. The agent behind that endpoint never hears that the build failed, and the failure waits until a person notices it.
Back off exponentially between attempts, and sign every attempt again with the current time as its timestamp. Receivers should reject any delivery whose timestamp is more than five minutes old, so a retry that reused the first attempt's signature would start failing that check after five minutes.
Stop at a cap. SEP-3415 says not to retry forever, and to cap both the number of attempts and how long they take: its example is 3 to 5 attempts over no more than 10 to 15 minutes. Two responses mean stop straight away: 410 Gone and 413 Payload Too Large.
An event retried by a delivery layer: attempt 1 times out, attempt 2 gets a 503, and attempt 3 gets a 200. If the endpoint had stayed down, the attempts would have stopped at the cap.
- A single POST to an endpoint that's mid-deploy fails, and the event is lost.
- Instead, a durable queue and a separate delivery process make the attempts.
- Attempt 1: nothing answers, and after 5 seconds it times out.
- 30 seconds later, attempt 2, signed again. Still starting up: 503.
- 2 minutes later, attempt 3 gets a 200.
- If the endpoint stays down, the delivery layer gives up at the cap.
The gaps between attempts in the diagram (30 seconds, 2 minutes, then 8 minutes) are an example. SEP-3415 says only to back off exponentially, within the cap.
Check callback URLs every time you deliver
Check each callback URL's resolved address every time your server delivers to it, not only when the client subscribes, and connect to the address you checked. The client chooses the URL your server calls, so this check decides whether a subscriber can make your server call into your own network.
Say a client subscribes with a hostname that resolves to a public address, so it passes. Later, the hostname's DNS changes to point at an internal address, such as 10.0.0.1. If you only checked at subscribe time, your server's next delivery goes to whatever runs at that internal address. That's server-side request forgery (SSRF).
For the same reason, never follow a redirect: it can point anywhere. SEP-3415 requires both rules, and callback URLs that use https.
A callback hostname resolves to a public address when the client subscribes, then to 10.0.0.1 at delivery time, and the delivery is blocked. A redirect, here to an internal address, isn't followed.
- In webhook mode, the client chooses the URL your server calls.
- The hostname passed at subscribe time, then resolves to 10.0.0.1: SSRF.
- Check the IP on every delivery, connect to it, and never follow redirects.
Keep delivery state outside your MCP server
Store each event and its retry state durably, outside your MCP server. That's our advice, and it goes beyond SEP-3415: the SEP lets a server keep its retry queue in memory. A redeploy empties an in-memory queue, and the events in it are gone unless the event type supports replay from the client's cursor. With delivery state outside your server, you can redeploy while delivery continues.
You can build the delivery layer yourself: What it takes to add MCP Events to your MCP server walks through the queues, workers and checks it needs.
Or use an existing one, such as Outpost, Hookdeck's open-source (Apache 2.0) service for sending webhooks and events. You can self-host Outpost or use it managed, and it queues, signs and retries each webhook delivery. Send MCP Events webhooks with Outpost shows how. One gap to know: SEP-3415 says not to retry 410 and 413 responses, and Outpost currently does.
An MCP server hands its events to a delivery layer; the server restarts, and the queued retries carry on. Outpost is one option for the delivery layer.
A redeploy loses retries in memory. A separate delivery layer carries on.
Receiving events reliably
Now switch sides. Say you run your own agent, it receives webhooks directly, and you need every event to arrive.
When your agent is down, the retries run out
Say a bad deploy takes your agent down for 20 minutes. Each delivery attempt times out, typically after about five seconds. The MCP server retries, but in the SEP's example, for 10 to 15 minutes at most.
Then the server stops. Your agent never sees the failed build it should have investigated, and the build stays broken until someone notices. Replay is optional for each event type, so you can't count on getting the event back later.
An agent goes down for 20 minutes. Each delivery attempt times out, the server's retries run out, and the event is lost.
- Your agent receives webhooks directly. A bad deploy takes it down for 20 minutes.
- Each delivery attempt times out, typically after about 5 seconds.
- The MCP server retries, but in the spec's example, only for about 15 minutes.
- Then retries stop, and the event is lost. Replay is optional.
Put a forward proxy in front of your agent
Put a forward proxy in front of your agent. In SEP-3415, a forward proxy is a service that receives webhooks on your agent's behalf and passes the events on to it.
You subscribe with the proxy's URL, and give it your secret. The proxy runs separately from your agent, so it keeps receiving events while your agent redeploys. It stores each event before it answers with a 200.
When your agent is back, it gets the events the proxy stored. In the SEP's example, the proxy serves the events to your agent's MCP client by poll or push, as an MCP server would. Other proxies deliver each event to your agent themselves, and retry if it doesn't answer.
You can run a forward proxy yourself, or use a hosted one. One option is Hookdeck Event Gateway. It gives you a public URL, stores each event, and delivers it to your agent with retries. Use Event Gateway as a forward proxy for MCP Events shows how, and the forward proxy demo is an agent that sets one up for each subscription. One gap to know: Event Gateway checks the 5-minute timestamp window on the verification handshake, but not on event deliveries.
The same outage with a forward proxy in front: the proxy accepts each valid delivery, queues events while the agent is down, and delivers them when it's back. Event Gateway is one option for the proxy.
- A forward proxy receives each event, then forwards it on to your agent.
- Subscribe with the proxy's URL. It stores each event before it answers 200.
- When your agent is back, it gets the events the proxy stored.
- One option: Hookdeck Event Gateway receives, stores and delivers, with retries.
Let the proxy apply the receiver rules
Apply SEP-3415's rules for receiving webhooks at the proxy, whichever proxy you use. The main ones:
- Answer the verification handshake, and don't pass the challenge on to your agent.
- Verify each delivery's signature against the raw request body (required), and reject a timestamp more than five minutes old (recommended).
- Drop duplicates by
webhook-id(recommended). A retried delivery carries the samewebhook-id, so dropping repeats stops your agent investigating the same failure twice. If you also deduplicate oneventId, scope it to the subscription. - Pass each event's
cursorandeventIdon to your agent's MCP client (required), so it can resume from the cursor and drop duplicates. - Pass
gapandterminatednotices on to your agent's MCP client (required). Agapnotice says events were skipped, so your agent should re-check anything it relies on. Aterminatednotice says the subscription has ended, for example because access was revoked.
If the proxy serves events by poll or push, your agent doesn't need a public URL at all: the proxy has one. That suits an agent behind NAT.
The forward proxy answers the verification challenge, rejects a forged delivery, drops a duplicate, and passes gap and terminated notices through.
- The proxy answers the verification handshake.
- It rejects a bad signature, or a timestamp more than 5 minutes old.
- It drops duplicates, and gives an agent behind NAT a public URL.
- It passes on the server's gap and terminated notices to your agent's client.
Treat every event as untrusted input
Treat every event as untrusted input, in every delivery mode. An event can wake your agent, but anything the agent does in response, such as calling a tool, still goes through normal MCP authorization.
A pull request title can say "ignore previous instructions". An agent that obeys it is working for whoever opened the pull request, with whatever access you gave the agent. SEP-3415 says clients must treat event data with the same caution as tool results. It also says they should sanitize or sandbox event data before the model sees it.
On the server side, keep payloads small and let the agent fetch details with tools. Each event then carries less text an attacker controls. SEP-3415 says webhook payloads should be 256 KiB or less.
An event arrives for a pull request titled 'Ignore previous instructions'. The client sandboxes the event data, and the agent reviews the pull request.
- An event wakes the agent. An attacker wrote the event's pull request title.
- The title is a prompt injection. The client sandboxed the event before the model read it.
Try MCP Events now with the bridge
You can try MCP Events today, even though few MCP servers support it yet. Many of the services your agent would want to hear from already send webhooks: GitHub, GitLab, Sentry, Linear, and your own apps.
The MCP Events bridge is an open-source (MIT) MCP server that turns webhooks into MCP events. Use it until those services offer MCP Events themselves, or for any that never will. It has built-in sources for GitHub and inbound email from Resend (an email API), takes services such as Stripe and Slack through Event Gateway's source types, and takes webhooks from any other sender that signs the request body or sends a shared credential.
The bridge runs on Hookdeck Event Gateway, which handles every event. It receives each service's webhooks on a public endpoint, verifies their signatures, turns each one into an MCP event, and delivers it to each subscriber, signed with that subscriber's secret on every attempt and with retries. The bridge is the MCP server: it offers each webhook type, such as GitHub's workflow_run, as an MCP event type, so your agent subscribes to it like any other, and it sets up each subscription in Event Gateway.
An agent on your laptop, or behind NAT, has no public URL. It can poll the bridge instead. Claude Code, which doesn't support MCP Events yet, does this through the bridge's plugin. Or run the bridge on the agent's machine: the bridge gives the agent a callback URL, and the Hookdeck CLI, a command-line tool, forwards each event from that URL to the agent's local port.
Turn any webhook into an MCP event with the MCP Events bridge walks through connecting ChatGPT and Claude Code, and adding your own services.
Services that send webhooks reach Hookdeck Event Gateway, which turns each one into an MCP event and delivers it to the subscribed agent. The MCP Events bridge sets up each subscription in Event Gateway.
- Few MCP servers offer events yet, but many services already send webhooks.
- The MCP Events bridge: an open-source MCP server, built on Hookdeck Event Gateway.
- Event Gateway turns the webhook into an MCP event and delivers it, with retries.
- No public URL? Poll the bridge, or use a callback URL through the Hookdeck CLI.
Guides, demos and specifications
Specifications:
- SEP-3415: Events Extension: the proposal itself.
- OpenAI's MCP Events guide: what ChatGPT supports.
Send MCP events from your MCP server:
- What it takes to add MCP Events to your MCP server: what you build if you run the delivery pipeline yourself.
- Send MCP Events webhooks with Outpost: add webhook delivery to your MCP server, with Outpost signing, retrying and logging each delivery, and test it with ChatGPT.
- MCP Events with Hookdeck Outpost demo: the working MCP server that guide is built from.
The Outpost guide and demo were built on the earlier design sketch and OpenAI's ChatGPT guide, so a server built that way works with ChatGPT. Some details, such as error codes, differ in SEP-3415.
Receive MCP events in your agent:
- Use Event Gateway as a forward proxy for MCP Events: set up an MCP Events source and a connection so Event Gateway answers the handshake, verifies and stores each delivery, and delivers it to your agent.
- Forward proxy demo: an agent that receives MCP events through Hookdeck Event Gateway.
Try it with services that send webhooks:
- MCP Events bridge: turn webhooks into MCP events.
All of these, and the video, are also on the MCP Events resources page.
FAQs
Is MCP Events part of the MCP specification?
Not yet. MCP Events is a draft extension, proposed on October 5, 2026, in SEP-3415, a Specification Enhancement Proposal from the MCP Triggers & Events Working Group. As of October 26, it's still in review and hasn't been voted on. A reference implementation in an official MCP SDK is still outstanding, and details may change before the SEP is accepted.
What are MCP events?
MCP events are the notifications an MCP server sends to a subscribed client when something happens, such as a CI build failing. Each one has an ID, an event type, a timestamp and its data. MCP Events, the draft extension that defines them, lets a client discover the event types a server offers, subscribe to them, and receive them by poll, push or webhook.
Does ChatGPT support MCP Events?
Yes, in webhook mode only. OpenAI's guide says ChatGPT supports webhook delivery and callback verification, but not polling, streaming, or the gap and terminated notices.
What's the difference between MCP Events and webhooks?
In webhook mode, each MCP event is a signed HTTP POST with Standard Webhooks headers. Around that, MCP Events adds discovery through events/list, subscriptions with arguments, endpoint verification, cursors, and two more delivery modes: poll and push.
What's the difference between MCP Events and MCP triggers?
They're the same idea. The extension comes from the MCP Triggers & Events Working Group, and some platforms call the feature triggers. SEP-3415 names its methods events/list, events/poll, events/stream, events/subscribe and events/unsubscribe.
Can MCP events arrive twice or out of order?
Yes. Delivery is at-least-once at best, so the same event can arrive more than once. In webhook mode, discard retried deliveries by their webhook-id. If you also deduplicate on the event's eventId, scope it to the subscription. Webhook deliveries can arrive out of order, so use the event's timestamp when order matters. Poll and push deliver in order within a subscription.
Which delivery mode does a client use?
SEP-3415's guidance for SDKs, which isn't binding, has the client's MCP SDK pick one that both the event type and the client support, preferring webhook, then push, then poll, unless the caller chooses a mode. Poll works almost anywhere, push suits a client that can hold a connection open, and webhook suits a cloud-hosted client with a public URL.
What happens when an MCP event arrives?
SEP-3415 leaves that to the client. For example, the client might add the event to the conversation, wake the agent's existing session, or queue it for later. The client also decides whether to invoke the model.
Can an agent trust what an MCP event says?
No. Event data is untrusted input: SEP-3415 says clients must treat it with the same caution as tool results. An event can wake an agent, but anything the agent does in response, such as calling a tool, still goes through normal MCP authorization.
Webhook infrastructure, managed for you
Hookdeck handles ingestion, delivery, observability, and error recovery — so you don't have to.