From cfc339e4f396bda0db9360fc4ce53d9fc5bc35dd Mon Sep 17 00:00:00 2001 From: Yongteng Lei Date: Wed, 30 Jul 2025 09:43:29 +0800 Subject: [PATCH] Feat: Enable MCP streamable-http model via docker compose (#9092) ### What problem does this PR solve? Enable MCP streamable-http model via docker compose ### Type of change - [x] New Feature (non-breaking change which adds functionality) --- docker/docker-compose.yml | 11 +++++++---- docker/entrypoint.sh | 20 +++++++++++++++++++- mcp/server/server.py | 4 ++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 2496ac9b5..3583afdf3 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -1,7 +1,5 @@ - include: - ./docker-compose-base.yml - # To ensure that the container processes the locally modified `service_conf.yaml.template` instead of the one included in its image, you need to mount the local `service_conf.yaml.template` to the container. services: ragflow: @@ -17,7 +15,13 @@ services: # - --mcp-base-url=http://127.0.0.1:9380 # - --mcp-script-path=/ragflow/mcp/server/server.py # - --mcp-mode=self-host - # - --mcp-host-api-key=ragflow-xxxxxxx + # - --mcp-host-api-key=ragflow-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx + # Optional transport flags for MCP (customize if needed). + # Host mode need to combined with --no-transport-streamable-http-enabled flag, namely, host+streamable-http is not supported yet. + # The following are enabled by default unless explicitly disabled with --no-. + # - --no-transport-sse-enabled # Disable legacy SSE endpoints (/sse and /messages/) + # - --no-transport-streamable-http-enabled # Disable Streamable HTTP transport (/mcp endpoint) + # - --no-json-response # Disable JSON response mode in Streamable HTTP transport (instead of SSE over HTTP) container_name: ragflow-server ports: - ${SVR_HTTP_PORT}:9380 @@ -34,7 +38,6 @@ services: - ../history_data_agent:/ragflow/history_data_agent - ./service_conf.yaml.template:/ragflow/conf/service_conf.yaml.template - ./entrypoint.sh:/ragflow/entrypoint.sh - env_file: .env environment: - TZ=${TIMEZONE} diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh index d4065c6fa..7570b73dd 100755 --- a/docker/entrypoint.sh +++ b/docker/entrypoint.sh @@ -37,6 +37,9 @@ MCP_BASE_URL="http://127.0.0.1:9380" MCP_SCRIPT_PATH="/ragflow/mcp/server/server.py" MCP_MODE="self-host" MCP_HOST_API_KEY="" +MCP_TRANSPORT_SSE_FLAG="--transport-sse-enabled" +MCP_TRANSPORT_STREAMABLE_HTTP_FLAG="--transport-streamable-http-enabled" +MCP_JSON_RESPONSE_FLAG="--json-response" # ----------------------------------------------------------------------------- # Host ID logic: @@ -91,6 +94,18 @@ for arg in "$@"; do MCP_SCRIPT_PATH="${arg#*=}" shift ;; + --no-transport-sse-enabled) + MCP_TRANSPORT_SSE_FLAG="--no-transport-sse-enabled" + shift + ;; + --no-transport-streamable-http-enabled) + MCP_TRANSPORT_STREAMABLE_HTTP_FLAG="--no-transport-streamable-http-enabled" + shift + ;; + --no-json-response) + MCP_JSON_RESPONSE_FLAG="--no-json-response" + shift + ;; --consumer-no-beg=*) CONSUMER_NO_BEG="${arg#*=}" shift @@ -150,7 +165,10 @@ function start_mcp_server() { --port="${MCP_PORT}" \ --base-url="${MCP_BASE_URL}" \ --mode="${MCP_MODE}" \ - --api-key="${MCP_HOST_API_KEY}" & + --api-key="${MCP_HOST_API_KEY}" \ + "${MCP_TRANSPORT_SSE_FLAG}" \ + "${MCP_TRANSPORT_STREAMABLE_HTTP_FLAG}" \ + "${MCP_JSON_RESPONSE_FLAG}" & } # ----------------------------------------------------------------------------- diff --git a/mcp/server/server.py b/mcp/server/server.py index cb000b3be..7cef2a056 100644 --- a/mcp/server/server.py +++ b/mcp/server/server.py @@ -374,6 +374,10 @@ __ __ ____ ____ ____ _____ ______ _______ ____ print(f"MCP port: {PORT}", flush=True) print(f"MCP base_url: {BASE_URL}", flush=True) + if not any([TRANSPORT_SSE_ENABLED, TRANSPORT_STREAMABLE_HTTP_ENABLED]): + print("At least one transport should be enabled, enable streamable-http automatically", flush=True) + TRANSPORT_STREAMABLE_HTTP_ENABLED = True + if TRANSPORT_SSE_ENABLED: print("SSE transport enabled: yes", flush=True) print("SSE endpoint available at /sse", flush=True)