Skip to content

Instantly share code, notes, and snippets.

@grahama1970
Last active February 22, 2025 16:46
Show Gist options
  • Save grahama1970/65cf2fe1c6e04d2493000d268015fb7d to your computer and use it in GitHub Desktop.
Save grahama1970/65cf2fe1c6e04d2493000d268015fb7d to your computer and use it in GitHub Desktop.
MCP Python & TypeScript SDKs fail to run persistently in Docker. mcp.run() exits immediately despite a defined lifespan, breaking deployments. No official examples work. If neither SDK functions in real-world use, MCP may not be production-ready.

README: MCP SDK Docker Deployment Issue

Problem Summary

MCP's Python and TypeScript SDKs fail to run persistently in Docker. Despite setting a lifespan in the Python SDK, mcp.run() exits immediately, shutting down the container. This issue affects all tested MCP projects, making real-world deployment impossible.

Reproducible Steps

  1. Create an MCP server using the Python SDK with a lifespan function to manage resources.
  2. Build and run the Docker container.
  3. The MCP server connects to ArangoDB, logs success, and then exits immediately.
  4. The same behavior is observed with the TypeScript SDK.

Expected Behavior

  • MCP server should stay running, allowing tools to execute.
  • Docker should keep the container active like any other long-running service.

Actual Behavior

  • MCP starts, connects to ArangoDB, and exits immediately.
  • The container stops despite defining lifespan.
  • No errors are logged, just unexpected termination.

Possible Causes

  • mcp.run() might not block as expected, making it unsuitable for long-lived Docker processes.
  • The SDKs may have unresolved issues preventing persistent execution.
  • Lack of real-world testing in containerized environments.

Next Steps

  • Check Issue #223 in the Python SDK for related problems.
  • Wait for official fixes if MCP is still in development.
  • Consider alternatives if deployment is critical.

🚨 Current Status: MCP is NOT production-ready for Docker. 🚨

import os
import sys
import asyncio
from typing import AsyncIterator
from contextlib import asynccontextmanager
from arango import ArangoClient
from arango.exceptions import ArangoError
from mcp.server.fastmcp import FastMCP
from mcp.types import TextContent
from loguru import logger
# Configure logging
logger.remove()
logger.add(sys.stderr, level="INFO", format="<green>{time:YYYY-MM-DD HH:mm:ss}</green> | <level>{level}</level> | <cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> - <level>{message}</level>")
# ArangoDB connection settings
ARANGO_URL = os.getenv("ARANGO_URL", "http://localhost:8529")
ARANGO_DB = os.getenv("ARANGO_DB", "verifaix")
ARANGO_USERNAME = os.getenv("ARANGO_USERNAME", "root")
ARANGO_PASSWORD = os.getenv("ARANGO_PASSWORD", "openSesame")
class ArangoDBContext:
"""Context manager for handling ArangoDB connection."""
def __init__(self):
self.client = None
self.db = None
async def connect(self):
"""Establish connection to ArangoDB."""
logger.info(f"πŸ”— Connecting to ArangoDB at {ARANGO_URL}...")
try:
self.client = ArangoClient(hosts=ARANGO_URL)
self.db = self.client.db(ARANGO_DB, username=ARANGO_USERNAME, password=ARANGO_PASSWORD)
version = self.db.version()
logger.info(f"βœ… Connected to ArangoDB. Version: {version}")
except ArangoError as e:
logger.error(f"❌ Failed to connect to ArangoDB: {str(e)}")
raise e
async def disconnect(self):
"""Disconnect from ArangoDB (if needed)."""
logger.info("πŸ›‘ Closing ArangoDB connection...")
self.client = None # ArangoDB client does not need explicit close
logger.info("βœ… ArangoDB connection closed.")
@asynccontextmanager
async def app_lifespan(server: FastMCP) -> AsyncIterator[dict]:
"""Manage application lifecycle with ArangoDB."""
context = ArangoDBContext()
try:
await context.connect() # βœ… Establish DB connection on startup
yield {"db": context.db} # βœ… Store the DB in the lifespan context
finally:
await context.disconnect() # βœ… Cleanup on shutdown
# Initialize MCP with lifespan support
mcp = FastMCP(
name="ArangoDB Tools",
version="0.1.0",
description="ArangoDB MCP Server",
lifespan=app_lifespan # βœ… Ensure server stays alive
)
@mcp.tool()
def list_collections(ctx) -> TextContent:
"""List all collections in the ArangoDB database."""
db = ctx.request_context.lifespan_context["db"] # βœ… Get DB from lifespan
try:
collections = db.collections()
collection_list = [col["name"] for col in collections]
logger.info(f"πŸ“‚ Listed {len(collection_list)} collections.")
return TextContent(type="text", text=str(collection_list))
except ArangoError as e:
logger.error(f"❌ Error listing collections: {str(e)}")
return TextContent(type="text", text=f"Error: {str(e)}")
if __name__ == "__main__":
try:
logger.info("πŸš€ Starting ArangoDB MCP server...")
mcp.run() # βœ… This should now block and keep the server running
except Exception as e:
logger.error(f"❌ MCP Server startup failed: {str(e)}")
sys.exit(1)
FROM python:3.10-slim
WORKDIR /app
# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
python3-dev \
curl \
&& rm -rf /var/lib/apt/lists/*
# Install uv and create virtual environment
RUN pip install uv && uv venv
# Activate virtual environment
ENV PATH="/app/.venv/bin:$PATH"
# Copy project files
COPY pyproject.toml .
COPY src/ src/
# Install dependencies using uv
RUN uv pip install -e .
RUN uv pip install "mcp[cli]"
# Set default environment variables
ENV ARANGO_URL=http://arangodb:8529
ENV ARANGO_DB=verifaix
ENV ARANGO_USERNAME=root
ENV ARANGO_PASSWORD=openSesame
CMD ["python", "-m", "arango_mcp.main"]
services:
mcp-server:
build: .
environment:
- ARANGO_URL=http://arangodb:8529 # Use container name as hostname
- ARANGO_DB=verifaix
- ARANGO_USERNAME=root
- ARANGO_PASSWORD=openSesame
ports:
- "3003:3000" # MCP server port
networks:
- default
volumes:
arango_data:
networks:
default:
name: docker_utils_sglang-network
external: true
2025-02-22 11:13:11 2025-02-22 16:13:11 | INFO | __main__:<module>:79 - πŸš€ Starting ArangoDB MCP server...
2025-02-22 11:13:11 2025-02-22 16:13:11 | INFO | __main__:connect:30 - πŸ”— Connecting to ArangoDB at http://arangodb:8529...
2025-02-22 11:13:11 2025-02-22 16:13:11 | INFO | __main__:connect:35 - βœ… Connected to ArangoDB. Version: 3.12.4
2025-02-22 11:13:11 2025-02-22 16:13:11 | INFO | __main__:disconnect:42 - πŸ›‘ Closing ArangoDB connection...
2025-02-22 11:13:11 2025-02-22 16:13:11 | INFO | __main__:disconnect:44 - βœ… ArangoDB connection closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment