Add proper support for progress flow during tool calling

This commit is contained in:
Pulkit Sharma
2025-04-05 01:46:57 +05:30
parent 06f237b1de
commit e35343537c
11 changed files with 204 additions and 61 deletions

View File

@@ -20,13 +20,13 @@ export type InspectorConfig = {
* Whether to reset the timeout on progress notifications. Useful for long-running operations that send periodic progress updates.
* Refer: https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/utilities/progress/#progress-flow
*/
MCP_SERVER_REQUEST_TIMEOUT_RESET_ON_PROGRESS: ConfigItem;
MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS: ConfigItem;
/**
* Maximum total time in milliseconds to wait for a response from the MCP server before timing out. Used in conjunction with MCP_SERVER_REQUEST_TIMEOUT_RESET_ON_PROGRESS.
* Refer: https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/utilities/progress/#progress-flow
*/
MCP_SERVER_REQUEST_TIMEOUT_MAX_TOTAL_TIMEOUT: ConfigItem;
MCP_REQUEST_MAX_TOTAL_TIMEOUT: ConfigItem;
/**
* The full address of the MCP Proxy Server, in case it is running on a non-default address. Example: http://10.1.1.22:5577

View File

@@ -25,12 +25,13 @@ export const DEFAULT_INSPECTOR_CONFIG: InspectorConfig = {
description: "Timeout for requests to the MCP server (ms)",
value: 10000,
},
MCP_SERVER_REQUEST_TIMEOUT_RESET_ON_PROGRESS: {
MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS: {
description: "Reset timeout on progress notifications",
value: true,
},
MCP_SERVER_REQUEST_TIMEOUT_MAX_TOTAL_TIMEOUT: {
description: "Maximum total timeout for requests sent to the MCP server (ms)",
MCP_REQUEST_MAX_TOTAL_TIMEOUT: {
description:
"Maximum total timeout for requests sent to the MCP server (ms) (Use with progress notifications)",
value: 60000,
},
MCP_PROXY_FULL_ADDRESS: {

View File

@@ -95,11 +95,10 @@ describe("useConnection", () => {
expect.objectContaining({
timeout: DEFAULT_INSPECTOR_CONFIG.MCP_SERVER_REQUEST_TIMEOUT.value,
maxTotalTimeout:
DEFAULT_INSPECTOR_CONFIG
.MCP_SERVER_REQUEST_TIMEOUT_MAX_TOTAL_TIMEOUT.value,
DEFAULT_INSPECTOR_CONFIG.MCP_REQUEST_MAX_TOTAL_TIMEOUT.value,
resetTimeoutOnProgress:
DEFAULT_INSPECTOR_CONFIG
.MCP_SERVER_REQUEST_TIMEOUT_RESET_ON_PROGRESS.value,
DEFAULT_INSPECTOR_CONFIG.MCP_REQUEST_TIMEOUT_RESET_ON_PROGRESS
.value,
}),
);
});

View File

@@ -8,7 +8,6 @@ import {
ClientRequest,
CreateMessageRequestSchema,
ListRootsRequestSchema,
ProgressNotificationSchema,
ResourceUpdatedNotificationSchema,
LoggingMessageNotificationSchema,
Request,
@@ -23,6 +22,7 @@ import {
ResourceListChangedNotificationSchema,
ToolListChangedNotificationSchema,
PromptListChangedNotificationSchema,
Progress,
} from "@modelcontextprotocol/sdk/types.js";
import { RequestOptions } from "@modelcontextprotocol/sdk/shared/protocol.js";
import { useState } from "react";
@@ -99,21 +99,38 @@ export function useConnection({
if (!mcpClient) {
throw new Error("MCP client not connected");
}
try {
const abortController = new AbortController();
// prepare MCP Client request options
const mcpRequestOptions: RequestOptions = {
signal: options?.signal ?? abortController.signal,
resetTimeoutOnProgress:
options?.resetTimeoutOnProgress ??
resetRequestTimeoutOnProgress(config),
timeout: options?.timeout ?? getMCPServerRequestTimeout(config),
maxTotalTimeout:
options?.maxTotalTimeout ??
getMCPServerRequestMaxTotalTimeout(config),
};
// If progress notifications are enabled, add an onprogress hook to the MCP Client request options
// This is required by SDK to reset the timeout on progress notifications
if (mcpRequestOptions.resetTimeoutOnProgress) {
mcpRequestOptions.onprogress = (params: Progress) => {
// Add progress notification to `Server Notification` window in the UI
if (onNotification) {
onNotification({
method: "notification/progress",
params,
});
}
};
}
let response;
try {
response = await mcpClient.request(request, schema, {
signal: options?.signal ?? abortController.signal,
resetTimeoutOnProgress:
options?.resetTimeoutOnProgress ??
resetRequestTimeoutOnProgress(config),
timeout: options?.timeout ?? getMCPServerRequestTimeout(config),
maxTotalTimeout:
options?.maxTotalTimeout ??
getMCPServerRequestMaxTotalTimeout(config),
});
response = await mcpClient.request(request, schema, mcpRequestOptions);
pushHistory(request, response);
} catch (error) {
@@ -291,7 +308,6 @@ export function useConnection({
if (onNotification) {
[
CancelledNotificationSchema,
ProgressNotificationSchema,
LoggingMessageNotificationSchema,
ResourceUpdatedNotificationSchema,
ResourceListChangedNotificationSchema,