refactor: remove deprecated SSE transport, keep streamable-http only
SSE is deprecated per MCP spec. Both clients (wizard, emo) already use type: "http" pointing to /mcp/mcp. Removes HandleSSE class, SseServerTransport, and /mcp/sse + /mcp/messages/ routes. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
73aefda82e
commit
0c64cb05e6
1 changed files with 2 additions and 30 deletions
|
|
@ -14,7 +14,6 @@ from fastapi import Depends, FastAPI, HTTPException
|
||||||
from fastapi.responses import Response
|
from fastapi.responses import Response
|
||||||
from fastapi.staticfiles import StaticFiles
|
from fastapi.staticfiles import StaticFiles
|
||||||
from mcp.server.fastmcp import FastMCP
|
from mcp.server.fastmcp import FastMCP
|
||||||
from mcp.server.sse import SseServerTransport
|
|
||||||
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
||||||
from starlette.routing import Mount, Route
|
from starlette.routing import Mount, Route
|
||||||
from starlette.types import ASGIApp, Receive, Scope, Send
|
from starlette.types import ASGIApp, Receive, Scope, Send
|
||||||
|
|
@ -1194,31 +1193,7 @@ class MCPAuthMiddleware:
|
||||||
|
|
||||||
app.add_middleware(MCPAuthMiddleware)
|
app.add_middleware(MCPAuthMiddleware)
|
||||||
|
|
||||||
# Mount SSE transport
|
# Streamable HTTP transport — the only MCP transport (SSE is deprecated).
|
||||||
sse_transport = SseServerTransport("/messages/")
|
|
||||||
|
|
||||||
|
|
||||||
class HandleSSE:
|
|
||||||
"""ASGI app for SSE connections."""
|
|
||||||
async def __call__(self, scope: Any, receive: Any, send: Any) -> None:
|
|
||||||
# Extract user from Authorization header for multi-user MCP
|
|
||||||
user_id = "default"
|
|
||||||
for name, value in scope.get("headers", []):
|
|
||||||
if name == b"authorization":
|
|
||||||
token = value.decode().removeprefix("Bearer ").strip()
|
|
||||||
resolved = _resolve_user_from_token(token)
|
|
||||||
if resolved:
|
|
||||||
user_id = resolved
|
|
||||||
break
|
|
||||||
_current_user.set(user_id)
|
|
||||||
async with sse_transport.connect_sse(scope, receive, send) as (read_stream, write_stream):
|
|
||||||
await mcp_server._mcp_server.run(
|
|
||||||
read_stream, write_stream, mcp_server._mcp_server.create_initialization_options()
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
# Streamable HTTP transport — session manager handles lifecycle automatically.
|
|
||||||
# More reliable through proxies than SSE since responses come in HTTP body.
|
|
||||||
streamable_session_mgr = StreamableHTTPSessionManager(
|
streamable_session_mgr = StreamableHTTPSessionManager(
|
||||||
app=mcp_server._mcp_server,
|
app=mcp_server._mcp_server,
|
||||||
json_response=True,
|
json_response=True,
|
||||||
|
|
@ -1247,10 +1222,7 @@ streamable_handler = HandleStreamableHTTP()
|
||||||
# Static files for UI (before MCP mount)
|
# Static files for UI (before MCP mount)
|
||||||
app.mount("/static", StaticFiles(directory=UI_DIR), name="static")
|
app.mount("/static", StaticFiles(directory=UI_DIR), name="static")
|
||||||
|
|
||||||
# Client connects to /mcp/sse, posts to /mcp/messages/ (SSE transport)
|
# MCP streamable-http transport at /mcp/mcp
|
||||||
# Client can also POST to /mcp/mcp (streamable-http transport)
|
|
||||||
app.router.routes.insert(0, Mount("/mcp", routes=[
|
app.router.routes.insert(0, Mount("/mcp", routes=[
|
||||||
Route("/sse", endpoint=HandleSSE()),
|
|
||||||
Mount("/messages", app=sse_transport.handle_post_message),
|
|
||||||
Route("/mcp", endpoint=streamable_handler, methods=["GET", "POST", "DELETE"]),
|
Route("/mcp", endpoint=streamable_handler, methods=["GET", "POST", "DELETE"]),
|
||||||
]))
|
]))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue