MCP Events Bridge
OfficialTurns Resend inbound email webhooks into MCP Events: agents subscribe to email.received, and when someone emails an address on the Resend receiving domain the event is delivered to the subscriber's callback with the sender, recipients and subject.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@MCP Events Bridgesubscribe me to email.received and show recent events"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
MCP Events bridge
Subscribe an agent to things that happen in apps whose vendors haven't shipped MCP Events. The bridge turns a provider's ordinary webhooks into MCP Events, with Hookdeck Event Gateway receiving, verifying and delivering them.
The first provider is Resend inbound email: someone emails an address on Resend, and an agent subscribed to email.received (for example in ChatGPT) wakes up and acts.
Status: a working demo, built in stages. See docs/PLAN.md for what's done and what's next, and docs/ARCHITECTURE.md for the design.
How it works
flowchart TB
P["Resend"] -- "webhook" --> SRC["Event Gateway<br>RESEND source"]
SRC -- "inbound connection" --> B["Bridge<br>map, match, sign"]
B -- "Publish API<br>one request per subscriber" --> T["Event Gateway<br>topic source"]
T -- "connection per subscription<br>filter, dedupe, retry" --> CB["Subscriber's callback<br>(for example ChatGPT)"]
AG["Agent host"] -- "MCP: events/*, tools" --> BEvent Gateway verifies the provider's signature, keeps every request, and delivers each MCP Event to each subscriber with retries.
The bridge is the MCP server: the event catalog, subscribe (with the endpoint challenge), and turning each provider webhook into a signed MCP Event per subscriber. It's stateless: subscriptions are Event Gateway connections, so there's no database.
The Hookdeck CLI forwards provider events to a bridge on your laptop during development, so you don't need a public URL.
In the Event Gateway dashboard, a running bridge looks like this:

bridge-resend(the Resend source) feeds one inbound connection per deployment:bridge-resend-fly(HTTP, to the bridge on Fly.io) andbridge-resend-dev(CLI, to a bridge on a laptop).bridge-out-email_receivedis the topic source the bridge publishes to. Each subscription is one connection from it,mcp-sub-<id>, with filter, dedupe and retry rules, to a destination at the subscriber's callback (here, ChatGPT's).bridge-hookdeck-notificationsreceives Event Gateway's issue notifications and forwards them to each deployment, so a bridge hears about failing callbacks.
Related MCP server: Sendmux Email Inbox API + Sending
Requirements
Node 22 or later.
A Hookdeck account, and a Hookdeck project for each deployment (for example one for development and one for production). Its Project API key and signing secret.
The Hookdeck CLI, for local development.
A Resend account and an API key that can create webhooks. Every Resend account gets a receiving domain (
<id>.resend.app; Emails > Receiving > ... > Receiving address), so no custom domain is needed. To send test emails, a verified sending domain.
Run it locally
Install:
npm install cp .env.example .envFill in
HOOKDECK_API_KEY,HOOKDECK_SIGNING_SECRETandRESEND_API_KEY. For the end-to-end check, alsoRESEND_INBOUND_ADDRESS(any address on your receiving domain) andRESEND_TEST_FROM(an address on your verified sending domain).Configure providers in
bridge.config.ts:import { defineConfig, env } from '@hookdeck/mcp-events-bridge'; import { resend } from '@hookdeck/mcp-events-bridge/providers'; export default defineConfig({ deployment: 'dev', providers: [resend({ apiKey: env('RESEND_API_KEY'), events: ['email.received'] })], });(This repo's own
bridge.config.tsimports from./srcinstead.)Create the Event Gateway resources and the Resend webhook:
npm run bridge -- setupThe first run generates an MCP secret; put it in
.envasBRIDGE_MCP_SECRET. Setup is safe to re-run.Run the bridge, and forward events to it with the Hookdeck CLI (the exact commands are printed by
setupandserve):npm run bridge -- serve hookdeck listen 8080 bridge-resend bridge-resend-dev hookdeck listen 8080 bridge-hookdeck-notifications bridge-notifications-devCheck the whole path with real email:
npm run e2eThis starts its own bridge and
hookdeck listen, subscribes a test subscriber (behind a cloudflared quick tunnel, because the MCP Events challenge needs a synchronous answer), sends emails through Resend, and checks delivery, thatwebhook-idequals Resend'ssvix-id,get_event, thefromfilter, and unsubscribe.E2E_EXTENDED=1adds a failed publish and its retry, a duplicate provider delivery, a410deleting a subscription, anddeliveryStatusfor a failing callback (about 10 minutes).
Deploy to Fly.io
fly.toml and the Dockerfile run one always-on machine; there's no volume, since Event Gateway is the store.
fly apps create <app> # then set app in fly.toml
fly secrets set HOOKDECK_API_KEY=... HOOKDECK_SIGNING_SECRET=... RESEND_API_KEY=... BRIDGE_MCP_SECRET=...
fly deploy
BRIDGE_DEPLOYMENT=fly BRIDGE_INBOUND=http BRIDGE_PUBLIC_URL=https://<app>.fly.dev npm run bridge -- setup
E2E_BRIDGE_URL=https://<app>.fly.dev npm run e2eUse a separate Hookdeck project for each deployment: deployments in one project share the provider source and the subscriptions.
Connect ChatGPT
With Developer mode on (ChatGPT Plus or above), go to Plugins, choose Add > Create MCP App, paste https://<app>.fly.dev/mcp/<BRIDGE_MCP_SECRET>, and choose No Authentication. Then, in a Work chat, ask to be told about new emails, for example from a particular sender. ChatGPT subscribes to email.received and sets up a monitoring task:

