The tasks extension (io.modelcontextprotocol/tasks) of the MCP protocol version 2026-07-28 lets a server run a long tools/call in the background. Instead of the tool result, the server returns a task handle, and the client asks for the task status until the task finishes. The methods of this topic raise an exception in the legacy era.
Set MCPOptions.Tasks.Enabled to True. The client then declares the extension in _meta.clientCapabilities of every request, and the server decides for each tools/call whether it runs as a task.
| Property | Description |
|---|---|
| Enabled | Declares the tasks extension. Default False. |
| AutoPoll | When True, a background thread polls tasks/get until the task reaches a terminal status. Default True. |
tools/call returns resultType task, OnMCPTaskCreated is raised first. Then OnMCPResponseTool is raised as usual, with the raw task handle JSON in aResponse.TaskResult.tasks/get every pollIntervalMs milliseconds (1000 when the server sends none). OnMCPTaskStatus is raised every time the status, the status message or the requested inputs change.completed, failed or cancelled, OnMCPTaskCompleted is raised and polling stops. Read the tool result from aTask.Result or the error from aTask.Error.input_required, the inputs are answered like a Multi Round-Trip Request (legacy handlers first, then OnMCPInputRequired with aMethod tasks/update) and sent with tasks/update.
| Property | Description |
|---|---|
| TaskId | Id of the task assigned by the server. |
| ToolName | Name of the tool that created the task. |
| Status | aimcptskWorking, aimcptskInputRequired, aimcptskCompleted, aimcptskFailed or aimcptskCancelled. |
| StatusMessage | Optional message sent by the server with the status. |
| CreatedAt, LastUpdatedAt | ISO 8601 timestamps sent by the server. |
| TTLMs | Time to live in milliseconds, -1 when unlimited. |
| PollIntervalMs | Poll interval suggested by the server. |
| Result | Tool result as raw JSON when the task is completed. |
| Error | Error as raw JSON when the task failed. |
| InputRequests | Inputs requested by the server as raw JSON. |
| Text | Raw JSON of the last task message. |
| IsTerminal | True when the status is completed, failed or cancelled. |
The events raised by the poller (OnMCPTaskStatus and OnMCPTaskCompleted) run in the background thread of the task. Use TThread.Queue or TThread.Synchronize to update visual controls. Pollers are stopped when Initialize is called again and when the component is destroyed.
The server side is described in MCP Server | Tasks.
procedure TForm1.RunLongJob;
begin
MCP.MCPOptions.Tasks.Enabled := True;
MCP.MCPOptions.Tasks.AutoPoll := True;
MCP.OnMCPTaskCreated := MCPTaskCreated;
MCP.OnMCPTaskStatus := MCPTaskStatus;
MCP.OnMCPTaskCompleted := MCPTaskCompleted;
MCP.RequestTool('long_job');
end;
procedure TForm1.MCPTaskCreated(Sender: TObject;
const aTask: TsgcAI_MCP_Client_Task);
begin
FTaskId := aTask.TaskId;
end;
procedure TForm1.MCPTaskStatus(Sender: TObject;
const aTask: TsgcAI_MCP_Client_Task);
begin
Log(aTask.TaskId + ': ' + aTask.StatusMessage);
end;
procedure TForm1.MCPTaskCompleted(Sender: TObject;
const aTask: TsgcAI_MCP_Client_Task);
begin
if aTask.Status = aimcptskCompleted then
Log('result: ' + aTask.Result)
else
Log('finished without result: ' + aTask.Error);
end;
procedure TForm1.CancelJob;
begin
MCP.TasksCancel(FTaskId);
end;