refactor(examples): migrate all HTTP examples to streamable_http_app() (#2291)
This commit is contained in:
parent
e1fd62e0f3
commit
abfb482246
2 changed files with 43 additions and 271 deletions
|
|
@ -7,7 +7,6 @@ A stateless MCP server example demonstrating the StreamableHttp transport withou
|
|||
- Uses the StreamableHTTP transport in stateless mode (mcp_session_id=None)
|
||||
- Each request creates a new ephemeral connection
|
||||
- No session state maintained between requests
|
||||
- Task lifecycle scoped to individual requests
|
||||
- Suitable for deployment in multi-node environments
|
||||
|
||||
## Usage
|
||||
|
|
|
|||
|
|
@ -1,17 +1,11 @@
|
|||
import contextlib
|
||||
import logging
|
||||
from collections.abc import AsyncIterator
|
||||
|
||||
import anyio
|
||||
import click
|
||||
import uvicorn
|
||||
from mcp import types
|
||||
from mcp.server import Server, ServerRequestContext
|
||||
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
||||
from starlette.applications import Starlette
|
||||
from starlette.middleware.cors import CORSMiddleware
|
||||
from starlette.routing import Mount
|
||||
from starlette.types import Receive, Scope, Send
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -104,39 +98,17 @@ def main(
|
|||
on_call_tool=handle_call_tool,
|
||||
)
|
||||
|
||||
# Create the session manager with true stateless mode
|
||||
session_manager = StreamableHTTPSessionManager(
|
||||
app=app,
|
||||
event_store=None,
|
||||
starlette_app = app.streamable_http_app(
|
||||
stateless_http=True,
|
||||
json_response=json_response,
|
||||
stateless=True,
|
||||
)
|
||||
|
||||
async def handle_streamable_http(scope: Scope, receive: Receive, send: Send) -> None:
|
||||
await session_manager.handle_request(scope, receive, send)
|
||||
|
||||
@contextlib.asynccontextmanager
|
||||
async def lifespan(app: Starlette) -> AsyncIterator[None]:
|
||||
"""Context manager for session manager."""
|
||||
async with session_manager.run():
|
||||
logger.info("Application started with StreamableHTTP session manager!")
|
||||
try:
|
||||
yield
|
||||
finally:
|
||||
logger.info("Application shutting down...")
|
||||
|
||||
# Create an ASGI application using the transport
|
||||
starlette_app = Starlette(
|
||||
debug=True,
|
||||
routes=[Mount("/mcp", app=handle_streamable_http)],
|
||||
lifespan=lifespan,
|
||||
)
|
||||
|
||||
# Wrap ASGI application with CORS middleware to expose Mcp-Session-Id header
|
||||
# for browser-based clients (ensures 500 errors get proper CORS headers)
|
||||
starlette_app = CORSMiddleware(
|
||||
starlette_app,
|
||||
allow_origins=["*"], # Allow all origins - adjust as needed for production
|
||||
allow_origins=["*"], # Note: streamable_http_app() enforces localhost-only Origin by default
|
||||
allow_methods=["GET", "POST", "DELETE"], # MCP streamable HTTP methods
|
||||
expose_headers=["Mcp-Session-Id"],
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in a new issue