前回の記事では、モデルコンテキストプロトコル (MCP) を使用して、ドメイン固有の問題を解決するためのツールを作成し、驚くべき結果を得ることについて説明しました。この短いシリーズは Amazon Interactive Video Service (Amazon IVS) に焦点を当てていますが、このアプローチは文字通りどんな分野のソリューションの作成にも適用できることを覚えておいてください。他の AWS のサービスについてもっと学びたいですか? 問題ありません ✅! ツールを別の AWS SDK を使うように改造するだけです! 、ゴルフ大会のデータベースを公開するサーバを作り、クライアントからゴルファー🏌️‍♂️や試合について深い洞察を得ることができるようにしたいですか?これももちろん、可能です!カスタム MCP サーバーをあなたのデータベースに向ける(または既製の MCP サーバーを使用する)だけです!

この記事では、アカウント内のAmazon IVSリソースを把握する MCP サーバーの構築方法をご紹介します。このサーバーは、Webから収集した公開IVSドキュメントを含むシンプルなRAGナレッジベースにもアクセスでき、その他にも作業を支援するツールやユーティリティがいくつか用意されています。ソリューション全体の概要を示す図を以下に示します。この図は、この記事と次の記事で詳しく説明します。

IVS MCP Arch Overview

MCP サーバーの作成

初めての MCP サーバー作成に役立つオンラインリソースはすでに豊富にあります。このドキュメントは、お好みの言語のSDKを見つけるための良い出発点となります。このデモでは、 TypeScript SDKを使用してサーバーを作成します。

💡注意: この記事では、IVS MCP サーバーを作成する手順をいくつか紹介します。基本的な Amazon IVS MCP サーバーの完全なサンプルサーバーコードは、この記事の下部にあります。

カスタム Amazon IVS MCP サーバーを作成するための最初のステップは、プロジェクトを作成し、MCP SDK をインストールすることです。

npm init es6 -y
npm install @modelcontextprotocol/sdk

次に、 src/index.jsを作成します。このファイルでは、SDK とstdioトランスポートをインポートし、サーバーを作成します。

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({
  name: "IVS-MCP-Server",
  version: "1.0.0"
});

このサーバーでは標準入力を使用します(HTTP SSE を使用することもできます)。StdioServerTransportサーバーを作成して起動しましょう。

const transport = new StdioServerTransport();
await server.connect(transport);

この時点でサーバーが作成できました。まだ何も機能はありませんが、準備は整っています。MCP Inspector を使って、次のコマンドを実行することでいつでもテストできます:

npx @modelcontextprotocol/inspector node src/index.js

Inspectorの表示は以下のようになります:
MCP Inspector

「Connect」を選択するとサーバーに接続されますが、ツールやリソースがまだ定義されていないため、あまり役に立ちません。

Amazon IVS 用 MCP サーバーツールの作成

モデルコンテキストプロトコルは、ツールやリソースからプロンプトやルートなど、さまざまな目的を持つ複数の概念を定義しています。それぞれの概念について詳しくは、ドキュメントを参照してください。ただし、すべてのクライアントがこれらの概念をすべて利用できるわけではありません。今回の実装では、Amazon Bedrock でツールの使用が強力にサポートされており(今後の記事で説明します)、tools は動的なデータを取得するのに最適な方法であるため、これに焦点を当てます。このサーバーでは Amazon IVS に焦点を当てているため、まずは AWS SDK for JavaScript (v3) 内の様々なモジュールを介して Amazon IVS 固有のデータを取得するためのツールセットを追加することから始めます。
MCP Server->IVS

まず、低レイテンシー、リアルタイム、チャット用の Amazon IVS クライアントモジュールをインストールしましょう。また、後で使用する HTML を Markdown に変換するライブラリも追加します。

$ npm install @aws-sdk/client-ivs @aws-sdk/client-ivs-realtime @aws-sdk/client-ivschat node-html-markdown

これで、ツールで使用する IvsClient のインスタンスを作成できます。いつものように、アプリケーション内で認証情報をハードコーディングすることは避けるべきなので、環境変数を使用して AWS 認証情報を渡します。

import {
    IvsClient,
    ListChannelsCommand,
} from "@aws-sdk/client-ivs";
import { z } from "zod";
const config = {
  region: process.env.AWS_REGION,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  }
};

const ivsClient = new IvsClient(config);

ツールを定義するには、サーバー側でserver.tool()を呼び出します。このメソッドは、ツール名、説明、パラメータ定義、そしてクライアントからツールが呼び出されたときに実行されるコールバックを受け取ります。

💡ヒント: MCP を使用する際には、LLM が特定のツールを呼び出すのが適切かどうかを判断するのに十分なコンテキストを与えるため、良い名前を付け、重要な説明を正確に与えることをお勧めします。

AWSアカウント内のAmazon IVS 低レイテンシーチャネルを一覧表示できる最初のツールを作成しましょう。このツールには nextTokenmaxResultsname の3つのオプショナルな入力パラメータがあります。これにより、LLM は必要に応じて、いつ、何を渡すべきかを判断できるように、各パラメータに適切な説明を記載することに焦点を当てます。

server.tool(
  "list-channels",
  "List all of the IVS channels for this account. Returns paginated results with a default max of 10.",
  {
    nextToken: z.string().optional().describe('The token for the next page of results'),
    maxResults: z.number().optional().default(10).describe('The maximum number of results to return (default: 10)'),
    name: z.string().optional().describe('The name of the channel to search for'),
  },
  async (params) => {
    const input = {};
    Object.assign(input, params?.nextToken && params.nextToken !== 'null' ? { nextToken: params.nextToken } : {});
    Object.assign(input, params?.maxResults ? { maxResults: params.maxResults } : {});
    Object.assign(input, params?.name ? { filterByName: params.name } : {});
    const command = new ListChannelsCommand(input);
    const listChannelsResponse = await ivsClient.send(command);
    return {
      content: [{ type: "text", text: JSON.stringify(listChannelsResponse) }]
    };
  }
);

これで、MCP Inspector に接続し、「Tools」を選択してから「List Tools」を選択し、list-channelsツールを選択できます。
MCP Tool List

オプショナルパラメータの値を入力し、「Run Tool」を選択して結果を確認します。
MCP Tool Result

この時点で、「これは単なる SDK の薄いラッパーだ」と思うかもしれません。その通りです。特に魔法のようなこと🧙‍♂️🪄は何も起きていません。唯一の「魔法」は、プロトコルに従っていることです。ツールとパラメータを標準化された方法で定義し、標準化されたインターフェースを介して公開しているだけです。ある意味、SOAP 🧼😂(「SはシンプルのS」を参照)に似ていますね。申し訳ありません、X世代の開発者っぽいことを言ってしまいました。話を戻します...

シンプルに見えますが、私たちがここで行ったことはその単純さにおいて素晴らしいものです。クライアントがこのサーバーの存在を認識すると、私たちは自分自身のデータについて質問し、洞察を得たり、パターンを発見したり、異常を発見したり、未使用のリソースを見つけたりすることができます。唯一の制限は実装です。しかし、話が少し先走りすぎました。今のところ、この MCP サーバーには、SDK の他のメソッドを公開するための追加ツールが必要です。私の IVS サーバーには、以下の IVS 低レイテンシ固有のツールを採用することにしました。

  • list-channels
  • get-channel
  • batch-get-channels
  • get-stream
  • get-recording-configuration
  • list-stream-sessions
  • get-stream-session
  • get-playback-restriction-policy
  • get-encoder-configuration
  • get-ingest-configuration
  • create-channel
  • list-stream-keys
  • get-stream-key
  • get-low-latency-stream-health-metrics
  • create-ingest-configuration
  • create-encoder-configuration

また、リアルタイムステージ用のツールもいくつか追加しました。

  • create-stage
  • list-stages
  • get-stage
  • list-participants
  • get-participant
  • list-stage-sessions
  • get-stage-session
  • get-real-time-stage-health-metrics

