Skip to content

Commit e977423

Browse files
author
文徐
committed
fid sse client disconnect
1 parent 959d4e3 commit e977423

File tree

8 files changed

+28
-14
lines changed

8 files changed

+28
-14
lines changed

examples/fastmcp/simple_echo.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@
22
FastMCP Echo Server
33
"""
44

5-
from mcp.server.fastmcp import FastMCP
5+
from mcp.server.fastmcp import FastMCP,Context
66

77
# Create server
88
mcp = FastMCP("Echo Server")
99

1010

1111
@mcp.tool()
12-
def echo(text: str) -> str:
12+
def echo(text: str, ctx: Context) -> str:
1313
"""Echo the input text"""
14+
ctx.request_context.request.query_params.get("session_id")
1415
return text
16+
17+
mcp.run(transport="sse")

examples/servers/simple-prompt/mcp_simple_prompt/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,8 @@ async def get_prompt(
9191
if transport == "sse":
9292
from mcp.server.sse import SseServerTransport
9393
from starlette.applications import Starlette
94-
from starlette.responses import Response
9594
from starlette.routing import Mount, Route
95+
from mcp.server.fastmcp.server import SilentResponse
9696

9797
sse = SseServerTransport("/messages/")
9898

@@ -103,7 +103,7 @@ async def handle_sse(request):
103103
await app.run(
104104
streams[0], streams[1], app.create_initialization_options()
105105
)
106-
return Response()
106+
return SilentResponse()
107107

108108
starlette_app = Starlette(
109109
debug=True,

examples/servers/simple-resource/mcp_simple_resource/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ async def read_resource(uri: AnyUrl) -> str | bytes:
5858
if transport == "sse":
5959
from mcp.server.sse import SseServerTransport
6060
from starlette.applications import Starlette
61-
from starlette.responses import Response
61+
from mcp.server.fastmcp.server import SilentResponse
6262
from starlette.routing import Mount, Route
6363

6464
sse = SseServerTransport("/messages/")
@@ -70,7 +70,7 @@ async def handle_sse(request):
7070
await app.run(
7171
streams[0], streams[1], app.create_initialization_options()
7272
)
73-
return Response()
73+
return SilentResponse()
7474

7575
starlette_app = Starlette(
7676
debug=True,

examples/servers/simple-tool/mcp_simple_tool/server.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ async def list_tools() -> list[types.Tool]:
5959
if transport == "sse":
6060
from mcp.server.sse import SseServerTransport
6161
from starlette.applications import Starlette
62-
from starlette.responses import Response
6362
from starlette.routing import Mount, Route
63+
from mcp.server.fastmcp.server import SilentResponse
6464

6565
sse = SseServerTransport("/messages/")
6666

@@ -71,7 +71,7 @@ async def handle_sse(request):
7171
await app.run(
7272
streams[0], streams[1], app.create_initialization_options()
7373
)
74-
return Response()
74+
return SilentResponse()
7575

7676
starlette_app = Starlette(
7777
debug=True,

src/mcp/server/fastmcp/server.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,16 @@
5252
logger = get_logger(__name__)
5353

5454

55+
class SilentResponse(Response):
56+
"""A response that does not send any HTTP response back to the client."""
57+
58+
def __init__(self) -> None:
59+
super().__init__()
60+
61+
async def __call__(self, scope: Scope, receive: Receive, send: Send) -> Awaitable[None]:
62+
pass
63+
64+
5565
class Settings(BaseSettings, Generic[LifespanResultT]):
5666
"""FastMCP server settings.
5767
@@ -748,7 +758,7 @@ async def handle_sse(scope: Scope, receive: Receive, send: Send):
748758
streams[1],
749759
self._mcp_server.create_initialization_options(),
750760
)
751-
return Response()
761+
return SilentResponse()
752762

753763
# Create routes
754764
routes: list[Route | Mount] = []

src/mcp/server/sse.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async def handle_sse(request):
2323
streams[0], streams[1], app.create_initialization_options()
2424
)
2525
# Return empty response to avoid NoneType error
26-
return Response()
26+
return SilentResponse()
2727
2828
# Create and run Starlette app
2929
starlette_app = Starlette(routes=routes)

tests/server/test_sse_security.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
import uvicorn
1111
from starlette.applications import Starlette
1212
from starlette.requests import Request
13-
from starlette.responses import Response
1413
from starlette.routing import Mount, Route
1514

1615
from mcp.server import Server
16+
from mcp.server.fastmcp.server import SilentResponse
1717
from mcp.server.sse import SseServerTransport
1818
from mcp.server.transport_security import TransportSecuritySettings
1919
from mcp.types import Tool
@@ -55,7 +55,7 @@ async def handle_sse(request: Request):
5555
except ValueError as e:
5656
# Validation error was already handled inside connect_sse
5757
logger.debug(f"SSE connection failed validation: {e}")
58-
return Response()
58+
return SilentResponse()
5959

6060
routes = [
6161
Route("/sse", endpoint=handle_sse),

tests/shared/test_sse.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from mcp.client.session import ClientSession
2020
from mcp.client.sse import sse_client
2121
from mcp.server import Server
22+
from mcp.server.fastmcp.server import SilentResponse
2223
from mcp.server.sse import SseServerTransport
2324
from mcp.server.transport_security import TransportSecuritySettings
2425
from mcp.shared.exceptions import McpError
@@ -91,7 +92,7 @@ def make_server_app() -> Starlette:
9192
async def handle_sse(request: Request) -> Response:
9293
async with sse.connect_sse(request.scope, request.receive, request._send) as streams:
9394
await server.run(streams[0], streams[1], server.create_initialization_options())
94-
return Response()
95+
return SilentResponse()
9596

9697
app = Starlette(
9798
routes=[
@@ -354,7 +355,7 @@ def run_context_server(server_port: int) -> None:
354355
async def handle_sse(request: Request) -> Response:
355356
async with sse.connect_sse(request.scope, request.receive, request._send) as streams:
356357
await context_server.run(streams[0], streams[1], context_server.create_initialization_options())
357-
return Response()
358+
return SilentResponse()
358359

359360
app = Starlette(
360361
routes=[

0 commit comments

Comments
 (0)