Skip to content

Model Context Protocol (MCP) 統合ガイド

このガイドでは、自然言語を使用して仮想マシン、ストレージ、およびネットワークを管理するために、AIエージェントをVapor MCP (Model Context Protocol) サーバーに接続する方法について説明します。


概要

Vaporは、MCP仕様 (2025-03-26)で定義されている Streamable HTTP トランスポートを使用して、/api/v1/mcp でリモートMCPサーバーを公開しています。MCP互換のAIクライアントは、このエンドポイントに接続して、21個のインフラ管理ツールを検出および呼び出すことができます。

主な仕様

プロパティ
トランスポートStreamable HTTP (POST/GET/DELETE)
エンドポイントhttps://<host>:7770/api/v1/mcp
プロトコルバージョン2025-03-26
認証Bearerトークン (JWTまたはAPIトークン)
TLSデフォルトで有効 (自己署名証明書)
セッション管理インメモリ、30分間のTTL

1. 認証

MCPエンドポイントは、Vaporの標準認証ミドルウェアの背後に配置されています。すべてのリクエストにおいて、有効な Authorization: Bearer <token> ヘッダーを提供する必要があります。

オプション A: APIトークン (AIエージェントに推奨)

APIトークンは有効期限が長く、永続的であり、マシン間 (M2M) 認証に最適です。サーバーが再起動しても維持され、明示的な有効期限を設定しない限り失効しません。

ステップ 1 — ログインしてセッションJWTを取得する:

bash
curl -ksS -X POST "https://<host>:7770/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"<user>","password":"<pass>","auth_type":"password"}'

レスポンス:

json
{
  "status": "success",
  "data": {
    "token": "eyJhbGci...",
    "expires_at": 1781400787,
    "user": {"username": "awanio", "uid": 1000}
  }
}

ステップ 2 — 永続的なAPIトークンを作成する:

bash
curl -ksS -X POST "https://<host>:7770/api/v1/auth/tokens" \
  -H "Authorization: Bearer <jwt-from-step-1>" \
  -H "Content-Type: application/json" \
  -d '{"name": "mcp-agent"}'

レスポンス:

json
{
  "status": "success",
  "data": {
    "token": "a1b2c3d4e5f6...64-char-hex-string...",
    "token_info": {
      "id": "uuid",
      "name": "mcp-agent",
      "username": "awanio",
      "created_at": "2026-06-13T01:00:00Z"
    }
  }
}

IMPORTANT

token の値は一度しか表示されないため、すぐに保存してください。この値を Authorization: Bearer <token> ヘッダーで使用します。

MCPでAPIトークンを使用するには、Basic認証ヘッダーとして渡します(ミドルウェアが自動識別します):

Authorization: Basic <base64(token:)>

または、Bearerトークンとして直接埋め込むこともできます。ミドルウェアは最初にAPIトークン検証を試み、失敗した場合にJWT解析にフォールバックします。

オプション B: JWTトークン (短期間)

JWTは24時間後に失効します。一時的なテストには適していますが、永続的なエージェントの構成には使用しないでください。

bash
curl -ksS -X POST "https://<host>:7770/api/v1/auth/login" \
  -H "Content-Type: application/json" \
  -d '{"username":"<user>","password":"<pass>","auth_type":"password"}'

返された data.token をその後のすべてのMCPリクエストで使用します。


2. 自己署名TLS証明書の処理

Vaporは、デフォルトで自己署名TLS証明書を使用します。ほとんどのMCPクライアントは、明示的に信頼を設定しない限り、証明書検証エラーで接続を拒否します。

問題の理解

Vaporを初めて起動すると、/var/lib/vapor/certs/ に自己署名証明書が自動生成されます。これらは信頼された認証局 (CA) によって署名されていないため、証明書検証を実行するHTTPSクライアントは接続を拒否し、以下のようなエラーが発生します:

  • CERTIFICATE_VERIFY_FAILED (Python)
  • DEPTH_ZERO_SELF_SIGNED_CERT (Node.js)
  • SSL certificate problem: self-signed certificate (curl)

CA証明書の取得

