From 93981b900804f7f9403e2aface73ee12fb28b002 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9=20Delion?= Date: Tue, 2 Dec 2025 21:15:00 +0100 Subject: [PATCH] feat(hosting): Offer classic stateless HTTP mode Issue: APPAI-150 --- .../src/developer_mcp_server/http_app.py | 19 +++++++++++ .../src/developer_mcp_server/sse_app.py | 7 ++++ .../src/secops_mcp_server/http_app.py | 34 +++++++++++++++++++ .../src/secops_mcp_server/sse_app.py | 4 +++ 4 files changed, 64 insertions(+) create mode 100644 packages/developer_mcp_server/src/developer_mcp_server/http_app.py create mode 100644 packages/secops_mcp_server/src/secops_mcp_server/http_app.py diff --git a/packages/developer_mcp_server/src/developer_mcp_server/http_app.py b/packages/developer_mcp_server/src/developer_mcp_server/http_app.py new file mode 100644 index 0000000..d30501e --- /dev/null +++ b/packages/developer_mcp_server/src/developer_mcp_server/http_app.py @@ -0,0 +1,19 @@ +"""ASGI application for MCP server over StreamableHTTP. + +This module exports the ASGI application for use with ASGI servers like gunicorn + uvicorn. +It imports the configured MCP server and exposes its StreamableHTTP application. +""" + +from fastmcp.server.http import create_streamable_http_app + +from developer_mcp_server.server import mcp + +# Note: We use StreamableHTTP with json_response=True and stateless_http=True to enable +# fully stateless operation. This allows horizontal scaling without sticky sessions +# since no session state is maintained between requests. +http_app = create_streamable_http_app( + server=mcp, + streamable_http_path="/mcp", + json_response=True, + stateless_http=True, +) diff --git a/packages/developer_mcp_server/src/developer_mcp_server/sse_app.py b/packages/developer_mcp_server/src/developer_mcp_server/sse_app.py index 57745a7..dc66e8d 100644 --- a/packages/developer_mcp_server/src/developer_mcp_server/sse_app.py +++ b/packages/developer_mcp_server/src/developer_mcp_server/sse_app.py @@ -1,3 +1,10 @@ +"""ASGI application for MCP server over HTTP/SSE. + +Note: This SSE transport requires sticky sessions for horizontal scaling since +session state is maintained in-memory per worker. For stateless operation, +use http_app.py instead which uses StreamableHTTP with JSON responses. +""" + from fastmcp.server.http import create_sse_app from developer_mcp_server.server import mcp diff --git a/packages/secops_mcp_server/src/secops_mcp_server/http_app.py b/packages/secops_mcp_server/src/secops_mcp_server/http_app.py new file mode 100644 index 0000000..4e41be1 --- /dev/null +++ b/packages/secops_mcp_server/src/secops_mcp_server/http_app.py @@ -0,0 +1,34 @@ +"""ASGI application for MCP server over StreamableHTTP. + +This module exports the ASGI application for use with ASGI servers like gunicorn + uvicorn. +It imports the configured MCP server and exposes its StreamableHTTP application. + +This module is specifically for production deployment with gunicorn. +For local development, use the run_http_with_uvicorn() function instead. + + +""" + +import logging + +from fastmcp.server.http import create_streamable_http_app +from gg_api_core.sentry_integration import init_sentry + +from secops_mcp_server.server import mcp + +logger = logging.getLogger(__name__) + +# Initialize Sentry for production deployment +init_sentry() + +# Note: We use StreamableHTTP with json_response=True and stateless_http=True to enable +# fully stateless operation. This allows horizontal scaling without sticky sessions +# since no session state is maintained between requests. +app = create_streamable_http_app( + server=mcp, + streamable_http_path="/mcp", + json_response=True, + stateless_http=True, +) + +logger.info("MCP application initialized for StreamableHTTP transport (stateless JSON mode)") diff --git a/packages/secops_mcp_server/src/secops_mcp_server/sse_app.py b/packages/secops_mcp_server/src/secops_mcp_server/sse_app.py index fbfdd8e..49f0a4f 100644 --- a/packages/secops_mcp_server/src/secops_mcp_server/sse_app.py +++ b/packages/secops_mcp_server/src/secops_mcp_server/sse_app.py @@ -5,6 +5,10 @@ This module is specifically for production deployment with gunicorn. For local development, use the run_http_with_uvicorn() function instead. + +Note: This SSE transport requires sticky sessions for horizontal scaling since +session state is maintained in-memory per worker. For stateless operation, +use http_app.py instead which uses StreamableHTTP with JSON responses. """ import logging