Skip to content

Commit 70178e6

Browse files
committed
fix: support exactOptionalPropertyTypes in Transport interface
Adds explicit `| undefined` to all optional callback properties on the Transport interface and all implementing classes. This allows consumers with `exactOptionalPropertyTypes: true` in their tsconfig.json to use the SDK without type errors. Without this fix, class properties initialized as `undefined` are incompatible with the interface under exactOptionalPropertyTypes, since `T | undefined` is not assignable to `T` when the property is present. Fixes #1314
1 parent 9aed95a commit 70178e6

10 files changed

Lines changed: 35 additions & 35 deletions

File tree

packages/client/src/client/sse.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,9 @@ export class SSEClientTransport implements Transport {
7676
private _fetchWithInit: FetchLike;
7777
private _protocolVersion?: string;
7878

79-
onclose?: () => void;
80-
onerror?: (error: Error) => void;
81-
onmessage?: (message: JSONRPCMessage) => void;
79+
onclose?: (() => void) | undefined;
80+
onerror?: ((error: Error) => void) | undefined;
81+
onmessage?: ((message: JSONRPCMessage) => void) | undefined;
8282

8383
constructor(url: URL, opts?: SSEClientTransportOptions) {
8484
this._url = url;

packages/client/src/client/stdio.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -96,9 +96,9 @@ export class StdioClientTransport implements Transport {
9696
private _serverParams: StdioServerParameters;
9797
private _stderrStream: PassThrough | null = null;
9898

99-
onclose?: () => void;
100-
onerror?: (error: Error) => void;
101-
onmessage?: (message: JSONRPCMessage) => void;
99+
onclose?: (() => void) | undefined;
100+
onerror?: ((error: Error) => void) | undefined;
101+
onmessage?: ((message: JSONRPCMessage) => void) | undefined;
102102

103103
constructor(server: StdioServerParameters) {
104104
this._serverParams = server;

packages/client/src/client/streamableHttp.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,9 @@ export class StreamableHTTPClientTransport implements Transport {
149149
private _serverRetryMs?: number; // Server-provided retry delay from SSE retry field
150150
private _reconnectionTimeout?: ReturnType<typeof setTimeout>;
151151

152-
onclose?: () => void;
153-
onerror?: (error: Error) => void;
154-
onmessage?: (message: JSONRPCMessage) => void;
152+
onclose?: (() => void) | undefined;
153+
onerror?: ((error: Error) => void) | undefined;
154+
onmessage?: ((message: JSONRPCMessage) => void) | undefined;
155155

156156
constructor(url: URL, opts?: StreamableHTTPClientTransportOptions) {
157157
this._url = url;

packages/client/src/client/websocket.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ export class WebSocketClientTransport implements Transport {
1010
private _socket?: WebSocket;
1111
private _url: URL;
1212

13-
onclose?: () => void;
14-
onerror?: (error: Error) => void;
15-
onmessage?: (message: JSONRPCMessage) => void;
13+
onclose?: (() => void) | undefined;
14+
onerror?: ((error: Error) => void) | undefined;
15+
onmessage?: ((message: JSONRPCMessage) => void) | undefined;
1616

1717
constructor(url: URL) {
1818
this._url = url;

packages/core/src/shared/transport.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,14 +98,14 @@ export interface Transport {
9898
*
9999
* This should be invoked when {@linkcode Transport.close | close()} is called as well.
100100
*/
101-
onclose?: () => void;
101+
onclose?: (() => void) | undefined;
102102

103103
/**
104104
* Callback for when an error occurs.
105105
*
106106
* Note that errors are not necessarily fatal; they are used for reporting any kind of exceptional condition out of band.
107107
*/
108-
onerror?: (error: Error) => void;
108+
onerror?: ((error: Error) => void) | undefined;
109109

110110
/**
111111
* Callback for when a message (request or response) is received over the connection.
@@ -114,21 +114,21 @@ export interface Transport {
114114
*
115115
* The {@linkcode MessageExtraInfo.requestInfo | requestInfo} can be used to get the original request information (headers, etc.)
116116
*/
117-
onmessage?: <T extends JSONRPCMessage>(message: T, extra?: MessageExtraInfo) => void;
117+
onmessage?: (<T extends JSONRPCMessage>(message: T, extra?: MessageExtraInfo) => void) | undefined;
118118

119119
/**
120120
* The session ID generated for this connection.
121121
*/
122-
sessionId?: string;
122+
sessionId?: string | undefined;
123123

124124
/**
125125
* Sets the protocol version used for the connection (called when the initialize response is received).
126126
*/
127-
setProtocolVersion?: (version: string) => void;
127+
setProtocolVersion?: ((version: string) => void) | undefined;
128128

129129
/**
130130
* Sets the supported protocol versions for header validation (called during connect).
131131
* This allows the server to pass its supported versions to the transport.
132132
*/
133-
setSupportedProtocolVersions?: (versions: string[]) => void;
133+
setSupportedProtocolVersions?: ((versions: string[]) => void) | undefined;
134134
}

packages/core/src/util/inMemory.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@ export class InMemoryTransport implements Transport {
1414
private _otherTransport?: InMemoryTransport;
1515
private _messageQueue: QueuedMessage[] = [];
1616

17-
onclose?: () => void;
18-
onerror?: (error: Error) => void;
19-
onmessage?: (message: JSONRPCMessage, extra?: { authInfo?: AuthInfo }) => void;
20-
sessionId?: string;
17+
onclose?: (() => void) | undefined;
18+
onerror?: ((error: Error) => void) | undefined;
19+
onmessage?: ((message: JSONRPCMessage, extra?: { authInfo?: AuthInfo }) => void) | undefined;
20+
sessionId?: string | undefined;
2121

2222
/**
2323
* Creates a pair of linked in-memory transports that can communicate with each other. One should be passed to a {@linkcode @modelcontextprotocol/client!client/client.Client | Client} and one to a {@linkcode @modelcontextprotocol/server!server/server.Server | Server}.

packages/core/test/shared/protocol.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ interface TestProtocol {
5454

5555
// Mock Transport class
5656
class MockTransport implements Transport {
57-
onclose?: () => void;
58-
onerror?: (error: Error) => void;
59-
onmessage?: (message: unknown) => void;
57+
onclose?: (() => void) | undefined;
58+
onerror?: ((error: Error) => void) | undefined;
59+
onmessage?: ((message: unknown) => void) | undefined;
6060

6161
async start(): Promise<void> {}
6262
async close(): Promise<void> {

packages/core/test/shared/protocolTransportHandling.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import type { EmptyResult, JSONRPCMessage, Notification, Request, Result } from
88
// Mock Transport class
99
class MockTransport implements Transport {
1010
id: string;
11-
onclose?: () => void;
12-
onerror?: (error: Error) => void;
13-
onmessage?: (message: unknown) => void;
11+
onclose?: (() => void) | undefined;
12+
onerror?: ((error: Error) => void) | undefined;
13+
onmessage?: ((message: unknown) => void) | undefined;
1414
sentMessages: JSONRPCMessage[] = [];
1515

1616
constructor(id: string) {

packages/server/src/server/stdio.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ export class StdioServerTransport implements Transport {
2525
private _stdout: Writable = process.stdout
2626
) {}
2727

28-
onclose?: () => void;
29-
onerror?: (error: Error) => void;
30-
onmessage?: (message: JSONRPCMessage) => void;
28+
onclose?: (() => void) | undefined;
29+
onerror?: ((error: Error) => void) | undefined;
30+
onmessage?: ((message: JSONRPCMessage) => void) | undefined;
3131

3232
// Arrow functions to bind `this` properly, while maintaining function identity.
3333
_ondata = (chunk: Buffer) => {

packages/server/src/server/streamableHttp.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -240,10 +240,10 @@ export class WebStandardStreamableHTTPServerTransport implements Transport {
240240
private _retryInterval?: number;
241241
private _supportedProtocolVersions: string[];
242242

243-
sessionId?: string;
244-
onclose?: () => void;
245-
onerror?: (error: Error) => void;
246-
onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;
243+
sessionId?: string | undefined;
244+
onclose?: (() => void) | undefined;
245+
onerror?: ((error: Error) => void) | undefined;
246+
onmessage?: ((message: JSONRPCMessage, extra?: MessageExtraInfo) => void) | undefined;
247247

248248
constructor(options: WebStandardStreamableHTTPServerTransportOptions = {}) {
249249
this.sessionIdGenerator = options.sessionIdGenerator;

0 commit comments

Comments
 (0)