Skip to content

Commit cb2c456

Browse files
committed
Drop the Tasks extension; defer to a SEP-2663 rewrite
The Tasks implementation was built against the 2025-11-25 in-core design still carried (types-only) in mcp_types, not SEP-2663 (the extension that ships in 2026-07-28). They diverge on nearly every wire-observable detail: SEP-2663 makes the server the sole decider (ignoring the legacy params.task), uses the {tasks/get, tasks/update, tasks/cancel} method set (no tasks/list or tasks/result), returns a CreateTaskResult discriminated by resultType: "task" (not a CallToolResult with _meta), advertises {} settings, gates on execution.taskSupport, and renames ttl/pollInterval to ttlMs/pollIntervalMs. Remove the extension, its tests, and its story rather than ship a spec-violating example; restore tasks to the deferred manifest list with a SEP-2663 pointer. The generic Extension API and the Apps reference extension are unaffected and still at 100% coverage. Tasks returns as a separate PR rewritten to SEP-2663 with the conformance tasks-* scenarios wired in.
1 parent aa78671 commit cb2c456

9 files changed

Lines changed: 20 additions & 629 deletions

File tree

docs/migration.md

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -419,18 +419,13 @@ construction:
419419
```python
420420
from mcp.server.mcpserver import MCPServer
421421
from mcp.server.apps import Apps
422-
from mcp.server.tasks import Tasks
423422

424-
mcp = MCPServer("demo", extensions=[Apps(), Tasks()])
423+
mcp = MCPServer("demo", extensions=[Apps()])
425424
```
426425

427-
Two reference extensions ship in their own modules:
428-
429-
- `mcp.server.apps.Apps` (`io.modelcontextprotocol/ui`) — binds a tool to a
430-
`ui://` UI resource via `_meta.ui.resourceUri`; `client_supports_apps(ctx)`
431-
gates the SEP-2133 text-only fallback.
432-
- `mcp.server.tasks.Tasks` (`io.modelcontextprotocol/tasks`) — intercepts
433-
task-augmented `tools/call` and serves the `tasks/*` methods.
426+
The reference extension is `mcp.server.apps.Apps` (`io.modelcontextprotocol/ui`):
427+
it binds a tool to a `ui://` UI resource via `_meta.ui.resourceUri`, and
428+
`client_supports_apps(ctx)` gates the SEP-2133 text-only fallback.
434429

435430
Clients advertise extension support with the new `Client(extensions=...)` /
436431
`ClientSession(extensions=...)` argument, mirrored into `ClientCapabilities.extensions`.

examples/stories/apps/README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,4 @@ uv run python -m stories.apps.client --http
3737

3838
## See also
3939

40-
`tasks/` (the interceptive half of the extension API),
4140
`custom_methods/` (registering a non-spec method without an extension).

examples/stories/manifest.toml

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,6 @@ lowlevel = false
5656
transports = ["in-memory", "http-asgi"]
5757
era = "dual-in-body"
5858

59-
[story.tasks]
60-
# Interceptive extension; the tasks/* methods drop to client.session like custom_methods.
61-
# extensions ride server/discover (modern-only), so the connection is pinned to "auto".
62-
lowlevel = false
63-
transports = ["in-memory", "http-asgi"]
64-
era = "dual-in-body"
65-
6659
[story.schema_validators]
6760

6861
[story.middleware]
@@ -157,5 +150,6 @@ fixed_port = 8000 # issuer/PRM metadata bake in :8
157150
[deferred]
158151
caching = "client honouring + per-result override unlanded"
159152
subscriptions = "#2901 — Client.listen / ServerEventBus"
153+
tasks = "SEP-2663 — tasks extension runtime (server-decided augmentation, CreateTaskResult)"
160154
skills = "#2896 — SEP-2640"
161155
events = "#2901 + #2896"

examples/stories/tasks/README.md

Lines changed: 15 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,24 @@
11
# tasks
22

