Skip to main content
Glama

docker-vm-mcp

sundar によって構築されました。

AIエージェントに完全なVMライフサイクル制御を提供するMCPサーバー — 作成、SSHログイン、コマンド実行、停止/起動/再起動、削除、ログ、リソース統計 — を、Dockerコンテナを基盤とする軽量な「VM」上で実現します。各VMは実際のsshdを実行する本物のUbuntuシステムであり、sudoと永続ディスクを備えているため、通常のログイン可能なマシンと同じように動作します。クラウドアカウントやネストされた仮想化は不要です。サーバー自体もコンテナ化され、Dockerイメージとして公開されており、Model Context Protocolを通じて完全に駆動されます。

セットアップが完了すると、Claudeに次のようなことを依頼できます:

  • 「dev-boxという名前のVMを2CPU・2GB RAMで作成して」

  • 「dev-boxにSSHで入れて」/「dev-boxのSSHログイン情報は?」

  • 「dev-boxにnginxをインストールして起動して」

  • 「dev-boxを停止して」/「dev-boxを削除して」

  • 「すべてのVMを一覧表示して」

Claudeは以下のツールを通じてライフサイクル全体を操作します。

仕組み

各「VM」は、小さなUbuntu 22.04イメージ(vm-image/Dockerfile)から構築されたDockerコンテナであり、実際のsshdを実行し、sudoを持ち、名前付きDockerボリュームがホームディレクトリとしてマウントされます(そのため、停止/再起動後もファイルは保持されます。EC2インスタンスにアタッチされたEBSボリュームに似ています)。MCPサーバー自体は、/var/run/docker.sockを介してローカルのDockerデーモンと通信します — サーバーがVMを実行するのではなく、既存のDocker Desktopインストールを操作します。

Claude  <--MCP/stdio-->  docker-vm-mcp container  <--docker.sock-->  Docker Desktop
                                                                          |
                                                                    vm-dev-box (Ubuntu + sshd)
                                                                    vm-staging (Ubuntu + sshd)
                                                                    ...

Related MCP server: Docker MCP Server

前提条件

  • MacでDocker Desktopがインストールされ、実行されていること

  • Node.js 20+(サーバーをDocker外で実行する場合のみ必要。必須ではありません)

1. ビルド

このフォルダから:

docker build -t docker-vm-mcp:latest .

これにより、MCPサーバーイメージのみがビルドされます。VMベースイメージ(docker-vm-mcp/vm-base:latest)は、初めてvm_createを呼び出したときに自動的にビルドされます — サーバーにはvm-image/Dockerfileがバンドルされており、初回使用時にDockerデーモンに対してビルドを実行します。自分で事前にビルドすることもできます:

docker build -t docker-vm-mcp/vm-base:latest ./vm-image

2. Claude Desktopでの実行/登録

stdio上のMCPサーバーは、クライアント(Claude Desktop)によって起動されます。単独で実行されるわけではありません。Claude Desktopの設定ファイル(~/Library/Application Support/Claude/claude_desktop_config.json)にこれを追加します:

{
  "mcpServers": {
    "docker-vm-mcp": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-v", "/var/run/docker.sock:/var/run/docker.sock",
        "-v", "docker-vm-mcp-state:/data",
        "docker-vm-mcp:latest"
      ]
    }
  }
}

その後、Claude Desktopを再起動します。2つのマウントは両方とも必須です:

  • /var/run/docker.sock — サーバーがVMコンテナを作成/起動/停止/実行できるようにします。

  • docker-vm-mcp-state(名前付きボリューム) — サーバーが各VMの生成されたSSHパスワードを再起動後も記憶する場所です。これがないと、MCPサーバーコンテナが再起動するたびにvm_ssh_infoが保存されたパスワードを失います(VMコンテナ自体は影響を受けません — 実行を継続します)。

Claude Desktopに接続する前に、イメージが実行され、Dockerに到達できることを確認できます:

docker run -i --rm \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v docker-vm-mcp-state:/data \
  docker-vm-mcp:latest
# should print nothing and just wait on stdin (that's correct — it's
# speaking MCP, not a REPL). Ctrl+C to exit.

このサーバーが公開するツール

ツール

機能

vm_create

新しいVMを作成して起動します。パラメータ: name, cpus, memoryMb, sshPort, sshUser, sshPublicKey。SSHコマンドと生成されたパスワードを返します。

vm_list

管理下のすべてのVMをステータスとSSHポートとともに一覧表示します。

vm_start

停止中のVMを起動します。

vm_stop

実行中のVMを停止します(ディスクは保持されます)。

vm_restart

VMを再起動します。

vm_delete

VMを完全に削除します(removeVolume=falseでない限り、ディスクボリュームも削除されます)。

vm_exec

Dockerを介してVM内でシェルコマンドを直接実行します(SSHは不要)。

vm_ssh_info

VMのSSHコマンド、ホスト、ポート、ユーザー、パスワードを取得します。

vm_set_password

VMのSSHパスワードを設定または再生成します(手動でパスワードを変更した後にvm_ssh_infoを再同期します)。

vm_logs

VMのコンソール/システムログ出力を追跡します。

vm_stats

実行中のVMのライブCPU % / メモリ使用量を表示します。

自分でログインする

