From 2a3295e6a91d8582069352c578d8e27f42e5c0d5 Mon Sep 17 00:00:00 2001 From: Dayna Blackwell Date: Mon, 4 May 2026 21:40:04 -0700 Subject: [PATCH 1/3] fix: check AbortSignal in handleAutomaticTaskPolling to stop cancelled requests The while loop in handleAutomaticTaskPolling polls indefinitely without checking ctx.mcpReq.signal.aborted. If a client cancels the request, the poll loop continues consuming server resources. The taskManager.ts implementation of the same pattern correctly checks signal.aborted (line 856). This brings handleAutomaticTaskPolling in line with that behavior. Fixes #2018 --- packages/server/src/server/mcp.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/server/src/server/mcp.ts b/packages/server/src/server/mcp.ts index fb45fd5db..19424fcbe 100644 --- a/packages/server/src/server/mcp.ts +++ b/packages/server/src/server/mcp.ts @@ -326,6 +326,9 @@ export class McpServer { const pollInterval = task.pollInterval ?? 5000; while (task.status !== 'completed' && task.status !== 'failed' && task.status !== 'cancelled') { + if (ctx.mcpReq.signal.aborted) { + throw new ProtocolError(ProtocolErrorCode.RequestCancelled, 'Request cancelled during task polling'); + } await new Promise(resolve => setTimeout(resolve, pollInterval)); const updatedTask = await ctx.task.store.getTask(taskId); if (!updatedTask) { From f6fb31d35255521fbc47f5f12bf3517f00f3be07 Mon Sep 17 00:00:00 2001 From: Dayna Blackwell Date: Mon, 4 May 2026 21:41:55 -0700 Subject: [PATCH 2/3] add changeset for patch release --- .changeset/fix-automatic-task-polling-abort.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/fix-automatic-task-polling-abort.md diff --git a/.changeset/fix-automatic-task-polling-abort.md b/.changeset/fix-automatic-task-polling-abort.md new file mode 100644 index 000000000..f83440fa8 --- /dev/null +++ b/.changeset/fix-automatic-task-polling-abort.md @@ -0,0 +1,5 @@ +--- +'@modelcontextprotocol/server': patch +--- + +Check AbortSignal in handleAutomaticTaskPolling to stop cancelled requests from polling indefinitely. Previously, if a client cancelled a tools/call request during automatic task polling, the poll loop continued consuming server resources until the task completed or the process died. From d1df061afdea1f6070adc07f7b07e387e1c6d025 Mon Sep 17 00:00:00 2001 From: Dayna Blackwell Date: Mon, 4 May 2026 21:46:05 -0700 Subject: [PATCH 3/3] fix: use InternalError code (RequestCancelled does not exist in enum) --- packages/server/src/server/mcp.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/server/src/server/mcp.ts b/packages/server/src/server/mcp.ts index 19424fcbe..7cf62ed77 100644 --- a/packages/server/src/server/mcp.ts +++ b/packages/server/src/server/mcp.ts @@ -327,7 +327,7 @@ export class McpServer { while (task.status !== 'completed' && task.status !== 'failed' && task.status !== 'cancelled') { if (ctx.mcpReq.signal.aborted) { - throw new ProtocolError(ProtocolErrorCode.RequestCancelled, 'Request cancelled during task polling'); + throw new ProtocolError(ProtocolErrorCode.InternalError, 'Request cancelled during task polling'); } await new Promise(resolve => setTimeout(resolve, pollInterval)); const updatedTask = await ctx.task.store.getTask(taskId);