Add /health endpoint for Docker healthchecks
- Create wrapper Starlette app with health route + FastMCP mount - Pass FastMCP lifespan to parent app for proper session management - Health returns JSON with status, version, timestamp, transport - Use uvicorn directly for better ASGI integration
This commit is contained in:
parent
322ed78427
commit
2e8517c62d
@ -12,6 +12,7 @@ Architecture uses official FastMCP MCPMixin pattern for clean separation of conc
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
from fastmcp import FastMCP
|
from fastmcp import FastMCP
|
||||||
from fastmcp.prompts import Prompt
|
from fastmcp.prompts import Prompt
|
||||||
@ -568,6 +569,11 @@ def main():
|
|||||||
|
|
||||||
if transport == "streamable-http":
|
if transport == "streamable-http":
|
||||||
# HTTP transport for hosted/Docker mode
|
# HTTP transport for hosted/Docker mode
|
||||||
|
import uvicorn
|
||||||
|
from starlette.applications import Starlette
|
||||||
|
from starlette.responses import JSONResponse
|
||||||
|
from starlette.routing import Route, Mount
|
||||||
|
|
||||||
host = os.environ.get("MCP_HOST", "0.0.0.0")
|
host = os.environ.get("MCP_HOST", "0.0.0.0")
|
||||||
port = int(os.environ.get("MCP_PORT", "8000"))
|
port = int(os.environ.get("MCP_PORT", "8000"))
|
||||||
|
|
||||||
@ -577,17 +583,37 @@ def main():
|
|||||||
except Exception:
|
except Exception:
|
||||||
pkg_version = "0.1.0"
|
pkg_version = "0.1.0"
|
||||||
|
|
||||||
|
# Health check endpoint
|
||||||
|
async def health_check(request):
|
||||||
|
return JSONResponse({
|
||||||
|
"status": "healthy",
|
||||||
|
"service": "mcwaddams",
|
||||||
|
"version": pkg_version,
|
||||||
|
"timestamp": datetime.now(timezone.utc).isoformat(),
|
||||||
|
"transport": "streamable-http",
|
||||||
|
})
|
||||||
|
|
||||||
|
# Get FastMCP's HTTP app
|
||||||
|
mcp_app = app.http_app()
|
||||||
|
|
||||||
|
# Create wrapper app with health endpoint + MCP routes
|
||||||
|
# IMPORTANT: Must pass mcp_app.lifespan to initialize task groups
|
||||||
|
wrapper_app = Starlette(
|
||||||
|
routes=[
|
||||||
|
Route("/health", health_check, methods=["GET"]),
|
||||||
|
Mount("/", app=mcp_app), # Mount MCP at root (serves /mcp)
|
||||||
|
],
|
||||||
|
lifespan=mcp_app.lifespan, # Required for FastMCP session management
|
||||||
|
)
|
||||||
|
|
||||||
print(f"🖨️ mcwaddams v{pkg_version}")
|
print(f"🖨️ mcwaddams v{pkg_version}")
|
||||||
print(f"📋 MCP Office Tools - Document Extraction Server")
|
print(f"📋 MCP Office Tools - Document Extraction Server")
|
||||||
print(f"🌐 Starting streamable-http transport on {host}:{port}")
|
print(f"🌐 Starting streamable-http transport on {host}:{port}")
|
||||||
print(f" Endpoint: http://{host}:{port}/mcp")
|
print(f" Endpoint: http://{host}:{port}/mcp")
|
||||||
|
print(f" Health: http://{host}:{port}/health")
|
||||||
print()
|
print()
|
||||||
|
|
||||||
app.run(
|
uvicorn.run(wrapper_app, host=host, port=port, log_level="info")
|
||||||
transport="streamable-http",
|
|
||||||
host=host,
|
|
||||||
port=port,
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
# Default stdio transport for local CLI usage
|
# Default stdio transport for local CLI usage
|
||||||
# CRITICAL: show_banner=False is required for stdio transport!
|
# CRITICAL: show_banner=False is required for stdio transport!
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user