Amazon Bedrock Knowledge Base を Amazon Bedrock AgentCore Gateway で MCP サーバー化する

記事タイトルとURLをコピーする

アプリケーションサービス部ディベロップメントサービス4課の越後です。

今回は、RAG として構築済みの Amazon Bedrock Knowledge Bases を、MCP サーバーとして公開する構成を CDK で組んだので、実装のポイントとハマりポイントをまとめます。

使ったのは 2025年10月 GA の Amazon Bedrock AgentCore Gateway です。CDK alpha パッケージで数行書くだけで MCP エンドポイントが立ち上がりました。ただし Amazon Cognito 認証との組み合わせに注意点があるので、それも含めて共有します。


背景:Knowledge Bases を MCP サーバー化する必要があった

AI エージェントや Claude Code・Cursor などの MCP クライアントが Knowledge Bases をツールとして自動呼び出しするには、Knowledge Bases を MCP サーバーとして公開する必要があります。Knowledge Bases Retrieve API は直接 MCP に対応していないため、MCP サーバー化のレイヤーが必要でした。

MCP サーバー化の選択肢は主に3つです。

  • パターンA: 公式 @aws/bedrock-kb-retrieval-mcp-server を stdio で動かす(ローカル、AWS 認証情報が各自必要)
  • パターンB: AWS Lambda ラッパー → AgentCore Gateway で公開(リモート、今回の選択)
  • パターンC: Amazon API Gateway + OpenAPI → AgentCore Gateway

AgentCore Gateway がマネージドな MCP エンドポイントと Amazon Cognito 認証を提供するため、パターンBを採用しました。

AgentCore Gateway の役割

AgentCore Gateway は MCP エンドポイントの統一フロントエンドです。次の3つを肩代わりします。

  • Translation: MCP の tools/call を AWS Lambda invocation に変換
  • Security Guard: Amazon Cognito M2M(OAuth client_credentials)または IAM SigV4 での認証
  • Composition: 複数ターゲット(AWS Lambda / REST API / 既存 MCP サーバー)を1つの MCP エンドポイントに統合

トランスポートは MCP 仕様 2025-03-26 で導入された Streamable HTTP Transport に対応(旧 HTTP+SSE トランスポートから置き換えられた形式)。

アーキテクチャ

事前準備(管理者が実施)

  1. 管理者が AWS CLI で AWS Secrets Manager から Client Secret を取得
  2. Client Secret を使って Amazon Cognito Token Endpoint から Bearer Token を取得
  3. Bearer Token を利用者に配布(1Password 等のシークレット共有ツール経由)

リクエストフロー(利用時)

  1. MCP クライアントが Bearer Token を Authorization ヘッダーに設定し、AgentCore Gateway に接続(Streamable HTTP)
  2. AgentCore Gateway が Amazon Cognito でトークンを検証し、AWS Lambda を呼び出す
  3. AWS Lambda が Knowledge Bases Retrieve API で Knowledge Bases を検索し、結果をクライアントに返す(Knowledge Bases は内部で Amazon Aurora PostgreSQL をベクトルストアとして使用)

なお、Amazon Cognito は RFC 7591(Dynamic Client Registration)非対応のため、Claude Desktop が期待するような OAuth フローの自動化はできません。Bearer Token の取得・配布は手動運用になります(詳細は後述)。

既存の RAG 実装で AWS Lambda が Retrieve API の呼び出しを担っていたため、その AWS Lambda をそのままターゲットとして登録しています。なお、AgentCore Gateway に Knowledge Bases を直接ターゲットとして登録することも可能です。

CDK 実装:@aws-cdk/aws-bedrock-agentcore-alpha

CDK では alpha パッケージを使います(API は今後変わる可能性あり)。

import * as agentcore from '@aws-cdk/aws-bedrock-agentcore-alpha';

const gateway = new agentcore.Gateway(this, 'KbGateway', {
  description: 'Knowledge Base Search Gateway',
});

