Building Docker Images for Python MCP Servers: A Production Guide with the Wordle Example

Use a multistage Dockerfile with Astral's uv package manager to build deterministic, minimal images (~30MB) for Python MCP servers, separating the build environment from the final production stage.

The Model Context Protocol (MCP) enables AI assistants to interact with external data sources through standardized server implementations. When deploying Python-based MCP servers in production, containerization ensures consistent environments and easy distribution. This guide examines the cr2007/mcp-wordle-python repository to demonstrate building Docker images for Python MCP servers using modern best practices.

Architecture of the Wordle MCP Server

The repository implements a minimal MCP server with three core components that influence the containerization strategy.

FastMCP Integration

The entry point at src/mcp_wordle/main.py instantiates a FastMCP object named WordleMCP and registers the asynchronous tool get_wordle_data. This tool fetches the official Wordle JSON from the New York Times API and returns the parsed solution.

Project Configuration

The pyproject.toml defines runtime dependencies (fastmcp and requests) and declares the mcp-wordle console script as the server entry point. This metadata drives the installation process inside the container.

Container Build Pipeline

A multistage Dockerfile leverages uv (Astral's high-performance Python package manager) to create reproducible builds with minimal layer caching invalidation.

Building Docker Images for Python MCP Servers

The Dockerfile implements a two-stage build strategy that separates dependency resolution from the final runtime environment.

The Builder Stage

The first stage uses ghcr.io/astral-sh/uv:0.7-python3.10-bookworm-slim as the base image. This stage installs the project into an isolated virtual environment:

FROM ghcr.io/astral-sh/uv:0.7-python3.10-bookworm-slim AS builder
WORKDIR /app
COPY pyproject.toml .
COPY src ./src
RUN uv sync --locked --no-dev

The uv sync --locked --no-dev command ensures deterministic builds using the locked dependency tree while excluding development dependencies.

The Production Stage

The final stage uses the official python:3.10-slim-bookworm image and copies only the prepared application directory from the builder:

FROM python:3.10-slim-bookworm
COPY --from=builder /app /app
ENV PATH="/app/.venv/bin:$PATH"
ENV PYTHONPATH="/app/src"
ENTRYPOINT ["mcp-wordle"]

This approach yields an image size of approximately 30MB, containing only the Python runtime, virtual environment, and application code.

Running the MCP Server Container

Configure your MCP client to launch the container using the Docker runtime:

{
  "mcpServers": {
    "Wordle MCP (Python)": {
      "command": "docker",
      "args": [
        "run",
        "--rm",
        "-i",
        "--init",
        "-e",
        "DOCKER_CONTAINER=true",
        "ghcr.io/cr2007/mcp-wordle-python:latest"
      ]
    }
  }
}

Pre-pull the image to avoid initialization delays:

docker pull ghcr.io/cr2007/mcp-wordle-python:latest

For local development without Docker, use uvx to run directly from the repository:

{
  "mcpServers": {
    "Wordle MCP (Python)": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/cr2007/mcp-wordle-python",
        "mcp-wordle"
      ]
    }
  }
}

Summary

  • Multistage builds separate dependency resolution from runtime, minimizing image size and attack surface when building Docker images for Python MCP servers.
  • Astral's uv provides deterministic, locked dependency installation via uv sync --locked --no-dev, significantly faster than traditional pip workflows.
  • The Wordle MCP server demonstrates production-ready containerization at approximately 30MB using python:3.10-slim-bookworm and the uv builder pattern.
  • Configure MCP clients to invoke containers via docker run with interactive flags (-i, --init) for proper signal handling and stdio communication.

Frequently Asked Questions

The python:3.10-slim-bookworm image (or similar slim variants) provides a minimal Debian-based runtime without unnecessary development tools. For the build stage, use ghcr.io/astral-sh/uv:0.7-python3.10-bookworm-slim to leverage the uv package manager's performance advantages and dependency locking capabilities.

How does uv improve Docker builds for Python MCP servers?

Uv implements a universal lockfile (uv.lock) that guarantees reproducible installations across environments. The uv sync --locked --no-dev command installs only production dependencies in a single layer, reducing build time and image size compared to traditional pip workflows that often require separate dependency resolution steps and larger base images.

Can I run the Wordle MCP server without Docker?

Yes. The repository supports running directly via uvx, which downloads and executes the package from GitHub without local cloning. Alternatively, install the package locally with pip install git+https://github.com/cr2007/mcp-wordle-python and invoke the mcp-wordle console script directly from your shell.

Why is the Docker image only 30MB when Python images are usually larger?

The minimal size results from three optimizations: using the slim Python base image (removing compilers and dev tools), excluding development dependencies via --no-dev, and copying only the compiled virtual environment from the builder stage. The final image contains only the Python runtime, the application code in /app/src, and the installed packages in /app/.venv.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →