|
1 | 1 | import asyncio |
2 | 2 | from importlib import metadata |
3 | | -from typing import Annotated |
| 3 | +from typing import Annotated, Any |
4 | 4 |
|
5 | 5 | import typer |
| 6 | +import uvicorn |
| 7 | +from fastapi import FastAPI |
| 8 | +from fastapi.responses import JSONResponse |
| 9 | +from starlette.middleware.base import BaseHTTPMiddleware |
| 10 | +from starlette.requests import Request |
6 | 11 |
|
7 | 12 | from open_targets_platform_mcp.create_server import create_server |
8 | 13 | from open_targets_platform_mcp.settings import TransportType, settings |
@@ -151,12 +156,26 @@ def root( |
151 | 156 |
|
152 | 157 | try: |
153 | 158 | if settings.transport == TransportType.HTTP: |
154 | | - mcp.run( |
| 159 | + |
| 160 | + class MCPMethodOverrideMiddleware(BaseHTTPMiddleware): |
| 161 | + async def dispatch(self, request: Request, call_next: Any) -> JSONResponse: |
| 162 | + if request.url.path in {"/mcp", "/mcp/"} and request.method in {"GET", "HEAD", "OPTIONS"}: |
| 163 | + return JSONResponse( |
| 164 | + status_code=405, |
| 165 | + content={"error": "Method Not Allowed"}, |
| 166 | + headers={"Allow": "POST"}, |
| 167 | + ) |
| 168 | + return await call_next(request) |
| 169 | + |
| 170 | + mcp_asgi = mcp.http_app( |
| 171 | + path="/", |
155 | 172 | transport=settings.transport.value, |
156 | | - host=settings.http_host, |
157 | | - port=settings.http_port, |
158 | 173 | stateless_http=settings.stateless_http, |
159 | 174 | ) |
| 175 | + app = FastAPI(lifespan=mcp_asgi.lifespan) |
| 176 | + app.mount("/mcp", mcp_asgi) |
| 177 | + app.add_middleware(MCPMethodOverrideMiddleware) |
| 178 | + uvicorn.run(app, host=settings.http_host, port=settings.http_port) |
160 | 179 | else: |
161 | 180 | mcp.run( |
162 | 181 | transport=settings.transport.value, |
|
0 commit comments