信頼を構成する前に、Vaporのサーバー証明書を取得する必要があります。取得方法は以下の3通りです:

  • オプション 1 — API経由でダウンロード (自動化に推奨):
    bash
    # 証明書をまだ信頼していないため、最初のダウンロードには -k を使用します
    curl -ksS "https://<vapor-host>:7770/api/v1/system/tls/server-cert" \
      -H "Authorization: Bearer <token>" \
      -o vapor-ca.crt
  • オプション 2 — Web UIからダウンロード: Vapor Webインターフェース → SettingsTLS Configuration"Download CA Certificate" をクリックします。これはサーバーの公開証明書のみをダウンロードし、秘密鍵は含まれません。
  • オプション 3 — サーバーから直接コピー:
    bash
    scp root@<vapor-host>:/var/lib/vapor/certs/server.crt ./vapor-ca.crt

アプローチ 1: 自己署名CAを信頼する (本番環境に推奨)

Vaporの自己署名証明書をシステムの信頼された証明書ストアに追加します。これは、TLS検証を維持できる最も安全なアプローチです。

MCPクライアントを実行しているマシン側で実行(上記で取得した vapor-ca.crt を使用):

bash
# Debian/Ubuntuの場合:
sudo cp vapor-ca.crt /usr/local/share/ca-certificates/vapor-ca.crt
sudo update-ca-certificates

# RHEL/CentOS/Fedoraの場合:
sudo cp vapor-ca.crt /etc/pki/ca-trust/source/anchors/vapor-ca.crt
sudo update-ca-trust

# macOSの場合:
sudo security add-trusted-cert -d -r trustRoot \
  -k /Library/Keychains/System.keychain vapor-ca.crt

証明書を信頼した後は、そのマシン上のすべてのHTTPSクライアントが特別のフラグなしでVaporのTLS接続を受け入れるようになります。

アプローチ 2: 実行時にCAバンドルを指定する

システム証明書ストアを変更せずに、MCPクライアントまたはHTTPライブラリに対してVaporの証明書ファイルを直接指定します。

curlの場合:

bash
curl --cacert /path/to/vapor-server.crt -X POST "https://<host>:7770/api/v1/mcp" ...

Node.jsの場合 (ほとんどのMCPクライアントSDKで使用):

bash
export NODE_EXTRA_CA_CERTS=/path/to/vapor-server.crt

Pythonの場合:

python
import httpx
client = httpx.Client(verify="/path/to/vapor-server.crt")

アプローチ 3: TLS検証を無効化する (開発環境のみ)

WARNING

これはすべての証明書検証を無効にするため、中間者攻撃 (Man-in-the-Middle) に対して脆弱になります。分離された開発環境でのみ使用してください。

curlの場合:

bash
curl -k ...

Node.jsの場合:

bash
export NODE_TLS_REJECT_UNAUTHORIZED=0

Pythonの場合:

python
import httpx
client = httpx.Client(verify=False)

アプローチ 4: 正式なCA証明書を使用する (複数ユーザーの本番環境に推奨)

