Skip to content

fix(core): add explicit | undefined to Transport interface optional properties#1766

Open
felixweinberger wants to merge 1 commit intomainfrom
fweinberger/transport-exact-optional-types
Open

fix(core): add explicit | undefined to Transport interface optional properties#1766
felixweinberger wants to merge 1 commit intomainfrom
fweinberger/transport-exact-optional-types

Conversation

@felixweinberger
Copy link
Contributor

Adds | undefined to optional properties on the Transport interface and TransportSendOptions so the interface matches what tsc emits in .d.ts for implementing classes.

Motivation and Context

Consumers using exactOptionalPropertyTypes: true without skipLibCheck hit TS2420 errors because the SDK's emitted .d.ts for classes like StreamableHTTPServerTransport includes | undefined on optional callbacks, but the Transport interface does not.

Fixes #1314

How Has This Been Tested?

pnpm check:all passes. Verified the interface change resolves the TS2420 error by enabling exactOptionalPropertyTypes locally against the test file.

Breaking Changes

None — adding | undefined to ?: T is a widening under default TS settings (no-op) and a fix under strict settings.

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

Thanks to @rechedev9 and @naman10parikh for the earlier PRs (#1661, #1736) exploring this fix. This PR consolidates the interface changes and adds sessionId and onresumptiontoken which were missed in the originals.

Supersedes #1507, #1661, #1736.

Workaround for older SDK versions: enable skipLibCheck: true in your tsconfig (recommended by TypeScript team and part of @tsconfig/strictest).

…roperties

Adds | undefined to optional properties on the Transport interface and
TransportSendOptions so the interface matches what tsc emits in .d.ts for
implementing classes. This fixes TS2420 errors for consumers using
exactOptionalPropertyTypes: true without skipLibCheck.

Fixes #1314
@felixweinberger felixweinberger requested a review from a team as a code owner March 26, 2026 16:07
@changeset-bot
Copy link

changeset-bot bot commented Mar 26, 2026

🦋 Changeset detected

Latest commit: 1497412

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

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

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

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

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 26, 2026

Open in StackBlitz

@modelcontextprotocol/client

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

@modelcontextprotocol/server

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

@modelcontextprotocol/express

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

@modelcontextprotocol/hono

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

@modelcontextprotocol/node

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

commit: 1497412

Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

LGTM -- straightforward type-level fix for exactOptionalPropertyTypes compatibility.

Extended reasoning...

Overview

This PR modifies a single source file (packages/core/src/shared/transport.ts) and adds a changeset. The change is purely at the type level: adding | undefined to optional properties on the Transport interface and one property on TransportSendOptions. This fixes TS2420 errors for consumers using exactOptionalPropertyTypes: true without skipLibCheck.

Security risks

None. This is a type-only change with zero runtime impact. No logic, control flow, or data handling is modified.

Level of scrutiny

Low scrutiny is appropriate. The change is mechanical and well-understood: under exactOptionalPropertyTypes, prop?: T and prop?: T | undefined have different semantics, and TypeScript's emitted .d.ts files for class implementations use the latter form. The PR aligns the interface declarations with what tsc emits, which is the correct fix.

Other factors

The bug report identifies two missed properties (relatedRequestId and resumptionToken in TransportSendOptions) that could also receive the | undefined treatment. This is a valid nit for consistency, but the practical impact is very low since TransportSendOptions is a type alias (not an interface implemented by classes), so it doesn't trigger the TS2420 error that motivated this PR. The core fix for the Transport interface is complete and correct. The PR also consolidates work from three prior PRs (#1507, #1661, #1736), includes a proper changeset, and the author confirms pnpm check:all passes.

Comment on lines 66 to 70
*
* This allows clients to persist the latest token for potential reconnection.
*/
onresumptiontoken?: (token: string) => void;
onresumptiontoken?: ((token: string) => void) | undefined;
};
Copy link

Choose a reason for hiding this comment

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

🟡 The | undefined fix for exactOptionalPropertyTypes was applied to onresumptiontoken in TransportSendOptions but not to the other two optional properties (relatedRequestId on line 55 and resumptionToken on line 62). For consistency, these should also get | undefined — a consumer passing { resumptionToken: undefined } would still get a type error under exactOptionalPropertyTypes: true.

Extended reasoning...

What the bug is

The PR adds | undefined to all optional properties on the Transport interface (onclose, onerror, onmessage, sessionId, setProtocolVersion, setSupportedProtocolVersions) and to onresumptiontoken in TransportSendOptions. However, it misses the other two optional properties in TransportSendOptions: relatedRequestId?: RequestId (line 55) and resumptionToken?: string (line 62). The changeset description even explicitly mentions TransportSendOptions as being fixed.

Concrete example

Under exactOptionalPropertyTypes: true, prop?: T means the property can be omitted but cannot be explicitly set to undefined. To allow explicit undefined, you need prop?: T | undefined. After this PR, a consumer writing:

const opts: TransportSendOptions = {
  resumptionToken: undefined,
  onresumptiontoken: myCallback
};

would get a type error on resumptionToken: undefined because it is still typed as resumptionToken?: string (without | undefined), even though onresumptiontoken in the same object is now correctly typed. The test file at packages/client/test/client/streamableHttp.test.ts:1099 actually does pass resumptionToken: undefined in exactly this way.

Impact

The practical impact is low. TransportSendOptions is a type alias, not a class-implemented interface, so the primary TS2420 error that motivated this PR does not apply here. The issue only manifests if a consumer explicitly passes undefined for these properties (rather than simply omitting them) while using exactOptionalPropertyTypes: true. This is an uncommon pattern, but it is inconsistent to fix one property and not the others in the same type.

Suggested fix

Add | undefined to the remaining two optional properties in TransportSendOptions:

relatedRequestId?: RequestId | undefined;
resumptionToken?: string | undefined;

This is a one-line-each change that makes the fix complete and consistent with the stated goal of the PR.

@rechedev9
Copy link

I pulled this branch locally and prepared a minimal follow-up for the missing enforcement piece: #1767

Why the follow-up:

The follow-up PR adds:

  • a dedicated packages/core/test/shared/transport.types.test.ts
  • packages/core/tsconfig.exact-optional.json
  • wiring into the existing core typecheck script
  • the adjacent createFetchWithInit fix surfaced by that stricter compile

Verified locally with:

  • pnpm --filter @modelcontextprotocol/core typecheck
  • pnpm --filter @modelcontextprotocol/core test -- transport.types.test.ts
  • pnpm --filter @modelcontextprotocol/core lint

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

error TS2420: Class 'StreamableHTTPServerTransport' incorrectly implements interface 'Transport'.

2 participants