Skip to content

Commit 54bbe7b

Browse files
[SEP-2663] refactor!: remove 2025-11 experimental tasks (impl + references)
Removes the 2025-11 experimental tasks side-channel through Protocol: TaskManager, processInbound*/processOutbound*, task interception, the experimental.tasks.* client/server accessors, and all task-augmented request handling. Also extends beyond the implementation deletion to scrub remaining references in examples, docs, and comments. The only task-related symbol remaining in packages/*.ts is `taskSupport` in ToolExecutionSchema, kept solely to match spec.types.ts (which still declares it); both are removed together in the next commit (spec regen). CHANGELOG entries are preserved (historical record). Migration docs retain a brief removal note. `microtask`/`platformBackgroundTask` are JS/platform terminology, not MCP tasks. Satisfies: SEP-2663 (core-removal half; tasks are now Extensions Track).
1 parent 22595b9 commit 54bbe7b

58 files changed

Lines changed: 238 additions & 17335 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CLAUDE.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,9 +104,7 @@ The repo also ships “middleware” packages under `packages/middleware/` (e.g.
104104

105105
### Experimental Features
106106

107-
Located in `packages/*/src/experimental/`:
108-
109-
- **Tasks**: Long-running task support with polling/resumption (`packages/core/src/experimental/tasks/`)
107+
Located in `packages/*/src/experimental/`. Currently empty.
110108

111109
### Zod Schemas
112110

@@ -201,7 +199,6 @@ The `ctx` parameter in handlers provides a structured context:
201199
- `notify(notification)`: Send related notification back
202200
- `http?`: HTTP transport info (undefined for stdio)
203201
- `authInfo?`: Validated auth token info
204-
- `task?`: Task context (`{ id?, store, requestedTtl? }`) when task storage is configured
205202

206203
**`ServerContext`** extends `BaseContext.mcpReq` and `BaseContext.http?` via type intersection:
207204

docs/client.md

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -544,7 +544,7 @@ All requests have a 60-second default timeout. Pass a custom `timeout` in the op
544544
```ts source="../examples/client/src/clientGuide.examples.ts#errorHandling_timeout"
545545
try {
546546
const result = await client.callTool(
547-
{ name: 'slow-task', arguments: {} },
547+
{ name: 'slow-operation', arguments: {} },
548548
{ timeout: 120_000 } // 2 minutes instead of the default 60 seconds
549549
);
550550
console.log(result.content);
@@ -581,7 +581,7 @@ let lastToken: string | undefined;
581581
const result = await client.request(
582582
{
583583
method: 'tools/call',
584-
params: { name: 'long-running-task', arguments: {} }
584+
params: { name: 'long-running-operation', arguments: {} }
585585
},
586586
{
587587
resumptionToken: lastToken,
@@ -596,18 +596,6 @@ console.log(result);
596596

597597
For an end-to-end example of server-initiated SSE disconnection and automatic client reconnection with event replay, see [`ssePollingClient.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/client/src/ssePollingClient.ts).
598598

599-
## Tasks (experimental)
600-
601-
> [!WARNING]
602-
> The tasks API is experimental and may change without notice.
603-
604-
Task-based execution enables "call-now, fetch-later" patterns for long-running operations (see [Tasks](https://modelcontextprotocol.io/specification/latest/basic/utilities/tasks) in the MCP specification). Instead of returning a result immediately, a tool creates a task that can be polled or resumed later. To use tasks:
605-
606-
- Call {@linkcode @modelcontextprotocol/client!experimental/tasks/client.ExperimentalClientTasks#callToolStream | client.experimental.tasks.callToolStream(...)} to start a tool call that may create a task and emit status updates over time.
607-
- Call {@linkcode @modelcontextprotocol/client!experimental/tasks/client.ExperimentalClientTasks#getTask | client.experimental.tasks.getTask(...)} and {@linkcode @modelcontextprotocol/client!experimental/tasks/client.ExperimentalClientTasks#getTaskResult | getTaskResult(...)} to check status and fetch results after reconnecting.
608-
609-
For a full runnable example, see [`simpleTaskInteractiveClient.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/client/src/simpleTaskInteractiveClient.ts).
610-
611599
## See also
612600

613601
- [`examples/client/`](https://github.com/modelcontextprotocol/typescript-sdk/tree/main/examples/client) — Full runnable client examples

docs/migration-SKILL.md

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -420,9 +420,7 @@ Request/notification params remain fully typed. Remove unused schema imports aft
420420
| `extra.requestInfo` | `ctx.http?.req` (standard Web `Request`, only `ServerContext`) |
421421
| `extra.closeSSEStream` | `ctx.http?.closeSSE` (only `ServerContext`) |
422422
| `extra.closeStandaloneSSEStream` | `ctx.http?.closeStandaloneSSE` (only `ServerContext`) |
423-
| `extra.taskStore` | `ctx.task?.store` |
424-
| `extra.taskId` | `ctx.task?.id` |
425-
| `extra.taskRequestedTtl` | `ctx.task?.requestedTtl` |
423+
| `extra.taskStore` / `taskId` / `taskRequestedTtl` | _removed; see §12_ |
426424

427425
`ServerContext` convenience methods (new in v2, no v1 equivalent):
428426

@@ -473,24 +471,26 @@ If a `*Schema` constant was used for **runtime validation** (not just as a `requ
473471

474472
`isCallToolResult(value)` still works, but `isSpecType` covers every spec type by name.
475473

476-
## 12. Experimental: `TaskCreationParams.ttl` no longer accepts `null`
474+
## 12. Experimental tasks interception removed
477475

478-
`TaskCreationParams.ttl` changed from `z.union([z.number(), z.null()]).optional()` to `z.number().optional()`. Per the MCP spec, `null` TTL (unlimited lifetime) is only valid in server responses (`Task.ttl`), not in client requests. Omit `ttl` to let the server decide.
476+
The 2025-11 task side-channel through `Protocol` is removed (was always `@experimental`). No mechanical migration; remove usages.
479477

480-
| v1 | v2 |
481-
| ---------------------- | ---------------------------------- |
482-
| `task: { ttl: null }` | `task: {}` (omit ttl) |
483-
| `task: { ttl: 60000 }` | `task: { ttl: 60000 }` (unchanged) |
478+
| Removed | Notes |
479+
| --- | --- |
480+
| `ProtocolOptions.tasks` | drop the option |
481+
| `protocol.taskManager` | gone |
482+
| `RequestOptions.task` / `.relatedTask`, `NotificationOptions.relatedTask` | drop the option |
483+
| `BaseContext.task` (`ctx.task?.*`) | gone |
484+
| `assertTaskCapability` / `assertTaskHandlerCapability` overrides | delete the override |
485+
| `*.experimental.tasks.*` accessors, `Experimental{Client,Server,McpServer}Tasks` | removed |
486+
| `requestStream` / `callToolStream` / `createMessageStream` / `elicitInputStream` | removed; no streaming variant |
487+
| `registerToolTask`, `ToolTaskHandler`, `TaskRequestHandler`, `CreateTaskRequestHandler` | removed |
488+
| `TaskMessageQueue`, `InMemoryTaskMessageQueue`, `Queued*`, `CreateTaskServerContext`, `TaskServerContext`, `TaskToolExecution` | removed |
489+
| `ResponseMessage`, `TaskStatusMessage`, `TaskCreatedMessage`, `ResultMessage`, `takeResult`, `toArrayAsync` | removed |
484490

485-
Type changes in handler context:
491+
`TaskStore` / `InMemoryTaskStore` / `CreateTaskOptions` / `isTerminal` (storage layer) are unchanged.
486492

487-
| Type | v1 | v2 |
488-
| ------------------------------------------- | ----------------------------- | --------------------- |
489-
| `TaskContext.requestedTtl` | `number \| null \| undefined` | `number \| undefined` |
490-
| `CreateTaskServerContext.task.requestedTtl` | `number \| null \| undefined` | `number \| undefined` |
491-
| `TaskServerContext.task.requestedTtl` | `number \| null \| undefined` | `number \| undefined` |
492-
493-
> These task APIs are `@experimental` and may change without notice.
493+
`TaskCreationParams.ttl` also no longer accepts `null` (`number | undefined` only); omit `ttl` to let the server decide.
494494

495495
## 13. Client Behavioral Changes
496496

docs/migration.md

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -591,9 +591,7 @@ The `RequestHandlerExtra` type has been replaced with a structured context type
591591
| `extra.closeSSEStream` | `ctx.http?.closeSSE` (only on `ServerContext`) |
592592
| `extra.closeStandaloneSSEStream` | `ctx.http?.closeStandaloneSSE` (only on `ServerContext`) |
593593
| `extra.sessionId` | `ctx.sessionId` |
594-
| `extra.taskStore` | `ctx.task?.store` |
595-
| `extra.taskId` | `ctx.task?.id` |
596-
| `extra.taskRequestedTtl` | `ctx.task?.requestedTtl` |
594+
| `extra.taskStore` / `taskId` / `taskRequestedTtl` | _removed — see "Experimental tasks interception removed" below_ |
597595

598596
**Before (v1):**
599597

@@ -853,46 +851,28 @@ try {
853851
}
854852
```
855853

856-
### Experimental: `TaskCreationParams.ttl` no longer accepts `null`
854+
### Experimental tasks interception removed
857855

858-
The `ttl` field in `TaskCreationParams` (used when requesting the server to create a task) no longer accepts `null`. Per the MCP spec, `null` TTL (meaning unlimited lifetime) is only valid in server responses (`Task.ttl`), not in client requests. Clients should omit `ttl` to let
859-
the server decide the lifetime.
856+
The 2025-11 experimental tasks side-channel woven through `Protocol` has been removed in preparation for the SEP-2663 Tasks Extension. The following are gone with no in-place replacement:
860857

861-
This also narrows the type of `requestedTtl` in `TaskContext`, `CreateTaskServerContext`, and `TaskServerContext` from `number | null | undefined` to `number | undefined`.
858+
- `ProtocolOptions.tasks` (the `{ taskStore, taskMessageQueue }` constructor option)
859+
- `protocol.taskManager` getter, `Protocol#_bindTaskManager`
860+
- `RequestOptions.task` / `RequestOptions.relatedTask`, `NotificationOptions.relatedTask`
861+
- `BaseContext.task` (`ctx.task?.store` / `ctx.task?.id` / `ctx.task?.requestedTtl`)
862+
- abstract `assertTaskCapability` / `assertTaskHandlerCapability`
863+
- `client.experimental.tasks.*` / `server.experimental.tasks.*` / `mcpServer.experimental.tasks.*` accessors and the `Experimental{Client,Server,McpServer}Tasks` classes
864+
- streaming methods (`requestStream`, `callToolStream`, `createMessageStream`, `elicitInputStream`) and the `ResponseMessage` types they yielded
865+
- `mcpServer.experimental.tasks.registerToolTask(...)`, `ToolTaskHandler`, `TaskRequestHandler`, `CreateTaskRequestHandler`
866+
- `TaskMessageQueue`, `InMemoryTaskMessageQueue`, `Queued*` message types, `CreateTaskServerContext`, `TaskServerContext`, `TaskToolExecution`
867+
- `examples/{client,server}/src/simpleTaskInteractive*.ts`
862868

863-
**Before (v1):**
864-
865-
```typescript
866-
// Requesting unlimited lifetime by passing null
867-
const result = await client.callTool({
868-
name: 'long-task',
869-
arguments: {},
870-
task: { ttl: null }
871-
});
869+
**Unchanged:** the storage layer (`TaskStore`, `InMemoryTaskStore`, `CreateTaskOptions`, `isTerminal`). It will be consumed by the SEP-2663 server-directed plugin in a follow-up.
872870

873-
// Handler context had number | null | undefined
874-
server.setRequestHandler('tools/call', async (request, ctx) => {
875-
const ttl: number | null | undefined = ctx.task?.requestedTtl;
876-
});
877-
```
871+
There is no migration path for the removed surface; it was always `@experimental`. Under SEP-2663, tasks reattach via a `DispatchMiddleware` (`mcp.use(tasksPlugin({ store }))`) and handlers read task context from `ctx.ext.task` instead of `ctx.task`.
878872

879-
**After (v2):**
880-
881-
```typescript
882-
// Omit ttl to let the server decide (server may return null for unlimited)
883-
const result = await client.callTool({
884-
name: 'long-task',
885-
arguments: {},
886-
task: {}
887-
});
888-
889-
// Handler context is now number | undefined
890-
server.setRequestHandler('tools/call', async (request, ctx) => {
891-
const ttl: number | undefined = ctx.task?.requestedTtl;
892-
});
893-
```
873+
#### `TaskCreationParams.ttl` no longer accepts `null`
894874

895-
> **Note:** These task APIs are marked `@experimental` and may change without notice.
875+
`TaskCreationParams.ttl` (the storage-layer creation parameter) is now `number | undefined`; `null` is no longer accepted. Per the MCP spec, `null` TTL (unlimited lifetime) is only valid in server responses (`Task.ttl`), not in creation requests. Omit `ttl` to let the store decide. This is a storage-interface change and is independent of the Protocol-level removals above.
896876

897877
## Enhancements
898878

docs/server.md

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -495,19 +495,6 @@ server.registerTool(
495495
);
496496
```
497497

498-
## Tasks (experimental)
499-
500-
> [!WARNING]
501-
> The tasks API is experimental and may change without notice.
502-
503-
Task-based execution enables "call-now, fetch-later" patterns for long-running operations (see [Tasks](https://modelcontextprotocol.io/specification/latest/basic/utilities/tasks) in the MCP specification). Instead of returning a result immediately, a tool creates a task that can be polled or resumed later. To use tasks:
504-
505-
- Provide a {@linkcode @modelcontextprotocol/server!index.TaskStore | TaskStore} implementation that persists task metadata and results (see {@linkcode @modelcontextprotocol/server!index.InMemoryTaskStore | InMemoryTaskStore} for reference).
506-
- Enable the `tasks` capability when constructing the server.
507-
- Register tools with {@linkcode @modelcontextprotocol/server!experimental/tasks/mcpServer.ExperimentalMcpServerTasks#registerToolTask | server.experimental.tasks.registerToolTask(...)}.
508-
509-
For a full runnable example, see [`simpleTaskInteractive.ts`](https://github.com/modelcontextprotocol/typescript-sdk/blob/main/examples/server/src/simpleTaskInteractive.ts).
510-
511498
## Shutdown
512499

513500
For stateful multi-session HTTP servers, capture the `http.Server` from `app.listen()` so you can stop accepting connections, then close each session transport:

examples/client/README.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,17 @@ Most clients expect a server to be running. Start one from [`../server/README.md
2424

2525
## Example index
2626

27-
| Scenario | Description | File |
28-
| --------------------------------------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
29-
| Interactive Streamable HTTP client | CLI client that exercises tools/resources/prompts, notifications, elicitation, and tasks. | [`src/simpleStreamableHttp.ts`](src/simpleStreamableHttp.ts) |
30-
| Backwards-compatible client (Streamable HTTP → SSE) | Tries Streamable HTTP first, falls back to legacy SSE on 4xx responses. | [`src/streamableHttpWithSseFallbackClient.ts`](src/streamableHttpWithSseFallbackClient.ts) |
31-
| SSE polling client (legacy) | Polls a legacy HTTP+SSE server and demonstrates notification handling. | [`src/ssePollingClient.ts`](src/ssePollingClient.ts) |
32-
| Parallel tool calls | Runs multiple tool calls in parallel. | [`src/parallelToolCallsClient.ts`](src/parallelToolCallsClient.ts) |
33-
| Multiple clients in parallel | Connects multiple clients concurrently to the same server. | [`src/multipleClientsParallel.ts`](src/multipleClientsParallel.ts) |
34-
| OAuth client (interactive) | OAuth-enabled client (dynamic registration, auth flow). | [`src/simpleOAuthClient.ts`](src/simpleOAuthClient.ts) |
35-
| OAuth provider helper | Demonstrates reusable OAuth providers. | [`src/simpleOAuthClientProvider.ts`](src/simpleOAuthClientProvider.ts) |
36-
| Client credentials (M2M) | Machine-to-machine OAuth client credentials example. | [`src/simpleClientCredentials.ts`](src/simpleClientCredentials.ts) |
37-
| URL elicitation client | Drives URL-mode elicitation flows (sensitive input in a browser). | [`src/elicitationUrlExample.ts`](src/elicitationUrlExample.ts) |
38-
| Task interactive client | Demonstrates task-based execution + interactive server→client requests. | [`src/simpleTaskInteractiveClient.ts`](src/simpleTaskInteractiveClient.ts) |
27+
| Scenario | Description | File |
28+
| --------------------------------------------------- | ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
29+
| Interactive Streamable HTTP client | CLI client that exercises tools/resources/prompts, notifications, and elicitation. | [`src/simpleStreamableHttp.ts`](src/simpleStreamableHttp.ts) |
30+
| Backwards-compatible client (Streamable HTTP → SSE) | Tries Streamable HTTP first, falls back to legacy SSE on 4xx responses. | [`src/streamableHttpWithSseFallbackClient.ts`](src/streamableHttpWithSseFallbackClient.ts) |
31+
| SSE polling client (legacy) | Polls a legacy HTTP+SSE server and demonstrates notification handling. | [`src/ssePollingClient.ts`](src/ssePollingClient.ts) |
32+
| Parallel tool calls | Runs multiple tool calls in parallel. | [`src/parallelToolCallsClient.ts`](src/parallelToolCallsClient.ts) |
33+
| Multiple clients in parallel | Connects multiple clients concurrently to the same server. | [`src/multipleClientsParallel.ts`](src/multipleClientsParallel.ts) |
34+
| OAuth client (interactive) | OAuth-enabled client (dynamic registration, auth flow). | [`src/simpleOAuthClient.ts`](src/simpleOAuthClient.ts) |
35+
| OAuth provider helper | Demonstrates reusable OAuth providers. | [`src/simpleOAuthClientProvider.ts`](src/simpleOAuthClientProvider.ts) |
36+
| Client credentials (M2M) | Machine-to-machine OAuth client credentials example. | [`src/simpleClientCredentials.ts`](src/simpleClientCredentials.ts) |
37+
| URL elicitation client | Drives URL-mode elicitation flows (sensitive input in a browser). | [`src/elicitationUrlExample.ts`](src/elicitationUrlExample.ts) |
3938

4039
## URL elicitation example (server + client)
4140

0 commit comments

Comments
 (0)