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
`ServerSession.send_progress_notification` takes an explicit progress token
decoupled from the request it belongs to, so it can keep emitting progress
for a request that has already completed -- which the spec forbids
("Progress notifications MUST stop after completion"). The request-scoped
`report_progress` (and `Context.report_progress`) is the supported path: it
reports against the inbound request's own token, no-ops when the caller did
not ask for progress, and stops when the request completes. The deprecated
method keeps working and emits `MCPDeprecationWarning`.
The warning message deliberately departs from the "<X> is deprecated as of
<version>" pattern used by the spec-driven deprecations: this one is an SDK
API decision, not a spec retirement (2026-07-28 does not retire
server-to-client progress).
For "stops when the request completes" to hold on every dispatcher,
`_DirectDispatchContext` now closes with its request the way
`_JSONRPCDispatchContext` already did: `close()` runs in the dispatch
handler's `finally`, after which `progress`/`notify` deliver nothing,
`can_send_request` is False, and `send_raw_request` raises
`NoBackChannelError` -- the closed state the `DispatchContext` protocol
documents. Two pre-existing tests that asserted `can_send_request` on a
context captured after its handler returned now sample it in-handler, and
the closed-state contract tests are parametrized over both dispatchers.
The interaction test that covered both the server and client side of late
progress is split in two. The server-side property is proved positively on
the wire through `report_progress`; it no longer relies on a session-bound
standalone stream, so it also runs on the stateless streamable-http arm.
The client-side late-drop test keeps using the deprecated explicit-token
method -- the only API that can still produce a late notification -- under
`pytest.warns`, and its arms are unchanged. The migration guide stops
recommending the deprecated method anywhere and documents the replacement.
Copy file name to clipboardExpand all lines: docs/advanced/deprecated.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -12,7 +12,7 @@ The table below names each deprecated feature, why it is going away, and the rep
12
12
|**Server-initiated sampling**: `ctx.session.create_message()`, the `sampling_callback=` you pass to `Client(...)`| SEP-2577 retires the capability. | Return `InputRequiredResult` and let the client retry the call (see **Multi-round-trip requests**). |
13
13
|**Protocol logging**: `ctx.log()`, `ctx.debug()`, `ctx.info()`, `ctx.warning()`, `ctx.error()`, `ctx.session.send_log_message()`, `client.set_logging_level()`| SEP-2577 retires the capability. Nothing in-protocol replaces it. | Ordinary `import logging` to stderr (see **Logging**). |
14
14
|**`ping`**: `client.send_ping()`|**Removed** from the protocol, not merely deprecated. There is no `ping` method in 2026-07-28. | Nothing. It only works against a `mode="legacy"` connection. |
15
-
|**Client->server progress**: `client.send_progress_notification()`| 2026-07-28 makes progress server->client only. | Nothing to send. Your *server* reports progress with `ctx.report_progress()` (see **Progress**). |
15
+
|**Client->server progress**: `client.send_progress_notification()`| 2026-07-28 makes progress server->client only. | Nothing to send. Your *server* reports progress with `ctx.report_progress()` (see **Progress**). The SDK separately deprecates the server-side explicit-token `ctx.session.send_progress_notification()` in favour of `report_progress` (same warning category, same replacement). |
### `ProgressContext` and `progress()` context manager removed
969
969
970
-
The `mcp.shared.progress` module (`ProgressContext`, `Progress`, and the `progress()` context manager) has been removed. This module had no real-world adoption — all users send progress notifications via `Context.report_progress()`or `session.send_progress_notification()`directly.
970
+
The `mcp.shared.progress` module (`ProgressContext`, `Progress`, and the `progress()` context manager) has been removed. This module had no real-world adoption — all users send progress notifications via `Context.report_progress()` directly.
**After — use `session.send_progress_notification()` (low-level):**
991
-
992
-
```python
993
-
await session.send_progress_notification(
994
-
progress_token=progress_token,
995
-
progress=25,
996
-
total=100,
997
-
)
998
-
```
999
-
1000
990
### Handler progress reporting: prefer `ctx.report_progress()` over manual `progress_token`
1001
991
1002
992
Reading `ctx.meta["progress_token"]` and calling `session.send_progress_notification(token, ...)` is specific to the JSON-RPC transport path. On the in-process modern path (`DirectDispatcher` / `Client(server)`), there is no wire token in `_meta`, so handlers that gate progress on the token's presence go silent.
1003
993
1004
-
`ctx.report_progress(progress, total, message)` works on every dispatcher: it sends a progress notification when a token is present and routes the update through the dispatcher's progress channel otherwise, no-opping only when the caller did not request progress at all. `session.send_progress_notification(progress_token, ...)` is unchanged and still works on JSON-RPC transports for code that already holds a token.
994
+
`ctx.report_progress(progress, total, message)` works on every dispatcher: it sends a progress notification when a token is present and routes the update through the dispatcher's progress channel otherwise, no-opping only when the caller did not request progress at all. `ServerSession.send_progress_notification(progress_token, ...)` is now deprecated; see **Progress API deprecations** below.
No migration is required during the deprecation window. New code should avoid building on these features, since they may be removed in a future spec version.
The 2026-07-28 spec restricts `notifications/progress` to the server-to-client direction only — `ProgressNotification` is no longer in `ClientNotification`. `Client.send_progress_notification()` and `ClientSession.send_progress_notification()` now carry `typing_extensions.deprecated` and emit `mcp.MCPDeprecationWarning` at runtime. They continue to work against servers negotiating 2025-11-25 or earlier.
1504
1494
1505
-
On the server side, prefer the new dispatcher-agnostic `ServerSession.report_progress(progress, total, message)` (and `Context.report_progress()` on `MCPServer`) over the raw `ServerSession.send_progress_notification(progress_token, …)`. `report_progress` encapsulates the "no-op when the caller did not request progress" rule and works on every dispatcher; the raw token-taking form remains for handlers that read `_meta.progressToken` directly.
1495
+
On the server side, `ServerSession.send_progress_notification(progress_token, ...)` is also deprecated. It takes an explicit progress token decoupled from any request's lifetime, so it can emit progress for a request that has already completed -- which the spec forbids ("Progress notifications MUST stop after completion"). Use `Context.report_progress(progress, total, message)` (or `ServerSession.report_progress(...)` from a low-level handler): it reports against the inbound request's own progress token, works on every dispatcher, no-ops when the caller did not request progress, and is closed with the request, so a late call after the handler has returned sends nothing.
0 commit comments