自己署名証明書を、信頼されたCA(Let's Encrypt、社内PKIなど)によって発行された証明書に置き換えます:

yaml
# vapor.conf
tls_enabled: true
tls_cert_file: "/etc/ssl/vapor/fullchain.pem"
tls_key_file: "/etc/ssl/vapor/privkey.pem"

その後、Vaporを再起動します:

bash
sudo systemctl restart vapor

これにより、すべてのクライアントにおいて証明書エラーの問題が完全に解消されます。


3. MCPプロトコルフロー

MCP Streamable HTTPトランスポートは、単一のエンドポイント(/api/v1/mcp)と3つのHTTPメソッドを使用します:

POST   /api/v1/mcp   ← JSON-RPCメッセージ (initialize, tools/list, tools/call, ping)
GET    /api/v1/mcp   ← Server-Sent Eventsストリーム (サーバー通知用)
DELETE /api/v1/mcp   ← セッションの終了

接続のライフサイクル

┌─────────┐                          ┌──────────┐
│  Client  │                          │  Vapor   │
└────┬─────┘                          └────┬─────┘
     │                                     │
     │  POST initialize                    │
     │────────────────────────────────────►│
     │◄────────────────────────────────────│
     │  200 + Mcp-Session-Id header        │
     │                                     │
     │  POST notifications/initialized     │
     │  (with Mcp-Session-Id header)       │
     │────────────────────────────────────►│
     │◄────────────────────────────────────│
     │  202 Accepted                       │
     │                                     │
     │  POST tools/list                    │
     │  (with Mcp-Session-Id header)       │
     │────────────────────────────────────►│
     │◄────────────────────────────────────│
     │  200 + tool definitions             │
     │                                     │
     │  POST tools/call                    │
     │  (with Mcp-Session-Id header)       │
     │────────────────────────────────────►│
     │◄────────────────────────────────────│
     │  200 + tool result                  │
     │                                     │
     │  DELETE (session termination)       │
     │  (with Mcp-Session-Id header)       │
     │────────────────────────────────────►│
     │◄────────────────────────────────────│
     │  204 No Content                     │
     └                                    └

curlによる操作手順

1. 初期化:

bash
curl -ksS -D /tmp/headers.txt -X POST "https://localhost:7770/api/v1/mcp" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "initialize",
    "params": {
      "protocolVersion": "2025-03-26",
      "capabilities": {},
      "clientInfo": {"name": "my-agent", "version": "1.0"}
    }
  }'

レスポンスヘッダーからセッションIDを抽出します:

bash
SESSION_ID=$(grep -i 'Mcp-Session-Id' /tmp/headers.txt | awk '{print $2}' | tr -d '\r')

2. 初期化完了通知:

bash
curl -ksS -X POST "https://localhost:7770/api/v1/mcp" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: ${SESSION_ID}" \
  -d '{"jsonrpc": "2.0", "method": "notifications/initialized"}'

3. 利用可能なツール一覧の取得:

bash
curl -ksS -X POST "https://localhost:7770/api/v1/mcp" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: ${SESSION_ID}" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}'

4. ツールの呼び出し:

bash
curl -ksS -X POST "https://localhost:7770/api/v1/mcp" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: ${SESSION_ID}" \
  -d '{
    "jsonrpc": "2.0",
    "id": 3,
    "method": "tools/call",
    "params": {
      "name": "vm_list",
      "arguments": {}
    }
  }'

5. セッションの終了:

bash
curl -ksS -X DELETE "https://localhost:7770/api/v1/mcp" \
  -H "Authorization: Bearer <token>" \
  -H "Mcp-Session-Id: ${SESSION_ID}"

4. 利用可能なツール

Vapor MCPサーバーは、ドメインごとにグループ化された21個のツールを公開しています:

仮想マシン管理

ツール名説明
vm_listすべてのVMをステータス、UUID、vCPU、メモリ、ディスク情報とともに一覧表示
vm_getUUIDまたは名前による詳細なVM情報の取得
vm_actionライフサイクル操作: start, shutdown, reboot, pause, resume, reset, force-off, force-reboot
vm_deleteVMの削除(オプションでディスクボリュームも削除)
vm_snapshotsVMスナップショットの一覧取得/作成/復元/削除
vm_backupsVMバックアップの一覧取得/作成/削除(フル/増分/差分)
vm_templatesVMテンプレートの一覧取得/情報取得/削除
vm_metricsリアルタイムなCPU、メモリ、ディスク、およびネットワークメトリクスの取得

仮想化ネットワーク管理

ツール名説明
virt_networklibvirt仮想ネットワークの管理: list, get, start, stop, delete, dhcp_leases

仮想化ストレージ管理

ツール名説明
virt_storage_poolストレージプールの管理: list, get, start, stop, delete
virt_volumeストレージボリュームの管理: list, get, create, delete, resize
virt_isoISOイメージの管理: list, get, delete

ホストネットワーク管理

ツール名説明
host_network_interfaces物理/仮想ネットワークインターフェースの一覧表示
host_network_bridgesLinuxブリッジデバイスの一覧表示
host_network_bondsネットワークボンドデバイスの一覧表示
host_network_vlansVLANインターフェースの一覧表示

