Model Context Protocol を構成する

このドキュメントでは、リモート Model Context Protocol(MCP)サーバーとして機能するように API Gateway を構成する方法について説明します。

始める前に

  • API の有効な OpenAPI 3.x 仕様があることを確認します。MCP は OpenAPI 2.0 ではサポートされていません。
  • API Gateway の基本を理解していることを確認します。

構成の検証

OpenAPI 仕様をアップロードすると、API Gateway は MCP 構成に対して次の検証を行います。

  • ロケーション: x-google-mcp-tool 拡張機能は、個々のオペレーション レベルでのみ指定する必要があります。
  • HTTP メソッド: GET、POST、PUT、PATCH、DELETE のオペレーションのみを MCP ツールとして公開できます。
  • ツールの名前: ツールの名前は [A-Za-z0-9_.-]{1,128} と一致し、仕様全体で一意である必要があります。
  • 説明: すべてのツールは、空でない説明(オペレーションの説明、概要、オーバーライドから取得)に解決する必要があります。解決可能な説明のないオペレーションは拒否されます。
  • セキュリティ: tools/list の認証を構成する場合は、components.securitySchemes で定義されたセキュリティ スキームを 1 つだけ指定する必要があります。スキームは、JWT スキームまたは API キー スキームにできます。JWT スキームを使用する場合は、仕様の最上位の security 要件で名前を指定する必要があります。

認証モデル

API Gateway は、呼び出された MCP メソッドに応じて異なる認証ルールを適用します。

  • プロトコルのライフサイクル: initialize メソッドと notifications/initialized メソッドは認証なしです。
  • ツール呼び出し(tools/call): OpenAPI 仕様の基盤となるオペレーションに定義された認証ポリシーを再利用します。REST エンドポイントを直接呼び出す場合と同じ API キーまたは JWT の要件が適用されます。
  • ツール検出(tools/list): デフォルトでは、このメソッドは認証されていません。ただし、セキュリティのベスト プラクティスとして、tools-list.security を使用してこのメソッドの認証を有効にし、ツールの検出を保護することを強くおすすめします。tools/list は、JWT または API キーで認証できます。

MCP を構成する手順

API を MCP ツールとして公開する手順は次のとおりです。

1. 公開するオペレーションを特定する

OpenAPI 仕様を確認し、AI エージェントが利用できるオペレーションを決定します。

2. OpenAPI 仕様を更新する

MCP は、対象となるすべてのオペレーションに対してグローバルに有効にするか、オペレーションごとに構成できます。

グローバル イネーブルメント

ドキュメント レベルで x-google-api-management に mcp フィールドを追加して、MCP をグローバルに有効にします。

openapi: 3.0.3
info:
  title: Bookstore API
  version: 1.0.0
x-google-api-management:
  mcp: true
  backends:
    bookstore-backend:
      address: https://bookstore-backend-12345678.us-central1.run.app

グローバルに有効にすると、対象となるすべてのオペレーション(HTTP メソッドとパスに基づく)が MCP ツールとして公開されます。デフォルトでは、ツール名はオペレーションの operationId で、説明はオペレーションの説明または概要です。

オペレーションごとの構成

x-google-mcp-tool を使用して、グローバル設定をオーバーライドするか、オペレーションを選択的に公開できます。

paths:
  /v1/shelves/{shelf}:
    delete:
      operationId: deleteShelf
      summary: Delete a shelf.
      x-google-backend: bookstore-backend
      x-google-mcp-tool:
        name: delete_shelf
        description: "Permanently delete a shelf and every book on it."

x-google-mcp-tool: false を設定して、グローバルに有効になっているオペレーションをオプトアウトすることもできます。

デフォルトでは、tools/list メソッド(使用可能なツールを列挙する)は認証されていません。セキュリティのベスト プラクティスとして、x-google-api-management/mcp で tools-list.security を構成して認証を適用することを強くおすすめします。JWT スキームまたは API キー スキームのいずれかに名前を付けることができます。

次の例では JWT が必要です。

x-google-api-management:
  mcp:
    tools-list:
      security:
        myJWT: []

次の例では API キーが必要です。クライアントは x-api-key HTTP ヘッダーでキーを送信する必要があります。tools/list はクエリ パラメータから API キーを読み取りません。有効なキーのないリクエストは、JSON-RPC エラーを受け取り、ツールリストを受け取りません。API キーの作成方法については、API キーを使用するをご覧ください。

x-google-api-management:
  mcp:
    tools-list:
      security:
        api_key: []
components:
  securitySchemes:
    api_key:
      type: apiKey
      name: x-api-key
      in: header

4. API 構成を作成してデプロイする

