Initial Checks
Description
Summary
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():
async def report_progress(self, progress: float, total: float | None = None, message: str | None = None) -> None:
progress_token = self.request_context.meta.progressToken if self.request_context.meta else None
if progress_token is None:
return
await self.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:
await self.request_context.session.send_progress_notification(
progress_token=progress_token,
progress=progress,
total=total,
message=message,
related_request_id=self.request_id,
)
Reproduction
- Create a FastMCP server with
stateless_http=True
- In a tool, call both
await ctx.info("test") and await ctx.report_progress(0.5, total=1.0, message="test")
- Observe that
info() messages are delivered via SSE but report_progress() messages are not
Environment
- MCP SDK version: 1.26.0
- Python version: 3.11
- Transport: Streamable HTTP (
stateless_http=True)
Example Code
Python & MCP Python SDK
- MCP SDK version: 1.26.0
- Python version: 3.11
Initial Checks
Description
Summary
Context.report_progress()notifications are not delivered to clients when using the streamable HTTP transport, whileContext.info()and other logging methods work correctly.Root Cause
In
src/mcp/server/fastmcp/server.py, thereport_progressmethod does not passrelated_request_idtosend_progress_notification():The SSE transport uses
related_request_idin the message metadata to route notifications to the correct client. Without it, progress notifications are silently dropped.In contrast,
send_log_message(used byinfo(),warning(), etc.) correctly passesrelated_request_id:Fix
Add
related_request_id=self.request_idto thesend_progress_notification()call:Reproduction
stateless_http=Trueawait ctx.info("test")andawait ctx.report_progress(0.5, total=1.0, message="test")info()messages are delivered via SSE butreport_progress()messages are notEnvironment
stateless_http=True)Example Code
Python & MCP Python SDK