そして IVS チャットについては:

  • list-rooms
  • get-room
  • get-logging-configuration

ご覧のとおり、Amazon IVS アカウントにリソースを作成できるツール (create-channelcreate-stageなど) も含めています。これが良いアイデアかどうかはまだわかりません。一方で、このサーバーに接続するクライアントに、これらのリソースを作成するために必要なコードを生成してもらい、そのコードを手動で実行するのは十分簡単かもしれません。結局のところ、ユースケースと要件によって、これらのツールを含めるかどうかが決まりますが、検証のためににこのサーバーに含めることにしました。いつものように、本番環境でこのようなツールを使用する影響を十分に認識し、実行するすべてのコードを適切に保護してください。

🌟ボーナスヒント: IDE に Amazon Q Developer 拡張機能をインストールしている場合は、作成したい様々なツール操作のインポート定義から始め、ツールを自動生成させましょう。ツールを 1 つ定義すると、Amazon Q Developer はそのフォーマットとインポートされたライブラリの分析情報を活用して残りのツールを自動的に定義してくれるので、時間を大幅に節約できます。

この時点で、MCPサポートを備えたクライアントをサーバーに接続すれば、AWSアカウントに関する貴重な情報を得ることができます。例えば:

give me an overview of my ivs channels

(私のIVS チャンネルの概要を教えてください)

I see you have multiple IVS channels in your account. Let me provide an overview of these channels:
(あなたのアカウントには複数の IVS チャンネルがあります。これらのチャンネルの概要を説明します)

### Your IVS Channels (First 10):

1. **[****channel****-****1****]**
   - Type: STANDARD
   - Latency Mode: LOW
   - Authorization required: No
   - Recording configuration: None
2. ****[channel-2]*
   - Type: STANDARD
   - Latency Mode: LOW
   - Authorization required: No
   - Recording configuration: None
3. **[****channel****-****3****]**
   - Type: STANDARD
   - Latency Mode: LOW
   - Authorization required: No
   - Recording configuration: None
... removed for brevity

There appear to be additional channels, as there's a "nextToken" value in the response. Would you like me to fetch the next page of channels for you, or would you like more detailed information about any specific channel?
(レスポンスに「nextToken」値があるため、さらにチャンネルがあるようです。次のページのチャンネルを取得しますか?または特定のチャンネルについての詳細情報が必要ですか?)

これは便利ですが、SDK を通じて list-channels を手動で呼び出すのとあまり変わりません。しかし、さらに踏み込んで、例えば次のようにチャンネル概要を要約するように指示することもできます:

how many channels have a recording configuration attached?
(録画設定のあるチャンネルはいくつありますか?)

After checking all your channels, here's a summary of channels with recording configurations:
(すべてのチャンネルを確認した結果、録画設定を持つチャンネルの概要は次のとおりです)

Channels with Recording Configurations: 3

  1. [redacted]
    • Recording configuration: arn:aws:ivs:us-east-1:[redacted]:recording-configuration/[redacted]
  2. [redacted]
    • Recording configuration: arn:aws:ivs:us-east-1:[redacted]:recording-configuration/[redacted]
  3. [redacted]
    • Recording configuration: arn:aws:ivs:us-east-1:[redacted]:recording-configuration/[redacted]

Total Channels: 13

None of the channels from the second page have recording configurations attached.
(2ページ目のチャンネルには録画設定が添付されているものはありません。)

Out of your 13 total IVS channels, only 3 channels (approximately 23%) have recording configurations.
(合計13のIVSチャンネルのうち、録画設定を持つチャンネルは3つのみ(約23%)です。)

Would you like more information about these recording configurations or any other aspects of your IVS channels?
(これらの録画設定や他のIVSチャンネルの側面について詳細情報が必要ですか?)

これで、クライアントは IVS アカウントに関する詳細かつ具体的なデータを取得できるようになりました。これをさらに発展させ、カスタムナレッジベースと組み合わせることで、IVSアカウントに関する詳細な情報を取得し、最終的にはリソースを操作するためのプロトタイプとコードを生成できるようになります。

ストリームとステージのヘルスメトリクス

IVS MCP -> CloudWatch

Amazon IVSはチャネルとステージのヘルスメトリクスをCloudWatchに記録するため、これらのメトリクスデータをクエリするためのツールを追加することもできます。MCP サーバーはストリームとステージのセッションを取得できるため、最終的にはクライアントを使用して特定のセッションの詳細または概要を得ることができます。そのためには、CloudWatch SDK をインストールします。

npm install @aws-sdk/client-cloudwatch

次に、CloudWatch クライアントを作成します。

const cloudWatchClient = new CloudWatchClient(config);

そして、必要なメトリクスデータをクエリするためのツールを作成します。以下は、指定された期間のリアルタイムステージのメトリクスを取得するツールです(読みやすくするために説明は省略しています)。

server.tool(
  "get-real-time-stage-health-metrics",
  "Get IVS Real-Time stage health metrics",
  {
    arn: z.string().describe('The ARN...'),
    startTime: z.number().optional().default(new Date().setHours(new Date().getHours() - 1)).describe('The start time...'),
    endTime: z.number().optional().default(Date.now()).describe('The end time...'),
    streamHealthMetrics: z.array(
      z.enum([
        "Subscribers",
        "Publishers",
        "SubscribeBitrate",
        "DownloadPacketLoss",
        "DroppedFrames",
        "PublishBitrate"
      ]))
      .optional()
      .default([
        "Subscribers",
        "Publishers",
        "SubscribeBitrate",
        "DownloadPacketLoss",
        "DroppedFrames",
        "PublishBitrate"
      ]).describe('The stage health metrics to retrieve...'),
    period: z.number().optional().default(5).describe('The granularity...')
  },
  async ({ arn, startTime, endTime, streamHealthMetrics, period }) => {
    startTime = new Date(startTime);
    endTime = new Date(endTime);
    const metricDataQueries = streamHealthMetrics.map((metric) => {
      return {
        Id: metric.toLowerCase(),
        MetricStat: {
          Metric: {
            MetricName: metric,
            Namespace: "AWS/IVSRealTime",
            Dimensions: [{ Name: "Stage", Value: arn.split("/")[1] }]
          },
          Period: period,
          Stat: "Average",
        }
      };
    });
    const getMetricDataInput = {
      StartTime: startTime,
      EndTime: endTime,
      MetricDataQueries: metricDataQueries,
      MaxDatapoints: 100
    };
    const getMetricDataRequest = new GetMetricDataCommand(getMetricDataInput);
    const getMetricDataResponse = await cloudWatchClient.send(getMetricDataRequest);
    console.error(getMetricDataResponse);
    return {
      content: [{ type: "text", text: JSON.stringify(getMetricDataResponse) }]
    };
  }
);

MCP クライアントを使用して、特定のリアルタイムステージの最新のセッションについて問い合わせると、次のような出力を得ることができます:

I've successfully retrieved the metrics for the latest session on demo-stage. Now I'll summarize this information for you:
(demo-stageの最新セッションのメトリクスを取得しました。この情報を要約します:)

Summary of Stage Metrics for Latest Session on demo-stage

Session Details:

  • *Session ID:* st-[redacted]
  • *Start Time:* April 2, 2025, 18:11:53 UTC
  • *End Time:* April 2, 2025, 19:00:38 UTC
  • *Duration:* Approximately 49 minutes

Key Performance Metrics:

  1. Participants:
  2. *Publishers:* Consistently around 2 publishers throughout the session
  3. *Subscribers:* Maintained around 2 subscribers with occasional fluctuations
  4. Bitrate Performance:
  5. *Publish Bitrate:* Averaged between 900,000 - 1,500,000 bps (0.9-1.5 Mbps)
  6. *Subscribe Bitrate:* Averaged between 500,000 - 900,000 bps (0.5-0.9 Mbps)
  7. Quality Indicators:
  8. *Download Packet Loss:* Very minimal, mostly 0% with occasional spikes to 0.1%
  9. *Dropped Frames:* Nearly zero throughout the session, with only two minor instances of frame drops