3-
Task-augmented tool execution. A client sends `tools/call` with a `task` field;
4-
the server records the call under a task id and the client polls `tasks/get` /
5-
`tasks/result`. This is the *interceptive* half of the extension API — the
6-
`Tasks` extension (`io.modelcontextprotocol/tasks`) wraps `tools/call` rather
7-
than only adding tools.
8-
9-
## Run it
10-
11-
```bash
12-
# stdio (default — the client spawns the server as a subprocess)
13-
uv run python -m stories.tasks.client
14-
15-
# HTTP — the client self-hosts the server on a free port, runs, then tears it down
16-
uv run python -m stories.tasks.client --http
17-
```
18-
19-
## What to look at
20-
21-
- `server.py` `MCPServer("tasks-example", extensions=[Tasks()])` — opt in at
22-
construction. The extension advertises `io.modelcontextprotocol/tasks` and
23-
serves `tasks/get`, `tasks/result`, `tasks/cancel`, and `tasks/list`. The
24-
`render_report` tool is the kind of slower, multi-step work a caller would
25-
rather run as a task than block on.
26-
- `mcp.server.tasks.Tasks.intercept_tool_call` — the interceptive seam: a plain
27-
call passes through; a call with a `task` field is recorded and returned with
28-
the task id in `_meta["io.modelcontextprotocol/related-task"]`.
29-
- `client.py` `main` — start the call as a task, read its `tasks/get` status,
30-
then fetch the payload with `tasks/result`. The `task` field and `tasks/*`
31-
methods are outside the spec verbs `Client` exposes, so the thin
32-
`_start_task` / `_get_task` / `_task_result` helpers wrap `client.session`.
33-
34-
## Caveats
35-
36-
This is a reference implementation for the extension API, not a production task
37-
runtime. A plain `tools/call` (no `task` field) is unchanged — only a call the
38-
client explicitly augments with a `task` field becomes a task. Three deliberate
39-
simplifications:
40-
41-
- The tool runs to completion inline, so a task is observed as `completed`
42-
immediately (no detached/background execution, no TTL eviction).
43-
- The augmented call returns a normal `CallToolResult` with the task id in
44-
`_meta` rather than the spec's `CreateTaskResult` — the `tools/call` result
45-
schema admits only `CallToolResult | InputRequiredResult` (see `TODO(L56)` in
46-
`mcp.server.runner`), so returning `CreateTaskResult` would require extending
47-
the methods-layer validation maps. The lifecycle runs through the dedicated
48-
`tasks/*` methods instead.
49-
- Any tool may be task-augmented on request; per-tool gating on the declared
50-
`ToolExecution.task_support` (`forbidden`/`optional`/`required`) is not enforced.
3+
Task-augmented execution: a requestor augments a `tools/call` with a `task`, the
4+
receiver returns a `CreateTaskResult` immediately, and the requestor polls
5+
`tasks/get` and retrieves the deferred result.
6+
7+
**Status: deferred.** Tasks ship in 2026-07-28 as
8+
[SEP-2663](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/seps/2663-tasks-extension.md),
9+
an `io.modelcontextprotocol/tasks` extension that is wire-incompatible with the
10+
2025-11-25 in-core design still carried (types-only) in `mcp_types`. The runtime
11+
needs to be built to the SEP — server-decided augmentation (ignoring the legacy
12+
`params.task`), the `{tasks/get, tasks/update, tasks/cancel}` method set, the
13+
`resultType: "task"` envelope, `execution.taskSupport` gating, and `ttlMs`
14+
fields — so it lands in a separate PR with the conformance `tasks-*` scenarios
15+
wired in.
5116

5217
## Spec
5318

54-
[Tasksextensions](https://modelcontextprotocol.io/specification/draft/extensions)
19+
[SEP-2663Tasks extension](https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/docs/seps/2663-tasks-extension.md)
5520
· [SEP-2133 — extensions capability](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/2133)
5621

5722
## See also
5823

59-
`apps/` (the additive half of the extension API),
60-
`custom_methods/` (a non-spec method without an extension),
61-
`middleware/` (the low-level `tools/call` wrapping the interceptor builds on).
24+
`apps/` (the additive half of the extension API).

examples/stories/tasks/__init__.py

Whitespace-only changes.

examples/stories/tasks/client.py

Lines changed: 0 additions & 56 deletions
This file was deleted.

examples/stories/tasks/server.py

Lines changed: 0 additions & 28 deletions
This file was deleted.

0 commit comments

Comments
 (0)