Docker MCP Server について
Docker MCP Serverは、AIエージェント向けにローカルまたはリモートのDockerデーモンを管理・監視する型付きツールを提供します。読み取り専用や破壊的操作の制限、出力の上限、ログや統計のリソースが特徴です。
主な機能
- 01コンテナ、イメージ、ネットワーク、ボリュームの管理
- 02SwarmサービスなどのDocker領域の操作
- 03読み取り専用・破壊的操作の識別
- 04全体モードによる書き込み制限
- 05リソースとしてのログと統計の参照
活用シーン
- 01コンテナ障害やリソース使用状況の調査
- 02ローカルおよびリモートのDocker環境の管理
- 03テスト環境と本番環境のデーモン状態の比較
MCP 対応
MCP サーバーとして、型付きのDocker操作ツールに加え、ログ、統計、SDKリファレンス、実行中のツールカタログをMCPクライアントに提供します。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
このサーバーのパッケージやリモートエンドポイントはまだ取得できていません。プロジェクトの README の手順に従ってください。
ツール
162掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| annotations | array | いいえ | |
| attest | array | いいえ | |
| build_args | object | いいえ | |
| build_contexts | object | いいえ | |
| builder | string | いいえ | |
| cache_from | array | いいえ | |
| cache_to | array | いいえ | |
| context | string | はい | |
| file | string | いいえ | |
| labels | object | いいえ | |
| load | boolean | いいえ | |
| no_cache | boolean | いいえ | |
| no_cache_filter | array | いいえ | |
| output | array | いいえ | |
| platforms | array | いいえ | |
| provenance | string | いいえ | |
| pull | boolean | いいえ | |
| push | boolean | いいえ | |
| sbom | string | いいえ | |
| secret | array | いいえ | |
| ssh | array | いいえ | |
| tags | array | いいえ | |
| target | string | いいえ | |
| timeout_seconds | number | いいえ |
詳細
docker-mcp-server
AI エージェントが Docker のコンテナ、イメージ、ネットワーク、ボリューム、swarm サービス、シークレット、設定、ノード、プラグインなどを管理できる、フル機能を備えたMCP サーバーであるだけでなく、Docker 環境を簡単に管理するためのワークフロー作成も支援します。
Docker CLI を直接呼び出すよりも、はるかに細かな制御と柔軟性を提供します。各操作は、それぞれ独立した型付きツールとして公開され、読み取り専用かどうかが明示されるほか、破壊的な操作には個別にフラグが付けられます。これにより、クライアントは読み取り操作を自動承認し、破壊的な操作は常に確認するようにできます。また、安全対策として、サーバー全体を読み取り専用モードまたは破壊的操作なしモードに切り替えることもできます。出力は際限なく増えることがないよう上限が設定されており、エージェントのコンテキストを黙ってあふれさせる代わりに、truncated フラグで切り詰められたことが示されます。
簡単なケースなら、設定不要でインストールしてすぐに使えます。読み込まれると、ローカルの Docker ソケットを検出し、すべてのコマンドを AI エージェントに公開します。より高度な用途では、1 回のセッションでローカルの開発環境とリモートの本番環境の両方など、複数の Docker デーモンを管理できます。接続にはTCP、TLS、または SSHを利用できます。一部のデーモンを読み取り専用として設定することもできるため、誤って変更を加えるリスクなしに監視できます。
Docker がインストールされていないマシン上でも実行でき、SSH、TLS、または TCP 経由でリモートデーモンを管理できます(一部の機能には SSH が必要です)。AI 自体にシェルや SSH へのアクセスは必要ありません。
MCP サーバーはログや統計情報などもリソースとして公開するため、監視や問題の切り分けが可能です。「コンテナがクラッシュしたのはなぜですか?」「swarm の状態はどうなっていますか?」「メモリ不足が発生していますか?」「ボリュームのディスク使用量はどれくらいですか?」「テスト環境と本番環境にはどのような違いがありますか?」といった質問に答えることができます。
ドキュメントは、設定する人だけでなくエージェント向けにも作られています。MCP リソースを通じて、セッション中に Docker SDK リファレンスを参照できます(リソースを読み取れないクライアント向けには、ツール呼び出しによる代替手段もあります)。また、ライブのツールカタログリソースには、現在の設定で登録されているツールが正確に表示されます。各ツールの説明には、最も近い用途のツールとそれぞれを選ぶべき状況、前提条件、副作用が平易な言葉で記載され、失敗する可能性についても正直に説明されています。そのため、エージェントは150以上の選択肢から推測で選ぶのではなく、最初から適切なツールを選べます。
docker-mcp-server は、ツールの遅延読み込みに対応した新世代の MCP クライアントで効率よく動作するよう最適化されています。すべてのツールを先読みするクライアント向けには、一部のドメインのツール(例:「swarm」と「scout」のツール)を除外して、ツール一覧のサイズを減らすよう任意で設定できます。また、MCP サーバーを「読み取り専用」モードまたは「破壊的操作なし」モードに設定し、書き込み機能または破壊的操作機能を持つツールが登録されないようにすることもできます。これによっても、使用するリソースを減らせます。
サーバーは、ネイティブ、mcpb バンドル、Claude プラグイン、またはコンテナとして、すべてお使いのマシン上で実行され、テレメトリーは送信されません。すべてを完全にご自身で管理できます。プライバシーポリシーをご覧ください。
要件
注:コンテナ化された MCP サーバーまたは MCPB バンドルを使用する場合、Python と uv の要件は自動的に満たされます。
- サーバーを実行するホストから到達可能な、稼働中の Docker デーモン(標準の
DOCKER_HOST/Unix ソケットの規則が適用されます) - Python ≥ 3.14
- 依存関係の管理用の uv
- Intel(x86_64)版 macOS のみ: ネイティブにインストールする場合(
uvx/pip、Claude プラグイン、.mcpbバンドル経由。いずれもローカルで依存関係を解決します)、Rust と OpenSSL 3.x が必要です。推移的依存関係であるcryptography(mcp->pyjwt[crypto]経由)は、バージョン 49.0.0 以降、x86_64 版 macOS 用のホイールが提供されておらず、そこでソースからビルドする必要があるためです。ビルドツールチェーンをインストールしたくない場合は、代わりにコンテナイメージを使用してください。Mac の CPU アーキテクチャに関係なく、同じビルド済み Linux バイナリが実行されるため、この要件は適用されません。詳しくはセキュリティに関する考慮事項をご覧ください。
サーバーの使用
サーバーは PyPI で docker-mcp-server として公開されています。AI ツールの MCP 設定(通常は mcp.json、またはクライアントの同等の設定)に、uvx でこのパッケージを指定するエントリーを追加してください。初回使用時に uv がパッケージを取得してキャッシュします。
{
"mcpServers": {
"docker-mcp-server": {
"command": "uvx",
"args": ["docker-mcp-server"],
"env": {}
}
}
}
特定のバージョンに固定するには、パッケージ名の末尾に ==<version> を追加します(例:docker-mcp-server==1.5.0)。代わりに PATH にインストールする場合は、pipx install docker-mcp-server を実行すると docker-mcp-server コンソールスクリプトが利用できます(docker-mcp エイリアスもインストールされます)。
代わりに git からインストールする場合。 このリポジトリから未リリースのリビジョンを直接実行するには、次のようにします。
{
"mcpServers": {
"docker-mcp-server": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/L337-org/docker-mcp.git",
"docker-mcp-server"
],
"env": {}
}
}
}
特定のリビジョンに固定するには、git URL の末尾に @<tag-or-commit> を追加します。
デスクトップ拡張機能(.mcpb)としてインストールする
Claude Desktop 用のワンクリックバンドルは、各
GitHub リリースに
docker-mcp-server-<version>.mcpb(対応する .sha256 付き)として添付されています。ダウンロードして
Settings > Extensions にドラッグするか、Settings > Extensions > Advanced settings > Install extension...
を選択してファイルを指定します。インストールダイアログには Docker host(s) フィールドと、読み取り専用/破壊的操作なし/ドメイン無効化の切り替え項目が表示されるため、JSON を手動で編集する必要はありません。
これは uv タイプのバンドルです。Claude Desktop が管理する
uv が依存関係を解決してサーバーを実行するため、ホストに必要なのは Docker のみです。
別途 Python、uv、git を用意する必要はありません。Docker host(s) フィールドを空欄にするとデフォルトの Docker コンテキストが使用されます。リモートデーモンにはエンドポイントを 1 つ(ssh://user@host)指定するか、複数指定してください(複数のデーモンの管理を参照)。
Claude プラグインとしてインストールする
claude-plugin/ フォルダーには、Anthropic のプラグインディレクトリ向けに、Claude Code と
Cowork 用プラグインとしてサーバーがパッケージ化されています。プラグインのビルド元であるリリースに固定された
uvx docker-mcp-server==<version> を実行するため、ホストに uv が必要です。
すべての依存関係をハッシュで固定するロックファイルが同梱されており、ディレクトリの説明では、固定された状態での起動により厳密に同じものがインストールされるとされています。それ以外の方法で読み込んだ場合、uvx はインストール時に依存関係を解決します。.mcpb のインストールダイアログと同じ設定(Docker host(s)、読み取り専用、破壊的操作なし、無効化するドメイン)を利用でき、Claude Code のプラグイン設定(/plugin)で指定します。リリースパイプラインは、PyPI へのリリース公開後、プラグインをインストールしてテストしてから、ディレクトリで提供されるプラグインを更新します。
コンテナとして実行する
サーバーをコンテナーとして実行すれば、Python/uv/git の前提条件がすべて不要になります。ホストに必要なのは Docker だけで、すでにインストールされています。ビルド済みのマルチアーキテクチャイメージ(linux/amd64 + linux/arm64)は、各リリース時に Docker Hub(gavinlucas/docker-mcp-server)と GHCR(ghcr.io/l337-org/docker-mcp-server)で公開されます。どちらも同一のイメージです。MCP クライアントから docker run を指定してください。
{
"mcpServers": {
"docker-mcp-server": {
"command": "docker",
"args": [
"run", "--rm", "-i",
"-v", "/var/run/docker.sock:/var/run/docker.sock",
"gavinlucas/docker-mcp-server:latest"
],
"env": {}
}
}
}
-i は必須です(サーバーは stdio 経由で MCP を使用します)。--rm を指定すると、クライアントの切断時にコンテナーが削除されます。バージョンを固定するには、:latest をリリースタグ(例::1.5.1)に置き換えてください。GHCR から取得する場合は、ghcr.io/l337-org/docker-mcp-server:latest を使用してください。
イメージ名が変更されました。 1.5.0 以降、イメージは
docker-mcp-server(PyPI の名前と一致)として公開されています。以前のghcr.io/gavinlucas/docker-mcpイメージは 1.4.0 で更新が終了しており、今後更新されません。新しいイメージを取得するには、ghcr.io/l337-org/docker-mcp-serverを指定してください。
イメージのバリアント。 2 つのバリアントが、両方のレジストリ(Docker Hub の gavinlucas/docker-mcp-server と GHCR の ghcr.io/l337-org/docker-mcp-server)で公開されています。どちらも 1 つの Dockerfile からビルドされます。CLI を使用するドメイン(Compose、Stack、Buildx、Scout、Context)は docker CLI とそのプラグインを呼び出します。Stack では stack_deploy のみがこれに該当します。
| バリアント | タグ | おおよそのサイズ | 含まれるもの |
|---|---|---|---|
full (デフォルト) | :latest、:<version> | 約 510 MB | docker CLI + compose + buildx + scout |
no-scout | :no-scout、:<version>-no-scout | 約 315 MB | docker CLI + compose + buildx |
Scout のプラグインバイナリだけで、no-scout から full への約 195 MB の増加分を占めます。また、no-scout イメージでは DOCKER_MCP_SERVER_DISABLE=scout がデフォルトで設定されているため、scout のツールは登録されません。CLI プラグインが存在しないツールがエージェントに提示されることはありません(呼び出すたびにエラーになる scout ツールではなく、より小規模でも完全に動作するツールリストが表示されます)。無効化する対象を変更する必要がある場合は、実行時に -e DOCKER_MCP_SERVER_DISABLE=... で上書きしてください(追記ではなく置き換えになる点に注意してください)。
自分でビルドする場合。 すべてのバリアントは、ビルド引数を使ってリポジトリの Dockerfile からビルドできます。
docker build -t docker-mcp-server:full . # full (default)
docker build --build-arg INSTALL_SCOUT=0 --build-arg DISABLE_DOMAINS=scout \
-t docker-mcp-server:no-scout . # no-scout
docker build --build-arg INSTALL_CLI=0 -t docker-mcp-server:lite . # lite (SDK-only, ~165 MB)
lite イメージ(docker-py SDK のツールのみ。Compose/Buildx/Scout/Context は「プラグインを利用できません」に切り替わります)はビルドできますが、公開されていません。
コンテナー内からデーモンに接続する方法。 イメージでは DOCKER_HOST のデフォルトが unix:///var/run/docker.sock に設定されているため、ホストのソケットをそのパスにマウントするだけで接続できます。ただし、ホストのソケットの場所は環境によって異なります。起動時に接続できない場合、サーバーはプラットフォームに応じたヒントを stderr に表示します。
- Linux:
-v /var/run/docker.sock:/var/run/docker.sock(rootless の場合:-v $XDG_RUNTIME_DIR/docker.sock:/var/run/docker.sock)。 - macOS(Docker Desktop): 実際のソケットは通常
~/.docker/run/docker.sockにあります。コンテナー内のパスにマウントしてください:-v $HOME/.docker/run/docker.sock:/var/run/docker.sock(または Settings > Advanced > Allow the default Docker socket を有効にして、/var/run/docker.sockを使用してください)。 - Windows(Docker Desktop/WSL2): エンジンは Unix ソケットではなく名前付きパイプを使用します。
-e DOCKER_HOST=tcp://host.docker.internal:2375を使用することをおすすめします(Docker Desktop で TCP エンドポイントを有効にしてください)。このエンドポイントは認証も暗号化もされていません。localhost にバインドした状態を保ち、使用していないときは無効にしてください。また、リモートデーモンには TLS またはDOCKER_HOST=ssh://...を使用してください。 - リモート/TLS/SSH デーモン: ソケットのマウントは省略し、
-e DOCKER_HOST=...(および以下の TLS 変数)を渡してください。リモートデーモンとの通信を参照してください。 ホストのファイルシステムへのアクセス。 コンテナ内では、ファイルパスを使うツール(image_save/container_exportのdest_path、image_load/container_archive_putのfrom_file、container_archive_get_to_file、および compose のproject_dir/files)は、ホスト上ではなく コンテナ内 のパスを解決します。ファイルをやり取りするディレクトリは、バインドマウントしてください。内外で同じパスを使うと、ホストとコンテナのパスが一致します。
-v $HOME/docker-work:$HOME/docker-work
これらのツールのいずれかをバインドマウントされていないパスで呼び出すと、サーバーは処理を開始する前に、追加すべき -v を正確に示すメッセージとともに拒否します。そうしないと、マッピングされていないパスへの書き込みは、コンテナの終了時に黙って破棄されてしまいます。(32 MiB を上限とするインバンドのバイトツールでは、マウントは不要です。)設定用の環境変数(DOCKER_MCP_SERVER_READONLY、DOCKER_HOST など)は、uvx のインストールと同じように、クライアントの env ブロックに指定します。
リモートデーモンへの接続
DOCKER_HOST が設定されている場合、サーバーはそれを直接使用します(docker.from_env() 経由のため、DOCKER_TLS_VERIFY / DOCKER_CERT_PATH も適用されます)。env でよく使用するオーバーライドは次のとおりです。
"env": {
"DOCKER_HOST": "tcp://remote-host:2375",
"DOCKER_TLS_VERIFY": "1",
"DOCKER_CERT_PATH": "/path/to/certs"
}
デフォルトのデーモン(DOCKER_HOST が未設定の場合)。 DOCKER_HOST が未設定の場合、サーバーは /var/run/docker.sock を前提とせず、docker CLI と同じ方法でデーモンを解決します。有効な Docker コンテキスト(DOCKER_CONTEXT、または ~/.docker/config.json の currentContext。エンドポイントはそのコンテキストの meta.json から取得)を確認し、そこで見つからなければ、一般的なソケットの場所(Docker Desktop 4.13+ の ~/.docker/run/docker.sock、rootless の $XDG_RUNTIME_DIR/docker.sock、その後に /var/run/docker.sock)を順に確認します。これは重要です。docker.from_env() だけではコンテキストが無視され、/var/run/docker.sock にフォールバックしますが、Docker Desktop 4.13+ ではデフォルトでこのソケットが作成されなくなりました(Settings > Advanced > Allow the default Docker socket を有効にしない限り、desktop-linux コンテキストが使用されます)。そのため、標準的な Desktop のインストールでは、CLI から接続できても、この方法では失敗する可能性があります。優先順位は次のとおりです。空でない DOCKER_HOST が常に優先され、docker.from_env() を直接使用します(コンテキストは無視されます)。DOCKER_CONTEXT / currentContext が参照されるのは DOCKER_HOST が未設定の場合のみで、ソケットの確認が行われるのは、どちらでも解決できなかった場合のみです。リモートコンテキストに関連付けられた TLS 証明書などは自動的には適用されません。tcp:// + TLS のコンテキストでも、DOCKER_HOST / DOCKER_CERT_PATH が必要です。
SSH 経由
DOCKER_HOST=ssh://user@remote-host は、純粋な Python のトランスポート(docker[ssh] 依存関係によってインストールされる paramiko)を介してサポートされています。システムの ssh バイナリは不要なため、ホストにインストールした場合もコンテナーイメージ内でも同じように動作します。通常の SSH 設定で認証されます。
- 鍵/エージェント。 鍵ベースの認証を使用してください。鍵をエージェントに読み込ませ(
ssh-add)、サーバーの環境でSSH_AUTH_SOCKが設定されていることを確認してください(または、鍵をデフォルトの~/.ssh/id_*パスに配置してください)。 - 既知のホスト。 paramiko は
~/.ssh/known_hostsと照合してホスト鍵を検証し、未知のホストは拒否します。信頼できる経路でフィンガープリントを検証してから、ホスト鍵を追加してください。対話的に一度ssh user@remote-hostで接続してプロンプトを確認するか、既知の正しいフィンガープリントとssh-keyscan remote-host | ssh-keygen -lf -の結果を照合してから追記してください。ssh-keyscanの出力をそのままknown_hostsにパイプするのは避けてください。返された鍵(中間者攻撃者の鍵を含む)を無条件に信頼することになります。 - コンテナー内。 SSH 関連ファイルを読み取り専用でマウントするか、(鍵と
known_hostsを含む)-v $HOME/.ssh:/root/.ssh:roを指定するか、エージェントのソケットを転送してください。ソケットのマウントもsshパッケージも不要です。
CLI ベースのツール(Compose、Stack、Buildx、Scout、Context)は docker CLI をシェルで実行します。通常、この CLI は ssh:// エンドポイントでシステムの ssh バイナリを使用します。代わりに、run_docker() は DOCKER_HOST=ssh://... を検出すると、呼び出しごとにローカル TCP プロキシ(docker_mcp/tools/_ssh_proxy.py)を透過的に起動します。このプロキシは docker-py が使用するものと同じ paramiko 接続を確立し、その接続を介して docker system dial-stdio を実行し、1 回の呼び出しの間、CLI のサブプロセスを tcp://127.0.0.1:<ephemeral port> に接続します。つまり、CLI ベースのツールは、上記の docker-py ベースのツールとまったく同じ認証情報とホスト鍵ポリシーで認証されます。直接接続にシステムの ssh バイナリは不要で、ホストへのインストール時とコンテナーイメージ内で同じように動作します。例外は ~/.ssh/config の ProxyCommand(踏み台/ジャンプホスト構成)です。paramiko は指定されたコマンドをそのまま実行しますが、一般的には ssh -W %h:%p ... です。そのため、直接接続では不要でも、ジャンプホスト経由の接続ではシステムの ssh クライアントがシェルから実行されます。
この一時的な 127.0.0.1 リスナーは、1 回の CLI 呼び出しの間、SSH 認証情報を使ってリモートの(root と同等の権限を持つ)デーモンに接続するため、同じループバックを共有するプロセスは、その短い時間中にリスナーへ接続できます。公開範囲は限定的で、localhost からのみアクセスでき、呼び出しが戻ると破棄されます。コンテナー内ではさらに範囲が狭く、そのコンテナーのネットワーク名前空間内のプロセスからのみアクセスできます。いずれの場合も、信頼境界となるのはデーモンです(セキュリティに関する考慮事項を参照してください)。
ローカルに Docker がない場合
Docker がローカルにインストールされていない場合、または呼び出しに必要なプラグインが見つからない場合でも、ほとんどのツールはこれまでどおりリモートホスト上で動作します。一部のツールファミリー(Compose、Buildx、Scout、および stack_deploy)は、SSH 経由で対象ホスト自体で実行されます。ローカルに Docker がインストールされていない場合、これらのコマンドでは TCP 接続と TLS 接続は機能しません。
知っておくとよいこと:
- これはフォールバックであり、優先される方法ではありません。 呼び出しを処理できるローカル CLI(バイナリと、その呼び出しに必要なプラグイン)があれば、常にそちらが使われるため、通常のインストールでは何も変わりません。
- コマンドが読み取るローカルファイルは、最初にリモートへコピーされます。Compose プロジェクトディレクトリ、bake ファイル、ビルドコンテキスト(
.dockerignoreに従います)などが、プライベートな0700の一時ディレクトリにコピーされ、呼び出しが戻ると削除されます。ただし、これはベストエフォートです。SSH 接続が切断されると、クリーンアップを実行できるものが残らないためです。削除されずに残った場合はdocker-mcp-server.stage.*という名前になり、失敗がログに記録されます。 - リモートホストの認証情報が適用されます。 レジストリへのログイン情報はリモートホストの
~/.docker/config.jsonから取得されるため、プライベートレジストリに対するcompose_pull、stack deploy --with-registry-auth、または大半の Scout 操作では、リモートホストでのdocker loginが必要になる場合があります。system_loginはデーモンと通信しますが、リモート CLI の設定ファイルには書き込みません。 - 作業ディレクトリ全体がコピーされます。Compose ファイルがどのファイルを参照するか(
build:、env_file:、include:はいずれも任意のパスを指定するため)を判別できないからです。ツールには大きな親ディレクトリではなくプロジェクトディレクトリを指定してください。そうしないと、サイズ制限エラー(200 MiB/50 000 エントリー)で呼び出しが拒否されます。 compose_cpは、コピー対象のうちローカル側にあるものを、同じ SSH 接続経由で中継します。ホスト上のソースは他の入力と同様にステージングされ、コンテナの結果はコピー成功後に実際の宛先へ取得されます。実際のコピーは引き続きリモートホスト上で本物のdocker compose cpを通じて実行されるため、すべてのパラメーターはローカルで実行する場合と同じように動作します。異なる点は、コンテナからホストへのコピーでは、ローカルの宛先がすでに存在する場合に拒否されることです。それを把握しているのはこのホストだけだからです。- 中途半端に実行するよりも拒否される操作がいくつかあります。
buildx_buildでは、output/cache_to内のファイルシステム上のdest=、cache_from内のローカルなsrc=、または任意のssh=が該当します。いずれもリモートマシン上で解決されるためです。 - リモート側で POSIX シェルを使用できる必要があります。 Linux/macOS/BSD のホストはいずれも対象となり、WSL ディストリビューション内で動作する sshd もサポートされています(Linux ターゲットであり、Docker Desktop の WSL2 バックエンドではデーモンもそこに存在します)。Windows 側の
cmd/PowerShell の sshd は、説明を含むエラーとともに拒否されます。また、MSYS/MinGW/Cygwin からのunameも拒否されます。Windows の方式は設計されていますが、実装されていません。シェルがwsl.exeの Windows sshd ではコマンドは WSL 内で実行されますが、SFTP サブシステムは Windows 側にとどまるため、ファイルコピーを行うツールはそこで拒否されます。コマンドの実行のみを行うツールは引き続き動作します。 context_*ツールはフォールバックしません。 これらはこのホストの CLI コンテキストレジストリを管理するものであり、リモートホストはその内容を把握していないためです。
複数のデーモンの管理
ここまでの設定はすべて、1つのデーモンを対象としています。1回のセッションで複数のデーモン(たとえば、ローカルの開発環境とリモートの本番デーモン)を管理するには、DOCKER_MCP_SERVER_HOSTS に name=endpoint のペアをカンマ区切りで設定します。
"env": {
"DOCKER_MCP_SERVER_HOSTS": "local=auto, prod=ssh://[email protected](ro)"
}
endpointはauto(上記のとおり、デフォルトのコンテキスト/ソケット)、local(コンテキストを無視してプラットフォームのローカルソケットを使用)、またはunix:///tcp:///ssh:///npipe://URL です。リモート接続にはssh://を推奨します(ホストごとの認証に SSH キーを使うため、TLS 証明書の設定は不要です)。TLS を使用するtcp://デーモンでは、証明書ディレクトリを指定する(tls=<dir>)マーカーが必要です。たとえば、prod=tcp://prod:2376(tls=/etc/docker/prod)のように指定します。このディレクトリにはca.pemが必要です(デーモンは常にこの証明書を使って検証されるため、自己署名デーモンもここに証明書を指定すれば使用できます)。デーモンがクライアント証明書を要求する場合(相互 TLS)のみ、cert.pemとkey.pemも追加してください。TLS の検証を行わないモードはありません。TLS 接続では常にデーモンが認証されるため、検証なしで暗号化だけが行われることはありません。- エンドポイントの後ろに
(ro)を付けると、そのホストは読み取り専用になります。変更を伴うツールや破壊的なツールは、そのホストに対する操作を拒否します。これはホストごとに適用時点で強制され、サーバー全体に適用されるDOCKER_MCP_SERVER_READONLYスイッチとは独立しています。本番ホストに(ro)を指定すれば、エージェントはいつでも調査できますが、変更はできません。一方、ローカルホストは読み書き可能なままです。 (nd)を付けると、そのホストは破壊的操作不可になります。削除、プルーン、強制終了などの破壊的なツールのみ、そのホストに対する操作を拒否します。読み取りや通常の変更(開始/停止/作成)は引き続き実行できます。これはサーバー全体に適用されるDOCKER_MCP_SERVER_NO_DESTRUCTIVEスイッチをホストごとに設定するものです。(ro)にはすでにこの制限が含まれるため、(ro)(nd)を組み合わせてもエラーにはなりませんが、冗長です。- 単一デーモンの場合の簡易形式。
name=のない値は、1つのホストを表す省略形です。たとえば、DOCKER_MCP_SERVER_HOSTS=ssh://ops@prod(またはauto、空欄)と指定できます。そのため、この項目は単一のリモート接続にも使用できます。DOCKER_MCP_SERVER_HOSTSが未設定の場合は引き続きDOCKER_HOSTが機能しますが、DOCKER_MCP_SERVER_HOSTSが設定されると、そちらが優先されます(その場合、DOCKER_HOSTは無視され、stderr に一度だけ通知が出力されます)。
エージェントによる操作方法。 ホストが2つ以上ある場合、デーモンを対象とするすべてのツールに、設定済みの名前に限定された省略可能な host 引数が追加されます。読み取り専用ツールでは、host を省略すると最初のホストがデフォルトになります。一方、変更を伴うツールや破壊的なツールでは、エージェントが誤って別のデーモンを変更しないよう、明示的な host の指定が必須です。host_list(および docker-mcp://hosts リソース)には、設定済みのホストとデフォルトのホストが表示されます。コンテナー/サービスの可観測性リソースもホストを認識します。デフォルトホストのログ末尾は docker-logs:///{id}(オーソリティが空であることに注意)、名前付きホストのログ末尾は docker-logs://{host}/{id} です。docker-stats://、service-logs://、service-tasks:// も同じパターンです。複数のホストを設定すると、単一ホスト用の省略形式(docker-logs://{id} など)は登録されません。survey_hosts プロンプトは、すべてのホストを読み取り専用で調査します。auto/local エンドポイントは具体的な URL に解決され、起動時に固定されます。そのため、SDK と CLI では常に同じデーモンが各名前に対応します。Docker コンテキストを変更した場合は、再起動して再解決してください。
エージェントにできること
読み込まれると、エージェントには Docker の各ドメイン別に分類された MCP ツールが提供されます。いくつか例を紹介します。
- コンテナー -
container_run、container_list(このサーバーが作成したものだけを一覧表示するにはmanaged_only=Trueを指定します。詳細は来歴ラベルを参照してください)、container_exec、container_logs、container_stop、container_commit、container_export/container_archive_get_to_file/container_archive_put(ホストパスとの間で tar アーカイブをストリーミングします) - イメージ -
image_build、image_pull、image_push、image_tag、image_prune(build_cache=Trueを指定すると、ダングリングイメージとは別のリソースであるデーモンのビルドキャッシュも対象になります)、image_save/image_load(dest_path/from_fileを介して、ホストパスとの間でイメージの tarball をストリーミングします)、image_import(フラットな rootfs tarball、URL、または既存のイメージから単一レイヤーのイメージをビルドします。docker importに相当し、image_loadとは異なります) - プラグイン -
plugin_install(レジストリからプルします。dry_run=Trueを指定すると、インストール前にプラグインが要求するホストアクセス権限を確認できます。デーモンはそれを非対話的に付与します)、plugin_enable/plugin_disable、plugin_configure、plugin_upgrade(同じくdry_runを指定できます)、plugin_list/plugin_inspect、plugin_remove(管理対象のエンジンプラグイン(ボリューム/ネットワーク/ロギングドライバー)を対象とし、dockerコマンド自体を拡張する CLI プラグインは対象外です) - ネットワーク/ボリューム -
network_create、network_connect、volume_create、volume_prune - Swarm -
swarm_init、swarm_join_tokens(初期化から参加までの一連の流れを完了します)、swarm_update(参加トークン/ロック解除キーをローテーションします)、service_create、service_scale、service_rollback(以前のサービス仕様を再適用します)、service_ps(1つのサービスのタスク、またはサービスを指定しない場合はクラスター内のすべてのタスクを取得します。ノードまたは希望する状態でフィルターできます。この操作を行う単一の CLI コマンドはありません)、service_logs(サービスまたは1つのタスクのログを取得します)、node_list、node_remove、secret_create、config_create - システム -
system_wait(唯一の待機ツールです。コンテナーの終了、ヘルシー状態への移行またはログ行の出力、サービスまたはスタックの収束、スタックの削除、ノードの準備完了、Compose プロジェクトの実行中/ヘルシー状態/終了、またはタグのレジストリへの登録を待機します。すべての待機にはタイムアウトがあり、デフォルトは600秒です。例外を発生させるのではなく、結果を報告します)、system_ping、system_info、system_version、system_df、system_events、host_list(設定済みのデーモンとデフォルトのデーモンを確認します。詳細は複数のデーモンの管理を参照してください)、system_login/system_logout(レジストリの認証情報をキャッシュまたは消去します)、system_reconnect(ホストの SDK クライアントを再構築して、応答しなくなった接続を復旧します) - Compose -
compose_up、compose_down、compose_stop、compose_start、compose_restart、compose_pause/compose_unpause、compose_kill、compose_ps、compose_list、compose_images、compose_top、compose_port、compose_logs、compose_config、compose_build、compose_pull、compose_run、compose_exec、compose_cp(docker composeCLI プラグインをラップします) - スタック -
stack_deploy、stack_list、stack_ps、stack_services、stack_remove(Compose ファイルをスタックとして swarm にデプロイします。stack_deployはdocker stack deployをラップし、Compose ファイルを変換します。その他は Engine API を使用します。swarm マネージャーが必要です) - コンテキスト -
context_list、context_inspect、context_create、context_use、context_remove(docker contextCLI をラップします) - レジストリ/Hub -
registry_tags、registry_manifest、registry_image_config(プルせずにイメージの環境変数/エントリーポイント/ラベルを読み取ります)、hub_tags、hub_repo_info、hub_rate_limit(残りのプル枠)(OCI v2 レジストリおよび Docker Hub API への HTTPS 通信を行います。デーモンは不要です。一時的な429エラーは透過的に再試行します) - Buildx -
buildx_build、buildx_bake、buildx_imagetools_inspect、buildx_imagetools_create、buildx_list、buildx_inspect、buildx_du、buildx_history_list/buildx_history_inspect(過去のビルド記録を詳しく確認します)、buildx_prune、buildx_create、buildx_use、buildx_remove(docker buildxCLI プラグインをラップします)。docker manifestの代わりにbuildx_imagetools_*を使用してください。このコマンドはメンテナンスモードにあり、OCI イメージインデックスとアテステーションをサポートしていません。 - Scout -
scout_cves、scout_quickview、scout_recommendations、scout_compare、scout_sbom(docker scoutCLI プラグインをラップします。scout_sbomを除くすべてのツールでは、CLI を実行するホストでdocker loginが必要です)。 SDK がバックエンドとなる機能は、Docker SDK リファレンスに準拠しています。そこに記載されている機能は、こちらでも利用できます。Compose と Context の機能は、Compose CLI および docker context のリファレンスに準拠しています。
このサーバーは、Docker SDK for Python のリファレンスと、選定された Docker CLI/レジストリのリファレンスも MCP リソースとして公開するため、エージェントは実行時に参照できます。セクションの索引には docker-docs://contents を、レンダリングされたページには docker-docs://<section>(例:docker-docs://containers、docker-docs://compose、docker-docs://oci-distribution-spec、docker-docs://dockerfile、docker-docs://build-best-practices、docker-docs://engine-security、docker-docs://engine-api)を読み取ってください。リソースを読み取れない MCP クライアント(例:Claude Desktop、Cursor)向けに、docs_lookup ツールでも同じ内容を参照できます。引数なしで呼び出すとセクションの索引が返され、docs_lookup(section=...) でページを取得できます。このツールは DOCKER_MCP_SERVER_DISABLE の設定にかかわらず常に利用できます。さらに、docker-mcp://tool-catalog リソースには、このサーバーが認識しているすべてのツールが、ドメイン、変更カテゴリ、現在の設定で登録されているかどうかとともに一覧表示されます。これは、ツールの影響範囲や、ライブリストに表示されない理由を確認するのに便利です。リソースを読み取れないクライアント向けには tool_list ツールでも同じ情報を参照でき、フィルタリング機能も利用できます。ある領域のツールを1行ずつ簡潔に確認するには tool_list(domain="buildx")、データを破壊する可能性のあるツールを確認するには tool_list(category="destructive")、名前、概要、パラメーター名を検索するには tool_list(keyword="logs one task") を使います。いずれかの単語に一致するツールがすべて返され、一致する単語が多いものから順に表示されます。現在の設定で登録されているツールだけが一覧表示され、一致するものがない場合は明示的な空の結果が返されます。docs_lookup と同様に、このツールも DOCKER_MCP_SERVER_DISABLE の設定にかかわらず常に利用できます。
コンテナーとサービスの可観測性もリソースとして公開されるため、クライアントはツールを呼び出さずにライブ状態をコンテキストとして追加できます。docker-logs://<id-or-name> はコンテナーのログの上限付き末尾部分を取得します(コンテナーの終了後も読み取り可能なため、終了理由の診断に便利です)。docker-stats://<id-or-name> は、実行中のコンテナーのリソース使用状況(CPU %、メモリー、ネットワーク、ブロック I/O)を計算して要約します。Swarm サービスにも同じ形式が用意されています。service-logs://<id-or-name> はログの上限付き末尾部分を、service-tasks://<id-or-name> はタスクとロールアウトの概要(実行中のタスク数と希望タスク数、失敗したタスク、現在のローリングアップデート状態)を計算して返します。container_list/service_list で列挙し、指定する ID または名前を確認してください。これらは対応するツール(container_logs/container_stats、service_logs)を補完します。services が無効の場合、サービス関連のリソースは非表示になります(containers は非表示になりません)。
プロンプトの例
多くの AI クライアントでは、登録済みの MCP プロンプトを直接呼び出せます(Claude Code では / と入力すると表示されます)。このサーバーには、複数ステップのワークフローのひな型となるテンプレートの小さなライブラリが docker_mcp/tools/prompts.py に含まれています。テンプレートは構造化された計画を出力し、エージェントはその計画に沿って Docker ツールを使って作業を実行します。
SDK ドキュメントを調べる
/lookup_docker_docs section=services
/verify_docker_method method=containers.run section=containers
…または、自然な英語で尋ねるだけです。
docker-docs://networksを読み、createとconnectの違いを教えてください。 コードを変更する前に、docker-docs://containersを確認し、runがrestart_policy引数を受け付けることを確かめてください。
コンテナーの作成と管理
/deploy_container image=nginx:1.27 name=web
/monitor_container_fleet
/triage_incident window_minutes=30
/troubleshoot_container container=api-1
/migrate_container container=api-1 new_image=myorg/api:v2
/inspect_stack label=com.example.app=web
/clean_environment scope=stopped
/plan_compose_stack description="wordpress + mysql sharing a named volume"
Compose、コンテキスト、レジストリ
/deploy_compose_project project_dir=/srv/myapp
/troubleshoot_compose_project project_dir=/srv/myapp
/deploy_swarm_stack stack_name=web compose_file=/srv/myapp/docker-stack.yml
/audit_docker_contexts
/find_latest_image_tag image=ghcr.io/org/repo
監査、セキュリティ、ホスト操作
/review_dockerfile dockerfile_path=/srv/myapp/Dockerfile
/audit_container_security
/debug_container_networking source=web target=db
/investigate_disk_usage
/backup_volume volume=pgdata dest_path=/backups/pgdata.tar
/restore_volume volume=pgdata source_path=/backups/pgdata.tar
/audit_swarm_health
Buildx、Scout、マルチアーキテクチャマニフェスト
/plan_multiarch_build image=ghcr.io/org/app:v1 platforms=linux/amd64,linux/arm64
/audit_image_cves image=alpine:3.19
/compare_image_versions old_image=org/app:v1 new_image=org/app:v2
/recommend_base_image image=org/app:v1
/inspect_multiarch_manifest image=alpine:3.19
/create_multiarch_manifest target_tag=org/app:v1 source_tags=org/app:v1-amd64,org/app:v1-arm64
/migrate_from_docker_manifest
…または、自然な英語で尋ねます。
redis:7-alpineをプルして、新しいapp-netネットワーク上でcacheというコンテナー名で実行し、ポート 6379 はそのネットワーク内だけに公開してください。 コンテナーapi-1が再起動を繰り返しています。直近 200 行のログを取得し、状態と終了コードを調べ、何も変更する前に問題を教えてください。 実行中のwebコンテナーをnginx:1.27に置き換え、現在のポート、マウント、再起動ポリシーは維持してください。 プライベートネットワーク上に、データベース用の名前付きボリュームを使う wordpress + mysql のスタックを計画してください。何か作成する前に計画を見せてください。com.example.app=webというタグが付いたコンテナー、ネットワーク、ボリュームをすべて、1 つのテーブルに表示してください。何も変更しないでください。 ディスク容量が不足しています。まずsystem_dfを表示し、停止中のコンテナーとダングリングイメージを削除してから、もう一度system_dfを表示してください。ボリュームは対象外です。/srv/myappにある Compose プロジェクトを起動してください。ただし、何かを開始する前にレンダリング済み設定を表示し、イメージをプルしてください。 Docker コンテキストを一覧表示し、この MCP サーバーが現在どのデーモンと通信しているか教えてください。ghcr.io/org/repoの最新の安定版タグをプルせずに見つけ、対応プラットフォームを教えてください。
設定
環境変数の命名。 このサーバーの環境変数には、公開パッケージ名に合わせて
DOCKER_MCP_SERVER_*という名前空間が付けられています。2.0 より前のDOCKER_MCP_*という別名表記は、現在はサポートされていません。
サーバーが通信するデーモンを選ぶには、リモートデーモンとの通信と複数のデーモンの管理(DOCKER_MCP_SERVER_HOSTS / DOCKER_HOST)を参照してください。以下の変数は、登録するツールを制限するものです。
サーバーの起動時に登録するツールを制限する環境変数は 3 つあります。ツールは登録時に除外されるため、無効にしたツールはクライアントのツール一覧に表示されません。これはクライアント側のプロンプトによるものではなく、サーバー側で保証されます。2 つのブール値スイッチには 1 / true / yes / on を設定してください。
DOCKER_MCP_SERVER_READONLY- 読み取り専用ツール(クエリ、ログ/データの読み取り、スキャン)のみを登録します。状態を変更するツールはすべて除外されます。何も変更できないようにする必要がある、監視または検査用のエージェントに使用してください。DOCKER_MCP_SERVER_NO_DESTRUCTIVE- 破壊的なツール(remove_*、prune_*、container_kill、compose_down、swarm_leave、context_remove、buildx_prune、buildx_remove)を除くすべてのツールを登録します。リソースの作成や起動は許可しつつ、データ損失を防ぐモードです。DOCKER_MCP_SERVER_READONLYのほうが制限が厳しく、両方が設定されている場合はこちらが優先されます。DOCKER_MCP_SERVER_DISABLE- カテゴリに関係なく、ドメイン(機能領域)をまとめて無効にする、カンマ区切りのリストです。たとえば、DOCKER_MCP_SERVER_DISABLE=swarm,services,nodes,configs,secretsは単一ホストのサーバーから Swarm 関連機能全体を除外し、DOCKER_MCP_SERVER_DISABLE=scout,buildxはエージェントが使用しないビルド/スキャンツールを除外します。ドメインとはツールモジュールの名前で、images、networks、volumes、compose、stack、context、buildx、scout、registry、swarm、services、nodes、plugins、configs、secretsです。systemとcontainersは無効にできないため、どちらを指定しても無視されます。systemには、エージェントが状況を把握して復旧するために必要な機能と、唯一の待機ツールが含まれています。containersは Docker サーバーの中核となる機能です。Compose、スタック、サービスの各ツールが起動するコンテナーは、これを介してのみ待機、読み取り、削除できます。containersを無効にしても、エージェントによるコード実行は防げません(Compose、スタック、service_create、image_buildはいずれもコードを実行します)。それを防ぐのはDOCKER_MCP_SERVER_READONLYであり、この設定ではレジストリへのログインもできなくなります。ドメインを無効にすると、そのドメインの対象はsystem_waitからも除外されます。名前の大文字と小文字は区別されません。認識されない名前を指定しても、何も無効になりません。ドメインに一致しない名前、または無効にできない名前を指定した場合は、MCP クライアントではサーバーの標準エラー出力が表示されないことが多いため、3 つの方法で通知されます。起動時に標準エラー出力へWARNING行が出力され、tool_listの結果のconfiguration_warningsエントリー(およびツールカタログのunknown_disabled_domains/ignored_disabled_domains)に記載され、さらにエージェントにtool_listを確認してユーザーに伝えるよう指示する行がサーバーの指示の先頭に追加されます。この設定はカテゴリ別の切り替えと併用されます。ツールが登録されるのは、そのカテゴリが有効であり、かつドメインが有効な場合のみです。ドメインを無効にすると、ツールだけでなく、対応するワークフローのプロンプトもスキップされます。そのため、サーバーが公開しなくなった機能領域を実行するプロンプトがエージェントに渡されることはありません。たとえば、scoutを無効にすると、登録されていないツールを呼び出すようエージェントに指示するaudit_image_cvesプロンプトも除外されます。また、対応するドキュメントのリソースはdocker-docs://contentsから非表示になります(たとえば、scout/scout-cliのセクションです)。ツールカタログのpromptsリストとdisabled_doc_sectionsフィールドで、どちらも確認できます。エージェントが必要としないドメインを除外すると、クライアントが処理するツール一覧のサイズも小さくなります。このサーバーの規模では、これは重要です。 この3つのいずれもネットワーク制御ではありません。DOCKER_MCP_SERVER_READONLYが制限するのはエージェントが変更できるものであり、サーバーが接続できるものではありません。レジストリと Hub のツールは読み取り専用ですが、読み取り専用サーバーでも、ツール引数で指定されたレジストリホストに対してアウトバウンド HTTPS リクエストを送信します。リクエストはサーバーが実行されている場所から送信されるため、サーバーが管理するデーモンよりも広いネットワークアクセスを持つマシンから実行される場合があります。レジストリからトークンチャレンジが返されない限り、これらのリクエストに認証情報は含まれません。また、認証情報を含むトークンエンドポイントは、最初に検証されます(スキーム、公開ホストへの平文通信がないこと、公開レジストリのレルムがプライベートアドレスまたはループバックアドレスを指していないこと)。それでもリクエスト自体は送信され、その応答はエージェントに返されます。docs_lookupとdocker-docs://リソースも、固定されたドキュメントホストのリストから取得します。アウトバウンドリクエストを停止する必要がある場合は、DOCKER_MCP_SERVER_DISABLE=registryを設定すると、そのドメイン全体が無効になります。それ以外の通信を制御するには、ホストのネットワークポリシーを使用してください。このサーバーが接続するすべての対象については、PRIVACY.mdをご覧ください。
これとは別に、登録される各ツールには MCP ToolAnnotations が付与されます。クエリには readOnlyHint、破壊的操作には destructiveHint(さらに prune 系には idempotentHint)が付与されるため、Claude Code などのクライアントは安全な読み取りを自動的に許可し、破壊的な呼び出しを制限できます。この分類は docker_mcp/server.py の TOOL_CATEGORIES にあります。実行時の全体像、つまり各ツールのドメイン、カテゴリ、有効なスイッチによって登録されているかどうかを確認するには、docker-mcp://tool-catalog MCP リソースを参照してください。
プライベートレジストリの場合、HTTPS を使用する registry_* ツールは、username/password 引数が明示的に渡されないとき、サーバーの環境変数 DOCKER_MCP_SERVER_REGISTRY_USERNAME/DOCKER_MCP_SERVER_REGISTRY_PASSWORD を使用します(明示的な引数が優先されます。環境変数のペアは、両方の引数が未設定の場合にのみ使用されます)。認証情報を環境変数に設定すると、多くの MCP クライアントがそのまま記録するツール引数に認証情報を含めずに済みます。パスワードには個人用アクセストークンを使用できます。
出自ラベル
エージェントがこのサーバーを通じて作成するすべての Docker オブジェクト(コンテナ、ネットワーク、ボリューム、swarm サービス、config、secret)には、このサーバーが作成したこと(docker-mcp-server.managed=true)、サーバーのバージョン、呼び出し元のツール、作成日時を記録する、docker-mcp-server.* ラベルが付与されます。これにより、後から(ユーザー自身またはクリーンアップジョブが)docker ... --filter label=docker-mcp-server.managed=true を実行するだけで、エージェントが作成したものだけを正確に列挙できます。container_list、network_list、volume_list、service_list の managed_only=True 引数は、ツール内で使えるショートカットです(渡した他の filters と組み合わせられます)。ラベル付与は追加的に行われ(同じキーが競合する場合は、ユーザー自身が渡したラベルが常に優先されます)、固有の名前空間を使用するため、デフォルトで安全です。DOCKER_MCP_SERVER_NO_LABELS=1 を設定すると、ラベル付与を完全に無効化できます。ビルドラベルによって生成されるイメージダイジェストが変わるため、イメージビルドには意図的にラベルを付与しません。
サーバーが作成したものだけを、ほかのものには触れずに削除するには、prune_managed ワークフロープロンプトを使用してください。削除の各ステップは docker-mcp-server.managed=true ラベルを対象とします(ボリュームは include_volumes=True を渡した場合に限り、確認後に削除されます)。
例:読み取り専用のモニタリングサーバー
これらはすべて、MCP クライアントの設定でサーバーエントリーの env ブロックに記述します(上記の DOCKER_HOST と同じ場所です)。たとえば、リモートデーモンを対象とした読み取り専用の検査サーバーは次のとおりです。
{
"mcpServers": {
"docker-mcp-server-readonly": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/L337-org/docker-mcp.git",
"docker-mcp-server"
],
"env": {
"DOCKER_HOST": "tcp://staging-host:2376",
"DOCKER_TLS_VERIFY": "1",
"DOCKER_MCP_SERVER_READONLY": "1"
}
}
}
}
DOCKER_MCP_SERVER_READONLY を DOCKER_MCP_SERVER_NO_DESTRUCTIVE に置き換えると、remove_* / prune_* / container_kill を実行できない状態を保ったまま、作成/起動/デプロイを許可できます。同じサーバーを異なる名前で2回登録することもできます。必要なときに有効化するフルアクセスのエントリーと、日常的に使う読み取り専用のエントリーを用意できます。claude mcp(Claude Code)では、同等の設定は次のとおりです。
claude mcp add docker-mcp-server-readonly \
--env DOCKER_MCP_SERVER_READONLY=1 \
-- uvx --from git+https://github.com/L337-org/docker-mcp.git docker-mcp-server
サーバーを使わない選択肢:l337-docker エージェントスキル
MCP サーバーが本当に必要なのか、という問いはもっともです。このリポジトリは、その答えをオープンに示しています。skills/l337-docker/ は、docker CLI のみを使って Docker を操作する Claude Code エージェントスキルです。サーバープロセスも Python も不要で、必要なのは docker バイナリだけです(いくつかのレジストリのレシピでは jq と curl も使います)。
このスキルは、スキル方式の限界を率直に示し、その長所と短所をこちらの言葉をうのみにせず判断できるようにするために用意されています。この方式で実現できる最善のものとなるよう作られています。ルーターとドメインごとのリファレンスおよびワークフローを備え、すべてのコマンドを実際のデーモンで検証し、シェルスニペットは CI で実行して陳腐化を防いでいます。単一のローカルデーモンで日常的に使うのであれば、これだけで十分かもしれません。その場合は、ぜひご利用ください。
限界となるのは対応範囲ではなく、強制力です。スキルの安全ルールはプロンプト内の指示ですが、サーバーの安全ルールはコードによる拒否です。
| MCP サーバー | l337-docker スキル | |
|---|---|---|
| 読み取り専用/破壊的操作なしのモード | 強制されます。ツールは登録されません | エージェントが従うよう求められる記述上のルールです |
デーモンごとの書き込み保護((ro)/(nd)) | 呼び出し境界で強制されます | 利用できません |
| 自己終了ガード | 強制されます | 記述上のルールです |
| 出力の上限設定 | 強制され、truncated フラグも付与されます | 記述上のルール(--tail、--no-stream)です |
| 複数デーモンへのターゲティング | 起動時に解決され、固定されます | セッション中に切り替わる可能性がある、暗黙的な Docker コンテキストを使用します |
| 要件 | Python ≥3.14、またはコンテナ | docker バイナリ |
この違いが最も重要になるのは、見落としやすい場面です。プロンプト内のルールは、切迫した状況で無視されたり、エージェントが読み取ったばかりのコンテナログに埋め込まれたプロンプトインジェクションによって回避されたりする可能性があります。登録されていないツールは、そもそも呼び出せません。そのため、本番環境を対象とする場合や、指示ではなく保証が必要な場合はサーバーを優先してください。リスクが低く、簡潔さを重視する場合はスキルを優先してください。
MCP_VS_SKILLS.md では、両者を詳しく率直に比較しています。積極的に読み込むクライアントではスキルのほうがはるかに低コストで、特にアイドル時はその差が顕著です。一方、遅延読み込みのクライアントでは、タスクあたりのコストはサーバーのほうが低くなります。さらに、それぞれが本当に優れている点と、すべてのツール、プロンプト、リソースを対象としたツールごとの対応状況も掲載しています。
インストールするには、リリースからアーカイブをダウンロードし、スキルディレクトリに展開してください。アーカイブ内のルートディレクトリは l337-docker/ なので、そのまま正しい場所に配置されます。
# personal (all projects)
tar -xzf l337-docker-skill-<version>.tar.gz -C ~/.claude/skills
# or per-project, checked into version control
tar -xzf l337-docker-skill-<version>.tar.gz -C .claude/skills
付属のチェックサム(sha256sum -c l337-docker-skill-<version>.tar.gz.sha256)で検証してください。アーカイブはバイト単位で再現可能なので、タグから再ビルドしても同じハッシュになります。スキルとサーバーは共存できます。作成するリソースにはそれぞれ異なるラベルを付け、互いのリソースを読み取ることはありません。
セキュリティに関する考慮事項
このサーバーを AI エージェントに接続すると、設定されたデーモンに対してローカルの Docker CLI セッションと同じレベルのアクセス権がエージェントに付与されます。その権限は広範です。デーモンのソケットは、実質的にホスト上の root と同等の権限を持ちます。エージェントを特権ユーザーとして扱い、サーバーを有効にする前に以下のリスクを検討してください。
- スコープを限定したデーモンを使用してください。 本番用ソケットではなく、エージェントが操作を許可されているワークロード専用のデーモン(開発用 VM、リモートサンドボックス、Docker Desktop、ルートレスインストール)を
DOCKER_HOSTで指定することを推奨します。デーモンが信頼境界であり、ツールごとの認可レイヤーはありません。 - コンテナとして実行する場合。
/var/run/docker.sockをコンテナにマウントすると、そのコンテナには、uvx でインストールした場合と同じく、そのデーモンに対する root 相当のアクセス権が付与されます。これ以上でも以下でもありませんが、今度はdocker runの行で明示されます。同じくスコープを限定したデーモンを使用してください。エージェントが制御を許可されているデーモンのソケットをマウントするか、そのデーモンをDOCKER_HOSTで指定することを推奨します。コンテナ化した場合、ファイルパスツールが読み書きするのは コンテナ自身の ファイルシステムであるため、ホスト上でアクセスできるのはバインドマウントしたディレクトリに限られます(コンテナとして実行を参照)。誤操作を防ぐため、破壊的なコンテナのライフサイクルツール(container_remove、container_kill、container_stop、container_restart、container_pause)はサーバー 自身の コンテナに対する操作を拒否するため、エージェントが呼び出しの途中で自身のセッションを終了することはありません。これは利便性のための措置であり、セキュリティ境界ではありません(DOCKER_MCP_SERVER_ALLOW_SELF_TERMINATE=1で回避でき、ホストシェルから人間がいつでもコンテナを復旧できます)。また、デーモン権限を持つエージェントがホストに影響を与えるその他の多くの方法を制限するものでもありません。 - 特権コンテナとホストのマウント。
container_runはprivileged=Trueと任意のvolumesを受け付けます。特権コンテナや、ホストの/をバインドマウントするコンテナは、容易にホストのファイルシステムへアクセスできます。リクエストを確認しない限り、エージェントにこれらを設定させないでください。Compose ファイルでも同様の指定が可能です。見慣れないプロジェクトでcompose_upを承認する前に、レンダリングされたcompose_configの出力を確認してください。 - パススルーの
extra_kwargs/updatesは表示されるスキーマを迂回します。container_run、container_create、service_create(extra_kwargs)、container_update、service_update(updates)は、任意の辞書をそのまま Docker SDK に渡します。たとえば、ツールの宣言済みパラメーターでprivileged=Falseを確認するクライアントでも、extra_kwargs={"privileged": True, "pid_mode": "host"}によって迂回できます。これらの回避手段は「デーモンが信頼境界」というモデルと整合していますが、MCP クライアント層で許可/拒否ポリシーを構築する場合は、名前付きパラメーターだけを信用せず、これらも考慮する必要があります。 - レジストリの認証情報。 多くの MCP クライアントはツール呼び出しをそのまま記録するため、ツールに渡すパスワードや
auth_configは露出するものとして扱ってください。- SDK を使用するツール(
system_login、image_push、image_registry_data)は認証情報を直接受け付けるほか、docker loginによって~/.docker/config.jsonにキャッシュされた認証情報も再利用できます。この MCP サーバーを実行するホストで一度docker loginを実行し、認証情報のパラメーターは未設定のままにすることを推奨します。(注:対象はデーモンではなく、サーバーを実行するホストです。DOCKER_HOSTがリモートデーモンを指定している場合に関係します。)system_loginに渡した認証情報は、クライアントが存続する間サーバーのメモリにキャッシュされます。system_logoutは~/.docker/config.jsonに触れずに、そのメモリ内キャッシュ(すべてのレジストリ、または一つ)を消去し、system_close/system_reconnectはクライアントを破棄してキャッシュを消去します。デーモン側に終了すべきセッションはありません。Engine の/authエンドポイントは検証のみを行います。 - HTTPS を使用するレジストリツール(
registry_tags、registry_manifest、registry_image_config、hub_tags、hub_repo_info、hub_rate_limit、およびレジストリタグを指定したsystem_wait)は HTTPS でレジストリに直接接続し、~/.docker/config.jsonは読み取りません。registry_*ツールはプライベートレジストリ向けにusername/passwordを受け付けます。あるいは、ツール引数を認証情報が通過しないよう、サーバーの環境からDOCKER_MCP_SERVER_REGISTRY_USERNAME/DOCKER_MCP_SERVER_REGISTRY_PASSWORDを読み込む方法を推奨します(設定を参照)。hub_*ツールが対応するのは公開 Hub リポジトリのみです。引数として認証情報を渡す場合は、長期間有効なパスワードではなく、必要最小限のスコープを持つ呼び出しごとのトークンを使用してください。レジストリがBearer認証チャレンジを返した場合、サーバーは送信前に、その参照先となるトークンのrealmを検証します。スキームは http/https でなければならず、ローカル以外のホストへの平文 HTTP は拒否されます。また、公開レジストリが認証情報付きトークンリクエストをプライベート/ループバックアドレスへリダイレクトすることも許可されません(SSRF 対策)。本当にローカルな開発用レジストリ(例:localhost:5000)では、ローカルの realm を引き続き使用できます。ページネーションも同様に固定されます。Docker Hub のnextURL は Hub 自身のオリジン上にとどまる必要があり、OCI のLinkヘッダーのホストは破棄され、問い合わせ先のレジストリが使用されます。そのため、レスポンスボディ によってサーバーが任意のホストへリダイレクトされることはありません。リダイレクト自体は意図的にホストをまたいで追跡します。レジストリは通常の動作として、blob の取得を別ホストの CDN へリダイレクトするためです。ただし、HTTP クライアントはオリジンをまたぐリダイレクト時にAuthorizationヘッダーを削除するため、認証情報がリダイレクト先へ渡ることはありません。
- SDK を使用するツール(
- Swarm のシークレット情報もツール呼び出しを通過します。 レジストリの認証情報に加えて、複数の Swarm ツールは、MCP クライアントに記録される可能性のあるシークレット情報を引数または戻り値として扱います。
secret_create(data=...)とconfig_create(data=...)はペイロードを引数に取り、secret_inspect/config_inspectは保存されたオブジェクトを返します。swarm_join(join_token=...)とswarm_unlock(key=...)はクラスタへの参加/ロック解除用シークレットを引数に取り、swarm_unlock_keyとswarm_join_tokensはクラスタの認証情報を 返します(swarm_updateによるローテーションで古いトークンは無効になります)。マネージャー用の参加トークンを持つ人は、マネージャーとして Swarm に参加でき、クラスタに対する root 相当の権限を得ます。ツールの通信を記録するクライアントでは、これらすべてが露出するものとして扱ってください。Swarm のシークレットの設定や参加トークンの取得は、エージェントを介さずホスト上で行うことを推奨します。エージェントにノードの参加を許可する必要がない場合は、DOCKER_MCP_SERVER_DISABLE=swarmで機能一式を無効にしてください(設定を参照)。 container_exec、compose_exec、compose_runは任意のコマンドを実行します。 コマンドの一部でもエージェントが制御する入力に由来する場合は、シェルを呼び出さない exec 形式の argv リストを使用してください(例:["python", "-V"])。シェルを呼び出す["sh", "-c", template]のようなリストでは、信頼できない文字列内のシェルメタ文字が解釈されます。- コンテナのアーカイブパス。
container_archive_getとcontainer_archive_putは、指定されたパスをそのままデーモンに渡します。信頼境界はコンテナです。コンテナのファイルシステムを信頼できない場合、..によるパストラバーサルが拒否されると想定しないでください。 - ファイルパスを扱うペイロードツールは、サーバーホストのファイルシステムを読み書きします。
image_save、container_export(dest_pathを指定)、container_archive_get_to_fileは、この MCP サーバーを実行するホスト上のdest_pathに書き込みます(overwrite=Trueでない限り、既存ファイルへの上書きは拒否されます)。image_load、image_import、container_archive_put(from_fileを指定)はホストのパスから読み込み、compose_cpはサービスコンテナとホストのパスとの間で双方向にコピーします。ホストの外部にアクセスするのはimage_import(from_url=...)だけです。デーモン が呼び出し元の指定した URL をデーモン自身のネットワーク名前空間で取得するため、デーモンが到達できるものには何にでもアクセスできます(これはimage_pullのレジストリ引数と同じく、呼び出し元が取得先を選ぶ方式です)。これらはサーバーのユーザーとして実行されるため、エージェントはそのユーザーが書き込めるファイルすべてに書き込み、そのユーザーが読み込めるファイルすべてを読み込めます。エージェントにホストのファイルシステムへのアクセスを許可したくない場合は、インバンドのバイトツール(上限 32 MiB)の使用を推奨します。DOCKER_MCP_SERVER_READONLYを有効にするとホストへの書き込みツールも除外されます。ただし、これは書き込みツールだけを対象とするものではありません。読み取り専用ツール のみ が登録されるため、image_loadとcontainer_archive_put(およびその他すべての変更/破壊的ツール)も除外されます。ファイル書き込みツールだけを除外するスイッチはありません。 - 破壊的な操作には組み込みの確認機能がありません。
prune_*、remove_*、container_kill、swarm_leave、compose_down(volumes=True)、compose_kill、スタック内のすべてのサービスを停止するstack_remove、常に--forceを指定して実行されるbuildx_prune、およびbuildx_removeは即座に実行されます。これらのツールにはdestructiveHintアノテーションが付いているため、Claude Code などのクライアントでは実行を制限できます。また、付属のclean_environmentプロンプトは、ボリュームの削除前にエージェントへ確認を求めます。ただし、ツール呼び出し自体はサーバーによって制限されません。確実に防ぐには、DOCKER_MCP_SERVER_NO_DESTRUCTIVE=1(対象ツールをすべて除外)またはDOCKER_MCP_SERVER_READONLY=1(設定を参照)を指定して実行してください。承認手順を設ける場合は、MCP クライアント側で設定してください。 - CLI を呼び出す際の攻撃対象領域。 Compose、Stack、Buildx、Scout、Context の各ツールは、この MCP サーバーを実行するホスト上で
dockerサブプロセスを起動します。すべての呼び出しで引数リストを渡すため、シェルやメタ文字の解釈は行われません。バイナリはshutil.whichで解決され、環境変数が整理された環境(DOCKER_HOST関連の変数のみ)で実行されます。位置引数(イメージ参照、サービス名/コンテキスト名/ビルダー名、ビルドコンテキスト、bake ターゲット)は、先頭が-の場合に拒否されるため、引数を CLI フラグとして紛れ込ませることはできません(例:--output=...という名前のサービス)。意図的な例外はcompose_exec/compose_runの末尾のコマンドで、任意の argv を渡すことを想定しています。compose_*に渡すファイルシステムパス(project_dir、files)は、サーバーホスト上で docker CLI によって読み込まれます。見慣れないパスを渡すと、サーバーのユーザーが読み込める任意の compose ファイルが露出する可能性があります。ローカルの docker CLI がなく、ターゲットがssh://の場合、これらのサブプロセスは代わりにリモートホスト上で実行されます(上記を参照)。これにより、次の 2 点が変わります。コマンドはリモート SSH ユーザーとして実行され、そのユーザー自身のレジストリ認証情報が使われます。また、コマンドが読み込むファイルは、まずリモートホストの一時ディレクトリにコピーされます。そのため、buildx_buildの--secret src=ファイルや、ステージングしたディレクトリ内のその他のファイルは、リモートディスク上に一時的に存在します(モード0700で、呼び出しの戻り時に削除されます。接続が切断された場合に限り、残存する可能性があります)。ステージングを伴うツールには、コピーしても問題のないディレクトリを指定してください。 - デーモンのセットは起動時に固定されます。慎重に選択してください。
DOCKER_HOST/DOCKER_MCP_SERVER_HOSTSが未設定の場合、サーバーの 初期 SDK 接続は、現在アクティブな Docker コンテキスト(DOCKER_CONTEXT/currentContext)に従います。これはdockerCLI が接続するものと同じデーモンです。そのコンテキストがリモートまたは本番用デーモンを指している場合、エージェントもそこに接続します。対象を意図的に固定するには、サーバー起動前にDOCKER_MCP_SERVER_HOSTS(またはDOCKER_HOST)を設定するか、スコープを限定したコンテキストを選択してください。DOCKER_MCP_SERVER_HOSTSを使用すると、auto/localエンドポイントは起動時に解決され、固定されるため、後からコンテキストが変わっても移動しません。起動後、context_useが変更するのは以降の CLI ベースのツールに対する CLI のデフォルトのみです。SDK ベースのツールは、プールされたクライアントが接続したデーモンを引き続き使用します。実行中に任意のエンドポイントのデーモンを追加したり、接続先を変更したりする方法はありません。system_reconnectは、すでに設定済みのホストのクライアントを 再構築 するだけで(接続が応答しなくなった場合の復旧用)、別の接続先を指定することはできません。デーモンを追加または変更するには、DOCKER_MCP_SERVER_HOSTSを編集して再起動してください。これは、信頼境界の拡大につながる経路を意図的に閉じるものです(エージェントがセッションの途中で root 相当の境界を未審査のエンドポイントに移すことはできません)。context_create(skip_tls_verify=True)はコンテキストの TLS 検証を無効にします。信頼できるローカルデーモンに対してのみ使用してください。 - ホストごとの読み取り専用設定は、誤操作を防ぐ措置であり、セキュリティ境界ではありません。
DOCKER_MCP_SERVER_HOSTSで(ro)と指定されたホストでは、呼び出し時に変更/破壊的ツールが操作を拒否します(ホストが複数ある場合は、誤ったデーモンに対してエージェントが指定漏れで変更を行わないよう、書き込みには対象ホストの明示が必要です)。guard_not_selfと同様、これはプロセス内での便宜的な制限です。このサーバーのツールを介したエージェントの操作は制限しますが、デーモン自体は依然として信頼境界です。エージェントに絶対に変更させてはならないホストには、このマーカーだけに頼らず、本当に読み取り専用またはスコープを限定したデーモンを指定してください。 - ホストごとの非破壊設定も同じ誤操作防止措置ですが、対象範囲はさらに狭くなります。
(nd)と指定されたホストでは、破壊的なツール呼び出し(強制終了、削除、プルーン)のみが拒否され、読み取りや通常の変更は引き続き実行できます。(ro)と同様、これはこのサーバーのガードによってプロセス内で適用される便宜的な制限であり、デーモンレベルの境界ではありません。 - **
cryptography(mcp->pyjwt[crypto]経由の間接依存関係)には、49.0.0 以降、x86_64/universal2 の macOS ホイールが提供されていません。これは一時的な問題ではなく、恒久的なものと確認されています。そのため、macOS へのネイティブインストール(uvx、pip、.mcpbバンドル)では、現行バージョンが選択され、ソースからビルドされるため、Rust と OpenSSL 3.x が必要です。**このプロジェクトは一時期、Intel macOS に限ったcryptography<49の上限設定によってビルドを回避しようとしました。しかし、この上限設定は指定したプラットフォームだけでなく すべて のプラットフォームのバージョンを固定してしまいました(プラットフォームを限定した上限設定だけではuv lockに解決を分岐させることはできません)。その結果、誰も気づかないうちに、後に発見された重大度の高い CVE の対象範囲内のバージョンに全員がとどまっていました(PKCS#7 EnvelopedData の復号における Bleichenbacher オラクル)。このプロジェクトは PKCS#7 エンベロープを自ら復号しませんが、あるプラットフォームでホイールのみのインストールを維持するために、悪用可能であることが知られている脆弱性を含む依存関係を承知のうえで提供するべきではありません。そのため、上限設定を別の設定に置き換えることなく削除しました。ビルドツールチェーンをインストールしたくない場合は、代わりに コンテナイメージを使用してください(Linux 上で一元的にビルドされるため、この問題は発生しません)。
パッケージと掲載先
| チャネル | リンク |
|---|---|
| PyPI | docker-mcp-server |
| GHCR(コンテナ) | ghcr.io/l337-org/docker-mcp-server |
| Docker Hub(コンテナ) | gavinlucas/docker-mcp-server |
| デスクトップ拡張(.mcpb) | GitHub リリース |
l337-docker エージェントスキル(.tar.gz) | GitHub リリース |
| 公式 MCP レジストリ | io.github.L337-org/docker-mcp-server |
| Glama | docker-mcp-server |
| mcp.so | docker-mcp-server |
| awesome-mcp-servers | punkpeye/awesome-mcp-servers |
プライバシーポリシー
docker-mcp-server はデータを収集せず、テレメトリーを送信せず、作者が運営するバックエンドもありません。ローカルで動作し、要求された操作の一環として、お客様が指定した Docker デーモンおよびコンテナレジストリとのみ通信します。全文はPRIVACY.mdをご覧ください。
貢献
貢献を歓迎します。このプロジェクトでは、Docker SDK の公開インターフェースと、公開する MCP ツールとの密接な対応を重視しています。プロジェクトの構成、ツールの規約、新しいツールモジュールを追加する際のチェックリスト、ローカルでの開発環境の設定については、CONTRIBUTING.mdをご覧ください。
商標
docker-mcp-server は独立したオープンソースプロジェクトです。Docker, Inc. との提携、同社による推奨や後援はありません。Docker は Docker, Inc. の商標または登録商標です。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。