MCP-Server mit Docker isolieren: Sichere und plattformunabhängige Containerisierung
Die Isolierung eines MCP-Servers mit Docker bedeutet, den Server samt Laufzeit und Abhängigkeiten in einem abgeschotteten Container auszuführen. Dadurch lassen sich die Datei-, Netzwerk- und Systemzugriffe eines LLM-gesteuerten Tools gezielt begrenzen, während die übrige Host-Umgebung weitgehend vom ausgeführten MCP-Server getrennt bleibt.
Was bedeutet MCP-Server-Isolierung via Docker?
Das Model Context Protocol (MCP) ermöglicht es KI-Anwendungen, externe Werkzeuge und Datenquellen über standardisierte Schnittstellen zu verwenden. Ein MCP-Server kann beispielsweise Dateien lesen, Datenbanken abfragen, APIs aufrufen oder Befehle über speziell dafür entwickelte Tools ausführen.
Bei einem lokalen MCP-Server kommt häufig der stdio-Transport zum Einsatz. Dabei startet der MCP-Client den Server als lokalen Prozess und kommuniziert über dessen Standardeingabe und Standardausgabe mit ihm. Wird ein solcher Server direkt über Node.js, Python oder eine andere Runtime auf dem Host gestartet, läuft er grundsätzlich im Kontext des lokalen Betriebssystems. Welche Dateien, Netzwerkziele oder Umgebungsvariablen er tatsächlich erreichen kann, hängt dann von den Berechtigungen des Prozesses und seiner eigenen Implementierung ab.
Docker fügt zwischen MCP-Server und Host eine zusätzliche Isolationsschicht ein. Der Server läuft mit einem eigenen Dateisystem, eigenen Prozess-Namensräumen und konfigurierbaren Berechtigungen. Zugriff auf Dateien des Hosts erhält er nur dann, wenn entsprechende Verzeichnisse gezielt eingebunden werden. Auch Netzwerkzugriffe und verfügbare Systemressourcen lassen sich zusätzlich einschränken.
Dabei sollte ein Container jedoch nicht als uneingeschränkte Sicherheitsgarantie verstanden werden. Besonders Optionen wie --privileged, weitreichende Host-Mounts oder das Einbinden des Docker-Sockets können die Schutzwirkung erheblich reduzieren.
- 100 % DSGVO-konform und sicher in Deutschland gehostet
- Die leistungsstärksten KI-Modelle auf einer Plattform
- Kein Vendor Lock-in durch Open Source
Sicherheitsvorteile der Containerisierung
Der wichtigste Vorteil besteht darin, dass Sie einem MCP-Server nach dem Prinzip der minimal notwendigen Rechte nur die Ressourcen zur Verfügung stellen können, die er tatsächlich benötigt.
✓ Das Dateisystem des Hosts bleibt weitgehend getrennt. Nur explizit eingebundene Verzeichnisse werden für den Container sichtbar. Wenn der MCP-Server Dateien lediglich lesen soll, können Sie diese zusätzlich als schreibgeschützten Mount einbinden.
✓ Die Rechte des Serverprozesses lassen sich reduzieren. Ein MCP-Server sollte innerhalb des Containers nicht als root, sondern als dedizierter User ohne administrative Rechte ausgeführt werden.
✓ Netzwerkzugriffe lassen sich begrenzen. Ein MCP-Server, der ausschließlich mit lokal eingebundenen Dateien arbeitet, kann beispielsweise mit --network=none ohne externen Netzwerkzugriff gestartet werden. Benötigt das Tool externe APIs oder Datenbanken, muss der notwendige Netzwerkzugriff entsprechend zugelassen werden.
✓ Zusätzliche Linux-Berechtigungen können entzogen werden. Optionen wie --cap-drop=ALL und --security-opt no-new-privileges=true reduzieren Möglichkeiten zur Privilegienausweitung weiter. Docker verwendet darüber hinaus standardmäßig ein Seccomp-Profil, das verschiedene sicherheitskritische Systemaufrufe blockiert.
✓ Abhängigkeiten bleiben vom Host-System getrennt. Node.js-, Python- oder Systembibliotheken befinden sich im Container-Image und müssen nicht global auf dem Entwicklungsrechner installiert werden. Unterschiedliche MCP-Server können dadurch unterschiedliche Versionen derselben Abhängigkeiten verwenden.
✓ Die Ausführungsumgebung wird reproduzierbarer. Dasselbe Image kann auf unterschiedlichen Systemen mit einer kompatiblen Docker-Umgebung eingesetzt werden. Host-spezifische Unterschiede verschwinden dadurch allerdings nicht vollständig: Insbesondere Pfade für Bind-Mounts und einige Plattformdetails müssen weiterhin berücksichtigt werden.
✓ Third-Party-Tools werden stärker isoliert. Enthält ein fremder MCP-Server fehlerhaften oder kompromittierten Code, begrenzt die Container-Konfiguration, auf welche Host-Ressourcen dieser zugreifen kann.
Schlankes Dockerfile für einen MCP-Server erstellen
Für einen Node.js-basierten MCP-Server eignet sich beispielsweise ein kleines offizielles Node-Image wie node:24-alpine. Im Gegensatz zum beweglichen Tag node:lts-alpine bleibt damit zumindest die Node.js-Major-Version festgelegt. Für vollständig reproduzierbare Builds sollte das Basis-Image zusätzlich auf eine konkrete Version oder einen Digest festgelegt werden. Alpine-basierte Images sind besonders kompakt, verwenden allerdings musl statt glibc. Bei nativen Abhängigkeiten kann deshalb eine Debian-basierte Slim-Variante kompatibler sein.
Ein einfaches Dockerfile kann folgendermaßen aufgebaut sein:
FROM node:24-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY --chown=node:node . .
ENV NODE_ENV=production
USER node
CMD ["node", "src/index.js"]dockerfileDie Anweisung FROM definiert zunächst das Basis-Image. Mit WORKDIR /app wird anschließend das Arbeitsverzeichnis innerhalb des Containers festgelegt.
Danach werden zunächst package.json und die zugehörige Lock-Datei kopiert und die Produktionsabhängigkeiten über npm ci --omit=dev installiert. Erst anschließend folgt der eigentliche Quellcode. Diese Reihenfolge ermöglicht es Docker, bereits erzeugte Build-Layer wiederzuverwenden, solange sich die Abhängigkeiten nicht geändert haben.
Besonders wichtig für die Isolation ist die Zeile USER node. Ohne eine entsprechende USER-Anweisung läuft der Hauptprozess eines Containers standardmäßig als root. Das offizielle Node-Image stellt bereits den User node bereit, sodass für dieses Beispiel kein zusätzlicher Benutzer angelegt werden muss.
Das Image bauen Sie anschließend beispielsweise mit folgendem Befehl:
docker build -t my-mcp-server:local .bashFür produktive oder besonders reproduzierbare Umgebungen empfiehlt es sich zusätzlich, Basis-Images kontrolliert zu aktualisieren oder auf einen konkreten Image-Digest festzulegen.
Schreibzugriffe zusätzlich beschränken
Ein Non-Root-Benutzer verhindert nicht automatisch sämtliche Schreibzugriffe innerhalb des Containers. Deshalb kann der Container zusätzlich mit einem schreibgeschützten Root-Dateisystem gestartet werden:
docker run --rm -i --read-only my-mcp-server:localbashFalls die Anwendung temporäre Dateien benötigt, kann /tmp separat als flüchtiger Speicher bereitgestellt werden:
--tmpfs /tmp:rw,nosuid,nodev,noexec,size=64mbashDie Daten in einem solchen tmpfs werden nicht dauerhaft gespeichert und verschwinden beim Beenden des Containers. Falls der MCP-Server ausführbare Dateien in /tmp ablegt oder startet, kann noexec zu Fehlern führen und sollte für diesen Anwendungsfall entfernt werden.
- Kostengünstige vCPUs und leistungsstarke dedizierte Cores
- Höchste Flexibilität ohne Mindestvertragslaufzeit
- Inklusive 24/7 Experten-Support
MCP-Server über Docker in den MCP-Client einbinden
Bei einem lokalen MCP-Server mit stdio muss der Client nicht mehr unmittelbar node, python oder eine andere Runtime starten. Stattdessen kann er docker run aufrufen. Docker startet daraufhin den isolierten Container und verbindet dessen Standardeingabe und Standardausgabe mit dem MCP-Client.
Bei Claude Desktop werden lokale MCP-Server über das Objekt mcpServers in der Datei claude_desktop_config.json konfiguriert. Dies ist von den über die Claude-Oberfläche eingerichteten Remote-MCP-Connectors zu unterscheiden.
Eine gehärtete Beispielkonfiguration kann folgendermaßen aussehen:
{
"mcpServers": {
"isolated-tools": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--read-only",
"--cap-drop=ALL",
"--security-opt",
"no-new-privileges=true",
"--pids-limit=128",
"--memory=512m",
"--cpus=1",
"--network=none",
"--tmpfs",
"/tmp:rw,nosuid,nodev,noexec,size=64m",
"--mount",
"type=bind,src=/ABSOLUTER/PFAD/ZUM/PROJEKT,dst=/data,readonly",
"my-mcp-server:local"
]
}
}
}jsonDer Platzhalter /ABSOLUTER/PFAD/ZUM/PROJEKT muss durch das Verzeichnis ersetzt werden, auf das der MCP-Server zugreifen darf. Benötigt der Server überhaupt keine Dateien vom Host, sollte auf diesen Mount vollständig verzichtet werden.
Die wichtigsten Parameter haben dabei folgende Funktionen:
| Docker-Parameter | Funktion beim MCP-Betrieb |
|---|---|
-i |
Hält stdin offen und ermöglicht die MCP-Kommunikation über stdio |
--rm |
Entfernt den Container automatisch nach dem Beenden. Nach einem Absturz des MCP-Clients sollten Sie mit docker ps prüfen, ob der Container weiterhin läuft. |
--mount … readonly |
Bindet einen Host-Pfad schreibgeschützt in den Container ein |
--read-only |
Macht das Root-Dateisystem des Containers schreibgeschützt |
--network=none |
Deaktiviert den Netzwerkzugriff des Containers |
--cap-drop=ALL |
Entfernt zusätzliche Linux-Berechtigungen |
--security-opt no-new-privileges=true |
Verhindert das Erlangen zusätzlicher Privilegien |
--memory, --cpus, --pids-limit |
Begrenzen Speicher, CPU und Prozessanzahl |
--tmpfs |
Stellt temporären, nicht persistenten Speicher bereit |
Nicht jeder MCP-Server benötigt sämtliche Härtungsoptionen. Ein Tool für eine Web-API funktioniert beispielsweise nicht mit --network=none, während ein Tool, das Dateien bearbeiten soll, ein gezielt freigegebenes Read-Write-Verzeichnis benötigt. Entscheidend ist deshalb, Rechte nicht pauschal einzuräumen, sondern vom tatsächlichen Einsatzzweck des Servers abzuleiten.
Für stdio-basierte MCP-Server gilt außerdem eine wichtige technische Regel: Die Standardausgabe stdout dient dem MCP-Protokoll. Zusätzliche Logmeldungen sollten daher über stderr ausgegeben werden. Bereits eine gewöhnliche Logausgabe auf stdout kann den JSON-RPC-Datenstrom stören.
Als Alternative zur manuellen Container-Konfiguration bietet Docker das MCP Toolkit mit Catalog und MCP Gateway an. Damit lassen sich containerisierte MCP-Server zentral verwalten und mit MCP-Clients verbinden. Das Toolkit wird in Docker Desktop über die Beta-Funktionen aktiviert: „Settings“ → „Beta features“ → „Enable Docker MCP Toolkit“. Die aktuelle Docker-Dokumentation beschreibt die Oberfläche ab Docker Desktop 4.62; ältere Versionen können davon abweichen.
Nur notwendige Verzeichnisse freigeben
Bind-Mounts gehören zu den wichtigsten Sicherheitsentscheidungen bei einem containerisierten MCP-Server. Ein Container benötigt beispielsweise keinen Zugriff auf das gesamte Home-Verzeichnis, wenn das Tool lediglich mit einem einzelnen Projektordner arbeiten soll.
Statt -v /Users/name:/data sollte daher möglichst nur der tatsächlich erforderliche Pfad eingebunden werden:
--mount type=bind,src=/Users/name/projekt,dst=/data,readonlybashBind-Mounts besitzen standardmäßig Schreibzugriff. Ein kompromittierter oder fehlerhafter MCP-Server könnte dadurch Dateien auf dem Host verändern oder löschen. Wenn Schreibzugriff nicht ausdrücklich benötigt wird, sollte der Mount deshalb mit readonly beziehungsweise ro versehen werden. Unter Linux gilt die Schreibschutzwirkung für enthaltene Unter-Mounts erst ab Kernel 5.12 rekursiv.
Vermieden werden sollte das Einbinden von /var/run/docker.sock, sofern der MCP-Server nicht ausdrücklich den Docker-Daemon verwalten muss. Zugriff auf diesen Socket erlaubt einem Container weitreichende Kontrolle über Docker und kann die zuvor aufgebaute Isolation praktisch aushebeln. Auch ein schreibgeschützter Socket-Mount beseitigt dieses Risiko nicht.
Grenzen der Container-Isolierung
Auch ein gehärteter Docker-Container bietet keine vollständige Trennung vom Host. Sicherheitslücken in Container-Runtime oder Docker können grundsätzlich Container-Escapes ermöglichen, weshalb Docker und die verwendeten Images regelmäßig aktualisiert werden sollten. Zusätzlichen Schutz können beispielsweise Rootless Docker mit der Docker Engine unter Linux oder Docker Desktops Enhanced Container Isolation (ECI, nur mit Docker-Business-Abo) bieten. Zugangsdaten und API-Keys sollten außerdem möglichst nicht unnötig als Umgebungsvariablen übergeben werden, sondern über geeignete Secret-Mechanismen bereitgestellt werden.
Fazit
Docker eignet sich gut, um lokale MCP-Server von der eigentlichen Entwicklungsumgebung zu trennen. Laufzeit, Bibliotheken und weitere Abhängigkeiten befinden sich im Container, während Datei-, Netzwerk- und Systemzugriffe gezielt eingeschränkt werden können. Dadurch lassen sich MCP-Tools reproduzierbarer und mit deutlich kleineren Berechtigungen betreiben als bei einer uneingeschränkten lokalen Ausführung.
Entscheidend ist die konkrete Container-Konfiguration. Ein Non-Root-Benutzer, möglichst kleine Images, restriktive und vorzugsweise schreibgeschützte Mounts, begrenzte Ressourcen und der Verzicht auf unnötige Netzwerk- oder Docker-Daemon-Zugriffe bilden zusammen eine sinnvolle Grundlage.