Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport by felixweinberger · Pull Request #2229 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport by felixweinberger · Pull Request #2229 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport by felixweinberger · Pull Request #2229 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport by felixweinberger · Pull Request #2229 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport by felixweinberger · Pull Request #2229 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport by felixweinberger · Pull Request #2229 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport by felixweinberger · Pull Request #2229 · modelcontextprotocol/typescript-sdk · GitHub
Skip to content

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport - #2229

Merged
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring
Jun 1, 2026
Merged

test(e2e): host the sse matrix column on the shipped legacy SSEServerTransport#2229
felixweinberger merged 1 commit into
mainfrom
fweinberger/sse-e2e-legacy-wiring

Conversation

@felixweinberger

Copy link
Copy Markdown
Contributor

Wire the e2e suite to the legacy SSE transport shipped by #2206: the sse matrix column now runs against the real SSEServerTransport, and the SSE back-compat requirements that were recorded as failures/deferred are now implemented.

Motivation and Context

#2206 ships SSEServerTransport in @modelcontextprotocol/server-legacy, but the e2e suite still records the SDK as not providing one:

  • transport:sse:server-transport was a knownFailure ("the server-side SSE transport was removed from the SDK")
  • the sse matrix column was hosted by a hand-written test-only bridge (helpers/sse-host.ts)
  • the two flow:compat:* requirements were deferred ("flows that require an SSE server are deferred")

This stacks on #2206 and resolves all three, so the package's back-compat claim is proven by the matrix (real SSEClientTransport against the real shipped server transport) rather than only by its ported v1 unit tests.

How Has This Been Tested?

  • Full e2e suite: 33 files, 1142 passed, 91 expected-fail, 0 unexpected failures
  • The existing sse-column knownFailures behave identically with the real transport, so no manifest churn
  • Typecheck and lint clean

Breaking Changes

None — test-only changes.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update

Checklist

  • I have read the MCP Documentation
  • My code follows the repository's style guidelines
  • New and existing tests pass locally
  • I have added appropriate error handling
  • I have added or updated documentation as needed

Additional context

  • helpers/sse-host.ts keeps its loopback listener and per-session routing; only the transport class is swapped (hand-written bridge → shipped SSEServerTransport)
  • New flow tests: dual-transport hosting (Streamable HTTP + SSE serving the same tools concurrently) and streamable→SSE fallback on 4xx, both citing the spec's backwards-compatibility section

@felixweinberger
felixweinberger requested a review from a team as a code ownerJune 1, 2026 13:46
@changeset-bot

changeset-botBot commented Jun 1, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: acd9fba

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

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

@pkg-pr-new

pkg-pr-newBot commented Jun 1, 2026

Copy link
Copy Markdown

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/codemod

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/codemod@2229

@modelcontextprotocol/server

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

@modelcontextprotocol/server-legacy

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

@modelcontextprotocol/express

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

@modelcontextprotocol/fastify

npm i https://pkg.pr.new/modelcontextprotocol/typescript-sdk/@modelcontextprotocol/fastify@2229

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: acd9fba

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the hand-written SSE bridge for the shipped SSEServerTransport and lifts the now-resolved deferred/knownFailure entries.

Extended reasoning...

Overview

