Skip to content

Commit 6459c61

Browse files
committed
fix: pass related_request_id in Context.report_progress()
Progress notifications sent via Context.report_progress() were silently dropped in stateless HTTP / SSE transports because the call to send_progress_notification() was missing the related_request_id parameter. The SSE transport relies on this field to route notifications back to the correct client stream. Add related_request_id=self.request_id to the send_progress_notification() call, consistent with how send_log_message() already passes it. Reported-by: hubbard-zlee Github-Issue: #2001
1 parent f8d98b6 commit 6459c61

3 files changed

Lines changed: 51 additions & 3 deletions

File tree

src/mcp/server/fastmcp/server.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1177,6 +1177,7 @@ async def report_progress(self, progress: float, total: float | None = None, mes
11771177
progress=progress,
11781178
total=total,
11791179
message=message,
1180+
related_request_id=self.request_id,
11801181
)
11811182

11821183
async def read_resource(self, uri: str | AnyUrl) -> Iterable[ReadResourceContents]:

tests/issues/test_176_progress_token.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,12 @@ async def test_progress_token_zero_first_call():
3636

3737
# Verify progress notifications
3838
assert mock_session.send_progress_notification.call_count == 3, "All progress notifications should be sent"
39-
mock_session.send_progress_notification.assert_any_call(progress_token=0, progress=0.0, total=10.0, message=None)
40-
mock_session.send_progress_notification.assert_any_call(progress_token=0, progress=5.0, total=10.0, message=None)
41-
mock_session.send_progress_notification.assert_any_call(progress_token=0, progress=10.0, total=10.0, message=None)
39+
mock_session.send_progress_notification.assert_any_call(
40+
progress_token=0, progress=0.0, total=10.0, message=None, related_request_id="test-request"
41+
)
42+
mock_session.send_progress_notification.assert_any_call(
43+
progress_token=0, progress=5.0, total=10.0, message=None, related_request_id="test-request"
44+
)
45+
mock_session.send_progress_notification.assert_any_call(
46+
progress_token=0, progress=10.0, total=10.0, message=None, related_request_id="test-request"
47+
)
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
from unittest.mock import AsyncMock, MagicMock
2+
3+
import pytest
4+
5+
from mcp.server.fastmcp import Context
6+
from mcp.shared.context import RequestContext
7+
8+
pytestmark = pytest.mark.anyio
9+
10+
11+
async def test_report_progress_passes_related_request_id():
12+
"""Test that Context.report_progress() passes related_request_id to
13+
send_progress_notification so that progress notifications are correctly
14+
routed in stateless HTTP / SSE transports.
15+
16+
Regression test for https://github.com/modelcontextprotocol/python-sdk/issues/2001
17+
"""
18+
mock_session = AsyncMock()
19+
mock_session.send_progress_notification = AsyncMock()
20+
21+
mock_meta = MagicMock()
22+
mock_meta.progressToken = "test-progress-token"
23+
24+
request_context = RequestContext(
25+
request_id="req-42",
26+
session=mock_session,
27+
meta=mock_meta,
28+
lifespan_context=None,
29+
)
30+
31+
ctx = Context(request_context=request_context, fastmcp=MagicMock())
32+
33+
await ctx.report_progress(0.5, total=1.0, message="halfway")
34+
35+
mock_session.send_progress_notification.assert_called_once_with(
36+
progress_token="test-progress-token",
37+
progress=0.5,
38+
total=1.0,
39+
message="halfway",
40+
related_request_id="req-42",
41+
)

0 commit comments

Comments
 (0)