From 64c372eb253b95b564bd1c8d6b80027b8995c6db Mon Sep 17 00:00:00 2001 From: John Donalson Date: Tue, 30 Dec 2025 05:38:11 -0500 Subject: [PATCH 1/4] Disable DNS rebinding protection for FastMCP in Docker Updated both mcp_indexer_server.py and mcp_memory_server.py to disable DNS rebinding protection in FastMCP by setting transport_security=TransportSecuritySettings(enable_dns_rebinding_protection=False). This change is necessary to allow proper internal networking when running the servers inside Docker containers. --- scripts/mcp_indexer_server.py | 9 ++++++--- scripts/mcp_memory_server.py | 11 +++++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/scripts/mcp_indexer_server.py b/scripts/mcp_indexer_server.py index 3da76d7d..ad6b59f6 100644 --- a/scripts/mcp_indexer_server.py +++ b/scripts/mcp_indexer_server.py @@ -213,10 +213,9 @@ def _highlight_snippet(snippet, tokens): # type: ignore try: - # Official MCP Python SDK (FastMCP convenience server) from mcp.server.fastmcp import FastMCP, Context # type: ignore + from mcp.server.transport_security import TransportSecuritySettings # type: ignore except Exception as e: # pragma: no cover - # Keep FastMCP import error loud; Context is for type hints only raise SystemExit("mcp package is required inside the container: pip install mcp") APP_NAME = os.environ.get("FASTMCP_SERVER_NAME", "qdrant-indexer-mcp") @@ -287,7 +286,11 @@ def _highlight_snippet(snippet, tokens): # type: ignore _work_script, ) -mcp = FastMCP(APP_NAME) +# Disable DNS rebinding protection - breaks Docker internal networking (Host: mcp:8000) +mcp = FastMCP( + APP_NAME, + transport_security=TransportSecuritySettings(enable_dns_rebinding_protection=False), +) # Capture tool registry automatically by wrapping the decorator once diff --git a/scripts/mcp_memory_server.py b/scripts/mcp_memory_server.py index 7db3fcdd..710a38bb 100644 --- a/scripts/mcp_memory_server.py +++ b/scripts/mcp_memory_server.py @@ -28,10 +28,11 @@ # FastMCP server and request Context (ctx) for per-connection state try: from mcp.server.fastmcp import FastMCP, Context # type: ignore + from mcp.server.transport_security import TransportSecuritySettings # type: ignore except Exception: - # Fallback: keep FastMCP import; treat Context as Any for type hints from mcp.server.fastmcp import FastMCP # type: ignore Context = Any # type: ignore + TransportSecuritySettings = None # type: ignore from scripts.mcp_auth import ( require_auth_session as _require_auth_session, @@ -122,7 +123,13 @@ def _ensure_once(name: str) -> bool: except Exception: return False -mcp = FastMCP(name="memory-server") +# Disable DNS rebinding protection - breaks Docker internal networking (Host: mcp:8000) +_security_settings = ( + TransportSecuritySettings(enable_dns_rebinding_protection=False) + if TransportSecuritySettings + else None +) +mcp = FastMCP(name="memory-server", transport_security=_security_settings) # Capture tool registry automatically by wrapping the decorator once _TOOLS_REGISTRY: list[dict] = [] From 54f571320d6f329eb59f8eed3b45bb9f5b045b79 Mon Sep 17 00:00:00 2001 From: John Donalson Date: Tue, 30 Dec 2025 05:46:12 -0500 Subject: [PATCH 2/4] Update mcp_indexer_server.py --- scripts/mcp_indexer_server.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/scripts/mcp_indexer_server.py b/scripts/mcp_indexer_server.py index ad6b59f6..09e3c270 100644 --- a/scripts/mcp_indexer_server.py +++ b/scripts/mcp_indexer_server.py @@ -214,10 +214,15 @@ def _highlight_snippet(snippet, tokens): # type: ignore try: from mcp.server.fastmcp import FastMCP, Context # type: ignore - from mcp.server.transport_security import TransportSecuritySettings # type: ignore except Exception as e: # pragma: no cover raise SystemExit("mcp package is required inside the container: pip install mcp") +# TransportSecuritySettings only exists in mcp >= 1.x with transport_security module +try: + from mcp.server.transport_security import TransportSecuritySettings # type: ignore +except ImportError: + TransportSecuritySettings = None # type: ignore + APP_NAME = os.environ.get("FASTMCP_SERVER_NAME", "qdrant-indexer-mcp") HOST = os.environ.get("FASTMCP_HOST", "0.0.0.0") PORT = safe_int( @@ -287,10 +292,12 @@ def _highlight_snippet(snippet, tokens): # type: ignore ) # Disable DNS rebinding protection - breaks Docker internal networking (Host: mcp:8000) -mcp = FastMCP( - APP_NAME, - transport_security=TransportSecuritySettings(enable_dns_rebinding_protection=False), +_security_settings = ( + TransportSecuritySettings(enable_dns_rebinding_protection=False) + if TransportSecuritySettings + else None ) +mcp = FastMCP(APP_NAME, transport_security=_security_settings) # Capture tool registry automatically by wrapping the decorator once From 8f59ff51c09e6b6671dc49ae131281e0380c8f83 Mon Sep 17 00:00:00 2001 From: John Donalson Date: Tue, 30 Dec 2025 11:44:15 -0500 Subject: [PATCH 3/4] Pin mcp and fastmcp versions in Dockerfiles Updated both Dockerfile and Dockerfile.mcp to explicitly pin mcp to 1.17.0 and fastmcp to 2.12.4 for consistency across services and alignment with requirements.txt. This ensures reproducible builds and avoids issues from unintentional upgrades. --- Dockerfile | 5 +++-- Dockerfile.mcp | 8 +++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Dockerfile b/Dockerfile index a3b544b8..8132373d 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,6 +14,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ && rm -rf /var/lib/apt/lists/* # Install Python dependencies for all services +# Pin mcp/fastmcp versions to match requirements.txt for consistency across services RUN pip install --no-cache-dir --upgrade \ qdrant-client \ fastembed \ @@ -22,8 +23,8 @@ RUN pip install --no-cache-dir --upgrade \ tokenizers \ tree_sitter \ tree_sitter_languages \ - mcp \ - fastmcp + 'mcp==1.17.0' \ + 'fastmcp==2.12.4' # Copy scripts for all services COPY scripts /app/scripts diff --git a/Dockerfile.mcp b/Dockerfile.mcp index 5d8a6a4f..aa6dbc01 100644 --- a/Dockerfile.mcp +++ b/Dockerfile.mcp @@ -8,8 +8,14 @@ ENV PYTHONDONTWRITEBYTECODE=1 \ TRANSFORMERS_CACHE=/tmp/cache # Install deps + create cache/rerank directories in single layer +# Pin versions to match requirements.txt for consistency across services # Pin qdrant-client to 1.15.x - version 1.16+ removed .search() which breaks OpenLit instrumentation -RUN pip install --no-cache-dir --upgrade mcp fastmcp 'qdrant-client>=1.15.0,<1.16.0' fastembed openlit \ +RUN pip install --no-cache-dir --upgrade \ + 'mcp==1.17.0' \ + 'fastmcp==2.12.4' \ + 'qdrant-client>=1.15.0,<1.16.0' \ + fastembed \ + openlit \ && mkdir -p /tmp/cache && chmod 755 /tmp/cache \ && mkdir -p /tmp/rerank_events /tmp/rerank_weights \ && chmod 777 /tmp/rerank_events /tmp/rerank_weights From 1c8817a6a1d3c8144ed880cacd36d90283b0cbe3 Mon Sep 17 00:00:00 2001 From: John Donalson Date: Tue, 30 Dec 2025 12:21:50 -0500 Subject: [PATCH 4/4] Refactor Dockerfiles to use shared requirements.txt Updated both Dockerfile and Dockerfile.mcp to install Python dependencies from a shared requirements.txt file for improved consistency and maintainability across services. --- Dockerfile | 15 +++------------ Dockerfile.mcp | 13 ++++--------- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8132373d..c9635c20 100644 --- a/Dockerfile +++ b/Dockerfile @@ -13,18 +13,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ curl \ && rm -rf /var/lib/apt/lists/* -# Install Python dependencies for all services -# Pin mcp/fastmcp versions to match requirements.txt for consistency across services -RUN pip install --no-cache-dir --upgrade \ - qdrant-client \ - fastembed \ - watchdog \ - onnxruntime \ - tokenizers \ - tree_sitter \ - tree_sitter_languages \ - 'mcp==1.17.0' \ - 'fastmcp==2.12.4' +# Python deps: reuse shared requirements file for consistency across services +COPY requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir --upgrade -r /tmp/requirements.txt # Copy scripts for all services COPY scripts /app/scripts diff --git a/Dockerfile.mcp b/Dockerfile.mcp index aa6dbc01..a97142ed 100644 --- a/Dockerfile.mcp +++ b/Dockerfile.mcp @@ -7,15 +7,10 @@ ENV PYTHONDONTWRITEBYTECODE=1 \ HF_HOME=/tmp/cache \ TRANSFORMERS_CACHE=/tmp/cache -# Install deps + create cache/rerank directories in single layer -# Pin versions to match requirements.txt for consistency across services -# Pin qdrant-client to 1.15.x - version 1.16+ removed .search() which breaks OpenLit instrumentation -RUN pip install --no-cache-dir --upgrade \ - 'mcp==1.17.0' \ - 'fastmcp==2.12.4' \ - 'qdrant-client>=1.15.0,<1.16.0' \ - fastembed \ - openlit \ +# Python deps: reuse shared requirements file for consistency across services +# Create cache/rerank directories in same layer +COPY requirements.txt /tmp/requirements.txt +RUN pip install --no-cache-dir --upgrade -r /tmp/requirements.txt \ && mkdir -p /tmp/cache && chmod 755 /tmp/cache \ && mkdir -p /tmp/rerank_events /tmp/rerank_weights \ && chmod 777 /tmp/rerank_events /tmp/rerank_weights