Skip to content

Type inconsistency: StreamableHTTPServerTransport.onclose widens Transport interface contract under exactOptionalPropertyTypes #2083

Description

@swadel

SDK version: 1.29.0. TypeScript version: 5.9.3. tsconfig flags: strict true, exactOptionalPropertyTypes true, noUncheckedIndexedAccess true, target ES2022, module NodeNext.

Problem: the Transport interface in shared/transport.d.ts declares onclose as optional with type () => void (no explicit | undefined). The concrete StreamableHTTPServerTransport class in server/streamableHttp.d.ts declares onclose via getter/setter typed (() => void) | undefined. Under exactOptionalPropertyTypes, these two declarations are incompatible: the concrete class widens the optional property to include undefined, but the interface contract does not. As a result, passing a StreamableHTTPServerTransport instance into McpServer.connect(transport: Transport) fails typecheck with TS2379.

Reproduction: create a TypeScript project with the flag set above, import StreamableHTTPServerTransport and McpServer, attempt server.connect(new StreamableHTTPServerTransport()).

Expected: typechecks cleanly because the SDK's own concrete transport class should be assignable to the SDK's own Transport interface.

Actual: TS2379 on the property variance.

Asymmetry note: the client-side StreamableHTTPClientTransport declares onclose with the narrower () => void shape and typechecks cleanly under EOPT. Only the server-side transport hits this.

Suggested fix: align StreamableHTTPServerTransport.onclose to () => void to match the Transport interface declaration, OR widen Transport.onclose explicitly to (() => void) | undefined. Either direction resolves the variance for EOPT consumers.

Workaround consumers must use today: targeted cast at the connect call site, e.g. server.connect(transport as Transport).

Metadata

Metadata

Assignees

No one assigned

    Labels

    potentially closeBot recommends closing — needs maintainer review

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions