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
{{ message }}
Repository navigation
Progress notifications not delivered via SSE in stateless HTTP mode #2001
Context.report_progress() notifications are not delivered to clients when using the streamable HTTP transport, while Context.info() and other logging methods work correctly.
Root Cause
In src/mcp/server/fastmcp/server.py, the report_progress method does not pass related_request_id to send_progress_notification():
asyncdefreport_progress(self, progress: float, total: float|None=None, message: str|None=None) ->None:
progress_token=self.request_context.meta.progressTokenifself.request_context.metaelseNoneifprogress_tokenisNone:
returnawaitself.request_context.session.send_progress_notification(
progress_token=progress_token,
progress=progress,
total=total,
message=message,
# related_request_id is missing here
)
The SSE transport uses related_request_id in the message metadata to route notifications to the correct client. Without it, progress notifications are silently dropped.
In contrast, send_log_message (used by info(), warning(), etc.) correctly passes related_request_id:
Fix
Add related_request_id=self.request_id to the send_progress_notification() call:
I checked this against current main (616476f) and the originally described missing related_request_id path appears to be fixed now.
Evidence:
Context.report_progress() in src/mcp/server/mcpserver/context.py now passes related_request_id=self.request_id to send_progress_notification().
The direct regression test passes locally:
uv run pytest tests/server/mcpserver/test_server.py::test_report_progress_passes_related_request_id -q
I also ran a small stateless streamable HTTP check with connect_over_streamable_http(..., stateless_http=True): a tool calling ctx.report_progress(1, 3) and ctx.report_progress(2, 3, "halfway") delivered both progress callbacks before returning.
Unless there is a remaining case beyond stateless streamable HTTP progress callback delivery, this may be closable.
Confirmed via independent analysis. On \main\ (v2), the code path was completely refactored — \Context.report_progress()\ now routes through _request_outbound.progress()\ (_SingleExchangeDispatchContext), which is inherently request-scoped via its own SSE sink (\src/mcp/server/_streamable_http_modern.py:113-121). No
elated_request_id\ needed because the channel is the request's own channel. All 47 progress-related tests pass across all transport modes including \streamable-http-stateless. Agree this is closable.
Apologies for the comment noise on this issue. The earlier comments were redundant — #2001 is already resolved (confirmed on main at 616476f, with a test at #2747). No further action needed.
v1.x has the same fix now: #2994 (commit 9678a3b3, merged 2026-06-26) adds related_request_id=self.request_id to Context.report_progress() in src/mcp/server/fastmcp/server.py, and updates tests/issues/test_176_progress_token.py to assert it. The comments above cover main; the v1.x side does not seem to have been noted here yet.
The part that may still matter for this issue: the fix is not in any published 1.x release.
1.28.1 was published 2026-06-26T12:32:57Z and uploaded to PyPI at 12:57:27Z.
v1.28.1...v1.x is currently ahead by 5 commits, and 9678a3b3 is one of them.
1.28.1 is still the latest mcp release on PyPI.
Checked against the released source rather than the branch: at tags v1.28.0 and v1.28.1, report_progress() calls send_progress_notification() without related_request_id. So an mcp>=1.28.1,<2.0 constraint still resolves to the pre-fix behavior.
For anyone landing here on 1.28.x, the workaround is to bypass ctx.report_progress() and pass the field the fix adds:
Thanks for the report. Closing this as it's been fixed in v2, which is now released (see #2038), and as noted above the same fix landed on the 1.x line via #2994. If you still run into this on v2, feel free to reopen.
Activity
fix: pass related_request_id in Context.report_progress()
koriyoshi2041 commentedon May 30, 2026
I checked this against current main (
616476f) and the originally described missingrelated_request_idpath appears to be fixed now.Evidence:
Context.report_progress()insrc/mcp/server/mcpserver/context.pynow passesrelated_request_id=self.request_idtosend_progress_notification().uv run pytest tests/server/mcpserver/test_server.py::test_report_progress_passes_related_request_id -qconnect_over_streamable_http(..., stateless_http=True): a tool callingctx.report_progress(1, 3)andctx.report_progress(2, 3, "halfway")delivered both progress callbacks before returning.Unless there is a remaining case beyond stateless streamable HTTP progress callback delivery, this may be closable.
shivamsingh-007 commentedon Jul 12, 2026
Confirmed via independent analysis. On \main\ (v2), the code path was completely refactored — \Context.report_progress()\ now routes through _request_outbound.progress()\ (_SingleExchangeDispatchContext), which is inherently request-scoped via its own SSE sink (\src/mcp/server/_streamable_http_modern.py:113-121). No
elated_request_id\ needed because the channel is the request's own channel. All 47 progress-related tests pass across all transport modes including \streamable-http-stateless. Agree this is closable.
shivamsingh-007 commentedon Jul 12, 2026
Apologies for the comment noise on this issue. The earlier comments were redundant — #2001 is already resolved (confirmed on main at 616476f, with a test at #2747). No further action needed.
kuotunyu commentedon Jul 25, 2026
v1.xhas the same fix now: #2994 (commit9678a3b3, merged 2026-06-26) addsrelated_request_id=self.request_idtoContext.report_progress()insrc/mcp/server/fastmcp/server.py, and updatestests/issues/test_176_progress_token.pyto assert it. The comments above covermain; thev1.xside does not seem to have been noted here yet.The part that may still matter for this issue: the fix is not in any published 1.x release.
v1.28.1...v1.xis currently ahead by 5 commits, and9678a3b3is one of them.mcprelease on PyPI.Checked against the released source rather than the branch: at tags
v1.28.0andv1.28.1,report_progress()callssend_progress_notification()withoutrelated_request_id. So anmcp>=1.28.1,<2.0constraint still resolves to the pre-fix behavior.For anyone landing here on 1.28.x, the workaround is to bypass
ctx.report_progress()and pass the field the fix adds:Confirmed on 1.28.1 with the official client SDK's
progress_callbackover both stdio and Streamable HTTP.Is a 1.x patch release including #2994 planned? That would let downstream consumers drop the workaround instead of pinning to a git ref.
Separately: #2207 targets
v1.xwith the same change and is still open, so it looks superseded by #2994.maxisbey commentedon Jul 29, 2026
Thanks for the report. Closing this as it's been fixed in v2, which is now released (see #2038), and as noted above the same fix landed on the 1.x line via #2994. If you still run into this on v2, feel free to reopen.
AI Disclaimer