Skip to content

Commit 1359e9f

Browse files
committed
pull transport send options into own named type
1 parent 621e65c commit 1359e9f

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

src/client/streamableHttp.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ export type StreamableHTTPClientTransportOptions = {
8888
* Options to configure the reconnection behavior.
8989
*/
9090
reconnectionOptions?: StreamableHTTPReconnectionOptions;
91+
9192
/**
9293
* Session ID for the connection. This is used to identify the session on the server.
9394
* When not provided and connecting to a server that supports session IDs, the server will generate a new session ID.
@@ -345,10 +346,11 @@ export class StreamableHTTPClientTransport implements Transport {
345346
this.onclose?.();
346347
}
347348

348-
async send(message: JSONRPCMessage | JSONRPCMessage[], options?: { lastEventId?: string, onLastEventIdUpdate?: (event: string) => void }): Promise<void> {
349+
async send(message: JSONRPCMessage | JSONRPCMessage[], options?: { resumptionToken?: string, onresumptiontoken?: (event: string) => void }): Promise<void> {
349350
try {
350351
// If client passes in a lastEventId in the request options, we need to reconnect the SSE stream
351-
const { lastEventId, onLastEventIdUpdate } = options ?? {};
352+
const lastEventId = options?.resumptionToken
353+
const onLastEventIdUpdate = options?.onresumptiontoken;
352354
if (lastEventId) {
353355
// If we have at last event ID, we need to reconnect the SSE stream
354356
this._startOrAuthSse({ lastEventId }).catch(err => this.onerror?.(err));

src/examples/client/simpleStreamableHttp.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ async function callTool(name: string, args: Record<string, unknown>): Promise<vo
302302
notificationsToolLastEventId = event;
303303
};
304304
const result = await client.request(request, CallToolResultSchema, {
305-
lastEventId: notificationsToolLastEventId, onLastEventIdUpdate
305+
resumptionToken: notificationsToolLastEventId, onresumptiontoken: onLastEventIdUpdate
306306
});
307307

308308
console.log('Tool result:');

src/integration-tests/taskResumability.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,8 +247,8 @@ describe('Transport resumability', () => {
247247
}
248248
}
249249
}, CallToolResultSchema, {
250-
lastEventId,
251-
onLastEventIdUpdate
250+
resumptionToken: lastEventId,
251+
onresumptiontoken: onLastEventIdUpdate
252252
});
253253

254254
// Wait for some notifications to arrive (not all)
@@ -311,8 +311,8 @@ describe('Transport resumability', () => {
311311
}
312312
}
313313
}, CallToolResultSchema, {
314-
lastEventId, // Pass the lastEventId from the previous session
315-
onLastEventIdUpdate
314+
resumptionToken: lastEventId, // Pass the lastEventId from the previous session
315+
onresumptiontoken: onLastEventIdUpdate
316316
});
317317

318318
// Verify we eventually received at leaset a few motifications

src/shared/protocol.ts

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -87,17 +87,20 @@ export type RequestOptions = {
8787
* May be used to indicate to the transport which incoming request to associate this outgoing request with.
8888
*/
8989
relatedRequestId?: RequestId;
90+
9091
/**
91-
* The last event ID to associate with the request.
92-
* Used to resume long-running requests that were interrupted when creating a new client instance.
92+
* The resumption token used to continue long-running requests that were interrupted.
93+
*
94+
* This allows clients to reconnect and continue from where they left off, if supported by the transport.
9395
*/
94-
lastEventId?: string;
96+
resumptionToken?: string;
9597

9698
/**
97-
* A callback that is invoked when the last event ID is updated.
98-
* This is used to notify the client that the last event ID has changed, so the client can update its state accordingly.
99+
* A callback that is invoked when the resumption token changes, if supported by the transport.
100+
*
101+
* This allows clients to persist the latest token for potential reconnection.
99102
*/
100-
onLastEventIdUpdate?: (event: string) => void;
103+
onresumptiontoken?: (token: string) => void;
101104
};
102105

103106
/**
@@ -512,7 +515,7 @@ export abstract class Protocol<
512515
resultSchema: T,
513516
options?: RequestOptions,
514517
): Promise<z.infer<T>> {
515-
const { relatedRequestId, lastEventId, onLastEventIdUpdate } = options ?? {};
518+
const { relatedRequestId, resumptionToken, onresumptiontoken } = options ?? {};
516519

517520
return new Promise((resolve, reject) => {
518521
if (!this._transport) {
@@ -554,7 +557,7 @@ export abstract class Protocol<
554557
requestId: messageId,
555558
reason: String(reason),
556559
},
557-
}, { relatedRequestId, lastEventId, onLastEventIdUpdate })
560+
}, { relatedRequestId, resumptionToken, onresumptiontoken })
558561
.catch((error) =>
559562
this._onerror(new Error(`Failed to send cancellation: ${error}`)),
560563
);
@@ -592,7 +595,7 @@ export abstract class Protocol<
592595

593596
this._setupTimeout(messageId, timeout, options?.maxTotalTimeout, timeoutHandler, options?.resetTimeoutOnProgress ?? false);
594597

595-
this._transport.send(jsonrpcRequest, { relatedRequestId, lastEventId, onLastEventIdUpdate }).catch((error) => {
598+
this._transport.send(jsonrpcRequest, { relatedRequestId, resumptionToken, onresumptiontoken }).catch((error) => {
596599
this._cleanupTimeout(messageId);
597600
reject(error);
598601
});

src/shared/transport.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,26 @@
11
import { JSONRPCMessage, RequestId } from "../types.js";
22

3+
/**
4+
* Options for sending a JSON-RPC message.
5+
*/
6+
export interface TransportSendOptions {
7+
/**
8+
* If present, `relatedRequestId` is used to indicate to the transport which incoming request to associate this outgoing message with.
9+
*/
10+
relatedRequestId?: RequestId;
11+
/**
12+
* The resumption token used to continue long-running requests that were interrupted.
13+
*
14+
* This allows clients to reconnect and continue from where they left off, if supported by the transport.
15+
*/
16+
resumptionToken?: string;
17+
/**
18+
* A callback that is invoked when the resumption token changes, if supported by the transport.
19+
*
20+
* This allows clients to persist the latest token for potential reconnection.
21+
*/
22+
onresumptiontoken?: (token: string) => void;
23+
}
324
/**
425
* Describes the minimal contract for a MCP transport that a client or server can communicate over.
526
*/
@@ -18,7 +39,7 @@ export interface Transport {
1839
*
1940
* If present, `relatedRequestId` is used to indicate to the transport which incoming request to associate this outgoing message with.
2041
*/
21-
send(message: JSONRPCMessage, options?: { relatedRequestId?: RequestId, lastEventId?: string, onLastEventIdUpdate?: (event: string) => void }): Promise<void>;
42+
send(message: JSONRPCMessage, options?: TransportSendOptions): Promise<void>;
2243

2344
/**
2445
* Closes the connection.

0 commit comments

Comments
 (0)