アノテーション付きの仕様から API 構成を作成し、標準フローを使用してゲートウェイにデプロイします。詳細については、ゲートウェイへの API のデプロイをご覧ください。

5. MCP のサポートを確認する

デプロイが完了したら、ゲートウェイが MCP リクエストを処理していることを確認できます。

Handshake

初期化リクエストを送信して、プロトコル バージョンと機能を確立します。

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -d '{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-11-25",
    "capabilities": {},
    "clientInfo": {"name": "demo-client", "version": "1.0.0"}
  }
}'

ハンドシェイクを確認する

初期化を確認します。ゲートウェイは HTTP 202 Accepted で応答します。

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc": "2.0", "method": "notifications/initialized"}'

ツールの検出

利用可能なツールを一覧表示します。tools-list.security を構成した場合は、一致する認証情報(JWT の場合は Authorization: Bearer ヘッダー、API キーの場合は x-api-key ヘッダーなど)を追加します。

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}'

引数が REST リクエストにどのようにマッピングされるか

ツールに渡される引数は、OpenAPI 仕様に基づいて基盤となる REST リクエストにマッピングされます。

  • パス パラメータとクエリ パラメータ: arguments オブジェクトの最上位のプロパティになり、OpenAPI パラメータ名でキー設定されます。
  • リクエスト本文: body という名前の単一のプロパティにネストされます。たとえば、リソースを作成するには、{"body": {"fieldName": "value"}} を渡します。
  • ヘッダー: 最上位プロパティにもなります。ゲートウェイは、バックエンド呼び出しで標準の HTTP ヘッダーとして挿入します。

トランスコードされたバックエンド リクエストは、バックエンド サービスへの直接 REST リクエストと区別できません。バックエンド サービスは、直接の REST 呼び出しと MCP からトランスコードされた呼び出しをプログラムで区別できません。

ツールを呼び出す

特定のツールを呼び出します。基盤となる REST オペレーションで必要な場合は、必要な認証トークンを含めます。

curl -X POST https://my-gateway-12345.uc.a.run.app/mcp \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -H "MCP-Protocol-Version: 2025-11-25" \
  -d '{
  "jsonrpc": "2.0",
  "id": 3,
  "method": "tools/call",
  "params": {
    "name": "delete_shelf",
    "arguments": {"shelf": "sci-fi"}
  }
}'

オブザーバビリティ

MCP リクエストは、標準の API Gateway 指標とログを生成します。リクエスト パス(通常は /mcp で終わる)を検査するか、カスタム指標を構成することで、MCP トラフィックと標準の REST トラフィックを区別できます。

MCP エラーのトラブルシューティング

MCP は、トランスポート障害とプロトコル障害を区別します。200 以外のレスポンスは多くの MCP クライアントでトランスポート レイヤの障害を引き起こす可能性があるため、ゲートウェイはプロトコル エラーとアプリケーション エラーに対して JSON-RPC エラー オブジェクトを含む HTTP 200 を返します。

次の表に、一般的な症状と修正方法を示します。

症状 JSON-RPC コード HTTP ステータス 意味と一般的な修正
許可されていないメソッドです なし 405 POST 以外のリクエストが /mcp に到達しました。HTTP POST のみがサポートされています。
JSON 解析エラー -32700 400 リクエスト本文が有効な JSON ではありません。
メソッドまたは ID がない/無効 -32600 200 本文は有効な JSON ですが、有効な JSON-RPC リクエストではありません。必須フィールド(jsonrpc、method、id)を確認します。
メソッドがサポートされていない -32601 200 メソッドがサポート対象範囲外である(例: ping)。
サポートされていないプロトコル バージョン -32602 200 protocolVersion は、ゲートウェイがサポートしていないバージョンを指定しています。
プロトコル バージョンがない -32602 200 initialize パラメータに protocolVersion が含まれていないか、が文字列ではありません。
不明なツール -32602 200 ツール名が見つかりません。クライアント キャッシュを消去するか、デプロイを確認します。
無効なツール引数 -32602 200 引数がないか、無効です。body キーのネストを確認します。
本文が大きすぎる -32000 200 レスポンス ペイロードがサイズ上限を超えました。
トランスポートの本文が大きすぎる なし 413 未加工の HTTP リクエストの本文がゲートウェイの転送上限を超えています。
サーバーエラー -32000 200 解析できないバックエンド レスポンス。ログを確認します。
未承認 / 禁止 なし 401/403 認証に失敗しました。レスポンスには、保護されたリソース メタデータを指す WWW-Authenticate ヘッダーが含まれています。

バックエンド アプリケーション エラーは通常、バックエンド エラー本文を含む result.isError: true を含む成功した JSON-RPC レスポンス(HTTP 200)として表面化します。

次のステップ