Overall Assessment:
The session shows stable performance with consistent publisher and subscriber counts. The bitrate was sufficient for good quality streaming, and the quality indicators suggest excellent network conditions with minimal packet loss and almost no dropped frames. The stage performed well during this 49-minute session with no significant issues detected.
(このセッションは一貫したパブリッシャーとサブスクライバー数で安定したパフォーマンスを示しています。ビットレートは良質なストリーミングに十分であり、品質指標は最小限のパケットロスとほぼフレームドロップがないという優れたネットワーク状態を示しています。このステージは49分間のセッション中、重大な問題なく良好に機能しました。)

Amazon IVS リソースの作成

これまで、カスタムサーバーを使用してAmazon IVSリソースに関する情報を取得する方法を見てきました。しかし、クライアントがユーザーからの指示に基づいて新しいリソースを作成する機能を追加することもできます。例えば、低レイテンシーのチャネルを作成するツールを作成するには、create-channelツールを作成します。ここでは読みやすさを考慮して説明を一部省略しています。完全な説明については、記事の下部のサーバー例をご覧ください。

server.tool(
  "create-channel",
  "Create a new IVS channel",
  {
    name: z.string().optional().describe('The name...'),
    latencyMode: z.enum(['LOW', 'NORMAL']).optional().default('LOW').describe('The latency mode....'),
    type: z.enum(['BASIC', 'STANDARD', 'ADVANCED_SD', 'ADVANCED_HD']).optional().default('STANDARD').describe('The type...'),
    authorized: z.boolean().optional().default(false).describe('Whether the channel...'),
    recordingConfigurationArn: z.string().optional().describe('The recording config...'),
    insecureIngest: z.boolean().optional().default(false).describe('Whether the channel...'),
    preset: z.enum(['HIGHER_BANDWIDTH_DELIVERY', 'CONSTRAINED_BANDWIDTH_DELIVERY']).optional().describe('Optional transcode...'),
    playbackRestrictionPolicyArn: z.string().optional().describe('The playback...'),
    containerFormat: z.enum(['FRAGMENTED_MP4', 'TS']).optional().default('TS').describe('The content-packaging ...'),
  },
  async ({ name, latencyMode, type, authorized, recordingConfigurationArn, insecureIngest, preset, playbackRestrictionPolicyArn, containerFormat, tags }) => {
    const input = {};
    Object.assign(input, name ? { name } : {});
    Object.assign(input, latencyMode ? { latencyMode } : {});
    Object.assign(input, type ? { type } : {});
    Object.assign(input, authorized ? { authorized } : {});
    Object.assign(input, recordingConfigurationArn ? { recordingConfigurationArn } : {});
    Object.assign(input, insecureIngest ? { insecureIngest } : {});
    Object.assign(input, preset ? { preset } : {});
    Object.assign(input, playbackRestrictionPolicyArn ? { playbackRestrictionPolicyArn } : {});
    Object.assign(input, containerFormat ? { containerFormat } : {});
    Object.assign(input, tags ? { tags } : {});

    const command = new CreateChannelCommand(input);
    const response = await ivsClient.send(command);
    return {
      content: [{ type: "text", text: JSON.stringify(response) }]
    };
  }
);

サンプルMCPサーバー

以下に基本的なAmazon IVS MCP サーバーの完全なコードを紹介します。独自のカスタムサーバーの作成を始める助けになります。このサンプルには、Bedrockナレッジベースのクエリと次回の投稿で説明する追加のユーティリティツールが含まれています。

サンプルサーバーコード

長いので「Create a Custom MCP Server for Working with AWS Services - Managing Yo...」を御覧ください。

まとめ

この投稿では、AWS アカウント内の Amazon IVS リソースと対話するためのツールセットを含むカスタム MCP サーバーの作成方法を学びました。次回の投稿では、カスタム RAG ナレッジベースの作成と追加のツールとリソースでサーバーを拡張する方法を見ていきます。