Container MCP servers

Run MCP servers in Docker or Podman containers.

Quick Start

Nothing to build: the servers from modelcontextprotocol/servers are published as images by Docker. Which of them to use, and when an image is the wrong answer, is in The official MCP servers.

# Pull the official images
podman pull docker.io/mcp/filesystem:latest
podman pull docker.io/mcp/memory:latest
podman pull docker.io/mcp/fetch:latest

# Create data directories
mkdir -p data/memory data/filesystem

Hangar used to ship docker/Dockerfile.* for these, and this guide gave the podman build commands. Two of them repackaged the same official npm package, one repackaged a third-party fork, and nothing in the repository built any of them -- so they were deleted (core#1095). There is no official sqlite server: that one was a third-party package whose upstream is archived, and it has no replacement here.

For a server you drive as a subprocess rather than a container, prefer the packages over the images -- npx -y @modelcontextprotocol/server-filesystem, uvx mcp-server-fetch. They are released continuously, while the published container images for filesystem and memory were last rebuilt in 2025.

Configuration

mcp_servers:
  filesystem:
    mode: container
    image: docker.io/mcp/filesystem:latest
    volumes:
      - "/absolute/path/to/data:/data:rw"
    network: bridge
    idle_ttl_s: 300
    resources:
      memory: 512m
      cpu: "1.0"

Important: Always use absolute paths. Relative paths (./data, ${PWD}) fail when MCP clients start the server from different directories.

Options

OptionDescriptionDefault
imageContainer imagerequired
volumesMount points (host:container:mode)[]
envEnvironment variables{}
networkNetwork mode: none, bridge, hostnone
network_modeAlias for network (Docker Compose compatibility)none
read_onlyRead-only root filesystemtrue
resources.memoryMemory limit512m
resources.cpuCPU limit1.0

Network Modes

  • none (default): No network access. Most secure, use for MCP servers that don't need external connectivity.
  • bridge: Isolated bridge network. Container can reach external services but is isolated from host network.
  • host: Share host network namespace. Required when MCP server needs to connect to services on localhost or has complex networking requirements.
# MCP Server that needs to connect to local Prometheus/VictoriaMetrics
prometheus:
  mode: docker
  image: ghcr.io/pab1it0/prometheus-mcp-server:latest
  network_mode: host  # or network: host
  env:
    PROMETHEUS_URL: "https://victoriametrics.example.com"

Custom Build

mcp_servers:
  custom:
    mode: container
    build:
      dockerfile: docker/Dockerfile.custom
      context: .
      tag: my-image:latest

Available Images

These are the servers from modelcontextprotocol/servers that Docker publishes. There is no official SQLite server -- the upstream one is archived -- so this guide no longer lists one.

Memory (Knowledge Graph)

memory:
  mode: container
  image: docker.io/mcp/memory:latest
  volumes:
    - "/path/to/data:/app/data:rw"

Tools: create_entities, create_relations, search_nodes, read_graph

hangar_call(calls=[{"mcp_server": "memory", "tool": "create_entities",
                    "arguments": {"entities": [
                        {"name": "Alice", "entityType": "Person", "observations": ["Engineer"]}
                    ]}}])

Filesystem

filesystem:
  mode: container
  image: docker.io/mcp/filesystem:latest
  volumes:
    - "/path/to/sandbox:/data:rw"

Tools: read_file, write_file, list_directory

Fetch

fetch:
  mode: container
  image: docker.io/mcp/fetch:latest
  network: bridge

Tools: fetch

hangar_call(calls=[{"mcp_server": "fetch", "tool": "fetch",
                    "arguments": {"url": "https://api.example.com/data"}}])

Troubleshooting

Container won't start

# Verify image
podman images docker.io/mcp/filesystem

# Test manually
echo '{"jsonrpc":"2.0","id":"1","method":"initialize","params":{}}' | \
  podman run --rm -i -v /path/to/data:/data:rw docker.io/mcp/filesystem:latest

Data not persisting

  1. Use absolute paths

  2. Check host directory permissions

  3. Verify mount:

    podman run --rm -v /path/to/data:/data:rw --entrypoint sh \
      docker.io/mcp/filesystem:latest -c "ls -la /data"

Permission denied

chmod 777 data/sqlite

Or set MCP_CI_RELAX_VOLUME_PERMS=true.

Environment Variables

VariableDefaultDescription
MCP_CONTAINER_RUNTIMEautoForce podman or docker
MCP_CI_RELAX_VOLUME_PERMSfalseChmod 777 on volumes (CI)