Skip to main content
The AgentArea MCP server is also an MCP Events server. Every stream you can read is an event type on it, so an MCP client outside the platform (your own service, a gateway, an assistant that speaks MCP Events) can follow what arrives in a stream without an agent run. Use it when something outside AgentArea must react to stream events. When an agent should react, attach a trigger instead. The server implements the MCP Events extension, 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

1

List the event types

Each entry is one stream you may read:
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.
2

Poll

Start with cursor: null. It returns no events and a cursor for “now”.
Pass the cursor back on the next poll; every response carries the next one, also when nothing arrived. Each event is {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.
3

Or subscribe a webhook

Generate the secret yourself: whsec_ followed by the base64 of 24 to 64 random bytes. The server never makes one for you.
Before it answers, the server POSTs a signed {"type":"verification","challenge":"<nonce>"} to your URL. Your endpoint checks the signature and answers 200 with {"challenge":"<nonce>"}. Then:
Each matching event is then POSTed with the headers 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/poll with 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-Id that events/subscribe returned.
  • The refresh answer’s deliveryStatus shows lastDeliveryAt and no lastError.

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 cursor you pass to events/subscribe is not replayed (truncated: true); read the backlog with events/poll. Webhook deliveries carry cursor: 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 410 or 413 answer is final for that event.
  • Delivery is at least once and may arrive out of order; use eventId and timestamp.
  • Polling reads the last 7 days of the stream (AGENTAREA_EVENT_RETENTION). A cursor older than that comes back with truncated: 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 use http://, for a receiver in development.

Troubleshooting

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.
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://.
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.

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
Last modified on October 19, 2026