Amazon Connect AIエージェントがMCPに対応したので、Bedrock AgentCore Gatewayと連携させてみた

Amazon Connect AIエージェントがMCPに対応したので、Bedrock AgentCore Gatewayと連携させてみた

2026.01.21

はじめに

Amazon Connect AIエージェントにて、MCP(Model Context Protocol) がサポートされました。

https://aws.amazon.com/jp/about-aws/whats-new/2025/11/amazon-connect-mcp-support/

これにより、AIエージェントが標準化されたツールを使用して情報を取得したり、アクションを実行したりすることが可能になります。
Amazon Connectで利用可能なMCPツールには、大きく分けて以下の3つのタイプがあります。

  1. Out-of-the-box tools(Amazon Connect標準搭載ツール)
    問い合わせ属性の更新やケース情報の取得など、一般的なタスク用に最初から用意されているツールです。
  2. Flow module tools(フローモジュールツール)
    ConnectのフローモジュールをMCPツールとして利用する形式です。既存のビジネスロジックを再利用できるのが特徴です。
  3. Third-party MCP tools(サードパーティーMCPツール)
    Amazon Bedrock AgentCore Gatewayを経由して、外部のカスタムツールやサードパーティーサービスを統合する形式です。

今回は、3つ目の 「サードパーティーMCPツール」 として、Bedrock AgentCore Gatewayを連携させる方法を試してみます。

前提条件

以前、以下の記事にてAmazon API Gateway、Step Functions、DynamoDBという構成で、データの新規登録や取得処理を実装しました。今回はこちらのAPI Gatewayを利用します。

https://dev.classmethod.jp/articles/amazon-apigateway-stepfunctions-dynamodb-crud/

また、上記の記事のAPI GatewayをターゲットとしたBedrock AgentCore Gatewayを作成し、Bedrock AgentCore GatewayからAPI Gatewayへ接続する構成でMCPサーバーを作成しました。今回はこちらを利用してみます。

https://dev.classmethod.jp/articles/amazon-bedrock-agentcore-gateway-apigateway-iam-auth/

Bedrock AgentCore Gatewayの作成

インバウンド認証の設定内容のみ紹介します。インバウンド認証以外は以下の記事と同じです。

https://dev.classmethod.jp/articles/amazon-bedrock-agentcore-gateway-apigateway-iam-auth/

  • 認証タイプはJWT
  • JWTスキーマは既存のIDプロバイダーの設定を使用
  • 検出URLは https://インスタンス名.my.connect.aws/.well-known/openid-configuration
    • インスタンス名は、各自変更ください
  • Allowed audiencesは適当な値
    • 作成後、生成されたゲートウェイIDを設定するため、一旦仮の値を入れる

cm-hirai-screenshot 2026-01-15 15.51.26

https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/3p-apps-mcp-server.html

設定のポイント

ここで設定している 検出 URLAllowed audiences は、Amazon Connect とのセキュアな接続を実現するための重要な設定です。

  • 検出 URL (Discovery URL)
    指定した Amazon Connect インスタンスが発行したトークンかどうか(送信元)を検証するために使用します。
  • Allowed audiences
    ドキュメントにも記載がある通り、JWTトークン内の aud クレームを検証し、トークンが正しい宛先(このゲートウェイ)向けに発行されたものかを確認する設定です。
    検証の結果、Amazon Connect はゲートウェイ呼び出し時に、この aud クレームへ自動的に「接続先のゲートウェイID」を含める挙動となるようです。そのため、ここにゲートウェイIDを設定することで、不正なトークンの使い回しを防ぐことができます。

許可されたオーディエンス: AgentCore Identity が JWT トークン内の aud クレームに対して検証する、許可されたオーディエンスのリストです。OAuth 2.0 におけるオーディエンスクレーム (aud) は、トークンがどのリソースサーバー (API) を対象としているかを指定します。リソースサーバーはリクエストを処理する前に aud クレームを検証して、それが正しい受信者であることを確認し、トークンが発行されていない別の API で再利用されるのを防ぎます。
https://docs.aws.amazon.com/ja_jp/bedrock-agentcore/latest/devguide/inbound-jwt-authorizer.html

作成後の設定変更

