|
1 | | -import contextlib |
2 | 1 | import logging |
3 | | -from collections.abc import AsyncIterator |
4 | 2 |
|
5 | 3 | import anyio |
6 | 4 | import click |
7 | 5 | import uvicorn |
8 | 6 | from mcp import types |
9 | 7 | from mcp.server import Server, ServerRequestContext |
10 | | -from mcp.server.streamable_http_manager import StreamableHTTPSessionManager |
11 | | -from starlette.applications import Starlette |
12 | 8 | from starlette.middleware.cors import CORSMiddleware |
13 | | -from starlette.routing import Mount |
14 | | -from starlette.types import Receive, Scope, Send |
15 | 9 |
|
16 | 10 | logger = logging.getLogger(__name__) |
17 | 11 |
|
@@ -104,39 +98,17 @@ def main( |
104 | 98 | on_call_tool=handle_call_tool, |
105 | 99 | ) |
106 | 100 |
|
107 | | - # Create the session manager with true stateless mode |
108 | | - session_manager = StreamableHTTPSessionManager( |
109 | | - app=app, |
110 | | - event_store=None, |
| 101 | + starlette_app = app.streamable_http_app( |
| 102 | + stateless_http=True, |
111 | 103 | json_response=json_response, |
112 | | - stateless=True, |
113 | | - ) |
114 | | - |
115 | | - async def handle_streamable_http(scope: Scope, receive: Receive, send: Send) -> None: |
116 | | - await session_manager.handle_request(scope, receive, send) |
117 | | - |
118 | | - @contextlib.asynccontextmanager |
119 | | - async def lifespan(app: Starlette) -> AsyncIterator[None]: |
120 | | - """Context manager for session manager.""" |
121 | | - async with session_manager.run(): |
122 | | - logger.info("Application started with StreamableHTTP session manager!") |
123 | | - try: |
124 | | - yield |
125 | | - finally: |
126 | | - logger.info("Application shutting down...") |
127 | | - |
128 | | - # Create an ASGI application using the transport |
129 | | - starlette_app = Starlette( |
130 | 104 | debug=True, |
131 | | - routes=[Mount("/mcp", app=handle_streamable_http)], |
132 | | - lifespan=lifespan, |
133 | 105 | ) |
134 | 106 |
|
135 | 107 | # Wrap ASGI application with CORS middleware to expose Mcp-Session-Id header |
136 | 108 | # for browser-based clients (ensures 500 errors get proper CORS headers) |
137 | 109 | starlette_app = CORSMiddleware( |
138 | 110 | starlette_app, |
139 | | - allow_origins=["*"], # Allow all origins - adjust as needed for production |
| 111 | + allow_origins=["*"], # Note: streamable_http_app() enforces localhost-only Origin by default |
140 | 112 | allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods |
141 | 113 | expose_headers=["Mcp-Session-Id"], |
142 | 114 | ) |
|
0 commit comments