From a2104917fdf17182ead7c28aafe8b0abf70fe0a4 Mon Sep 17 00:00:00 2001 From: Yigit Colakoglu Date: Tue, 30 Dec 2025 16:42:38 -0800 Subject: [PATCH] Add /health endpoint for Docker healthcheck MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The healthcheck was hitting /mcp which requires auth, causing unhealthy status. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- Dockerfile | 2 +- src/server.py | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 43a49c9..b577ef4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -35,7 +35,7 @@ EXPOSE 8000 # Health check HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \ - CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/mcp')" || exit 1 + CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')" || exit 1 # Use entrypoint to fix permissions, then run as mcp user ENTRYPOINT ["/entrypoint.sh"] diff --git a/src/server.py b/src/server.py index 31ec67e..0ad7f89 100644 --- a/src/server.py +++ b/src/server.py @@ -165,8 +165,15 @@ if __name__ == "__main__": import signal import uvicorn + from starlette.responses import JSONResponse + from starlette.routing import Route + from middleware import APIKeyAuthMiddleware + async def health_check(request): + """Health check endpoint for Docker/Traefik.""" + return JSONResponse({"status": "healthy"}) + async def main(): await initialize() @@ -176,6 +183,9 @@ if __name__ == "__main__": # Get the underlying ASGI app from FastMCP app = mcp.http_app(path="/mcp") + # Add health check route + app.routes.append(Route("/health", health_check)) + # Add authentication middleware if API key is configured if settings.mcp_api_key: app.add_middleware(