Commit graph

12 commits

Author SHA1 Message Date
Peter Alexander
754be6ce47
Add rationale for three delivery modes to Key Design Decisions
Records why poll, push, and webhook all exist as protocol-level modes
rather than picking one: the deployment topologies are disjoint and no
mode subsumes another. Acknowledges the departure from the usual
one-way-to-do-it stance and the spec/SDK cost it carries, and notes the
rejected alternative (one mode + proxy synthesis) and why.
2026-05-14 18:36:25 +01:00
Peter Alexander
197c32b4c5
Align push correlation with SEP-2575 and rename duration fields to Ms suffix
- Push notifications now carry the parent events/stream request id in params._meta["io.modelcontextprotocol/subscriptionId"] (per SEP-2575) instead of params.requestId
- Rename nextPollSeconds -> nextPollMs and maxAge -> maxAgeMs (integer milliseconds) to match the MCP duration-field convention; example values and prose updated
2026-05-10 16:45:42 +01:00
Peter Alexander
d4faef9758
Add nextCursor to events/list and _meta to event types and occurrences
events/list response now shows nextCursor for consistency with base MCP list pagination. Event-type definitions and EventOccurrence both gain optional _meta, matching Tool/Resource/Prompt.
2026-05-01 20:15:53 +01:00
Peter Alexander
8c6a1343cc
Redact example secret to avoid triggering secret scanners 2026-04-30 23:11:37 +01:00
Peter Alexander
58df0af65b
Revise Events design sketch: gap model, replay bounding, identity hardening, decisions table
- Unify cursor expiry into in-band `truncated: true` (drop -32014 CursorExpired): poll result body, push re-sends notifications/events/active mid-stream, webhook refresh response + {"type":"gap"} control envelope; client never re-subscribes for a gap
- Add `maxAge` (seconds) to bound replay across all modes; servers may decline by truncating to now
- Heartbeat carries cursor (push) and refresh response carries the safe-watermark cursor (webhook) so the client's position advances during quiet periods
- Webhook now requires an authenticated principal (key is (principal, url, name, params)); drop body `id` (route via X-MCP-Subscription-Id); add Non-event webhook bodies subsection (gap/terminated/verification with `type` discriminator)
- Drop subscription `id` from poll/stream (one sub per request; correlate via JSON-RPC id / requestId)
- Rewrite Summary as a how-it-works overview; add Key Design Decisions table; add OQ5 (task state changes as events) and OQ6 (endpoint verification + asymmetric server signing)
- Consistency pass across diagrams, examples, error lists, and appendix step references
2026-04-30 23:02:10 +01:00
Peter Alexander
26ba242ff0
Revise Events design sketch: Standard Webhooks, client-supplied secret, tuple-based identity
- Adopt Standard Webhooks as the delivery signature scheme (webhook-id/timestamp/signature, v1 base64, multi-sig rotation); keep X-MCP-Subscription-Id as the one MCP-specific header
- Webhook secret is now client-supplied and REQUIRED (whsec_ + 24-64B base64, server MUST reject otherwise); server never generates one
- Subscription identity is (principal?, delivery.url, name, params); the response returns a server-derived id used only for routing, never as input
- Revert to no-mode-mandatory for delivery modes
- TLS is now MUST for delivery.url
- Allow cursor: null in any delivery for event types without replay; clarify CursorExpired always implies a possible gap
2026-04-30 15:02:32 +01:00
Peter Alexander
249efdcc63
Revise Events design sketch: poll mandatory, webhook delivery profile, SEP review fixes
Make poll a mandatory delivery mode so every events-capable server is reachable by every client (push/webhook remain optional optimizations). Add a Webhook Delivery Profile subsection with WAF-relevant invariants (POST-only, required headers, 256 KiB body SHOULD, TLS termination) and defer User-Agent to SEP-1336 and egress-IP discovery to SEP-2127. Incorporate further fixes from adversarial review.
2026-04-30 14:30:53 +01:00
Peter Alexander
3dfc90566d
Remove revision deltas doc 2026-04-17 11:53:51 +01:00
Peter Alexander
641eca02a7
Revise Events design sketch: webhook cursor model, subscription identity, security hardening
Resolve internal contradictions and design gaps found in review:
- Webhook cursors are now client-owned (per-event retry, no server watermark); name/params/delivery.url are immutable identity fields; unsubscribe requires delivery.url
- Unify error/terminated shape across modes; define heartbeat and terminated notifications; renumber error codes to -32011..-32016 to avoid base-spec collision
- SSRF: validate at delivery time, block fe80::/10, MUST NOT follow redirects; HMAC: X-MCP-Subscription-Id header, hex-lowercase encoding, mandatory timestamp, retry regenerates
- events/stream scoped to event notifications only (existing GET SSE retained); StreamEventsResult send rules clarified per transport
- Broadcast emit now uses author-supplied match/transform hooks with ctx; poll lease keyed on (principal, eventName, hash(params)); eventId SHOULD be upstream's stable identifier
- Qualify at-least-once for emit-only types; refresh reactivates suspended delivery; capability uses listChanged
- Add Open Questions on multi-event-name subscriptions and ownership-verification handshake

Add design-sketch-revision-deltas.md documenting all changes for implementations built against the prior revision.
2026-04-17 11:52:12 +01:00
Peter Alexander
4f8a1129d8
Add delivery-mode diagrams, e2e webhook appendix, and clarifications
- Mermaid sequence diagrams for poll/push/webhook delivery
- Appendix: end-to-end GitHub example with Redis sub store
- Push: clarify multiple concurrent streams allowed; note HTTP/2 dependency
- Webhook: specify 2xx ACK requires durability or end-consumer processing
- Use nextPollSeconds consistently
2026-04-10 12:41:21 +01:00
Peter Alexander
603f5de12a
Add Events design sketch proposal 2026-04-09 21:30:11 +01:00
Peter Alexander
3314cd8dba
Initial commit: WG scaffolding (README, CONTRIBUTING, LICENSE, CODEOWNERS) 2026-04-09 16:53:28 +01:00