io.modelcontextprotocol/events
(SEP-3415, the draft of 2026-10-16 for protocol 2026-07-28), with two delivery
modes: poll (events/poll) and webhook (events/subscribe). There is no
push mode (events/stream): the MCP endpoints are stateless.
Prerequisites
- A stream with events in it: see Collect events into a stream.
- A bearer token for a member of the stream’s workspace. A token of a non-member is refused.
- For webhook delivery, an endpoint reachable at an
https://URL that can verify Standard Webhooks signatures.
Which endpoint
All three MCP endpoints serve the same methods. An event type is named<workspace slug>/<stream id> on every one of them.
initialize (and server/discover on 2026-07-28) reports the extension as
capabilities.extensions["io.modelcontextprotocol/events"], and also as the
top-level capabilities.events that clients written against the pre-SEP sketch
read.
Steps
List the event types
inputSchema lists the arguments that narrow a subscription; all are optional.payloadSchema is the event envelope every subscriber receives as data:
id, kind, key, source_type, session_key, sender, received_at,
occurred_at, correlation_id, causation_id, data (the headers without
credentials, and the body as sent) and attachments.Poll
Start with Pass the cursor back on the next poll; every response carries the next one,
also when nothing arrived. Each event is
cursor: null. It returns no events and a cursor for “now”.{eventId, name, timestamp, data}.
When hasMore is true, poll again at once; otherwise wait nextPollMs.
maxEvents caps a page (default 50, at most 500). maxAgeMs skips events older
than that many milliseconds.Or subscribe a webhook
Generate the secret yourself: Before it answers, the server POSTs a signed
Each matching event is then POSTed with the headers
whsec_ followed by the base64 of 24 to 64
random bytes. The server never makes one for you.{"type":"verification","challenge":"<nonce>"} to your URL. Your endpoint
checks the signature and answers 200 with {"challenge":"<nonce>"}. Then:webhook-id (the event
id), webhook-timestamp, webhook-signature (v1, and the base64
HMAC-SHA256 of webhook-id.webhook-timestamp.body under your secret) and
X-MCP-Subscription-Id. Verify the signature over the raw body, reject a
timestamp older than five minutes, and deduplicate on eventId.Call events/subscribe again with the same name, arguments and URL before
refreshBefore. The same call rotates the secret and reactivates a subscription
whose deliveries failed. To stop, call events/unsubscribe with
{name, arguments, delivery: {url}}.Verify
events/pollwith the cursor from the previous answer returns the event you just sent to the stream, and the cursor changes.- Your endpoint logs one POST per event whose signature verifies, with the
X-MCP-Subscription-Idthatevents/subscribereturned. - The refresh answer’s
deliveryStatusshowslastDeliveryAtand nolastError.
Limits
- A subscription lasts at most 24 hours without a refresh (at least one
minute; one hour when you send no
ttlMs).ttlMs: null, no expiry, is answered with the 24-hour grant. - A webhook subscription starts at the end of the stream. A
cursoryou pass toevents/subscribeis not replayed (truncated: true); read the backlog withevents/poll. Webhook deliveries carrycursor: null. - A failed delivery is retried after 30 s, 2 min, 10 min, 30 min, 1 h and 2 h,
each attempt with a fresh timestamp and signature. After the last one the
subscription is marked failed and receives nothing until you refresh it. A
410or413answer is final for that event. - Delivery is at least once and may arrive out of order; use
eventIdandtimestamp. - Polling reads the last 7 days of the stream (
AGENTAREA_EVENT_RETENTION). A cursor older than that comes back withtruncated: true. - A workspace holds at most 100 webhook subscriptions.
- Deliveries leave through the outbound policy for member-set addresses: no
redirects, every address resolved and vetted before connecting. A callback
that resolves to a private address is refused unless the deployment allows
it in
AGENTAREA_HTTP_PRIVATE_ALLOWLIST; only such an allowed private host may usehttp://, for a receiver in development.
Troubleshooting
events/subscribe fails with -32027 CallbackEndpointError
events/subscribe fails with -32027 CallbackEndpointError
data.reason names the failure: challenge_failed when the endpoint answered
without echoing the challenge, connection_refused, timeout or tls_error
when it could not be reached, http_4xx or http_5xx for its status. The
endpoint must verify the signature with the secret you just sent and answer
before the 10 s timeout.events/subscribe fails with -32602 for the URL
events/subscribe fails with -32602 for the URL
The URL is not
https://. Only a private host listed in
AGENTAREA_HTTP_PRIVATE_ALLOWLIST (or any private host with
AGENTAREA_HTTP_ALLOW_PRIVATE=true) may use http://.-32024 Forbidden or a 403 response
-32024 Forbidden or a 403 response
The token’s user is not a member of the workspace, or may not read the stream.
On
/mcp/w/{workspace} a non-member is refused with HTTP 403 before any method
runs.Related
Event streams
Sources, streams and who reads them
Collect events into a stream
Point a webhook at a stream
Issue access tokens
Tokens for the MCP endpoints
MCP on AgentArea
How the platform serves and consumes MCP