ゲートウェイIDはゲートウェイを作成した後でないと発行されません。 そのため、作成時は一旦仮の値を入力しておき、作成後に正しいIDに書き換える手順が必要となります。

作成後、発行されたゲートウェイID(今回の場合は restaurantreservationgateway-tmz4zivtr1)を Allowed audiences に設定し直します。
※この際、ターゲット設定もリセットされてしまうため、再度設定する必要がありました。

v88cjjjzuptwsogfl2zk

cm-hirai-screenshot 2026-01-13 16.13.32

Amazon Connect サードパーティーのアプリケーション追加

サードパーティーのアプリケーション設定にて、対象のConnectインスタンスに、MCPサーバーとしてBedrock AgentCore Gatewayを関連付けます。

選択できるのは、Bedrock AgentCore Gatewayの検出 URL で設定されているConnectインスタンスのみです。

cm-hirai-screenshot 2026-01-13 16.59.29

AIエージェントの作成

AI エージェントタイプはオーケストレーションタイプを選択し、SelfServiceOrchestratorからコピーします。

cm-hirai-screenshot 2026-01-13 17.11.33

ロケールは日本語、セキュリティプロファイルはAdmin権限を指定しました。

AIプロンプトについては、プロンプト内容は変更せず、モデルを「global.anthropic.claude-sonnet-4-5-20250929-v1:0」に設定しました。
cm-hirai-screenshot 2026-01-13 17.42.52

ツールは2つ追加します。Namespacesに作成したゲートウェイを選択すると、追加可能なAIツールが2つ(CheckReservationとCreateReservation)表示されました。
cm-hirai-screenshot 2026-01-15 17.40.07

CheckReservation

Input Schemaは、以下の2つです。実際にはbasePathは不要で、電話番号を伝えると予約確認ができます。

  • basePath
  • phone
    cm-hirai-screenshot 2026-01-16 14.21.58

Instructions(ツールの使用方法の説明)とExampleは以下のように設定しました。
cm-hirai-screenshot 2026-01-16 14.24.13

Instructions
既存のレストラン予約状況を確認するためにこのツールを使用してください。
このツールを実行するには、顧客の「phone」(電話番号)が必須です。
入力する電話番号は以下のルールで整形してください:
1. 国際番号「+81」が含まれる場合は「0」に変換する。
2. ハイフン(-)やスペースが含まれる場合はすべて削除し、数字のみにする。

会話履歴に電話番号が含まれていない場合は、必ず顧客に質問して情報を得てください。電話番号を推測したり、適当な値を入れたりすることは禁止です。
もし顧客が電話番号を覚えていない場合や、ツールがエラーを返した場合は、無理に続けず人間のエージェントへの転送を提案してください。
Example
Example 1: 正常系
User: "予約を確認したい。番号は 090-1234-5678 です。"
<thinking>
顧客は予約確認を希望しており、電話番号「090-1234-5678」を提供した。
ツールに入力するために、電話番号からハイフンを削除して「09012345678」に整形する必要がある。
必須引数が揃ったので、復唱してツールを実行する。
</thinking>
<message>
承知いたしました。お電話番号 090-1234-5678 でご予約を確認いたします。
</message>
[Agent invokes RestaurantReservation___CheckReservation with phone='09012345678']
Example
Example 2: エラー時のエスカレーション提案(Good Example準拠)
User: "電話番号は合ってるはずなのに、予約が見つからないってどういうこと?"
<thinking>
顧客は電話番号が正しいと主張しているが、ツールで予約が見つからないため苛立っている。
システム上の不整合は私には解決できないため、人間のエージェントへのエスカレーションを提案すべきである。
</thinking>
<message>
ご心配をおかけして申し訳ございません。システム上で確認が取れないようですので、担当のスタッフにお繋ぎして詳しくお調べしましょうか?
</message>

CreateReservation

CreateReservationツールでは、Input SchemaがbasePathのみでした。これは、API Gateway側で設定変更が必要です。

cm-hirai-screenshot 2026-01-14 8.12.17

API Gatewayの設定変更

なぜ設定変更が必要なのか?(モデルの役割について)

