You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
subscriptions/listen: let extensions add filter fields and events (Tasks taskIds) #3127
In 2.4.0 the listen router only understands the four core subscription types:
honoredSubset keeps only toolsListChanged, promptsListChanged, resourcesListChanged and resourceSubscriptions. Any other field the client requests is dropped from notifications/subscriptions/acknowledged.
ServerEvent and listenFilterAccepts are a closed union of the matching four event kinds. The code comment says the filter governs "ONLY the four subscription-gated change types".
The Tasks extension defines a subscription filter field: notifications.taskIds in TaskSubscriptionNotificationsV2Schema. It ships helpers for it, contributeTaskFilterV2 on the client and readAcceptedTaskIdsV2 for reading the accepted filter. But a server can't honor that field through createMcpHandler or serveStdio. The ack drops it, and there's no way to publish a task status event through the bus.
So a server that supports task subscriptions has to intercept subscriptions/listen before the SDK handler and re-implement the whole stream:
SSE framing and the ack sent first;
keep-alive;
subscription limits;
subscription-ID stamping;
teardown.
All of that already exists in createListenRouter.
Proposal: an extension point that createMcpHandler and serveStdio both accept, for example:
listenExtensions?: Array<{// fields of the requested filter this extension honors, given server capabilitieshonor(requested: Record<string,unknown>,capabilities: ServerCapabilities): Record<string,unknown>|undefined;// whether an extension event matches the honored filteraccepts(honored: Record<string,unknown>,event: ExtensionServerEvent): boolean;}>
ServerEvent would gain an extension variant that maps straight onto its wire notification:
The SDK keeps owning the wire behavior: ack ordering, filtering, ID stamping and teardown. ext-tasks could then ship a ready-made listenExtensions entry next to contributeTaskFilterV2.
Related: modelcontextprotocol/ext-tasks#24 (missed transitions after reconnect). This proposal would give that recovery work one place to live in the SDK.
Context: our component currently keeps a roughly 530-line custom subscriptions/listen stream for this reason, and would delete it.
Activity