This PR only touches the e2e test workspace (test/e2e/**), its package.json/tsconfig.json path mappings, and pnpm-lock.yaml. It replaces the hand-written LegacySseServerTransport test bridge in helpers/sse-host.ts with the real SSEServerTransport from @modelcontextprotocol/server-legacy/sse (shipped by #2206), removes the corresponding knownFailures/deferred entries in requirements.ts, and adds two new compat flow tests (dual-transport hosting and streamable→SSE fallback). No production package code is modified.

Correctness checks

I verified the constructor and surface usage against the shipped transport: new SSEServerTransport(POST_PATH, res) matches packages/server-legacy/src/sse/sse.ts:47, and the host's use of sessionId, handlePostMessage, and close() all exist with compatible semantics (the shipped transport writes the SSE headers and endpoint event in start(), exactly as the deleted bridge did). SdkHttpError is exported from @modelcontextprotocol/client via the core public re-export, and a POST of initialize to the SSE host's /sse path falls through to the 404 branch, which the streamable HTTP client surfaces as an SdkHttpError with status 404 — so the fallback test's 400/404/405 assertion is sound. The new requirement notes accurately describe the new behavior (no prose/code mismatch).

Security risks

None — this is test infrastructure only; the loopback HTTP listener binds to 127.0.0.1 on an ephemeral port inside the test process and nothing here ships in any published package.

Level of scrutiny

Low-to-medium: the diff is moderately sized but is a net deletion of test-only bridge code in favor of exercising the real shipped transport, which strictly improves coverage fidelity for the back-compat claim made by #2206. The remaining risk (e.g., the stacked dependency on #2206 being present) is fully covered by CI — if the base PR isn't merged, typecheck/tests fail loudly. The bug-hunting pass found no issues, the author reports the full e2e suite passing with no manifest churn, and the changeset-bot warning is expected since @modelcontextprotocol/test-e2e is a private test package.

Base automatically changed from feature/v2-server-legacy-package to mainJune 1, 2026 14:33
…Transport
The sse column was hosted by a hand-written test-only bridge because v2
removed the server-side SSE transport. Now that the server-legacy package
ships SSEServerTransport, the matrix can exercise the real transport end
to end:
- replace the bridge transport in helpers/sse-host.ts with
SSEServerTransport from @modelcontextprotocol/server-legacy/sse
- resolve the transport:sse:server-transport knownFailure and probe the
legacy package in its surface test
- un-defer and implement the two flow:compat requirements:
dual-transport hosting (streamable HTTP + SSE serving the same tools
concurrently) and streamable-then-SSE fallback on 4xx
@felixweinberger
felixweinbergerforce-pushed the fweinberger/sse-e2e-legacy-wiring branch from d292267 to acd9fbaCompareJune 1, 2026 14:38
@felixweinberger
felixweinberger enabled auto-merge (squash) June 1, 2026 14:38
@felixweinberger
felixweinberger merged commit c54abdb into mainJun 1, 2026
18 of 20 checks passed
@felixweinberger
felixweinberger deleted the fweinberger/sse-e2e-legacy-wiring branch June 1, 2026 14:43

@claudeclaudeBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

LGTM — test-only wiring that swaps the e2e SSE host's hand-written bridge for the shipped SSEServerTransport from #2206; no runtime or public-API changes.

Extended reasoning...

Overview

This PR is confined to the e2e test workspace (test/e2e/) plus a pnpm-lock.yaml entry for the new workspace link. It replaces the hand-written LegacySseServerTransport bridge in helpers/sse-host.ts with the real SSEServerTransport shipped by @modelcontextprotocol/server-legacy/sse (added in #2206), removes the now-resolved knownFailures/deferred markers from three requirements, and adds two new flow tests (dual-transport hosting and streamable→SSE fallback). I verified the shipped transport's surface against packages/server-legacy/src/sse/sse.ts — the constructor signature (endpoint, res), sessionId getter, handlePostMessage(req, res), and close() all match how the host helper uses it, and server.connect(tx) calling start() correctly emits the SSE headers and endpoint event the SSEClientTransport expects.

Security risks

None. No production code, auth, crypto, or transport implementation is touched — only test helpers, test scenarios, requirement metadata, the test package's devDependencies/tsconfig paths, and the lockfile link. The fallback test correctly relies on the host returning 404 for a POST to the SSE path, which is within the spec's 400/404/405 fallback signal set.

Level of scrutiny

Low-to-moderate. This is test infrastructure for the e2e back-compat matrix, not shipped SDK code. The riskiest aspect would be a test that passes for the wrong reason, but the swap actually strengthens coverage: the matrix now exercises both shipped halves of the legacy transport rather than a test-only stand-in, and the previously-deferred compat flows are now implemented against the real server transport. The new fallback test asserts the spec-mandated 4xx fallback behavior with a concrete spec citation.

Other factors

No changeset is needed (@modelcontextprotocol/test-e2e is private, and the changeset bot's note is informational). The bug hunting system found no issues. The author reports the full e2e suite (1142 passed, 91 expected-fail, 0 unexpected) plus typecheck/lint clean, and the diff is consistent with that claim — the removed knownFailure for transport:sse:server-transport is genuinely satisfied because SSEServerTransport matches the test's /sse/i + /server/i export filter. The PR follows the existing host/wire patterns in the e2e helpers (per-session factory, 404 for unknown sessions, 500 on handler failure).

Sign up for freeto 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.

2 participants

@felixweinberger@KKonstantinov