CheckReservation (GET) の時は自動的にパラメータ(phone)が表示されたのに、 CreateReservation (POST) では表示されなかったのは、API Gateway におけるパラメータの定義方法の違いが原因です。

  • GET (クエリパラメータ) の場合
    API Gateway の設定画面で「URL クエリ文字列パラメータ」としてキー名(phoneなど)を登録します。Bedrock AgentCore Gateway はこの設定を直接読み取れるため、自動的に Input Schema に反映されます。
  • POST (リクエストボディ) の場合
    データはリクエスト本文(Body)の中に JSON 形式などで格納されますが、デフォルトの状態では「中身にどんなデータ構造が入るか」までは定義されていません。そのため、Bedrock 側も「パラメータとして何を送ればいいか」を認識できず、Input Schema が空(basePathのみ)になってしまいます。

そこで、AI エージェントに「この API は phonename といったデータを受け取る仕様」と正しく認識させるために、API Gateway 側で「モデル」を作成します。

モデルとは、APIが受け取るデータの構造(スキーマ)を定義した「設計図」のようなものです。これを作成することで、Bedrock AgentCore Gateway がパラメータを理解できるようになります。

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/models-mappings-models.html

具体的な手順は以下の通りです。

  1. モデルの作成

    • API Gateway コンソールの左メニューから 「モデル」 を選択し、「モデルの作成」 をクリックします。
    • モデル名: ReservationInputModel (任意)
    • Content-Type: application/json
    • モデルのスキーマ: 以下のJSONを貼り付けます。cm-hirai-screenshot 2026-01-14 8.06.52
      {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "title": "ReservationInput",
        "type": "object",
        "properties": {
          "phone": { "type": "string" },
          "time": { "type": "string" },
          "name": { "type": "string" },
          "count": { "type": "integer" }
        },
        "required": ["phone", "time", "name", "count"]
      }
      
    • 「モデルの作成」をクリックします。
  2. メソッドへの紐付け

    • リソース /reservationsPOST メソッドを選択します。
    • 「メソッドリクエスト」 をクリックします。
    • 「リクエスト本文」 に以下を設定します。
      • Content-Typeapplication/json
      • モデル名は先ほど作成した ReservationInputModel
        cm-hirai-screenshot 2026-01-14 8.07.36
  3. デプロイと同期

    • 「API のデプロイ」 を実行します。
    • その後、Bedrock AgentCore Gateway のコンソールに戻り、ターゲットを編集し追加し直すと、CreateReservation の Input Schema に phone, time, name, count が自動的に現れるようになります。なお、ターゲットを編集し追加し直さない場合、反映されませんでした。
      cm-hirai-screenshot 2026-01-14 8.11.03

更新後、数分後に再度AIエージェントのCreateReservationを確認しましたが、Input Schemaは変わっていませんでした。

しかし、ツールを新規作成すると、Input SchemabasePathに加え以下の4つが表示されました。

  • phone
  • name
  • count
  • time
    cm-hirai-screenshot 2026-01-16 14.38.23

Instructions(ツールの使用方法の説明)とExampleは以下のように設定しました。
cm-hirai-screenshot 2026-01-16 14.39.48

Instructions
レストランの新規予約を作成するためにこのツールを使用してください。
このツールを実行するには、以下の4つの情報がすべて必須です。
1. phone (電話番号): 「+81」は「0」に変換し、ハイフンやスペースは削除して数字のみにする。
2. time (予約日時): 必ず「YYYY-MM-DDTHH:mm」のISO 8601形式(例: 2026-01-14T12:00)に変換する。
3. name (予約者名)
4. count (人数): 半角数字のみ。

これらの情報が不足している場合は、ツールを呼び出す前に必ず顧客に質問して情報を収集してください。
顧客が曖昧な日時(例:「来週の金曜」)を伝えた場合は、具体的な日付と時刻を確認してから入力してください。
Example
Example 1: 正常系(日時と電話番号の変換)