ホストストレージ管理

ツール名説明
host_storage_disks物理ブロックデバイスの一覧表示
host_storage_lvm_vgsLVMボリュームグループ(VG)の一覧表示
host_storage_lvm_lvsLVM論理ボリューム(LV)の一覧表示
host_storage_lvm_pvsLVM物理ボリューム(PV)の一覧表示
host_storage_raidRAID/MDアレイの一覧表示

5. クライアント構成

Claude Desktop

以下をClaude Desktop構成ファイルに追加します:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
json
{
  "mcpServers": {
    "vapor": {
      "type": "streamableHttp",
      "url": "https://<vapor-host>:7770/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer <your-api-token>"
      }
    }
  }
}

自己署名証明書を使用する場合は、Claude Desktopを起動する前に、OSレベルでCAを信頼してください(セクション2、アプローチ1を参照)。

Cursor / VS Code MCP 拡張機能

プロジェクトの .cursor/mcp.json または同等のMCP設定において:

json
{
  "mcpServers": {
    "vapor": {
      "type": "streamableHttp",
      "url": "https://<vapor-host>:7770/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer <your-api-token>"
      }
    }
  }
}

Node.jsベースのMCPクライアントで自己署名証明書を使用する場合は、起動前に環境変数を設定してください:

bash
export NODE_EXTRA_CA_CERTS=/path/to/vapor-server.crt

6. エラー処理

JSON-RPC エラー

MCPサーバーは、標準のJSON-RPC 2.0エラーコードを使用します:

コード意味説明
-32700パースエラーリクエストボディのJSONが無効
-32600無効なリクエストjsonrpcフィールドの欠落またはバージョン不良
-32601メソッド未検出不明なメソッド名
-32602パラメータ無効メソッドに対する無効なパラメータ
-32603内部エラーサーバー側のエラー

ツール実行エラー

ツール実行エラーは、結果オブジェクト内に isError: true を含めた正常なJSON-RPCレスポンスとして返されます:

json
{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "content": [{"type": "text", "text": "Failed to start VM: domain is already running"}],
    "isError": true
  }
}

これにより、AIエージェントはエラーメッセージを参照して次のアクションを自律的に決定できます。

認証エラー

HTTPステータス意味
401Authorization ヘッダーの欠落または無効
403トークンは有効だが権限が不足

7. セッション管理

  • セッションは、initialize リクエストの送信時に自動作成されます。
  • サーバーは Mcp-Session-Id ヘッダーを返すため、それ以降のすべてのリクエストにこのヘッダーを含める必要があります。
  • セッションは 30分間 非アクティブ状態が続くと失効します。
  • セッションは メモリ内 に保存され、サーバーの再起動時には維持されません。
  • セッションを早期に終了するには、セッションヘッダーを指定して DELETE /api/v1/mcp を送信します。

セッションが失効した場合、クライアントは新しい initialize リクエストを送信して再初期化を行う必要があります。


8. セキュリティについての考慮事項

  1. 常にTLSを使用してください。 MCPエンドポイントは認証トークンを送信し、機密性の高いインフラデータを返す可能性があります。ネットワーク環境において、TLSなしでVaporを実行しないでください。
  2. エージェントにはAPIトークンを使用してください。 APIトークンはユーザーごとにスコープが設定され、永続的で、個別に失効させることができます。AIエージェントの統合ごとに専用のトークンを作成し、分かりやすい名前(例:claude-desktopcursor-ide)を付けてください。
  3. ネットワークアクセスを制限してください。 特定のマシンからのみVaporホストにアクセスする場合は、ファイアウォールルールを使用してポート7770へのアクセスを制限してください。
  4. 不要になったトークンは失効させてください:
    bash
    curl -ksS -X DELETE "https://<host>:7770/api/v1/auth/tokens/<token-id>" \
      -H "Authorization: Bearer <jwt>"
  5. ツール呼び出しの監視。 すべてのMCPツール呼び出しは、監査の目的でセッションIDとともにVaporによってログに記録されます。サーバーログで [MCP] 形式のエントリを確認してください。