各VMはSSHポートをMacにバインドするため、ClaudeがVMを作成したら、ターミナルから直接SSHでログインすることもできます:

ssh vmuser@localhost -p <port>   # port and password from vm_create / vm_ssh_info

vm_createにsshPublicKey(~/.ssh/id_ed25519.pubの内容)を渡すと、パスワードをスキップしてキーでログインできます。

このイメージの公開

共有する場合(例:チームメイトや別のマシンがソースからビルドする代わりにdocker pullできるようにする):

docker tag docker-vm-mcp:latest <your-dockerhub-username>/docker-vm-mcp:latest
docker push <your-dockerhub-username>/docker-vm-mcp:latest

イメージには秘密情報は焼き込まれていません — 資格情報は実行時にVMごとに生成され、コンテナを実行しているマシンのローカルdocker-vm-mcp-stateボリュームにのみ保存されます。公開しても安全です。

セキュリティに関する注意(自分のマシン以外に公開する前に読んでください)

  • Dockerソケットのマウントはrootと同等です。 /var/run/docker.sockにアクセスできるものは、このツールが作成するVMだけでなく、マシン上のすべてのコンテナを制御できます。このマウントを信頼できるマシンでのみ実行し、MCPサーバー自体(またはそれへのポート)を信頼できない呼び出し元に公開しないでください。

  • SSHパスワードは平文で保存されます docker-vm-mcp-stateボリューム(/data/credentials.json)に保存され、vm_ssh_infoが後で返すことができます。個人用のローカル開発ツールには問題ありませんが、マルチテナントや本番用途に転用しないでください(例:キーのみの認証に切り替え、パスワードの永続化をやめるなど)。

  • VMコンテナはデフォルトでSSHポートを0.0.0.0に公開します(Dockerのデフォルト)。つまり、ファイアウォールが許可していれば、ローカルネットワーク上の他のデバイスが到達できる可能性があります。明示的なsshPortを渡してファイアウォールで保護するか、127.0.0.1のみにバインドするか(src/tools/createVm.tsのPortBindingsホストIPを127.0.0.1に編集して再ビルド)を検討してください。

実世界での検証: ServiceNow Discovery

このプロジェクトは、実際のServiceNowインスタンスのライブDiscoveryターゲットとして使用されてきました。ローカルで実行されるMIDサーバー(これもDocker化)を介してです — おもちゃではなく、本物のSSHで到達可能なLinuxホストとして動作する証拠です:

  • 標準Discovery、MIDサーバー → MacのLAN IPとVMの公開SSHポート(例:192.168.x.x:<port>)を介してVMに接続 — ホスト名、OS、RAM、CPUの詳細をSSH経由でライブ取得し、cmdb_ci_linux_server CIを正常に作成しました。

  • Quick Discoveryも同様に動作します。

  • MIDサーバーコンテナとVMコンテナはどちらもDockerのデフォルトのbridgeネットワーク上にあるため、公開ポートなしで、標準SSHポート(22)の内部コンテナIPを介して直接相互に到達することもできます。MacのLAN IP(ネットワークによって変わる)に依存しません。

  • 自分で試す場合に知っておくべき癖が1つあります:検出されたCPUメーカーが「Apple」と表示されます。これは正しく、バグではありません — Docker Desktop for MacはコンテナをホストのApple Siliconチップ上で直接起動されたlinuxkit VM内で実行するため、SSHプローブが/proc/cpuinfoを読み取ると、他のホストと同じように実際のハードウェアが見えます。

プロジェクト構造

docker-vm-mcp/
├── Dockerfile              # MCP server image
├── package.json
├── tsconfig.json
├── vm-image/
│   └── Dockerfile          # base "VM" image (Ubuntu + sshd), built on first vm_create
└── src/
    ├── index.ts            # MCP server entrypoint (stdio transport)
    ├── docker.ts            # Docker client, image-build, container lookup helpers
    ├── state.ts             # local credential store (/data/credentials.json)
    ├── util.ts              # exec/log demuxing helpers
    └── tools/
        ├── createVm.ts
        ├── listVms.ts
        ├── startVm.ts
        ├── stopVm.ts
        ├── restartVm.ts
        ├── deleteVm.ts
        ├── execVm.ts
        ├── sshInfo.ts
        ├── setPassword.ts
        ├── logsVm.ts
        └── statsVm.ts

検証方法に関する注記

これはnpmレジストリにアクセスできないサンドボックス環境でビルドおよび型チェックされたため、npm install / npm run buildをここでエンドツーエンドで実行できませんでした。TypeScriptはNode自身の型定義に対してエラーなしでチェックされました。残るチェックは@modelcontextprotocol/sdk、dockerode、zodの型に対するものだけですが、それらはそのサンドボックスではインストールできませんでした。プロジェクトをMacにコピーした後、最初のdocker buildの前にこれを一度実行してください:

npm install
npm run build

tscが上記で既に処理されたもの以外を報告する場合、それはおそらく@modelcontextprotocol/sdkのバージョン固有のAPI変更です(急速に進化しているパッケージです) — 修正はほとんどの場合、src/index.tsのインポートパス(@modelcontextprotocol/sdk/server/mcp.js / .../server/stdio.js)をnpm installが解決したバージョンに合わせて少し調整するだけです。

Related MCP Connectors

Related MCP Servers