User: "明日の夜7時から2名で予約したい。電話は 080-9876-5432、名前は鈴木です。"
<thinking>
顧客は新規予約を希望している。必要な情報を抽出・整形する。
- phone: "080-9876-5432" -> ツール用にはハイフンを削除して "08098765432" とする。復唱用にはハイフン付きのまま使用する。
- time: "明日の夜7時" -> 本日を2026-01-14と仮定し、ISO形式 "2026-01-15T19:00" に変換する。
- name: "鈴木"
- count: "2"
すべての必須情報が揃ったので、電話番号を含めて復唱し、ツールを実行する。
</thinking>
<message>
鈴木様、ありがとうございます。お電話番号 080-9876-5432、明日の19時から2名様でご予約の手続きを進めます。
</message>
[Agent invokes RestaurantReservation___CreateReservation with phone='08098765432', time='2026-01-15T19:00', name='鈴木', count='2']
Example
Example 2: 必須情報が不足している場合

User: "予約をお願いします。"
<thinking>
顧客は予約を希望しているが、詳細情報が提供されていない。
必須となる4つの情報(日時、人数、名前、電話番号)を聞き出す必要がある。
まだツールは呼び出せない。
</thinking>
<message>
喜んで承ります。ご希望の日時と人数、お名前、お電話番号を教えていただけますか?
</message>
Example
Example 3: 顧客が苛立っている場合のエスカレーション(Good Example準拠)

User: "さっきから何度も日時を言ってるのに、なんで通じないんだ!"
<thinking>
顧客は繰り返し情報を伝えていると感じており、苛立ちを見せている。
これ以上同じ質問を続けると不満が高まるため、人間のエージェントへの交代を提案する。
</thinking>
<message>
ご不快な思いをさせてしまい申し訳ございません。スムーズにご案内できていないようですので、担当のスタッフにお繋ぎして直接ご予約を承りましょうか?
</message>

これでAIエージェントを保存し公開します。

Connectフロー

全体のフローは以下の通りです。
cm-hirai-screenshot 2026-01-16 16.03.54

ポイントとして、「顧客の入力を取得する」ブロックでLexボットを指定し、先程作成したAIエージェントを指定する必要があります。
szyyltnhgk7oecqyd3bz

動作確認

チャットのテストで試します。

CheckReservation (GET) ツールを試してみます。

事前にDynamoDBに予約データを入れておきます。

以下を伝えます。

  • 予約を確認したい。電話番号は、09011111111です。

以下の返答がきました。

承知いたしました。お電話番号 090-1111-1111 でご予約を確認いたします。

お待たせいたしました。お電話番号 090-1111-1111 で2件のご予約が見つかりました。

1件目は、2026年1月18日の12時から2名様で、佐藤次郎様のお名前でご予約いただいております。

2件目は、2026年1月19日の12時から3名様で、同じく佐藤次郎様のお名前でご予約いただいております。

他にご確認されたいことはございますか。

cm-hirai-screenshot 2026-01-16 16.19.34

返答に10秒かかりました。AIプロンプトのモデルは、global.anthropic.claude-sonnet-4-5-20250929-v1:0です。apac.anthropic.claude-sonnet-4-20250514-v1:0の場合、返答は7秒でした。

なお、CreateReservation (POST) を試しましたが、エラーとなりました。以下を伝えると

  • 1月18日の夜7時から2名で予約したい。電話は 080-1111-1111、名前は鈴木です

以下の返答になりました。

鈴木様、ありがとうございます。1月18日の19時から2名様、お電話番号080-1111-1111でご予約の手続きを進めさせていただきます。

申し訳ございません。現在システムの不具合によりご予約の手続きが完了できない状況です。お手数をおかけして大変恐縮ですが、担当のスタッフにお繋ぎして直接ご予約を承りましょうか?

cm-hirai-screenshot 2026-01-16 16.19.02

Bedrock AgentCore Gatewayログを確認したところ、Bedrock AgentCore Gateway側からAPI Gatewayへリクエストを送信する際に、パラメータがリクエストボディに正しく格納されず、空のボディとして送信されていました。

AWSサポートに確認したところ、AWS側の問題とのことで、修正対応中とのことでした。

Bedrock AgentCore GatewayからAPI Gatewayをターゲットにした際、アウトバウンド認証をIAMロールにしていますが、APIキーであれば回避できるようです。

解決されたら、POSTについては再検証したいと思います。

この記事をシェアする

FacebookHatena blogX

関連記事