Skip to content

Commit df78b21

Browse files
authored
Merge pull request #838 from alexsee/alexsee/fix/report-progress-missing-related-request-id
fix: report_progress missing passing related_request_id causes notifications not working in streaming-http
2 parents ab2ad0b + ec24a07 commit df78b21

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

src/fastmcp/server/context.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ async def report_progress(
122122
progress=progress,
123123
total=total,
124124
message=message,
125+
related_request_id=self.request_id,
125126
)
126127

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

tests/client/test_streamable_http.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
import json
33
import sys
44
from collections.abc import AsyncGenerator
5+
from unittest.mock import AsyncMock
56

67
import pytest
78
import uvicorn
89
from mcp import McpError
10+
from mcp.types import TextContent
911
from starlette.applications import Starlette
1012
from starlette.routing import Mount
1113

14+
from fastmcp import Context
1215
from fastmcp.client import Client
1316
from fastmcp.client.transports import StreamableHttpTransport
1417
from fastmcp.server.dependencies import get_http_request
@@ -38,6 +41,12 @@ async def sleep(seconds: float) -> str:
3841
await asyncio.sleep(seconds)
3942
return f"Slept for {seconds} seconds"
4043

44+
@server.tool
45+
async def greet_with_progress(name: str, ctx: Context) -> str:
46+
"""Report progress for a greeting."""
47+
await ctx.report_progress(0.5, 1.0, "Greeting in progress")
48+
return f"Hello, {name}!"
49+
4150
# Add a resource
4251
@server.resource(uri="data://users")
4352
async def get_users():
@@ -63,8 +72,10 @@ def welcome(name: str) -> str:
6372
return server
6473

6574

66-
def run_server(host: str, port: int, **kwargs) -> None:
67-
fastmcp_server().run(host=host, port=port, **kwargs)
75+
def run_server(host: str, port: int, stateless_http: bool = False, **kwargs) -> None:
76+
server = fastmcp_server()
77+
server.settings.stateless_http = stateless_http
78+
server.run(host=host, port=port, **kwargs)
6879

6980

7081
def run_nested_server(host: str, port: int) -> None:
@@ -88,8 +99,12 @@ def run_nested_server(host: str, port: int) -> None:
8899

89100

90101
@pytest.fixture()
91-
async def streamable_http_server() -> AsyncGenerator[str, None]:
92-
with run_server_in_process(run_server, transport="streamable-http") as url:
102+
async def streamable_http_server(
103+
stateless_http: bool = False,
104+
) -> AsyncGenerator[str, None]:
105+
with run_server_in_process(
106+
run_server, stateless_http=stateless_http, transport="streamable-http"
107+
) as url:
93108
async with Client(transport=StreamableHttpTransport(f"{url}/mcp")) as client:
94109
assert await client.ping()
95110
yield f"{url}/mcp"
@@ -117,6 +132,24 @@ async def test_http_headers(streamable_http_server: str):
117132
assert json_result["x-demo-header"] == "ABC"
118133

119134

135+
@pytest.mark.parametrize("streamable_http_server", [True, False], indirect=True)
136+
async def test_greet_with_progress_tool(streamable_http_server: str):
137+
"""Test calling the greet tool."""
138+
progress_handler = AsyncMock(return_value=None)
139+
140+
async with Client(
141+
transport=StreamableHttpTransport(streamable_http_server),
142+
progress_handler=progress_handler,
143+
) as client:
144+
result = await client.call_tool("greet_with_progress", {"name": "Alice"})
145+
146+
assert isinstance(result, list)
147+
assert isinstance(result[0], TextContent)
148+
assert result[0].text == "Hello, Alice!"
149+
150+
progress_handler.assert_called_once_with(0.5, 1.0, "Greeting in progress")
151+
152+
120153
async def test_nested_streamable_http_server_resolves_correctly():
121154
# tests patch for
122155
# https://github.com/modelcontextprotocol/python-sdk/pull/659

0 commit comments

Comments
 (0)