Skip to content

Keep standalone SSE resume IDs separate from POST responses - #296

Open
EhsanAzish80 wants to merge 5 commits into
modelcontextprotocol:mainfrom
EhsanAzish80:fix/isolate-sse-resume-id
Open

EhsanAzish80 wants to merge 5 commits into
modelcontextprotocol:mainfrom
EhsanAzish80:fix/isolate-sse-resume-id

Conversation

@EhsanAzish80

@EhsanAzish80 EhsanAzish80 commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #281. The standalone GET stream keeps its own event ID, while each interrupted POST SSE stream can resume with its own ID. Concurrent POST requests do not share a cursor.

The branch is updated to current main and includes the Ubuntu CI setup and client-test timing fixes shared with #307.

Tests: 562 Swift tests and DocC passed locally before this update. All six CI jobs passed on b589337, including Ubuntu tests. AI helped write the tests; I ran them.

Copy link
Copy Markdown

Separating the standalone GET cursor from POST SSE cursors fixes cross-stream contamination, but this version appears to discard POST resumability completely.

processResponse calls:

processSSE(stream, recordsGETEventID: false)

for an SSE response to POST, so event IDs from that stream are never retained. The 2025-11-25 Streamable HTTP spec says resumption applies regardless of whether the original stream was initiated by POST or GET: after a disconnection the client should issue a GET carrying the Last-Event-ID for the stream that disconnected, and the server must not replay a different stream.

So one global cursor was wrong, but a GET-only cursor is also insufficient: if a POST response stream carries event IDs and disconnects before its terminal response, the client no longer has the cursor needed to resume that POST stream.

Would it make sense to keep per-stream resume state (at least a distinct cursor for each active POST SSE stream) and have the recovery GET use that stream's ID? A regression where a POST SSE emits id: post-1 and then disconnects before completion would pin this.

AI-assisted review; checked the current PR head against the 2025-11-25 resumability/redelivery rules before posting.

@EhsanAzish80

Copy link
Copy Markdown
Contributor Author

I added POST SSE resumption using each request’s own event ID, including concurrent requests. The standalone GET cursor stays separate. All 555 Swift tests passed locally. AI helped write the new tests; I ran them. Could a maintainer review this and approve CI?

@EhsanAzish80
EhsanAzish80 force-pushed the fix/isolate-sse-resume-id branch from 68705a2 to 033b1ec Compare October 24, 2026 18:14
@EhsanAzish80
EhsanAzish80 requested a review from a team as a code owner October 24, 2026 18:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HTTPClientTransport shares one lastEventID between all SSE streams, so the standalone GET can resume a POST stream

2 participants