Skip to content

Commit d7110cf

Browse files
committed
fix http transport
1 parent 3bdb693 commit d7110cf

File tree

2 files changed

+33
-2
lines changed

2 files changed

+33
-2
lines changed

fastapi_mcp/server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ def mount_http(
347347

348348
assert isinstance(router, (FastAPI, APIRouter)), f"Invalid router type: {type(router)}"
349349

350-
http_transport = FastApiStreamableHttpTransport()
350+
http_transport = FastApiStreamableHttpTransport(mcp_server=self.server)
351351
dependencies = self._auth_config.dependencies if self._auth_config else None
352352

353353
self._register_mcp_endpoints_http(router, http_transport, mount_path, dependencies)

fastapi_mcp/transport/http.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import logging
22

33
from fastapi import Request, Response, HTTPException
4+
from mcp.server.lowlevel.server import Server
45
from mcp.server.streamable_http import StreamableHTTPServerTransport
56
from mcp.server.transport_security import TransportSecuritySettings
67

@@ -14,6 +15,7 @@ def __init__(
1415
is_json_response_enabled: bool = True, # Default to JSON for HTTP transport
1516
event_store=None,
1617
security_settings: TransportSecuritySettings | None = None,
18+
mcp_server: Server | None = None,
1719
):
1820
super().__init__(
1921
mcp_session_id=mcp_session_id,
@@ -22,8 +24,10 @@ def __init__(
2224
security_settings=security_settings,
2325
)
2426
logger.debug(f"FastApiStreamableHttpTransport initialized with session_id: {mcp_session_id}")
27+
self._mcp_server = mcp_server
28+
self._server_running = False
2529

26-
async def handle_fastapi_request(self, request: Request) -> Response:
30+
async def handle_fastapi_request(self, request: Request, mcp_server: Server | None = None) -> Response:
2731
"""
2832
The approach here is different from FastApiSseTransport.
2933
In FastApiSseTransport, we reimplement the SSE transport logic to have a more FastAPI-native transport.
@@ -37,6 +41,33 @@ async def handle_fastapi_request(self, request: Request) -> Response:
3741
"""
3842
logger.debug(f"Handling FastAPI request: {request.method} {request.url.path}")
3943

44+
# Use the stored server if available, or the passed one
45+
server = self._mcp_server or mcp_server
46+
if not server:
47+
raise HTTPException(status_code=500, detail="No MCP server available")
48+
49+
# Initialize the transport if not already done
50+
if not self._server_running:
51+
import anyio
52+
53+
async def start_server():
54+
self._server_running = True
55+
async with self.connect() as (reader, writer):
56+
await server.run(
57+
reader,
58+
writer,
59+
server.create_initialization_options(notification_options=None, experimental_capabilities={}),
60+
raise_exceptions=False,
61+
)
62+
63+
# Start the server in a background task
64+
import asyncio
65+
66+
asyncio.create_task(start_server())
67+
68+
# Give the server a moment to initialize
69+
await anyio.sleep(0.1)
70+
4071
# Capture the response from the SDK's handle_request method
4172
response_started = False
4273
response_status = 200

0 commit comments

Comments
 (0)