Cancel Task
cancel_taskCancel a posted task and receive a full refund if no worker is assigned; pay a cancellation fee if work has started. This action is irreversible.
Instructions
Cancel a previously posted task. Use when the task is no longer needed or was posted in error. If no worker has been assigned, the full budget is refunded. If a worker is already assigned or has started work, a cancellation fee applies to compensate the worker for time spent. The response includes the exact refund amount and any fees. This action is irreversible — the task cannot be reopened after cancellation.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| task_id | Yes | The task ID to cancel | |
| reason | No | Optional reason for cancellation |
Implementation Reference
- src/tools/cancel-task.ts:7-55 (handler)Main handler function that registers the 'cancel_task' tool with the MCP server. Takes task_id (required) and reason (optional, max 500 chars). Calls either the API client's cancelTask method or the mock fallback. Returns refund amount and cancellation fee details.
export function registerCancelTask( server: McpServer, client: ApiClient | null, ): void { server.registerTool( 'cancel_task', { title: 'Cancel Task', description: 'Cancel a previously posted task. Use when the task is no longer needed or was posted in error. ' + 'If no worker has been assigned, the full budget is refunded. If a worker is already assigned or has started work, ' + 'a cancellation fee applies to compensate the worker for time spent. The response includes the exact refund amount and any fees. ' + 'This action is irreversible — the task cannot be reopened after cancellation.', inputSchema: z.object({ task_id: z.string().describe('The task ID to cancel'), reason: z .string() .max(500) .optional() .describe('Optional reason for cancellation'), }), annotations: { readOnlyHint: false, destructiveHint: true }, }, async (args) => { try { const result = client ? await client.cancelTask(args.task_id, args.reason) : mockCancelTask(args.task_id, args.reason); return { content: [ { type: 'text' as const, text: [ result.message, `Refund: $${result.refund_usd.toFixed(2)}`, result.cancellation_fee_usd > 0 ? `Cancellation fee: $${result.cancellation_fee_usd.toFixed(2)}` : 'No cancellation fee.', ].join('\n'), }, ], }; } catch (error) { return toolError(error); } }, ); } - src/types.ts:93-99 (schema)Type definition for the CancelTask response, including task_id, status (always 'cancelled'), refund_usd, cancellation_fee_usd, and a message string.
export interface CancelTaskResponse { task_id: string; status: 'cancelled'; refund_usd: number; cancellation_fee_usd: number; message: string; } - src/server.ts:57-62 (registration)Registration call that wires the cancel_task tool into the MCP server at startup.
registerPostTask(server, client); registerCheckTask(server, client); registerListCapabilities(server, client); registerCancelTask(server, client); registerSendTaskMessage(server, client); registerListTaskMessages(server, client); - src/mock.ts:165-174 (helper)Mock implementation of cancelTask for when no API client is available. Returns a hardcoded $5.00 refund with no fee.
export function mockCancelTask(taskId: string, _reason?: string): CancelTaskResponse { mockTasks.delete(taskId); return { task_id: taskId, status: 'cancelled', refund_usd: 5.0, cancellation_fee_usd: 0, message: `Task ${taskId} cancelled successfully (mock mode).`, }; } - src/api-client.ts:68-74 (helper)API client method that sends a POST request to /v1/tasks/{taskId}/cancel with an optional reason body.
async cancelTask(taskId: string, reason?: string): Promise<CancelTaskResponse> { return this.request<CancelTaskResponse>( 'POST', `/v1/tasks/${encodeURIComponent(taskId)}/cancel`, reason ? { reason } : undefined, ); }