Skip to content

Commit 32ad855

Browse files
fix: fix auto-poll task store access and sendRequest wrapping
- Fix handleAutomaticTaskPolling to create task store from server.tasks when extra.task is not set (auto-poll creates tasks internally) - Fix sendRequest wrapping to activate on taskContext (not just relatedTaskId) so task creation handlers can properly set input_required status Integration: 482/487 pass (5 failures in HTTP message queuing delivery).
1 parent 26cdc6d commit 32ad855

File tree

2 files changed

+22
-7
lines changed

2 files changed

+22
-7
lines changed

packages/core/src/shared/protocol.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -509,13 +509,14 @@ export abstract class Protocol<SendRequestT extends Request, SendNotificationT e
509509
}
510510

511511
// Build sendRequest closure, potentially wrapped with task metadata
512+
// Wrap when there's a task context (either relatedTaskId or task creation params)
512513
let sendRequest = async <U extends AnySchema>(r: SendRequestT, resultSchema: U, options?: RequestOptions) => {
513514
return await this.request(r, resultSchema, { ...options, relatedRequestId: request.id });
514515
};
515-
if (relatedTaskId && this._taskManager) {
516-
const taskStore = taskInfo?.taskContext?.taskStore;
516+
if (taskInfo?.taskContext && this._taskManager) {
517+
const taskStore = taskInfo.taskContext.taskStore;
517518
sendRequest = this._taskManager.wrapSendRequest(
518-
relatedTaskId,
519+
relatedTaskId ?? '',
519520
taskStore,
520521
(r: SendRequestT, resultSchema: AnySchema, options?: RequestOptions) =>
521522
this.request(r, resultSchema, { ...options, relatedRequestId: request.id })

packages/server/src/server/mcp.ts

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import type {
99
CompleteResult,
1010
CreateTaskRequestHandlerExtra,
1111
CreateTaskResult,
12+
JSONRPCRequest,
1213
GetPromptResult,
1314
Implementation,
1415
ListPromptsResult,
@@ -366,14 +367,27 @@ export class McpServer {
366367
request: RequestT,
367368
extra: RequestHandlerExtra<ServerRequest, ServerNotification>
368369
): Promise<CallToolResult> {
369-
if (!extra.task?.taskStore) {
370+
// For automatic polling, we need a task store. Use the one from extra.task if available,
371+
// otherwise create one from the server's TaskManager (auto-poll creates tasks internally).
372+
const taskStore = extra.task?.taskStore ?? this.server.tasks?.createRequestTaskStore(
373+
{ jsonrpc: '2.0', id: extra.requestId, method: request.method, params: request.params } as JSONRPCRequest,
374+
extra.sessionId
375+
);
376+
if (!taskStore) {
370377
throw new Error('No task store provided for task-capable tool.');
371378
}
372379

380+
// Build a task context for the handler
381+
const taskContext: CreateTaskRequestHandlerExtra['task'] = extra.task ?? {
382+
taskId: '',
383+
taskStore,
384+
requestedTtl: undefined
385+
};
386+
const taskExtra = { ...extra, task: taskContext } as CreateTaskRequestHandlerExtra;
387+
373388
// Validate input and create task
374389
const args = await this.validateToolInput(tool, request.params.arguments, request.params.name);
375390
const handler = tool.handler as ToolTaskHandler<ZodRawShapeCompat | undefined>;
376-
const taskExtra = { ...extra, task: extra.task } as CreateTaskRequestHandlerExtra;
377391

378392
const createTaskResult: CreateTaskResult = args // undefined only if tool.inputSchema is undefined
379393
? await Promise.resolve((handler as ToolTaskHandler<ZodRawShapeCompat>).createTask(args, taskExtra))
@@ -387,15 +401,15 @@ export class McpServer {
387401

388402
while (task.status !== 'completed' && task.status !== 'failed' && task.status !== 'cancelled') {
389403
await new Promise(resolve => setTimeout(resolve, pollInterval));
390-
const updatedTask = await extra.task.taskStore.getTask(taskId);
404+
const updatedTask = await taskStore.getTask(taskId);
391405
if (!updatedTask) {
392406
throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
393407
}
394408
task = updatedTask;
395409
}
396410

397411
// Return the final result
398-
return (await extra.task.taskStore.getTaskResult(taskId)) as CallToolResult;
412+
return (await taskStore.getTaskResult(taskId)) as CallToolResult;
399413
}
400414

401415
private _completionHandlerInitialized = false;

0 commit comments

Comments
 (0)