はじめに レッドハットのソリューションアーキテクトの森です。 本記事は、Red Hat Connectivity Link入門シリーズの第6回です。 今回は、RHCL 1.3.3 で Tech Preview として追加された新機能、 MCP Gateway について紹介します。 過去の記事はこちらから rheb.hatenablog.com MCP Gateway は、AI エージェント開発における新しいプロトコル Model Context Protocol (MCP) を RHCL の Gateway API エコシステムに統合する機能です。複数の MCP サーバーからツール(Tools)を集約し、AI クライアントに統一されたインターフェースを提供します。 本記事では、以下の内容をカバーします: MCP(Model Context Protocol) とは何か RHCLにおける MCP Gateway の役割とアーキテクチャ RHCLにおける MCP Gateway のサンプル を手動でデプロイする手順 サンプルの 動作確認 と期待される結果 MCP Gateway とは Model Context Protocol (MCP) について Model Context Protocol (MCP) は、AI エージェントがさまざまなデータソースやツールに接続するための オープンスタンダードプロトコル です。2024年11月に Anthropic 社によって公開され、AI アプリケーション開発における標準化を目指しています。 MCP の主な特徴: 統一されたインターフェース : AI エージェントが異なるデータソースやツールに一貫した方法でアクセスできる ツールの集約 : 複数の MCP サーバーから提供されるツール(Functions)を統合 セッション管理 : クライアントとサーバー間の状態を管理 JSON-RPC ベース : シンプルで実装しやすいプロトコル MCP の公式ドキュメント : modelcontextprotocol.io MCP Gateway の役割 MCP Gateway は、RHCL における MCP プロトコルのゲートウェイ実装です。以下の役割を果たします: MCP サーバーの集約(Tool Federation) 複数の MCP サーバーからツールを収集し、単一のエンドポイントとして公開 Gateway API との統合 Kubernetes Gateway API リソース(Gateway、HTTPRoute)を活用した柔軟なルーティング Kuadrant Policy の適用 AuthPolicy、RateLimitPolicy などの Policy を MCP エンドポイントに適用可能 Tool Prefix による Namespace 管理 複数の MCP サーバーから提供されるツール名の衝突を回避 MCP Gateway の利用シーン AI エージェント開発 : 複数のバックエンド API を統合し、AI エージェントに提供 ツールの標準化 : 異なるツールを MCP プロトコルで統一 アクセス制御 : AuthPolicy による認証・認可の実装 Rate Limiting : トークン消費の制御 RHCL における MCP Gateway のアーキテクチャ コンポーネント構成 RHCL の MCP Gateway は、以下のコンポーネントで構成されます: 1. MCP Gateway Operator MCP Gateway の管理を担当する Kubernetes Operator です。以下の CRD(Custom Resource Definition)を提供します: MCPGatewayExtension : Gateway を MCP プロトコルに拡張 MCPServerRegistration : Backend MCP サーバーを登録 MCPVirtualServer (オプション): 特定のツールのみを公開する仮想エンドポイント 2. MCP Gateway Broker MCP ブローカーは、クライアントからのリクエストを受け付け、以下の処理を行います: Session 管理 : JWT トークンによるセッション追跡 Tool Federation : 複数の MCP サーバーからツールを集約 Request Routing : ツール呼び出しを適切な backend MCP サーバーに転送 3. Backend MCP Servers 実際のツール(Functions)を提供する MCP サーバーです。例: データベースクエリツール API 呼び出しツール ファイル操作ツール カスタムビジネスロジック 4. Gateway API リソース MCP Gateway は、Kubernetes Gateway API リソースを活用します: Gateway : エントリーポイント(Listener 定義) HTTPRoute : ルーティングルール ReferenceGrant : Cross-namespace 参照の許可 5. Kuadrant Policy(オプション) MCP エンドポイントに適用可能なポリシー: DNSPolicy : DNS レコードの自動管理 TLSPolicy : TLS 証明書の自動取得 AuthPolicy : API Key / JWT 認証 TokenRateLimitPolicy : Tokenベースのレート制限 リクエストフロー MCP クライアントから Backend MCP サーバーまでのリクエストフローは以下の通りです: External Client → http://mcp.example.com/mcp (HTTP listener - MCP Gateway の標準構成) Gateway → MCP Broker MCP Broker → Hairpin Request → Gateway → HTTPRoute → Backend MCP Server Backend MCP Server → Tool 実行結果を返却 Hairpin Request : MCP Broker が Gateway 自身を経由して backend に接続する仕組み。Gateway API のルーティングや Policy を適用可能。 Custom Resource Definition (CRD) MCP Gateway で使用する主要な CRD を紹介します。 MCPGatewayExtension Gateway を MCP プロトコルに拡張する CRD です。 apiVersion : mcp.kuadrant.io/v1alpha1 kind : MCPGatewayExtension metadata : name : mcp-gateway-extension namespace : mcp-system spec : targetRef : group : gateway.networking.k8s.io kind : Gateway name : mcp-gateway # 対象のGateway名 namespace : ai-gateway # Gatewayを設置している Namespase sectionName : http-mcp # HTTP listener を指定 publicHost : mcp.example.com # 自分の環境のHostnameに置き換える privateHost : mcp-gateway-istio.ai-gateway.svc.cluster.local:80 httpRouteManagement : Enabled # HTTPRoute の自動管理を有効化 主要フィールド : フィールド 説明 targetRef 対象の Gateway リソース(Cross-namespace 参照可能) sectionName Gateway の Listener 名(MCP 内部通信用) publicHost 外部からアクセスする際のホスト名 privateHost Hairpin リクエスト用の内部ホスト名(Gateway Service) httpRouteManagement HTTPRoute の自動管理(Enabled / Disabled) MCPServerRegistration Backend MCP サーバーを登録する CRD です。 apiVersion : mcp.kuadrant.io/v1alpha1 kind : MCPServerRegistration metadata : name : test-server1 namespace : mcp-system spec : path : /mcp toolPrefix : test1_ targetRef : group : gateway.networking.k8s.io kind : HTTPRoute name : mcp-server1-route 主要フィールド : フィールド 説明 path MCP エンドポイントのパス(例: /mcp ) toolPrefix ツール名のプレフィックス(例: test1_ → test1_greet )。複数サーバーのツール名衝突を回避 targetRef Backend MCP サーバーへのルート(HTTPRoute を指定) MCP Gateway のサンプル環境/設定の手動デプロイ手順 ここでは、RHCL の MCP Gateway Upstream リポジトリ( Kuadrant/mcp-gateway )で提供されている test-server1 サンプルを手動でデプロイする手順を紹介します。 前提条件 OpenShift Container Platform 4.19 以上 OpenShift Service Mesh 3.2 以上 RHCL 1.3.3 がインストール済み( 第1回参照 ) oc CLI ツールが利用可能 サンプルアーキテクチャ 今回デプロイするサンプルは以下の構成です: Gateway : mcp-gateway (ai-gateway namespace) HTTP listener (port 80) - MCP Gateway の標準構成 MCP 内部用 listener ( *.mcp.local ) Backend MCP Server : mcp-test-server1 提供ツール: greet , time , slow , headers , add_tool イメージ: ghcr.io/kuadrant/mcp-gateway/test-server1:latest なお、このサンプル MCP Server は、動作確認用として以下の 5 つの MCP Tools を提供します。 greet : 指定した名前に対して挨拶メッセージを返します。 time : 現在時刻を返します。 slow : 指定した秒数だけ待機してからレスポンスを返します。 headers : MCP Gateway 経由で受け取った HTTP ヘッダー情報を確認できます。 add_tool : 新しいツールを動的に追加する挙動を確認できます。 以降の手順では、これらのツールが MCP Gateway によって検出され、 tools/list や tools/call 経由で利用できることを確認します。 デプロイ手順 ステップ1: MCP Gateway Operator のインストール OpenShift Web Console から、 Ecosystem -> Software Catalog を選択し、Filter に、 MCP Gateway と入れてください。 MCP Gatewat Operator (Tech Preview) を選択します。 インストール時の設定については、下記のようにします。(2026/05時点) Update channel : preview Version : 0.6.0 Istallation mode : All namespaces on the cluster (default) ステップ2: Namespace の作成 Gateway、HTTPRoute、MCP Server などを配置する Namespace を作成します。 oc create namespace ai-gateway oc create namespace mcp-system ステップ3: ReferenceGrant の作成 Cross-namespace 参照を許可します( mcp-system → ai-gateway (Gateway を配置する Namespace))。 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1beta1 kind: ReferenceGrant metadata: name: mcp-gateway-cross-namespace namespace: ai-gateway # Gateway を配置する Namespace spec: from: - group: mcp.kuadrant.io kind: MCPGatewayExtension namespace: mcp-system # MCP Server を配置する Namespace to: - group: gateway.networking.k8s.io kind: Gateway EOF 重要 : ReferenceGrant は、参照される側の namespace(この場合 ai-gateway )に作成します。 ステップ4: Gateway の作成 MCP Server にアクセスするための Gatewayリソースを作成します。 (詳細は 第2回参照 ) oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: mcp-gateway namespace: ai-gateway # Gateway を配置する Namespace spec: gatewayClassName: istio listeners: - name: http-mcp hostname: 'mcp.example.com' # 自分の環境のHostnameに置き換える port: 80 protocol: HTTP allowedRoutes: namespaces: from: All - name: mcps port: 80 protocol: HTTP hostname: '*.mcp.local' allowedRoutes: namespaces: from: All EOF 注 : hostname は実際の環境に合わせて変更してください 確認 : oc get gateway -n ai-gateway 期待される出力の例: NAME CLASS ADDRESS PROGRAMMED AGE mcp-gateway istio a98f1593264b1474aafc6fff5736c2d9-661449485.us-... True 1m ステップ5: MCPGatewayExtension の作成 oc apply -f - <<EOF apiVersion: mcp.kuadrant.io/v1alpha1 kind: MCPGatewayExtension metadata: name: mcp-gateway-extension namespace: mcp-system spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: mcp-gateway namespace: ai-gateway sectionName: http-mcp # 内部 hairpin は HTTP を使用 publicHost: mcp.example.com # 自分の環境のHostnameに置き換える privateHost: mcp-gateway-istio.ai-gateway.svc.cluster.local:80 # Gatewayが生成するServiceのHostname httpRouteManagement: Enabled EOF 重要 : sectionName は http-mcp を指定します。MCP Gateway の内部 hairpin リクエストは HTTP を使用するためです。 確認 : oc get mcpgatewayextension -n mcp-system 期待される出力: NAME READY AGE mcp-gateway-extension True 30s ステップ6: DNS Provider Secretの作成 DNSPolicyを使用するための、DNSプロバイダーの認証情報を設定します。 (詳細は 第2回参照 ) # AWS認証情報Secretの作成(Gatewayネームスペース用) oc -n ai-gateway create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY # cert-managerネームスペース用 oc -n cert-manager create secret generic aws-credentials \ --type=kuadrant.io/aws \ --from-literal=AWS_ACCESS_KEY_ID=$KUADRANT_AWS_ACCESS_KEY_ID \ --from-literal=AWS_SECRET_ACCESS_KEY=$KUADRANT_AWS_SECRET_ACCESS_KEY 以下の変数は、自分の環境でのIDとKEYに置き換えてください。 $KUADRANT_AWS_ACCESS_KEY_ID $KUADRANT_AWS_SECRET_ACCESS_KEY ステップ7: DNSPolicy の作成 Route53 に DNS レコードを自動作成します。 (詳細は 第2回参照 ) oc apply -f - <<EOF apiVersion: kuadrant.io/v1 kind: DNSPolicy metadata: name: mcp-gateway-dns namespace: ai-gateway # Gateway のNamespace spec: targetRef: group: gateway.networking.k8s.io kind: Gateway name: mcp-gateway sectionName: http-mcp # HTTP listener に適用 providerRefs: - name: aws-credentials # 先ほど作成したDNS Provider Secret EOF providerRefs に、先ほど作成した DNS Provider Secret を設定してください。 注意 : DNS Record が作成され、DNS伝播するまでに少々時間がかかる場合があります。 ステップ8: Backend MCP Server のデプロイ oc apply -f - <<EOF apiVersion: apps/v1 kind: Deployment metadata: name: mcp-test-server1 namespace: mcp-system spec: replicas: 1 selector: matchLabels: app: mcp-test-server1 template: metadata: labels: app: mcp-test-server1 spec: containers: - name: mcp-test-server1 image: ghcr.io/kuadrant/mcp-gateway/test-server1:latest imagePullPolicy: Always command: ["/mcp-test-server"] args: ["--http", "0.0.0.0:9090"] ports: - containerPort: 9090 name: http env: - name: LOG_LEVEL value: "info" --- apiVersion: v1 kind: Service metadata: name: mcp-test-server1 namespace: mcp-system spec: selector: app: mcp-test-server1 ports: - name: http port: 9090 targetPort: 9090 protocol: TCP EOF 確認 : oc get pods -n mcp-system -l app=mcp-test-server1 期待される出力: NAME READY STATUS RESTARTS AGE mcp-test-server1-6f6f6bf5dd-jhlgr 1/1 Running 0 1m ステップ9: 内部用 HTTPRoute の作成 Backend MCP Server への内部ルートを作成します。 oc apply -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: mcp-server1-route namespace: mcp-system labels: mcp-server: 'true' spec: parentRefs: - name: mcp-gateway namespace: ai-gateway hostnames: - 'server1.mcp.local' rules: - matches: - path: type: PathPrefix value: / filters: - type: RequestHeaderModifier requestHeaderModifier: set: - name: Accept value: "application/json, text/event-stream" backendRefs: - name: mcp-test-server1 port: 9090 EOF 重要 : filters で Accept: application/json, text/event-stream ヘッダーを設定します。MCP プロトコルでは両方の Content-Type が必要です。 application/json のみを設定すると、Backend MCP Server が "Accept must contain both 'application/json' and 'text/event-stream'" エラーを返し、tools/call が失敗します。 ステップ10: MCPServerRegistration の作成 Backend MCP Server を MCP Gateway に登録します。 oc apply -f - <<EOF apiVersion: mcp.kuadrant.io/v1alpha1 kind: MCPServerRegistration metadata: name: test-server1 namespace: mcp-system spec: path: /mcp toolPrefix: test1_ targetRef: group: gateway.networking.k8s.io kind: HTTPRoute name: mcp-server1-route EOF 確認 : oc get mcpserverregistration -n mcp-system 期待される出力: NAME PREFIX TARGET PATH READY TOOLS CREDENTIALS AGE test-server1 test1_ mcp-server1-route /mcp True 5 12h 確認ポイント : READY が True で、 TOOLS が 5 であることを確認してください。これは、5つのツール(greet, time, slow, headers, add_tool)が正常に検出されたことを示します。 ステップ11: DNS 解決の確認 ローカルマシンから DNS 解決を確認します。 nslookup mcp.example.com # 自分の環境のHostnameに置き換える 期待される出力: Server: 8.8.8.8 Address: 8.8.8.8#53 Non-authoritative answer: mcp.example.com canonical name = *****-*****.reagioin.elb.amazonaws.com. Name: *****-*****.reagioin.elb.amazonaws.com Address: 13.59.251.55 Name: *****-*****.reagioin.elb.amazonaws.com Address: 3.12.127.167 AWS ELB(Istio Gateway Service)の IP アドレスが返却されれば、DNS レコードが正しく作成されています。 サンプルの検証手順と期待値 ここでは、デプロイした MCP Gateway サンプルの動作確認を行います。ローカルマシンから HTTP 経由で MCP リクエストを送信します。 環境変数の設定 自分の環境のHostnameに置き換えて、 MCP_URL を設定してください。 MCP_URL="http://mcp.example.com/mcp" ① Initialize Request(セッション初期化) MCP セッションを初期化します。 curl -v ${MCP_URL} \ -X POST \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "jsonrpc": "2.0", "method": "initialize", "params": { "protocolVersion": "2025-11-25", "capabilities": {}, "clientInfo": { "name": "manual-test", "version": "1.0.0" } }, "id": 1 }' 期待される結果 : < HTTP/1.1 200 OK < content-type: application/json < mcp-session-id: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...(略) < date: Sun, 24 May 2026 14:21:40 GMT < content-length: 176 < x-envoy-upstream-service-time: 0 < server: istio-envoy < {"jsonrpc":"2.0","id":1,"result":{"protocolVersion":"2025-11-25","capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"Kuadrant MCP Gateway","version":"0.0.1"}}} 確認ポイント : HTTP ステータス: 200 OK mcp-session-id ヘッダーに JWT トークンが含まれている レスポンス JSON に protocolVersion と serverInfo が含まれている Session ID を環境変数に保存 : SESSION_ID="<上記レスポンスの mcp-session-id の値>" ② Tools List Request(利用可能なツールのリスト取得) curl -s ${MCP_URL} \ -X POST \ -H "Content-Type: application/json" \ -H "mcp-session-id: ${SESSION_ID}" \ -d '{ "jsonrpc": "2.0", "method": "tools/list", "id": 2 }' | jq . 期待される結果 ( jq でフォーマット済み): { " jsonrpc ": " 2.0 ", " id ": 2 , " result ": { " tools ": [ { " _meta ": {} , " annotations ": { " title ": " add " } , " description ": " dynamically add a new tool (triggers notifications/tools/list_changed) ", " inputSchema ": { " additionalProperties ": false , " properties ": { " description ": { " description ": " the description of the new tool ", " type ": " string " } , " name ": { " description ": " the name of the new tool to add ", " type ": " string " } } , " required ": [ " name ", " description " ] , " type ": " object " } , " name ": " test1_add_tool " } , { " _meta ": {} , " annotations ": {} , " description ": " say hi ", " inputSchema ": { " additionalProperties ": false , " properties ": { " name ": { " description ": " the name to say hi to ", " type ": " string " } } , " required ": [ " name " ] , " type ": " object " } , " name ": " test1_greet " } , { " _meta ": {} , " annotations ": {} , " description ": " get headers ", " inputSchema ": { " additionalProperties ": false , " properties ": {} , " required ": [] , " type ": " object " } , " name ": " test1_headers " } , { " _meta ": {} , " annotations ": {} , " description ": " delay N seconds ", " inputSchema ": { " additionalProperties ": false , " properties ": { " seconds ": { " description ": " number of seconds to wait ", " type ": " integer " } } , " required ": [ " seconds " ] , " type ": " object " } , " name ": " test1_slow " } , { " _meta ": {} , " annotations ": { " title ": " time " } , " description ": " get current time ", " inputSchema ": { " additionalProperties ": false , " properties ": {} , " required ": [] , " type ": " object " } , " name ": " test1_time " } ] } } 確認ポイント : tools 配列に 5 つのツールが含まれている 各ツール名に test1_ プレフィックスが付いている(MCPServerRegistration の toolPrefix 設定) inputSchema でツールの引数が定義されている ③ Tool Call Requests(ツールの実行) 各ツールを実行して、動作を確認します。 ③-1. test1_time - 現在時刻取得 curl -s ${MCP_URL} \ -X POST \ -H "Content-Type: application/json" \ -H "mcp-session-id: ${SESSION_ID}" \ -d '{ "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "test1_time", "arguments": {} }, "id": 10 }' 期待される結果 : event: message data: {"jsonrpc":"2.0","id":10,"result":{"content":[{"type":"text","text":"2026-05-25 00:16:49.122721849 +0000 UTC m=+439.191493349"}]}} 確認ポイント : Server-Sent Events 形式のレスポンス UTC タイムスタンプが返却される その他のツール( test1_greet 、 test1_headers 、 test1_slow 、 test1_add_tool )も同様に tools/call で実行できます。 検証完了条件 : ✅ 5 つのツール全てが正常に実行され、期待通りのレスポンスが返る ✅ Hairpin リクエスト(MCP Gateway → Backend MCP Server)が正常に動作 ✅ Server-Sent Events 形式のレスポンスが正しく返却される 終わりに 本記事では、RHCL 1.3.3 で Tech Preview として追加された MCP Gateway についてサンプルを用いて紹介しました。 今後、Red Hat Connectivity Linkは、AI Gatewayとしての機能をさらに充実していく予定となっておりますので、乞うご期待ください!