Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

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

Open Beginner friendly
#2,083 2 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
68/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Quiet
Tech stack
typescript
Domain
api

Research direction

Compare shared/transport.d.ts with server/streamableHttp.d.ts, focusing on the onclose declarations, then reproduce the issue with TypeScript 5.9.3 and exactOptionalPropertyTypes enabled. Done means the StreamableHTTPServerTransport instance passes to McpServer.connect without TS2379, while the client-side declaration remains unaffected.

Written by the indexing model from the issue text.

Description

potentially close

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).

Dominant language
TypeScript
Stars
13.5k
Forks
2.2k
Avg merge
3d 11h
Merged PRs (30d)
32

Getting set up

First steps

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

More from modelcontextprotocol/typescript-sdk

All issues in modelcontextprotocol/typescript-sdk

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.