Add message queue for SSE messages POST endpoint (#459)

This commit is contained in:
Akash D
2025-05-06 17:10:43 -07:00
committed by GitHub
parent 58c5e7223c
commit 3b1b213a96
26 changed files with 1247 additions and 50 deletions

View File

@@ -44,6 +44,7 @@ from mcp.server.lowlevel.helper_types import ReadResourceContents
from mcp.server.lowlevel.server import LifespanResultT
from mcp.server.lowlevel.server import Server as MCPServer
from mcp.server.lowlevel.server import lifespan as default_lifespan
from mcp.server.message_queue import MessageDispatch
from mcp.server.session import ServerSession, ServerSessionT
from mcp.server.sse import SseServerTransport
from mcp.server.stdio import stdio_server
@@ -90,6 +91,11 @@ class Settings(BaseSettings, Generic[LifespanResultT]):
sse_path: str = "/sse"
message_path: str = "/messages/"
# SSE message queue settings
message_dispatch: MessageDispatch | None = Field(
None, description="Custom message dispatch instance"
)
# resource settings
warn_on_duplicate_resources: bool = True
@@ -569,12 +575,21 @@ class FastMCP:
def sse_app(self) -> Starlette:
"""Return an instance of the SSE server app."""
message_dispatch = self.settings.message_dispatch
if message_dispatch is None:
from mcp.server.message_queue import InMemoryMessageDispatch
message_dispatch = InMemoryMessageDispatch()
logger.info("Using default in-memory message dispatch")
from starlette.middleware import Middleware
from starlette.routing import Mount, Route
# Set up auth context and dependencies
sse = SseServerTransport(self.settings.message_path)
sse = SseServerTransport(
self.settings.message_path, message_dispatch=message_dispatch
)
async def handle_sse(scope: Scope, receive: Receive, send: Send):
# Add client ID from auth context into request context if available
@@ -589,7 +604,14 @@ class FastMCP:
streams[1],
self._mcp_server.create_initialization_options(),
)
return Response()
return Response()
@asynccontextmanager
async def lifespan(app: Starlette):
try:
yield
finally:
await message_dispatch.close()
# Create routes
routes: list[Route | Mount] = []
@@ -666,7 +688,10 @@ class FastMCP:
# Create Starlette app with routes and middleware
return Starlette(
debug=self.settings.debug, routes=routes, middleware=middleware
debug=self.settings.debug,
routes=routes,
middleware=middleware,
lifespan=lifespan,
)
async def list_prompts(self) -> list[MCPPrompt]: