You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/specification/draft/basic/utilities/cancellation.mdx
+9-39Lines changed: 9 additions & 39 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,12 +15,9 @@ indicate that a previously-issued request should be terminated.
15
15
When a party wants to cancel an in-progress request, it sends a `notifications/cancelled`
16
16
notification containing:
17
17
18
-
- For non-task requests: The ID of the request to cancel
19
-
- For task cancellation: The ID of the task to cancel
18
+
- The ID of the request to cancel
20
19
- An optional reason string that can be logged or displayed
21
20
22
-
### Cancelling Non-Task Requests
23
-
24
21
```json
25
22
{
26
23
"jsonrpc": "2.0",
@@ -32,49 +29,23 @@ notification containing:
32
29
}
33
30
```
34
31
35
-
### Cancelling Tasks
36
-
37
-
For task-augmented requests, once the `CreateTaskResult` is returned, the original request is complete and `requestId` becomes ambiguous. Therefore, task cancellation **MUST** use `taskId`:
38
-
39
-
```json
40
-
{
41
-
"jsonrpc": "2.0",
42
-
"method": "notifications/cancelled",
43
-
"params": {
44
-
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
45
-
"reason": "User requested cancellation"
46
-
}
47
-
}
48
-
```
49
-
50
32
## Behavior Requirements
51
33
52
-
### General Requirements
53
-
54
-
1. Cancellation notifications **MUST** only reference requests or tasks that:
34
+
1. Cancellation notifications **MUST** only reference requests that:
55
35
- Were previously issued in the same direction
56
36
- Are believed to still be in-progress
57
37
2. The `initialize` request **MUST NOT** be cancelled by clients
58
38
3. Receivers of cancellation notifications **SHOULD**:
59
-
- Stop processing the cancelled request or task
39
+
- Stop processing the cancelled request
60
40
- Free associated resources
61
-
- For non-task requests: Not send a response for the cancelled request
- Processing has already completed (for non-task requests) or reached a terminal status (for tasks)
66
-
- The request or task cannot be cancelled
43
+
- The referenced request is unknown
44
+
- Processing has already completed
45
+
- The request cannot be cancelled
67
46
5. The sender of the cancellation notification **SHOULD** ignore any response to the
68
47
request that arrives afterward
69
48
70
-
### Task-Specific Requirements
71
-
72
-
1. For task cancellation, `taskId`**MUST** be provided (not `requestId`)
73
-
2.`requestId`**MUST NOT** be used for task cancellation once `CreateTaskResult` has been returned
74
-
3. When a receiver receives a `notifications/cancelled` notification with a `taskId`, it **SHOULD** immediately move the task to `cancelled` status
75
-
4. If a cancellation notification arrives after a task has already reached a terminal status (`completed`, `failed`, or `cancelled`), receivers **SHOULD** ignore the notification
76
-
5. Requestors **SHOULD** poll with `tasks/get` after sending a cancellation notification to confirm the task has transitioned to `cancelled` status
77
-
78
49
## Timing Considerations
79
50
80
51
Due to network latency, cancellation notifications may arrive after request processing
@@ -106,10 +77,9 @@ sequenceDiagram
106
77
107
78
Invalid cancellation notifications **SHOULD** be ignored:
108
79
109
-
- Unknown request IDs or task IDs
110
-
- Already completed requests or tasks in terminal status
80
+
- Unknown request IDs
81
+
- Already completed requests
111
82
- Malformed notifications
112
-
- Using `requestId` for task cancellation (should use `taskId` instead)
113
83
114
84
This maintains the "fire and forget" nature of notifications while allowing for race
Copy file name to clipboardExpand all lines: docs/specification/draft/basic/utilities/tasks.mdx
+70-44Lines changed: 70 additions & 44 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -27,7 +27,7 @@ Servers declare if they support tasks, and if so, which server-side requests can
27
27
"capabilities": {
28
28
"tasks": {
29
29
"list": {},
30
-
"delete": {},
30
+
"cancel": {},
31
31
"requests": {
32
32
"tools": {
33
33
"call": {}
@@ -47,7 +47,7 @@ Clients declare if they support tasks, and if so, which client-side requests can
47
47
"capabilities": {
48
48
"tasks": {
49
49
"list": {},
50
-
"delete": {},
50
+
"cancel": {},
51
51
"requests": {
52
52
"sampling": {
53
53
"createMessage": {}
@@ -73,7 +73,7 @@ The set of capabilities in `capabilities.tasks.requests` is exhaustive. If a req
73
73
74
74
`capabilities.tasks.list` controls if the `tasks/list` operation is supported by the party.
75
75
76
-
`capabilities.tasks.delete` controls if the `tasks/delete` operation is supported by the party.
76
+
`capabilities.tasks.cancel` controls if the `tasks/cancel` operation is supported by the party.
77
77
78
78
### Tool-Level Negotiation
79
79
@@ -314,17 +314,17 @@ To retrieve a list of tasks, requestors send a `tasks/list` request. This operat
314
314
}
315
315
```
316
316
317
-
### Deleting Tasks
317
+
### Cancelling Tasks
318
318
319
-
To explicitly delete a task and its associated results, requestors send a `tasks/delete` request.
319
+
To explicitly cancel a task, requestors send a `tasks/cancel` request. The request can optionally include a `delete` parameter to immediately delete the task and its results after cancellation.
320
320
321
-
**Request:**
321
+
**Request (basic cancellation):**
322
322
323
323
```json
324
324
{
325
325
"jsonrpc": "2.0",
326
326
"id": 6,
327
-
"method": "tasks/delete",
327
+
"method": "tasks/cancel",
328
328
"params": {
329
329
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
330
330
}
@@ -338,6 +338,41 @@ To explicitly delete a task and its associated results, requestors send a `tasks
338
338
"jsonrpc": "2.0",
339
339
"id": 6,
340
340
"result": {
341
+
"status": "cancelled",
342
+
"executionStopped": true,
343
+
"_meta": {
344
+
"modelcontextprotocol.io/related-task": {
345
+
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
346
+
}
347
+
}
348
+
}
349
+
}
350
+
```
351
+
352
+
**Request (cancellation with deletion):**
353
+
354
+
```json
355
+
{
356
+
"jsonrpc": "2.0",
357
+
"id": 7,
358
+
"method": "tasks/cancel",
359
+
"params": {
360
+
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840",
361
+
"delete": true
362
+
}
363
+
}
364
+
```
365
+
366
+
**Response:**
367
+
368
+
```json
369
+
{
370
+
"jsonrpc": "2.0",
371
+
"id": 7,
372
+
"result": {
373
+
"status": "cancelled",
374
+
"executionStopped": true,
375
+
"deleted": true,
341
376
"_meta": {
342
377
"modelcontextprotocol.io/related-task": {
343
378
"taskId": "786512e2-9e0d-44bd-8f29-789f320fe840"
@@ -417,37 +452,27 @@ stateDiagram-v2
417
452
418
453
1. All requests, notifications, and responses related to a task **MUST** include the `modelcontextprotocol.io/related-task` key in their `_meta`, with the value set to an object with a `taskId` matching the associated task ID.
419
454
1. For example, an elicitation that a task-augmented tool call depends on **MUST** share the same related task ID with that tool call's task.
420
-
1. For the `tasks/get`, `tasks/list`, `tasks/result`, and `tasks/delete` operations, the `taskId` parameter in the request **MUST** be used as the source of truth for identifying the target task. Requestors **SHOULD NOT** include `modelcontextprotocol.io/related-task` metadata in these requests, and receivers **MUST** ignore such metadata if present in favor of the RPC method parameter.
455
+
1. For the `tasks/get`, `tasks/list`, `tasks/result`, and `tasks/cancel` operations, the `taskId` parameter in the request **MUST** be used as the source of truth for identifying the target task. Requestors **SHOULD NOT** include `modelcontextprotocol.io/related-task` metadata in these requests, and receivers **MUST** ignore such metadata if present in favor of the RPC method parameter.
421
456
422
457
### Task Progress Notifications
423
458
424
459
Task-augmented requests support progress notifications as defined in the progress notification specification. The `progressToken` provided in the initial request remains valid throughout the task's lifetime.
425
460
426
-
### Task Cancellation
427
-
428
-
1. Requestors **MAY** send `notifications/cancelled` at any time during task execution.
429
-
1. For task cancellation, the `notifications/cancelled` notification **MUST** include a `taskId` field:
430
-
1. The `taskId`**MUST** correspond to a task previously created in the same direction.
431
-
1. Once a task-augmented request returns `CreateTaskResult`, the original request is complete and `requestId` becomes ambiguous. Therefore, `requestId`**MUST NOT** be used for task cancellation.
432
-
1. When a receiver receives a `notifications/cancelled` notification with a `taskId`, the receiver **SHOULD** immediately move the task to the `cancelled` status and cease all processing associated with that task.
433
-
1. Due to the asynchronous nature of notifications, receivers **MAY** not cancel task processing instantaneously. Receivers **SHOULD** make a best-effort attempt to halt execution as quickly as possible.
434
-
1. If a `notifications/cancelled` notification arrives after a task has already reached a terminal status (`completed`, `failed`, or `cancelled`), receivers **SHOULD** ignore the notification.
435
-
1. After a task reaches `cancelled` status and its `keepAlive` duration has elapsed, receivers **MAY** delete the task and its metadata.
436
-
1. Because notifications do not provide confirmation of receipt, requestors **SHOULD** continue to poll with `tasks/get` after sending a cancellation notification to confirm the task has transitioned to `cancelled` status. If the task does not transition to `cancelled` within a reasonable timeframe, requestors **MAY** assume the cancellation was not processed.
437
-
438
461
### Task Listing
439
462
440
463
1. Receivers **SHOULD** use cursor-based pagination to limit the number of tasks returned in a single response.
441
464
1. Receivers **MUST** include a `nextCursor` in the response if more tasks are available.
442
465
1. Requestors **MUST** treat cursors as opaque tokens and not attempt to parse or modify them.
443
466
1. If a task is retrievable via `tasks/get` for a requestor, it **MUST** be retrievable via `tasks/list` for that requestor.
444
467
445
-
### Task Deletion
468
+
### Task Cancellation
446
469
447
-
1. Receivers **MAY** accept or reject delete requests for any task at their discretion.
448
-
1. If a receiver accepts a delete request, it **SHOULD** delete the task and all associated results and metadata.
449
-
1. Receivers **MAY** choose not to support deletion at all, or only support deletion for tasks in certain statuses (e.g., only terminal statuses).
450
-
1. Requestors **SHOULD** delete tasks containing sensitive data promptly rather than relying solely on `keepAlive` expiration for cleanup.
470
+
1. Receivers **MUST** reject cancellation requests for tasks already in a terminal status (`completed`, `failed`, or `cancelled`) with error code `-32602` (Invalid params).
471
+
1. Upon receiving a valid cancellation request, receivers **SHOULD** attempt to stop the task's execution (best effort) and **MUST** transition the task to `cancelled` status before sending the response.
472
+
1. Once a task is cancelled, it **MUST** remain in `cancelled` status even if execution continues to completion or fails.
473
+
1. If the `delete` parameter is `true`, receivers **SHOULD** delete the task and all associated results and metadata after transitioning to `cancelled` status. Receivers **MAY** choose not to support deletion and ignore this parameter.
474
+
1. If the `delete` parameter is `false` or omitted, receivers **MUST** retain the task in `cancelled` status subject to the `keepAlive` duration.
475
+
1. Requestors **SHOULD** use the `delete` parameter to clean up tasks containing sensitive data promptly rather than relying solely on `keepAlive` expiration.
"message": "Task deletion not supported for tasks in 'working' status"
798
+
"code": -32602,
799
+
"message": "Cannot cancel task: already in terminal status 'completed'"
774
800
}
775
801
}
776
802
```
@@ -808,20 +834,20 @@ The `tasks/result` endpoint returns exactly what the underlying request would ha
808
834
1. Receivers **SHOULD** scope task IDs to prevent unauthorized access:
809
835
1. Bind tasks to the session that created them (if sessions are supported)
810
836
1. Bind tasks to the authentication context (if authentication is used)
811
-
1. Reject `tasks/get`, `tasks/list`, `tasks/result`, or `tasks/delete` requests for tasks from different sessions or auth contexts
837
+
1. Reject `tasks/get`, `tasks/list`, `tasks/result`, or `tasks/cancel` requests for tasks from different sessions or auth contexts
812
838
1. Receivers that do not implement session or authentication binding **SHOULD** document this limitation clearly, as task results may be accessible to any requestor that can guess the task ID.
813
839
1. Receivers **SHOULD** implement rate limiting on:
814
840
1. Task creation to prevent resource exhaustion
815
841
1. Task status polling to prevent denial of service
816
842
1. Task result retrieval attempts
817
843
1. Task listing requests to prevent denial of service
818
-
1. Task deletion requests to prevent abuse
844
+
1. Task cancellation requests to prevent abuse
819
845
820
846
### Resource Management
821
847
822
848
<Warning>
823
849
824
-
Task results may persist longer than the original request execution time. For sensitive operations, requestors should carefully consider the security implications of extended result retention and may want to retrieve results promptly and request shorter `keepAlive` durations. Requestors are encouraged to use `tasks/delete` to explicitly clean up tasks containing sensitive data rather than relying solely on `keepAlive` expiration.
850
+
Task results may persist longer than the original request execution time. For sensitive operations, requestors should carefully consider the security implications of extended result retention and may want to retrieve results promptly and request shorter `keepAlive` durations. Requestors are encouraged to use `tasks/cancel` with the `delete` parameter set to `true` to explicitly clean up tasks containing sensitive data rather than relying solely on `keepAlive` expiration.
0 commit comments