gateway.addLambdaTarget('KbSearchTarget', {
  gatewayTargetName: 'kb-search',
  lambdaFunction: kbSearchFunction,
  toolSchema: agentcore.ToolSchema.fromInline([{
    name: 'search_knowledge_base',
    description: 'ナレッジベースを検索します',
    inputSchema: {
      type: agentcore.SchemaDefinitionType.OBJECT,
      properties: { query: { type: agentcore.SchemaDefinitionType.STRING } },
      required: ['query'],
    },
  }]),
});

これだけで Amazon Cognito User Pool(M2M App Client 含む) が自動生成され、AgentCore Gateway の実行ロールには lambda:InvokeFunction が自動付与されます。AWS Lambda 関数自体が必要とする bedrock:Retrieve 等の権限は別途 addToRolePolicy で追加してください。CDK Output にエンドポイント URL とトークンエンドポイントを出しておくと接続テストに便利です。

ハマりポイント1:ツール名は {targetName}___{toolName} になる

実機確認したとき「Claude Code から見えるツール名がドキュメントの例と違う?」となりました。

AgentCore Gateway は複数ターゲットを1つの MCP エンドポイントに合成(Composition)するため、ツール名を {targetName}___{toolName}(アンダースコア3つ)でネームスペース化します。上のコードだと実際のツール名はこうなります。

kb-search___search_knowledge_base

MCP クライアント側の許可ツールリストなどを設定するときは、この合成後の名前を使う必要があります。

ハマりポイント2:OAuth スコープはカンマ→スペースに変換が必要

CDK Output で返ってくる Amazon Cognito の OAuth スコープは カンマ区切りですが、OAuth 2.0 の client_credentials フローのリクエストボディでは スペース区切りが必要です(RFC 6749)。400 Bad Request が返る場合はまずここを確認してください。

# CDK Output はカンマ区切り → OAuth リクエスト前にスペース区切りへ変換
SCOPES_SPACE=$(echo "$SCOPES" | tr ',' ' ')

また、スペースのエンコードを確実にするため、curl でスコープを渡す際は -d より --data-urlencode を使う方が安全です。

ハマりポイント3:Amazon Cognito だと Claude Desktop の自動 OAuth が動かない

Claude Desktop は MCP サーバーに接続するとき、OAuth 2.1 の自動フローを開始しようとします。そのために以下の RFC が必要なのですが、Amazon Cognito はどちらも未実装です。

  • RFC 8414: OAuth 認可サーバーメタデータ(/.well-known/oauth-authorization-server
  • RFC 7591: Dynamic Client Registration

詳細は amazon-bedrock-agentcore-samples#1056 にまとまっています。

回避策は Bearer Token を手動取得してヘッダーに注入するパターンです。Claude Code は MCP 設定で Authorization ヘッダーを直接書けるため、これで問題なく接続できます。

トークン取得後の接続確認はこのように行います。

curl -s -X POST "$MCP_ENDPOINT" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "kb-search___search_knowledge_base",
      "arguments": { "query": "Lambda" }
    }
  }'

まとめ

AgentCore Gateway + CDK alpha は「リモート MCP として Knowledge Bases を公開しつつ認証もマネージドに」したい場合の最短ルートだと思います。気をつける点をまとめると:

  • ツール名は {targetName}___{toolName} に変わる — クライアント側の設定はこの名前で
  • OAuth スコープはカンマ→スペースに変換してリクエスト
  • Claude Desktop など自動 OAuth フローを期待するクライアントは Amazon Cognito 単体だと厳しい

特に最後の Amazon Cognito 制約は、アーキテクチャを選ぶ前に把握しておくと後で困りません。Claude Code のようにヘッダー注入できるクライアントが主用途なら、Amazon Cognito で十分実用に乗ります。

参考リンク

越後 元貴 (記事一覧)

アプリケーションサービス本部ディベロップメントサービス4課

2023年新卒入社