fix(mcp): fix SSE streaming crash and reduce get_canvas token usage
- Replace BaseHTTPMiddleware with pure ASGI middleware in auth.py to fix the "Unexpected message: http.response.start" crash on SSE streams - Migrate from SseServerTransport to StreamableHTTPSessionManager in main.py - Add _slim_canvas() in tools.py to strip React Flow layout fields from get_canvas responses (60-80% payload reduction) - Update tests: assert canvas slimming, mock session_manager.handle_request in auth tests to avoid uninitialized task group errors
This commit is contained in:
+13
-14
@@ -1,7 +1,7 @@
|
||||
from contextlib import asynccontextmanager
|
||||
from fastapi import FastAPI
|
||||
from fastapi import FastAPI, Request
|
||||
from mcp.server import Server
|
||||
from mcp.server.sse import SseServerTransport
|
||||
from mcp.server.streamable_http_manager import StreamableHTTPSessionManager
|
||||
|
||||
from .auth import ApiKeyMiddleware
|
||||
from .backend_client import backend
|
||||
@@ -13,29 +13,28 @@ mcp_server = Server("homelable")
|
||||
register_resources(mcp_server)
|
||||
register_tools(mcp_server)
|
||||
|
||||
session_manager = StreamableHTTPSessionManager(
|
||||
app=mcp_server,
|
||||
json_response=False,
|
||||
stateless=True,
|
||||
)
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
async def lifespan(app: FastAPI):
|
||||
await backend.start()
|
||||
yield
|
||||
async with session_manager.run():
|
||||
yield
|
||||
await backend.stop()
|
||||
|
||||
|
||||
app = FastAPI(title="Homelable MCP", lifespan=lifespan)
|
||||
app.add_middleware(ApiKeyMiddleware)
|
||||
|
||||
sse = SseServerTransport("/mcp/messages")
|
||||
|
||||
|
||||
@app.get("/mcp")
|
||||
async def mcp_sse(request):
|
||||
async with sse.connect_sse(request.scope, request.receive, request._send) as streams:
|
||||
await mcp_server.run(streams[0], streams[1], mcp_server.create_initialization_options())
|
||||
|
||||
|
||||
@app.post("/mcp/messages")
|
||||
async def mcp_messages(request):
|
||||
await sse.handle_post_message(request.scope, request.receive, request._send)
|
||||
@app.api_route("/mcp", methods=["GET", "POST", "DELETE"])
|
||||
async def mcp_endpoint(request: Request):
|
||||
await session_manager.handle_request(request.scope, request.receive, request._send)
|
||||
|
||||
|
||||
@app.get("/health")
|
||||
|
||||
Reference in New Issue
Block a user