When an email arrives, the task runs with the event: sender, recipients and subject.

The URL is a credential: anyone with it can use the bridge's MCP endpoint. Keep it private. OAuth options are planned (see "Authentication" in the architecture doc).
Configuration
Variable | Purpose |
| Project API key, for the Event Gateway API and the Publish API |
| Verifies Event Gateway's signature on requests to the bridge |
| Creates the Resend webhook (referenced from |
| Secret path segment of the MCP URL; |
| Names this deployment's Event Gateway resources (read by this repo's |
|
|
| For |
| Listener port (default 8080) |
MCP surface
events/list,events/subscribe,events/unsubscribe(webhook delivery).get_event(eventId)andlist_recent_events(name?, since?, limit?): past events, read from Event Gateway.list_providers(): configured providers and their subscriptions.
Tests
npm test # unit and in-process integration tests, with a fake Event Gateway
npm run typecheckLicense
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Webhooks for AI agents: send events, manage endpoints, inspect and retry deliveries.
- webhook.coOAuthco.webhook
Receive, inspect, replay and deliver webhooks — with signature verification and agent triggers.
Turn inbound email into a webhook — verify, parse, route, and store incoming messages.
A webhook inbox for agents: one call returns a live URL. Mock, verify, inspect and replay.
Related MCP Servers
- AlicenseAqualityDmaintenanceMCP server for Sendook - an AI email communication platform. Enables AI agents to send and receive emails, manage inboxes, threads, and webhooks programmatically.16MIT

Sendmux Email Inbox API +official
AlicenseAqualityAmaintenanceSendmux is an email inbox API and email API for AI agents. Use this MCP server to let authorised agents work with Sendmux mailboxes, inbound email, clean JSON parsing, webhooks, outbound sending, provider routing, logs, billing, and team controls.3265MIT- AlicenseNot gradedqualityAmaintenanceA webhook management and delivery service with MCP tools for endpoints, deliveries, relay, and incoming webhooks, enabling autonomous agents to send, track, and relay webhooks.MIT

mcp-events-outpost-demoofficial
AlicenseNot gradedqualityBmaintenanceEnables agents such as ChatGPT to subscribe to events happening behind an MCP server (for example, order.created with filters) and receive them as signed webhooks without the builder implementing delivery itself. Hookdeck Outpost handles filtering, Standard Webhooks signing, retries, and delivery to each subscriber's callback URL.MIT