Skip to content

fix(client): recover streamable HTTP session on 404 for session-bound requests#1718

Open
Maverick-666 wants to merge 2 commits intomodelcontextprotocol:mainfrom
Maverick-666:codex/issue-1708-404-session-reset
Open

fix(client): recover streamable HTTP session on 404 for session-bound requests#1718
Maverick-666 wants to merge 2 commits intomodelcontextprotocol:mainfrom
Maverick-666:codex/issue-1708-404-session-reset

Conversation

@Maverick-666
Copy link
Copy Markdown

Summary

Handle session-expired 404s in StreamableHTTPClientTransport when requests are session-bound.

What changed

  • In send() (POST path), when a request is sent with mcp-session-id and receives 404:
    • clear internal session state
    • throw a recoverable SdkError tagged with sessionExpired: true
  • In _startOrAuthSse() (GET path), apply the same 404 session-expiry handling.
  • Added regression tests for both POST and GET session-bound 404 paths.
  • Preserved existing behavior for non-session-bound 404 responses.
  • Added a changeset patch for @modelcontextprotocol/client.

Why

Per MCP session management requirements, a 404 for a request carrying Mcp-Session-Id indicates an invalid/expired session. The client should not keep sending a stale session ID.

Testing

  • pnpm --filter @modelcontextprotocol/client test -- test/client/streamableHttp.test.ts
  • pnpm exec prettier --check packages/client/src/client/streamableHttp.ts packages/client/test/client/streamableHttp.test.ts .changeset/gentle-maps-smile.md

Closes #1708

@Maverick-666 Maverick-666 requested a review from a team as a code owner March 20, 2026 04:03
@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 20, 2026

🦋 Changeset detected

Latest commit: d2d6587

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@modelcontextprotocol/client Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new bot commented Mar 20, 2026

Open in StackBlitz

@modelcontextprotocol/client

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/client@1718

@modelcontextprotocol/server

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/server@1718

@modelcontextprotocol/express

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/express@1718

@modelcontextprotocol/hono

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/hono@1718

@modelcontextprotocol/node

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/node@1718

commit: d2d6587

Copy link
Copy Markdown
Contributor

@felixweinberger felixweinberger left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this. Could we simplify? The spec (Session Management, item 4) says:

When a client receives HTTP 404 in response to a request containing an MCP-Session-Id, it MUST start a new session by sending a new InitializeRequest without a session ID attached.

The transport's piece is "without a session ID attached". Clear _sessionId so the next request omits the header. Client.connect() already handles the re-init when transport.sessionId is undefined (client.ts:497).

Suggested minimal change (both _startOrAuthSse and send, before the existing throw):

if (response.status === 404 && this._sessionId !== undefined) {
    this._sessionId = undefined;
}

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.

StreamableHTTPClientTransport doesn't handle 404 per spec (no session clear + re-init)

2 participants