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
Adapt the Tasks extension to main after rebasing onto the released 2026-07-28 line
The 15-commit branch rebased onto latest main with four textual conflicts
(extension.py + mcpserver/server.py, the everything-server, client/__init__.py,
whats-new.md), all resolved to main's structure plus the branch's additions.
This commit carries the semantic adaptations that the merge could not surface:
- Gate task augmentation on the declared-capabilities fact, not clientInfo.
Main made clientInfo optional on the 2026-07-28 wire (spec #3002) and split
`session.client_capabilities` from `session.client_params`, so a conformant
client can declare the extension while `client_params` is None. The
interceptor's `_client_declared_tasks` now reads `client_capabilities`,
matching main's rewritten `require_client_extension` (whose main body the
relocated function carries). A pair-only declaring envelope is augmented.
- Interceptors now run at the handler layer (`compose_tool_call_handler`), so
`call_next` returns the wrapped handler's domain result rather than a
serialized dict, and every modern-era result envelope carries the
`serverInfo` `_meta` identity stamp. The stored/inlined tool result stays
the un-enveloped payload. Reword `_wire_payload` and the error-fold comment
accordingly, and have the tests assert-and-strip the envelope stamp through
strict helpers mirroring tests/_stamp.py instead of hard-coding it into
every snapshot. A short-circuited `input_required` interim is now sieved to
the core shape like any handler result, so its fixture is core-shaped.
- Declare `name_param = "taskId"` on GetTaskRequest/CancelTaskRequest/
UpdateTaskRequest: main added `Request.name_param` as the per-request key a
client mirrors into the `Mcp-Name` header, built expressly for the tasks
verbs (its placeholder test models `tasks/get`). The server-side
NAME_BEARING_METHODS rows remain the source of the spec-mandated validation.
- Follow main's spelling and toolchain moves: httpx -> httpx2 in the tasks
server tests, `mcp.types` (not `mcp_types`) in docs/example imports with the
matching `hl_lines` shift, and the GitHub form for SEP-2663 links.
- Refresh prose that the merge left stale: the migration guide's "Detached
work" note now points at the extension for the fetch-later half, and the
tasks story's docstring states the fixed-contract invariant rather than
claiming identity with a task-less server's stamped result.
Tasks ([SEP-1686](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1686)) have been removed from the MCP specification and are no longer part of this SDK. The `mcp.client.experimental`, `mcp.server.experimental`, `mcp.shared.experimental`, and `mcp.server.lowlevel.experimental` modules have been removed, along with the `experimental` properties on `ClientSession`, `ServerSession`, `Server`, and `ServerRequestContext`. The corresponding `Task*` types remain in `mcp.types` as types-only definitions, except the `TaskExecutionMode` alias, whose literal is now inlined on `ToolExecution.task_support`.
2012
2012
2013
-
Tasks have since returned as the built-in `Tasks` extension ([SEP-2663](https://modelcontextprotocol.io/seps/2663-tasks-extension.md)), with a different wire shape than the experimental SEP-1686 surface. See [Extensions](advanced/extensions.md) and [Tasks](advanced/tasks.md) for the new design.
2013
+
Tasks have since returned as the built-in `Tasks` extension ([SEP-2663](https://github.com/modelcontextprotocol/modelcontextprotocol/pull/2663)), with a different wire shape than the experimental SEP-1686 surface. See [Extensions](advanced/extensions.md) and [Tasks](advanced/tasks.md) for the new design.
2014
2014
2015
2015
There is no drop-in replacement for the tasks runtime (`server.experimental.enable_tasks()`, `ctx.experimental.run_task()`, `ServerTaskContext`, and the client's `session.experimental.call_tool_as_task()` / `poll_task()` / `get_task_result()`); the port depends on what the code used tasks for.
2016
2016
@@ -2052,7 +2052,7 @@ result = await client.call_tool("long_running_task", {}, progress_callback=on_pr
2052
2052
2053
2053
**Gathering user input mid-work** (`task.elicit()`, `task.create_message()`). Don't port these to inline `ctx.elicit()` / `ctx.session.create_message()` calls: those are server-initiated requests, refused with `NoBackChannelError` on 2026-07-28 connections (the default for an in-process `Client(server)`). Use the resolver dependencies (`Elicit`, `Sample`) or return an `InputRequiredResult` — both work on every protocol version, and `Client.call_tool()` retries the `InputRequiredResult` rounds automatically; see [Multi-round-trip requests](handlers/multi-round-trip.md) and [Server-initiated sampling, elicitation, and roots raise `NoBackChannelError`](#server-initiated-sampling-elicitation-and-roots-raise-nobackchannelerror). The client's existing `elicitation_callback` / `sampling_callback` serve both eras.
2054
2054
2055
-
**Detached work** (create the task now, fetch its result on a later connection or after a client restart) has no v2 equivalent until the SEP-2663 extension is implemented.
2055
+
**Detached work** (create the task now, fetch its result on a later connection or after a client restart): the built-in [Tasks](advanced/tasks.md) extension covers the fetch-later half for clients that declare `io.modelcontextprotocol/tasks` on a 2026-07-28 connection — an augmented `tools/call` returns a `CreateTaskResult`, and a later declaring connection holding the task id polls `tasks/get` (or calls `wait_task(session, task_id)` from `mcp.client.tasks`) to collect the outcome, which is retained per the task's `ttlMs` (with no TTL configured, for the store's lifetime). Two caveats: the default store is in-memory and per-process, so surviving a *server* restart or spanning workers needs a custom `Tasks(store=...)`; and the tool still runs inline inside the original `tools/call`, so there is no create-now, compute-in-the-background equivalent of the v1 task runtime yet.
2056
2056
2057
2057
Also drop `execution=ToolExecution(taskSupport=types.TASK_REQUIRED)` from tool definitions: the `TASK_REQUIRED` / `TASK_OPTIONAL` / `TASK_FORBIDDEN` constants are gone from `mcp.types` (`ToolExecution.task_support` takes the plain `"required"` / `"optional"` / `"forbidden"` literal), and no v2 client or server reads the field.
0 commit comments