Docker MCP Server について
Docker MCP Serverは、DockerとComposeを操作する構造化ツールをAIエージェントに提供します。開発・運用担当者がコンテナ、ログ、ヘルス状態、データベースを調べられ、SSH経由でリモートホストも扱えます。
主な機能
- 01コンテナの状態・ヘルス・リソースを確認
- 02範囲を指定してログを取得
- 03データベースをクエリしダンプを作成
- 04Composeプロジェクトとサービスを管理
- 05SSH経由のリモートDockerホストを設定
活用シーン
- 01Composeスタックのヘルス問題を診断
- 02コンテナのエラーログを調査
- 03サービスのリソース使用量を確認
- 04ローカルとリモートのホストでデプロイを管理
MCP 対応
公式MCP SDKで構築されたネイティブMCPサーバーで、構造化されたDockerツールをMCPクライアントに公開します。クライアントはローカルのDockerデーモン、またはSSH接続を設定したリモートホストを利用できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
npx -y @hypnosis/docker-mcp-serverDOCKER_MCP_PROFILES_FILEAbsolute path to the JSON file describing the Docker hosts this agent may reach. Without it the server answers about the Docker on this machine.DOCKER_PROFILESThe same profiles JSON inline, used when no profiles file is set.DOCKER_MCP_ALLOW_SSH_FALLBACKKeep going when a profile's SSH key is missing, instead of refusing the profile. Defaults to false.LOG_LEVELLog verbosity: error, warn, info or debug. Defaults to info.ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ツール
10掲載時のツール一覧 · 2 週間前に更新
| パラメーター | 型 | 必須 | 説明 |
|---|---|---|---|
| action | enum | はい | list:プロジェクト内のすべてのコンテナと、その状態およびヘルス。stats:この時点での 1 つのサービスの CPU、メモリ、ネットワーク、ディスク使用量。list | stats |
| profile | string | いいえ | プロファイル名で Docker ホストを指定します。デフォルト:デフォルトとしてマークされたプロファイル。 |
| project | string | いいえ | compose プロジェクトを指定します。デフォルト:作業ディレクトリのプロジェクト。該当する名前がない場合はエラーとなり、ホスト上のすべてのコンテナにフォールバックしません。action が list で省略された場合:ホスト上で compose によって実行されているすべてのコンテナ。 |
| service | string | いいえ | compose ファイルに記載されたサービス名。action が stats の場合に必須です。 |
| compose_path | string | いいえ | compose ファイルの場所。ファイル自体、またはファイルを含むディレクトリを指定します。ホスト上にプロジェクトラベルが付いたコンテナがない場合、つまりこのホストでプロジェクトが一度も起動されていない場合にのみ必要です。ディレクトリに複数の compose ファイルがある場合は、名前を示して拒否し、推測で選ぶことはありません。 |
詳細
Docker MCP Server — AI エージェント向け Docker ツール
AI エージェントが、壊れやすいシェルコマンドやターミナル形式の出力ではなく、構造化された Docker ネイティブのツールを使って Compose スタックを操作できる Docker MCP サーバーです。
コンテナーの確認、ログの読み取り、ヘルスチェック、データベースへのクエリー、ダンプの取得、スタックの起動や停止ができます。ノート PC 上でも、プロファイル名を指定すれば世界中のサーバー上でも操作できます。
普段の Docker と同じように、Compose ファイル、プロジェクト名、サービス名を使えます。回答は ASCII テーブルを解析して推測するのではなく、エージェントが操作できるだけの情報を含む名前付きフィールドで返されます。
Claude Code、Codex CLI、Cursor、opencode、Gemini CLI、Qwen Code、その他の MCP クライアントで動作します。
インストール · ツール · セットアップ · セキュリティ · ドキュメント · 変更履歴
30 秒でインストール
グローバルインストールは不要です。初回使用時に npx がパッケージをダウンロードします。
npx -y @hypnosis/docker-mcp-server
すべてのプロジェクトで使えるように、MCP クライアント(たとえば Claude Code)に追加します。
claude mcp add docker -s user -- npx -y @hypnosis/docker-mcp-server
このマシン上の Docker には、これだけでセットアップが完了します。プロファイルファイルも環境変数も不要です。サーバーはローカルの Docker ソケットを使用し、作業ディレクトリの Compose プロジェクトについて回答します。
別のマシン上の Docker ホストを使う場合は、SSH 経由で接続するサーバーを記述したファイルを 1 つ追加します。
claude mcp add docker -s user \
-e DOCKER_MCP_PROFILES_FILE="$HOME/.claude/docker-profiles.json" \
-- npx -y @hypnosis/docker-mcp-server
{
"default": "local",
"profiles": {
"local": { "mode": "local" },
"production": {
"host": "prod.example.com",
"username": "deployer",
"privateKeyPath": "~/.ssh/id_ed25519"
}
}
}
これで、すべてのツールが profile を受け取るようになり、docker_health({ action: "profiles" }) でサーバーに設定された内容を一覧表示できます。
Codex、Cursor、opencode、その他のクライアントについては、Docker MCP サーバーのセットアップをご覧ください。
プラグインとしてインストール
Claude Code など、一部のクライアントでは、全体をプラグインとして利用できます。
/plugin marketplace add hypnosis/docker-mcp-server
/plugin install docker-mcp-server@docker-mcp-server
プラグインは設定なしで、このマシン上の Docker に対してサーバーを起動します。上記と同じ方法で DOCKER_MCP_PROFILES_FILE を使えば、他のホストにも接続できます。
要件
Node.js 18+ と、すでにアクセス可能な Docker デーモン(ローカルソケット、または SSH キーを使ったリモートホスト)が必要です。
Docker が起動しているかどうかにかかわらず、サーバーは起動します。デーモンが停止している間に呼び出すと「Docker を起動してください」と応答し、MCP クライアントを再起動しなくても、次の試行で動作します。
バージョンを固定したい場合、オフラインで作業する場合、または起動時のレジストリ確認を減らしたい場合は、npm install -g @hypnosis/docker-mcp-server を実行して、npx の代わりにコマンドとして docker-mcp-server を使用してください。
この Docker MCP サーバーの対象ユーザー
- Docker Compose を使ってアプリケーションを構築、実行、デバッグする AI 支援開発者。
- 問題の解決中に、コーディングエージェントでコンテナ、ログ、ヘルスチェック、データベース、Compose サービスを調査する必要があるバックエンドおよびフルスタック開発者。
- Docker アプリケーションを自分のサーバーにデプロイし、ローカル開発と本番環境に共通するエージェントのワークフローを求める個人開発者や小規模なプロダクトチーム。
- 開発、ステージング、本番環境の Docker 環境を管理するプラットフォームエンジニア。
- インシデントの確認、日常的なコンテナ作業、Compose ベースのサービスの迅速な調査に AI コーディングエージェントを使用する DevOps エンジニアや SRE。
- クライアントアプリケーションを保守する代理店や技術チーム。変更を加える前に、エージェントが不慣れな Compose スタックを理解する必要がある場合に適しています。
- リリース前に、テストスタック、サービスの状態、ログ、データベースを繰り返し確認する必要がある QA エンジニアやリリースエンジニア。
Docker CLI を直接使う代わりに Docker MCP サーバーを使う理由
Docker CLI は、ターミナルを使う人にとって非常に優れたツールです。一方、AI エージェントには別のものが必要です。直接問い合わせられる Docker と Compose の概念、推論に使える結果、そして実行された内容、見つからなかった内容、確認できなかった内容を明確に区別する仕組みです。
コンテキストを減らし、AI のコストを抑える
docker ps、docker stats、docker logs は、画面で人が読むことを前提に設計されています。出力にはラベル、値、単位、書式が入り混じっており、エージェントは利用する前に解析しなければなりません。
Docker MCP ツールは、サービス、プロジェクト、状態、ヘルス、ポート、タイムスタンプ、バイト数、終了コード、ログストリームなど、タスクに必要なフィールドを返します。エージェントが受け取るターミナルのノイズが減り、解釈に使うトークンも少なくなり、解決中の問題により多くのコンテキストを割けます。
Docker Compose をシステムとしてデバッグする
Docker アプリケーションは、単なるコンテナの一覧ではありません。サービス、依存関係、ヘルスチェック、ログ、データベース、相互に影響するリソースで構成される Compose プロジェクトです。
このサーバーを使うと、エージェントは日常的に使っている名前、つまりプロジェクト、サービス、Compose ファイルを指定して、そのシステムについて問い合わせられます。1 回の呼び出しでスタックの状態とヘルスを確認し、別の呼び出しで範囲を限定したログを調べたり、サービスを計測したり、隣で実行中のデータベースに問い合わせたりできます。エージェントはシェルコマンドを組み立てて解析するのではなく、原因の特定に処理を使えます。
明示的な結果に基づいて判断する
シェルコマンドは、空のテーブル、途中で切れた出力、通常のテキストに併記されたエラーを返すことがあります。エージェントにとって、これらはそれぞれ異なる状況です。同じものとして扱うと、推測につながります。
Docker MCP の結果は、何が見つかったか、何が見つからなかったか、何が途中で打ち切られたか、そしてアクションが実行されなかった理由を示します。ヘルスチェックがないことは、ヘルスチェックの失敗ではありません。空のリストは、読み取りの失敗ではありません。終了コードがないコマンドは、実行が始まっていません。これにより、エージェントは次のステップを確かな根拠に基づいて選べます。また、正しそうに見えて実際には誤っている修正を減らせます。
SSH 経由でローカルとリモートの Docker ホストを管理する
手元の Docker デーモンでも、リモートサーバー上の Docker デーモンでも、同じ Docker MCP ツールを使えます。リモート Docker ホストはプロファイルとして管理します。プロファイルには、固定の名前、SSH 接続、その接続に必要な認証情報が含まれます。エージェントはツール呼び出しでそのプロファイルを指定します。
docker_container({ "action": "list", "profile": "production" })
profile を省略すると、デフォルトの Docker ホストが応答するため、ローカル開発を手間なく続けられます。ホストに登録されていないプロファイル名を指定すると、別のマシンに黙ってリクエストを送るのではなく、ホストが把握しているプロファイルの一覧が応答に含まれます。
リモートの Docker Compose プロジェクトは、コンテナがすでに持っているラベルを使って特定します。そのホスト上のどこにあっても、名前でプロジェクトを指定できます。リモートの作業ディレクトリや固定の Compose ファイルパスを管理する必要はありません。そのホストでまだ実行したことのないプロジェクトでは、compose_path を使ってファイルを明示的に指定します。
Model Context Protocol 向けに構築
公式 MCP SDK を基盤にしたネイティブの Docker MCP サーバーであり、ターミナルの自動化ではなく、AI エージェント向けに設計された構造化ツールを備えています。
その動作は、モックだけでなく実際の Docker コンテナに対して実行するユニットテストとエンドツーエンドテストで検証されています。
Docker MCP と Docker CLI の比較:実用例
ターミナルを人が操作する場合は、Docker CLI が適切なインターフェースです。AI エージェントが Docker Compose アプリケーションを調査し、結果を理解して、次に安全なステップを選ぶ場合に何が変わるかを、以下の例で示します。
各比較では、実際に起こりうる同じ作業を取り上げます。まずエージェントが処理しなければならないコマンドと出力を示し、続いて、エージェントがそのまま使える構造化された Docker MCP の結果を示します。
Docker Compose スタックの健全性を診断する
状況: デプロイ直後です。サイトの動作が遅く、コンテナが停止しているのか、ヘルスチェックに失敗しているのか、何かがメモリを大量に消費しているのか分かりません。
質問:「このスタックは正常ですか?」
生の docker CLI
$ docker compose ps
NAME IMAGE STATUS PORTS
shop-api-1 shop-api:latest Up 4 minutes (healthy) 0.0.0.0:8080->8080/tcp
shop-postgres-1 postgres:16 Up 4 minutes (unhealthy) 5432/tcp
shop-worker-1 shop-worker:latest Exited (1) 2 minutes ago
$ docker stats --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
1f2c4d5e6a7b shop-api-1 3.10% 214.8MiB / 7.66GiB 2.74% 12.4MB / 8.9MB 0B / 4.1MB
9a8b7c6d5e4f shop-postgres-1 0.42% 1.204GiB / 7.66GiB 15.7% 3.2MB / 44MB 112MB / 890MB
$ docker inspect --format '{{.State.Health.Status}}' shop-postgres-1
unhealthy
$ docker inspect --format '{{.State.Health.Status}}' shop-worker-1
Template parsing error: executing "" at <.State.Health.Status>: nil pointer evaluating *types.Health.Status
3 つのコマンドと 3 種類の形式です。最後のコマンドは、worker イメージにヘルスチェックが定義されていないため失敗します。何も壊れているわけではなく、単に読み取るものがありません。しかし、エージェントは「ヘルスチェックがない」状態と「ヘルスチェックに失敗している」状態を区別しなければならず、テーブルからはその判断に役立つ情報を得られません。
構造化された MCP の結果
docker_container({ "action": "list", "project": "shop" })
{
"action": "list",
"project": "shop",
"containers": [
{ "name": "shop-api-1", "service": "api", "project": "shop", "state": "running",
"health": "healthy", "image": "shop-api:latest",
"ports": ["0.0.0.0:8080->8080/tcp"], "created": "2026-08-24T09:14:02Z" },
{ "name": "shop-postgres-1", "service": "postgres", "project": "shop", "state": "running",
"health": "unhealthy", "image": "postgres:16",
"ports": ["5432/tcp"], "created": "2026-08-24T09:14:01Z" },
{ "name": "shop-worker-1", "service": "worker", "project": "shop", "state": "exited",
"health": null, "image": "shop-worker:latest",
"ports": [], "created": "2026-08-24T09:14:01Z" }
],
"reason": null,
"legend": {
"containers[].state=running": "Running now.",
"containers[].state=exited": "Stopped. Its logs survive, its processes do not.",
"containers[].health=healthy": "Its own healthcheck passed last run.",
"containers[].health=unhealthy": "Its own healthcheck failed enough times in a row to give up on it.",
"containers[].health=null": "The image declares no healthcheck, so nothing is measured. Not the same as failing."
}
}
エージェントにとっての違い
| 生の docker CLI | 構造化された MCP | 得られるメリット |
|---|---|---|
| 3 つのコマンドと 3 種類の出力形式 | サービスごとの状態、ヘルス、ポートをまとめた 1 回の呼び出し | 往復回数の削減 |
| ヘルスチェックがないとエラーになるか、失敗として読み取られる | health: null の意味が回答自体に説明される | 誰も作成していないチェックの責任をコンテナに負わせない |
| コンテナ名をサービスに対応付ける必要がある | 各行に service、project、name が含まれる | エージェントはコンテナ ID ではなく Compose の用語で扱える |
凡例は、この回答が使った用語だけを、それらの用語を使ったフィールドのすぐそばで説明します。そのため、unhealthy の意味を知るために、何百ものメッセージ前にあるツールの説明を探す必要はありません。
状態ではなく数値が必要ですか? docker_container({ action: "stats", service: "postgres" }) は、CPU、上限に対するメモリ使用量、ネットワーク、ディスクの数値を返します。また、その回答では、これは平均値ではなく、ある瞬間の測定値であることが明確に示されます。
ヘルスチェック自体の情報が必要ですか? docker_health({ action: "services" }) は各サービスの判定結果を報告し、チェックと失敗の数を集計します。ヘルスチェックがないサービスは、異常として数えるのではなく none として示します。
コンテキストを失わずにコンテナログを調査する
状況: 約10分前からAPIが502を返し始めました。コンテナは1週間稼働しており、数十万行のログが出力されています。
質問:「障害が起きたとき、何が出力されていましたか?」
Docker CLI の生出力
$ docker compose logs api --tail 200
api-1 | 2026-08-24T10:31:07.104Z INFO request GET /health 200 3ms
api-1 | 2026-08-24T10:31:07.882Z INFO request GET /health 200 2ms
... 196 more lines of the same ...
api-1 | 2026-08-24T10:39:14.522Z ERROR database connection timed out after 30000ms
$ docker compose logs api --since 10m | grep -i error
api-1 | 2026-08-24T10:39:14.522Z ERROR database connection timed out after 30000ms
最初の呼び出しでは、ヘルスチェックのノイズにコンテキストを200行分も費やしました。2回目はエラーを見つけましたが、その前後の行は捨てられ、どちらの出力にもストリームがstdoutかstderrか、途中で何かが欠落したかは示されていません。
構造化された MCP の結果
docker_logs({ "service": "api", "project": "shop", "since": "10m", "lines": 50 })
{
"service": "api",
"project": "shop",
"date": "2026-08-24",
"lines": [
{ "stream": "stdout", "time": "10:39:14.518",
"text": "INFO pool exhausted, waiting for a free connection" },
{ "stream": "stderr", "time": "10:39:14.522",
"text": "ERROR database connection timed out after 30000ms" },
{ "stream": "stderr", "time": "10:39:14.530",
"text": "ERROR upstream 502 while proxying GET /api/orders" }
],
"returned_lines": 3,
"since": "10m",
"until": null,
"truncated": false,
"truncated_reason": null,
"clipped_lines": 0,
"follow": false,
"reason": null,
"legend": {
"lines[].stream=stderr": "the stream the container wrote to; many programs write their ordinary progress there, so a line is not an error for being here"
}
}
エージェントにとっての変化
| Docker CLI の生出力 | 構造化された MCP | 得られるメリット |
|---|---|---|
| 末尾からの行数指定は推測です。少なすぎると見逃し、多すぎると埋もれます | since と until で時間範囲を絞り、その後 lines で行数を指定します | ノイズに使うトークンが減ります |
| 1つのテキストの塊にストリームとタイムスタンプが埋め込まれています | 各行に個別の stream、time、text が含まれます | grepではなくフィールドでエラーを見つけられます |
| 途中で欠落していても、ログが静かなだけの場合と見分けがつきません | truncated、truncated_reason、clipped_lines で、どこが切り取られたかをすべて示します | 部分的な読み取りをもとに「ログに問題はない」と判断することがありません |
各行が何日に属するかは最初に一度だけ示され、その後、各行には時刻だけが含まれます。すべての行に同じタイムスタンプを繰り返すと、その分のテキストにもコストがかかります。複数日にまたがる行には完全なタイムスタンプが付き、その理由も回答に示されます。
since には日付やUNIXタイムスタンプも指定できます。また、follow: true を指定すると、後続の行を待ち受けます。ストリームを開いたまま無期限に待つのではなく、独自の時間とサイズの上限内で届いた内容を返します。
Docker で動作するデータベースをクエリする
状況: ダッシュボードに注文が表示されなくなりました。データベースの内容を確認したいのですが、データベースはコンテナ内で動作しており、コンテナ内にクライアントがあって、マシンにはポートが公開されていません。
質問:「テーブルには実際に何が入っていますか?」
Docker CLI の生出力
$ docker compose exec -T postgres psql -U app -d shop -c "select status, count(*) from orders group by status"
status | count
-----------+-------
paid | 1284
pending | 17
(2 rows)
$ docker compose exec -T redis redis-cli info keyspace
db0:keys=41822,expires=41822,avg_ttl=3600000
データベースエンジンごとに、それぞれ異なるクライアント、フラグ、ユーザーやデータベースの指定方法が必要です。フラグを1つ間違えるだけで、シェルはエラーを出力します。エージェントはそれをテキストとして読み取らなければなりませんが、呼び出し自体は「成功」扱いです。
構造化された MCP の結果
docker_db({ "action": "query", "service": "postgres", "project": "shop",
"query": "select status, count(*) from orders group by status" })
{
"action": "query",
"service": "postgres",
"project": "shop",
"engine": "postgresql",
"query": "select status, count(*) from orders group by status",
"output": " status | count\n-----------+-------\n paid | 1284\n pending | 17\n(2 rows)",
"stderr": "",
"exit_code": 0,
"clipped_bytes": 0,
"warnings": [],
"reason": null,
"legend": {}
}
エージェントにとっての変化
| Docker CLI の生出力 | 構造化された MCP | 得られるメリット |
|---|---|---|
| データベースエンジンごとにクライアント、フラグのセット、ユーザーが異なります | PostgreSQL、MySQL/MariaDB、Redis、MongoDB、SQLite に対応する1つのツールです | 覚えることは1つだけで、5種類のデータベースを扱えます |
| 拒否されたステートメントでも、コマンドの成功と同じように見えます | exit_code と stderr は output と分けて示されます | 失敗が失敗として表示されます |
| 認証情報をコマンドラインに再入力します | コンテナに設定されたユーザーとデータベースがデフォルトで使われます | トランスクリプトに含まれるシークレットが減ります |
status はデータベース自体に問い合わせ、バージョン、サイズ、稼働時間、接続数などを確認します。また、format: "csv" を指定すると、PostgreSQLの行が解析しやすい形式で出力されます。データベース全体やキー空間全体を破壊する可能性のあるステートメントは、確認マーカーを付けないと実行されません。AI エージェント向けの破壊的コマンドの保護を参照してください。
リスクのあるマイグレーションの前にデータベースをバックアップする
状況: マイグレーションでテーブルを書き換える予定です。まずダンプを取り、マイグレーションで何かを変更する前に、そのダンプが実際に存在することも確認したいと考えています。
質問:「本当にバックアップは取れていますか?」
Docker CLI の生出力
$ docker compose exec -T postgres pg_dump -U app shop | gzip > backup.sql.gz
$ echo $?
0
$ ls -lh backup.sql.gz
-rw-r--r-- 1 you staff 20B 24 Aug 11:02 backup.sql.gz
終了コードが0だったのは、パイプ内の最後のコマンドである gzip からであり、pg_dump からではありません。20バイトのアーカイブは空です。ユーザーを間違えたためにダンプが失敗し、エラーはターミナルに出力されましたが、シェルは成功と報告しました。存在しないバックアップを頼りに、マイグレーションが実行されようとしています。
構造化された MCP の結果
docker_db_admin({ "action": "backup", "service": "postgres", "project": "shop" })
{
"action": "backup",
"service": "postgres",
"project": "shop",
"engine": "postgresql",
"file": "/backups/shop-2026-08-24T11-02-17.dump.gz",
"bytes": 48219553,
"verified": true,
"message": null,
"confirmed": false,
"restarted": false,
"reason": null,
"legend": {
"verified": "The file was read back around the call, and bytes is its size on disk. This is the difference between a dump that exists and a command that did not fail."
}
}
エージェントにとっての変更点
| 生の Docker CLI | 構造化された MCP | 得られるメリット |
|---|---|---|
| パイプでは最後のコマンドの終了コードが報告されます | ダンプを読み戻し、そのサイズを名前付きで示します | 空のバックアップが正常なものとして扱われることはありません |
| エンジンごとに異なるダンプコマンドとフラグが必要です | PostgreSQL、MySQL、MongoDB、SQLite、Redisで1回の呼び出し | スタックの構成にかかわらず、同じワークフローで済みます |
| 「完了」は単なる言葉です | verified はフィールドで、bytes: null は不明な理由を示します | エージェントは、何が分からないかを把握できます |
ファイルを読み戻せない場合、サイズを主張するのではなく、その旨を応答します。verified
は false のまま、bytes は null となり、message には処理を妨げた原因が示されます。不明なサイズが空のファイルとして
報告されることはありません。
データベースへの復元も同じツールで行います。action: "restore" を指定します。既存の内容を上書きするため、
呼び出しの confirm フィールドに確認マーカーが含まれていない場合は拒否されます。また、拒否時には、まずここでバックアップを取るよう案内します。
クリーンアップの前に Docker のディスク使用量を把握する
状況: サーバーのディスク使用率が90%です。原因は Docker と思われますが、 イメージ、ボリューム、停止中のコンテナ、ビルドキャッシュのどれか分かりません。誤ったものをプルーニングすると、 データベースが破損します。
質問:「何を安全に削除できますか?」
生の Docker CLI
$ docker system df
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 48 9 31.2GB 22.4GB (71%)
Containers 21 7 1.8GB 412MB (22%)
Local Volumes 19 6 64.9GB 38.1GB (58%)
Build Cache 264 0 9.7GB 9.7GB
$ docker system df -v | head -40
... several screens of per-image, per-container and per-volume tables ...
人には読みやすい概要ですが、エージェントにとっては処理コストが高くなります。括弧内のパーセンテージ、
単位が混在するテキスト形式のサイズ、そして数画面にわたる詳細表示が含まれるためです。「再利用可能なボリューム」と
「再利用可能なイメージ」を比較するには、エージェントが 64.9GB や
38.1GB (58%) を数値に変換し直す必要があります。
構造化された MCP の結果
docker_resource({ "action": "disk" })
{
"action": "disk",
"count": 4,
"total_bytes": 115534368358,
"disk": [
{ "group": "images", "count": 48, "active": 9,
"size_bytes": 33500985344, "unused_bytes": 24051816448 },
{ "group": "containers", "count": 21, "active": 7,
"size_bytes": 1932735283, "unused_bytes": 431994470 },
{ "group": "volumes", "count": 19, "active": 6,
"size_bytes": 69686362112, "unused_bytes": 40908324864 },
{ "group": "build_cache", "count": 264, "active": 0,
"size_bytes": 10414285619, "unused_bytes": 10414285619 }
],
"reason": null,
"legend": {
"disk[].active": "How many of them something uses right now: a running container, or an image behind one.",
"disk[].unused_bytes": "Size of what nothing uses at the moment. Removing it frees less than this: what is shared stays until its last holder is gone.",
"disk[].group=images": "Images are counted by their layers on disk, so this is what they really take; the sizes of separate images add up to more, because a shared layer belongs to each of them.",
"disk[].group=containers": "Only what a container wrote on top of its image. What the image itself takes is counted with the images."
}
}
エージェントにとっての変更点
| 生の Docker CLI | 構造化された MCP | 得られるメリット |
|---|---|---|
| 単位やパーセンテージが混在するテキスト形式のサイズ | 4つの名前付きグループで、バイト数を数値として表示 | エージェントは解析せずに比較できます |
| 詳細表示に数画面分かかります | 1回の呼び出しで、グループごとに1つの数値を返します | 同じ答えを得るためのトークン数を削減できます |
| 「再利用可能」という表示では、何がボリュームを保持しているか分かりません | active は使用中のものを、unused_bytes は未使用のものを数えます | ビルドキャッシュは削除され、データベースのボリュームは残ります |
images、volumes、networks は、ホストが保持しているものを一覧表示します。ボリュームについては、
サイズと、それを保持しているコンテナ数も示されます。空のリストは、問い合わせて何も見つからなかったことを意味します。問い合わせ自体が行われていない場合とは異なります。
AI エージェント向けの組み込み破壊的コマンド保護
AI エージェントは、構文としては有効でも、実行すべきではないコマンドを生成することがあります。このサーバーは、 Docker やデータベースクライアントに処理が渡る前にローカルでガードを行い、取り消せない操作には、実行を要求する呼び出し内で明示的な確認を必須にします。
ガードは、データを保持するもの(データベース、ボリューム、または最上位ディレクトリ)の削除と、その中のデータの変更または削除を区別します。前者は、確認されるまで拒否されます。後者は実行できますが、何が変更されたかを明記した警告を返します。
取り返しのつかない損失を防ぎ、破壊的な変更には警告する
| 拒否 — 器そのもの | 警告のみ — 中身 |
|---|---|
DROP DATABASE、DROP SCHEMA、dropdb | DROP TABLE、TRUNCATE |
FLUSHALL、FLUSHDB(Redis) | WHERE のない DELETE FROM |
db.dropDatabase()(MongoDB) | 空のフィルターを指定した deleteMany({})、updateMany({}) |
docker volume rm、docker volume prune | docker image prune、docker container prune |
docker system prune | docker network prune |
rm -rf /、rm -rf ~、rm -rf /srv | rm -rf /srv/app/cache |
mkfs、dd of=/dev/... |
警告は拒否ではありません。操作は実行され、何が破壊されたかが回答の warnings に事実として記載されます。WHERE を指定した DELETE FROM orders は何も指摘されません。通常のステートメントだからです。
削除の判断は、コマンドが指し示す場所に基づきます。ルート直下に直接置かれたディレクトリには、アプリケーション、データ、システムなど、何か全体が含まれています。そのため、rm -rf /srv は拒否されますが、rm -rf /srv/app/cache はファイル削除の用途に沿った操作です。sh -c でラップされたコマンドは、隠れているシェルの数にかかわらず展開して読み取ります。コマンドは1つの argv として実行されるため、最上位の区切り文字は引数です。echo "hi"; rm -rf /data は1行を出力するだけで、何も削除しません。
意図的な破壊的操作を確認する
禁止が永続することはありません。3つのツールが、それぞれ危険な操作の箇所で確認を受け取ります。
docker_exec({ "service": "api",
"command": "rm -rf /srv/legacy # CONFIRMED-DESTRUCTIVE" })
docker_db({ "action": "query", "service": "redis",
"query": "FLUSHDB # CONFIRMED-DESTRUCTIVE" })
docker_compose_control({ "action": "down", "volumes": true,
"confirm": "# CONFIRMED-DESTRUCTIVE" })
マーカーは呼び出しの中に含まれるため、その呼び出しだけ拒否を解除し、それ以外には影響しません。マーカー自体がデータベースやシェルに届くことはありません。実行前にステートメントから取り除かれます。
拒否の理由には、何が失われるかが必ず示されます。そのため、先に進む前に確認でき、操作を再実行するときにも見落とされません。例:DROP DATABASE shop destroys the database itself. Add # CONFIRMED-DESTRUCTIVE to the command to run it.
ガードは呼び出しごとに処理します。ある呼び出しでの削除と次の呼び出しでの読み取りを関連付けることはできず、認識しているツールにも限りがあります。ディレクトリを消去するカスタムバイナリは認識されません。これはシートベルトであり、ポリシーエンジンではありません。復旧可能な操作を実行するかどうかは、引き続きユーザーの判断に委ねられます。
コンテナー、Compose、データベース向けの Docker MCP ツール
AI エージェントがよく行う作業に特化した Docker MCP ツールキットです。Compose スタックの調査、サービスの診断、ライフサイクルの管理、データベースの操作、ホストリソースの把握ができます。すべてのパラメーターと使用例は docs/tools.md にあります。
すべてのツールで、共通の Docker Compose 用語を使用します。profile は Docker ホストを選択し、project は Compose プロジェクトを選択し、service は生成されたコンテナー名ではなく、Compose ファイルからサービスを選択します。profile を省略すると、デフォルトのホストが応答します。project を省略すると、作業ディレクトリ内のプロジェクトが対象になります。Docker がホスト上でまだプロジェクトを実行しておらず、プロジェクトを解決できない場合に限り、compose_path を使用してください。
Docker Compose スタックを調査する
| ツール | 内容 |
|---|---|
docker_container | 状態、ヘルス、ポートを含めてプロジェクトを一覧表示するか、1つのサービスのリソース消費量を測定します |
docker_logs | 時間で区切られた範囲内で、コンテナーが出力した内容を1行ずつ読み取ります |
docker_compose | 解決済みの Compose ファイルやその変数など、プロジェクトの定義を読み取ります |
docker_health | サービスのヘルスチェック、このサーバーのヘルス、割り当てられたホストを確認します |
docker_resource | ホストのイメージ、ボリューム、ネットワークと、ディスクの使用状況を確認します |
サービスとスタックのライフサイクルを管理する
| ツール | 内容 |
|---|---|
docker_container_control | 1つのサービスを起動、停止、再起動し、操作前の状態を報告します |
docker_compose_control | スタック全体を起動するか、停止します |
Docker で実行中のデータベースを操作する
| ツール | 機能 |
|---|---|
docker_db | ステートメントを実行するか、データベース自体について問い合わせます |
docker_db_admin | ダンプを取得するか、ダンプからデータベースにデータを投入します |
PostgreSQL、MySQL/MariaDB、Redis、MongoDB、SQLite には、イメージに最初から含まれているクライアントを通じて接続します。コンテナに何かをインストールする必要はありません。
シークレットはデフォルトで非表示
docker_compose でプロジェクトの変数を読み取る際、キー名にシークレットを示す語句(PASSWORD、TOKEN、KEY、SECRET、PRIVATE、CREDENTIALS のいずれか)を含む値は非表示になります。各変数には非表示かどうかが示されるため、マスクされた値を実際の値と取り違えることはありません。必要な場合は mask: false を指定して値を返します。
専用ツールがない場合にコマンドを実行する
| ツール | 機能 |
|---|---|
docker_exec | サービスコンテナ内でコマンドを実行し、stdout と stderr を分けて出力します |
MCP クライアントでの安全なデフォルト設定
標準の MCP アノテーションにより、クライアントは確認なしで実行しても安全なツールを判別できます。読み取り用の 5 つのツールには readOnlyHint が指定されています。制御用の 2 つのツールには destructiveHint と idempotentHint が指定されており、同じ呼び出しを 2 回行っても状態は変わりません。docker_db、docker_db_admin、docker_exec には destructiveHint のみが指定されています。これらはサーバーが書き込んだものではない内容を扱うため、何が起きるかは渡した内容によって決まります。
Docker MCP サーバーをセットアップする
ローカルの Docker を使う場合は、MCP クライアントにサーバーを追加してすぐに作業を開始できます。プロファイルファイルや Docker エンドポイントの設定は不要です。サーバーはこのマシン上の Docker ソケットを使用します。
AI エージェントから SSH 経由でリモートの Docker ホストに接続する場合にのみ、プロファイルを設定してください。
リモート Docker ホストを設定する
MCP クライアントが設定を保存する場所にプロファイルファイルを保存します。各プロファイルには、Docker ホストの名前と、エージェントに必要な SSH 接続情報を指定します。
{
"default": "local",
"profiles": {
"local": { "mode": "local" },
"production": {
"host": "prod.example.com",
"username": "deployer",
"port": 22,
"privateKeyPath": "~/.ssh/id_ed25519"
},
"staging": {
"host": "staging.example.com",
"username": "deployer",
"port": 2222,
"privateKeyPath": "~/.ssh/id_ed25519_staging"
}
}
}
mode: "local" のプロファイルは、このマシン上の Docker を指します。リモートプロファイルには host と username が必要です。port のデフォルト値は 22 です。そのサーバー上の Compose プロジェクトの場所を指定する必要はありません。プロジェクトは、コンテナに付与されたラベルから特定されます。default には、呼び出しで profile が省略された場合に使うプロファイルを指定します。
鍵を使うことをおすすめします。privateKeyPath を指定しないプロファイルは SSH エージェントを使用します。鍵が暗号化されている場合は、この方法が適しています。
ホスト鍵は確認されます。初回接続時に ~/.ssh/known_hosts に記録され、その後、異なる鍵を提示したマシンからの接続は拒否されます。鍵を別のファイルで管理している場合は、プロファイルの knownHostsPath でそのファイルを指定します。
Claude Code、Codex、Cursor などの MCP クライアントを設定する
Claude Code — 1 つのコマンドで設定できます。-s user を指定すると、すべてのプロジェクトでサーバーを利用できます。
claude mcp add docker -s user \
-e DOCKER_MCP_PROFILES_FILE="$HOME/.claude/docker-profiles.json" \
-- npx -y @hypnosis/docker-mcp-server
Codex CLI
codex mcp add docker \
--env DOCKER_MCP_PROFILES_FILE="$HOME/.codex/docker-profiles.json" \
-- npx -y @hypnosis/docker-mcp-server
Cursor — ~/.cursor/mcp.json に設定します。
{
"mcpServers": {
"docker": {
"command": "npx",
"args": ["-y", "@hypnosis/docker-mcp-server"],
"env": {
"DOCKER_MCP_PROFILES_FILE": "~/.cursor/docker-profiles.json"
}
}
}
}
opencode — ~/.config/opencode/opencode.json に設定します。
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"docker": {
"type": "local",
"command": ["npx", "-y", "@hypnosis/docker-mcp-server"],
"enabled": true,
"environment": {
"DOCKER_MCP_PROFILES_FILE": "~/.config/opencode/docker-profiles.json"
}
}
}
}
その他の MCP クライアント — Gemini CLI、Qwen Code、Cline、エディタープラグイン、自作のエージェントでも同様に使えます。必要なのは、実行するコマンドと、リモートホストの場合は環境変数 1 つだけです。
接続を確認する
MCP クライアントを再起動し、docker_health({ action: "profiles" }) を実行します。サーバーが設定から受け取った Docker ホストの一覧が表示されます。読み取れなかったプロファイルがある場合は、そのプロファイルと、確認が必要なフィールドも表示されます。
Docker MCP サーバーの設定
| 変数 | 説明 | デフォルト |
|---|---|---|
DOCKER_MCP_PROFILES_FILE | プロファイル JSON のパスです。設定しない場合は、ローカルの Docker のみを使用します | — |
DOCKER_PROFILES | プロファイルファイルが設定されていない場合に使う、同じ JSON のインライン指定です | — |
DOCKER_MCP_ALLOW_SSH_FALLBACK | プロファイルのキーが見つからない場合に拒否せず、処理を続けます | false |
LOG_LEVEL | debug、info、warn、error | info |
DOCKER_PROFILES_FILE は、最初の変数の非推奨の表記です。引き続き使用できますが、名前を変更するよう求めるログが出力されます。
存在しないキーを参照するプロファイルは、デフォルトでは拒否されます。その際、対象のパスと対処方法が示されます。キーが見つからないままにすると、接続が試行され、原因がわかりにくいところでかなり後になって失敗するためです。
Docker MCP サーバーの制限事項
このサーバーは、自由形式または暗黙的な動作よりも、範囲が限定された明示的なツール呼び出しを優先します。現在の制限事項は次のとおりです。
- ログの追跡には上限があります。
follow: trueは、10 秒または 1 MB に達するまでに届いた内容を返します。これはライブストリームの確認であり、サブスクリプションではありません。 - ガードが読み取るのは一度に 1 回の呼び出しです。 ある呼び出しでの削除と次の呼び出しでの読み取りを関連付けることはできず、認識できるのは既知のツールに限られます。ディレクトリを消去するカスタムバイナリは対象外です。
- ホストのリソースはプロジェクトごとではなく、ホストごとです。
docker_resourceはデーモンが保持するすべてのものについて回答します。プロジェクトを 1 つに絞るにはdocker_containerを使用します。 - Windows での動作は検証されていません。 サーバーは特定のプラットフォーム向けに実装されていませんが、Windows でエンドツーエンドのテストは実施されていません。
Docker MCP サーバーの開発とテスト
npm install
npm run build # tsc
npx tsc --noEmit # types
npm run test:unit # unit tests
npm run docker:test:up # start the test containers
npm run test:e2e # end-to-end suite against those containers
エンドツーエンドのテストスイートは、実際の PostgreSQL、MySQL、MariaDB、MongoDB、Redis、および Web サービスのコンテナーを使用して実行されます。単体テストやモックだけでは検証できない、Docker 連携の動作を確認します。プロジェクトの構成については、docs/architecture.md を参照してください。
Docker MCP Server を応援する
このツールがチームの役に立ったら、GitHub でプロジェクトにスターを付けてください。ほかの開発者にも見つけてもらいやすくなります。
Docker MCP サーバーへの貢献
github.com/hypnosis/docker-mcp-server で、イシューやプルリクエストを歓迎しています。
ライセンス
MIT — LICENSE を参照してください。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。