modelcontextprotocol / modelcontextprotocol/typescript-sdk

Streamable HTTP: close replayed request streams once no in-flight requests remain

Open
#2,558 4 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P2 ready for work v1 v2
Dominant language
TypeScript
Stars
13.4k
Forks
2.2k
Avg merge
3d 15h
Merged PRs (30d)
4

Description

When a client resumes a request stream with Last-Event-ID, the replayed stream stays open indefinitely (keep-alive now keeps it healthy) even when every correlated response has already been delivered or stored.

Three narrow races follow from this:

  • A response that becomes store-visible while a resume is mid-flight is missed by that replay's snapshot and never delivered to the now-permanent successor.
  • A superseded successor's dedup state does not transfer, so a double reconnect during an in-flight store write can double-deliver a response.
  • A stream resumed after closeSSEStream polling delivers the replayed response but never ends.

Closing a replayed request stream after replay whenever no in-flight requests map to it turns the polling loop into one that converges: the client re-polls until a replay snapshot includes the response.

Applies to both main and v1.x (the send()/replay code has the same shape in both). Split out from the review discussion on #2547.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the send()/replay code for Streamable HTTP in both the main and v1.x implementations, and trace how closeSSEStream polling handles resumed streams. Verify the three replay races and ensure a replayed request stream closes after replay when no in-flight requests map to it. Done means polling converges without missed or duplicate responses and the replayed stream ends.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
api
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
52/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.