refactor(examples): migrate all HTTP examples to streamable_http_app() (#2291)

This commit is contained in:
Max Isbey 2026-03-16 11:37:01 +00:00 • committed by GitHub
commit abfb482246
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 43 additions and 271 deletions

View file

@ -6,9 +6,7 @@ A simple MCP server example demonstrating the StreamableHttp transport, which en
- Uses the StreamableHTTP transport for server-client communication
- Supports REST API operations (POST, GET, DELETE) for `/mcp` endpoint
- Task management with anyio task groups
- Ability to send multiple notifications over time to the client
- Proper resource cleanup and lifespan management
- Resumability support via InMemoryEventStore
## Usage

View file

@ -1,16 +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
from .event_store import InMemoryEventStore
@ -127,47 +122,21 @@ def main(
# For production, use a persistent storage solution.
event_store = InMemoryEventStore()
# Create the session manager with our app and event store
session_manager = StreamableHTTPSessionManager(
app=app,
event_store=event_store, # Enable resumability
starlette_app = app.streamable_http_app(
event_store=event_store,
json_response=json_response,
)
# ASGI handler for streamable HTTP connections
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 managing session manager lifecycle."""
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"],
)
import uvicorn
uvicorn.run(starlette_app, host="127.0.0.1", port=port)
return 0