modelcontextprotocol / modelcontextprotocol/python-sdk

FastMCP: streamable_http_app() silently breaks when BaseHTTPMiddleware is added

Đang mở
#2,702 5 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

bug needs repro P3 potentially close
Ngôn ngữ chính
Python
Star
24.3k
Fork
4k
Merge trung bình
1 ngày 1 giờ
Pull request đã merge (30 ngày)
31

Mô tả

Description

Adding a Starlette BaseHTTPMiddleware (e.g., for auth) to FastMCP.streamable_http_app() silently breaks the MCP server. Every request crashes with ClosedResourceError — the client sees "peer closed connection without sending complete message body."

Reproduction

from mcp.server.fastmcp import FastMCP
from starlette.middleware.base import BaseHTTPMiddleware

mcp = FastMCP("test")

# Any BaseHTTPMiddleware — even a no-op passthrough
class AuthMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        return await call_next(request)

mcp.streamable_http_app().add_middleware(BaseHTTPMiddleware, dispatch=AuthMiddleware)

Run the server, send any MCP initialize request → ClosedResourceError.

Root cause

BaseHTTPMiddleware wraps the ASGI receive/send channels in a way incompatible with SSE streaming. This is a known Starlette limitation (encode/starlette#919), but FastMCP users hit it naturally when they reach for the obvious auth pattern.

Expected behavior

At minimum: warn at startup when a BaseHTTPMiddleware subclass is detected on a streamable HTTP app. Ideally: document prominently that users should use FastMCP's own Middleware class (fastmcp.server.middleware.Middleware) instead of Starlette's BaseHTTPMiddleware.

Workaround (raw ASGI middleware)

from starlette.types import ASGIApp, Receive, Scope, Send

class RawAuthMiddleware:
    def __init__(self, app: ASGIApp):
        self.app = app

    async def __call__(self, scope: Scope, receive: Receive, send: Send):
        # auth check here — read headers from scope
        await self.app(scope, receive, send)

mcp.streamable_http_app().add_middleware(RawAuthMiddleware)

Environment

  • mcp / FastMCP from modelcontextprotocol/python-sdk
  • Starlette (any version — this is architectural, not a regression)
  • Python 3.12

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu từ điểm vào FastMCP.streamable_http_app() và kiểm tra cách middleware được đăng ký xung quanh ứng dụng HTTP streamable. Tái hiện lỗi bằng ví dụ no-op BaseHTTPMiddleware, sau đó xác định cách hoạt động của việc phát hiện khi khởi động và hành vi cảnh báo. Được xem là hoàn tất khi lỗi được nêu rõ ràng và người dùng được hướng đến Middleware của FastMCP hoặc giải pháp thay thế ASGI thô.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
python
Lĩnh vực
backend-api-design
Loại issue
Lỗi
Độ khó
3/5
Thời gian dự kiến
1-2 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
64/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.