Add RequestOptions.timeout

This commit is contained in:
Justin Spahr-Summers 2024-11-16 16:30:20 +00:00
commit 2cc3bc8a40
No known key found for this signature in database
2 changed files with 46 additions and 3 deletions

View file

@ -37,6 +37,11 @@ export type ProtocolOptions = {
enforceStrictCapabilities?: boolean;
};
/**
* The default request timeout, in miliseconds.
*/
export const DEFAULT_REQUEST_TIMEOUT_MSEC = 60000;
/**
* Options that can be given per request.
*/
@ -50,6 +55,13 @@ export type RequestOptions = {
* Can be used to cancel an in-flight request. This will cause an AbortError to be raised from request().
*/
signal?: AbortSignal;
/**
* A timeout (in milliseconds) for this request. If exceeded, an McpError with code `RequestTimeout` will be raised from request().
*
* If not specified, `DEFAULT_REQUEST_TIMEOUT_MSEC` will be used as the timeout.
*/
timeout?: number;
};
/**
@ -379,7 +391,13 @@ export abstract class Protocol<
};
}
let timeoutId: ReturnType<typeof setTimeout> | undefined = undefined;
this._responseHandlers.set(messageId, (response) => {
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
if (options?.signal?.aborted) {
return;
}
@ -396,8 +414,7 @@ export abstract class Protocol<
}
});
options?.signal?.addEventListener("abort", () => {
const reason = options?.signal?.reason;
const cancel = (reason: unknown) => {
this._responseHandlers.delete(messageId);
this._progressHandlers.delete(messageId);
@ -411,9 +428,34 @@ export abstract class Protocol<
});
reject(reason);
};
options?.signal?.addEventListener("abort", () => {
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
cancel(options?.signal?.reason);
});
this._transport.send(jsonrpcRequest).catch(reject);
const timeout = options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC;
timeoutId = setTimeout(
() =>
cancel(
new McpError(ErrorCode.RequestTimeout, "Request timed out", {
timeout,
}),
),
timeout,
);
this._transport.send(jsonrpcRequest).catch((error) => {
if (timeoutId !== undefined) {
clearTimeout(timeoutId);
}
reject(error);
});
});
}

View file

@ -105,6 +105,7 @@ export const JSONRPCResponseSchema = z
export enum ErrorCode {
// SDK error codes
ConnectionClosed = -1,
RequestTimeout = -2,
// Standard JSON-RPC error codes
ParseError = -32700,