メインコンテンツに移動

builders.flash

日常で楽しむクラウドテクノロジー

クラウドを利用して、MCP (Model Context Protocol) で MCP (Minecraft Play)して親の威厳をもう一度取り戻す冬 ~ AWS IoT サービスを添えて ~

2026-01-06 | Author : 市川 純

はじめに

MCP (Model Context Protocol) で MCP (Minecraft Play)して親の威厳を取り戻したソリューションアーキテクトの呉から無茶振りされたプロトタイピングソリューションアーキテクトの市川です。無茶振りにつながった前回の話は、こちらの記事「MCP (Model Context Protocol) で MCP (Minecraft Play) して親の威厳を取り戻す夏 ~ Strands Agents を添えて ~」をご覧ください。

前回は、Raspberry Pi 上で Strands Agents を利用し無事 Minecraft Play(MCP) を動かしましたが、気づいたらもう冬になってました。その間にすっかりと親の威厳を失ってしまったので、クラウドを巻き込んでもう一度親としての威厳を取り戻したいと思います !

この回では Minecraft Play (MCP) が動くラズパイに対してクラウド経由で遠隔から操作したいと呉さんに、どのようなイメージかをホワイトボードに書いてもらいました。その時の図がこちらとなります。この図を元にどのように実現するかを考えてみることにしました。

 

X ポスト » | Facebook シェア » | はてブ »

Missing alt text value

ご注意

本記事で紹介する AWS サービスを起動する際には、料金がかかります。builders.flash メールメンバー特典の、クラウドレシピ向けクレジットコードプレゼントの入手をお勧めします。

*ハンズオン記事およびソースコードにおける免責事項 »

builders.flash メールメンバー登録

builders.flash メールメンバー登録で、毎月の最新アップデート情報とともに、AWS を無料でお試しいただけるクレジットコードを受け取ることができます。

今すぐ登録 »

実装方法

クラウド経由で Minecraft Play(MCP) を実現する場合、クラウド側で AI エージェントをホストし、その AI エージェントの指示をラズパイに送信し、ラズパイは指示を受けて行動する仕組みが必要です。詳細は後述しますが、エージェントのホストには Amazon Bedrock AgentCore、エージェントの指示をラズパイに送信するのは AWS IoT Core、実際に行動を起こすのは AWS IoT Greengrass を用いることとしました。

AWS IoT Core は マネージドサービスの MQTT ブローカーを提供しています。MQTT を利用することで、トピックを通してデバイス側と双方向のコミュニケーションを実現することができますが、 MQTT は HTTP と違い実行結果を戻り値として受け取ることができません。そのため、指示用のトピックと、結果通知用のトピックを別にし MCP サーバー側で AWS IoT Core に対してメッセージを送った後に、結果が保存される DynamoDB を監視して、結果を受け取る実装としています。(図の AWS Lambda で AWS IoT Device SDK などを利用し、トピックにサブスクライブし結果を受け取る方法もあります)

アーキテクチャ図

デモ動画

デモ動画では、WebのチャットUIから指示を入力すると、Raspberry Pi 上で動いている AWS IoT Greengrass のコンポーネントにコマンドが送信され、Minecraft のアプリを操作します。

AWS IoT Core のコンソールで対象の Thing Group に新しいデバイスを追加すると、チャットの UI から入力された指示が、新しく追加したデバイスに対しても送信されるのが確認できるかと思います。(ただし、デモでは実際に新しい Raspberry Pi は接続されていないため、新しく追加した Raspberry Pi からのレスポンスがないため、コマンドが成功しなかったと結果が表示されています。

アーキテクチャ解説

Agents as Tools

今回の仕組みでは増えていく Raspberry Pi を Agent が操作する必要がありますが、それぞれの Raspberry Pi 上で動作する Minecraft の環境は異なる可能性があり、操作するときはそれぞれの環境に合わせて Agent が判断し操作する必要が出てきます。そこで Agents as Tools という考え方を取り入れました。これは、Orchestrator と呼ばれる Agent が元の指示を受け、 特定の処理をしてくれる Tool Agent を tool として利用するパターンです。図にするとこのような関係になります。

今回は同じ処理を行う Agent を利用しているだけですが、異なる機能を持つ Agent を組み合わせると、例えばスマートホームの全体を管理する Ochestrator Agent に「寝るから快適な設定にして」と指示を出すと、エアコンを操作する Agent 、照明を操作する Agent を利用して部屋の状態を変えるといった使い方も考えられるかなと思います。

Missing alt text value

コードに定義

今回のコードでは、以下のように advanced/cdk/lib/agent/agent.py に定義しています。

python
class MCPMCPAgentTool:

〜〜中略〜〜

    @tool
    def device_agent(self, thing_name: str, instruction: str):
        """Call a specific device agent with instructions
        Args:
            thing_name: AWS IoT Thing name
            instruction: instructions for the agent
        Returns:
            {"device": "ThingName": "result": "result from device"}
        """
        device_prompt = f"""
    You are a Minecraft specialist for device: {thing_name}
    You must:
    1. Always capture current situation first
    2. Respond based on YOUR device's specific context
    3. Report results back to orchestrator agent
    4. Coordinate with other devices when requested

    Target device: {thing_name}
    """

        mcp_client = MCPClient(
            lambda: self.create_streamable_http_transport(self.gateway_url)
        )

        model = BedrockModel(model_id="jp.anthropic.claude-haiku-4-5-20251001-v1:0")
        with mcp_client:
            mcp_tools = self.get_full_tools_list(mcp_client)

            device_agent = Agent(
                model=model, tools=[mcp_tools], system_prompt=device_prompt
            )

            # デバイス固有の指示でエージェント実行
            target = f"\n操作対象デバイス: {thing_name}\n指示: {instruction}"
            response = device_agent(target)

            return {
                "device": thing_name,
                "result": response.message["content"][0]["text"],
            }

Strands Agents に指定

呼び出す側では、以下のように tool として Strands Agents に指定します。

python
@app.entrypoint
def invoke(payload):

〜〜中略〜〜
    # デバイス上のMinecraftを遠隔から操作するためのAgent
    mcpmcp_tool = MCPMCPAgentTool(GATEWAY_URL, token)

    model = BedrockModel(model_id="jp.anthropic.claude-haiku-4-5-20251001-v1:0")

〜〜中略〜〜
    orchestrator_agent = Agent(
        model=model,
        tools=[mcpmcp_tool.device_agent],
        system_prompt=orchestrator_prompt,
    )

これで、Orchestrator Agent が必要に応じて Tool Agent を必要な数動かします。

Agent のホスティング

生成 AI を使って IoT デバイス (今回は Raspberry Pi) を操作する場合、手元の PC 上で Agent を実行する方法も考えられますが、今回はより実践的な使い方として Agent をクラウド上でホスティングしたいと考えました。そこで利用できるのが、Amazon Bedrock AgentCore です。Amazon Bedrock AgentCore は高機能エージェントを安全かつ大規模に構築、デプロイ、運用できるエージェントプラットフォームであり、マネージドサービスとして提供されています。AgentCore Runtime は Agent を実行するために利用できるサービスで、作成した Agent を低レイテンシーなサーバーレスサービスとしてホストすることができます。 サンプルコードでは advanced/cdk/lib/agent が Agent のコードとなっており、AWS CDK の L2 コンストラクトを利用して簡単にデプロイすることができます。コードは advanced/cdk/lib/constructs/mcpagent.ts の以下の部分です。

python
    const agentRuntimeArtifact =
      aws_bedrockagentcore_alpha.AgentRuntimeArtifact.fromAsset(
        path.join(__dirname, '\..agent')
      );

    const runtime = new aws_bedrockagentcore_alpha.Runtime(this, 'Runtime', {
      runtimeName: 'MCPMCPAgentRuntime',
      agentRuntimeArtifact: agentRuntimeArtifact,
      environmentVariables: {
        AWS_DEFAULT_REGION: Stack.of(this).region,
        GATEWAY_URL: gateway.gatewayUrl!,
        THING_GROUP_NAME: 'RpiMCP',
      },
    });

MCP サーバーのホスティング

前回は Raspberry Pi 上で MCP サーバーを動かして操作しましたが、遠隔から複数台を操作するとなると、MCP サーバーをクラウド上で動かす必要があります。AgentCore Runtime 上で MCP サーバーを動かす こともできますが、今回は AgentCore Gateway を使ってみました。

AgentCore Gatewayは既存の Lambda や API などを MCP サーバーとして利用することができるサービスで、Agent からの利用する時の認証と、Gateway を通して利用するサービスの認証の情報を管理することができます。

今回のサンプル advanced/cdk/lib/constructs/mcpagent.ts では Agent <> Gateway 間と、Gateway <> Lambda 間は IAM を使った認証を行なっています。Agent <> Gateway 間は Streamable HTTP を使う必要がありますが、IAM 認証の場合は SigV4 を使った URL で接続する必要があります。このサンプルでは mcp-proxy-for-aws の aws_iam_streamablehttp_client (参考) を利用しています。 advanced/cdk/lib/agent/agent.py の以下の部分です。

MCP サーバーのホスティング設定

python
@asynccontextmanager
    async def create_streamable_http_transport(self):
        """
        IAMを使った認証のため、SIGV4を利用するstreamablehttp clientを作成する
        https://github.com/aws/mcp-proxy-for-aws
        """

        async with aws_iam_streamablehttp_client(
            endpoint=self.gateway_url,
            aws_service="bedrock-agentcore",
            aws_region=AWS_DEFAULT_REGION,
        ) as result:
            yield result

以上で、このサンプルの Agent 側の仕組みが理解していただけたかと思います。

サンプルのセットアップ

ここからは、デモで利用した環境を再現するための手順を紹介します。

注意

  • 今回用意しているサンプルは、Linux/Mac 上で実行することを前提としたスクリプトも含まれている為、手元にそのような環境がない場合は、 Amazon EC2 のインスタンスを立ち上げその中で以下の作業を進めてください
  • CDK やインストーラーのセットアップコマンドを実行する前に、 AWS CLI のクレデンシャル情報 または 環境変数 が設定されていることを確認してください
  • 様々なリソースを作成する為、クレデンシャル情報は十分な権限を持つものを利用してください
  • リージョンは ap-northeast-1、us-west-2 で確認しています。

1. CDK を使って必要なリソースを作成

実行する際には、AdministratorAccess の権限を持つ環境または、環境変数 (AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN) に指定する必要があります。また、リージョンを AWS_DEFAULT_REGION に指定してください。以下の例では東京リージョンを指定しています。 サンプルコードの advanced/cdk には、今回の記事で作成した AWS のリソースを構築する為のコードが含まれています。

bash
AWS_DEFAULT_REGION=ap-northeast-1

git clone https://github.com/aws-samples/mcp-mcp
cd mcp-mcp/advanced/cdk
npm install
cdk bootstrap
cdk deploy

出力結果を確認

デプロイが成功すると、以下のような出力が確認できます。これらの値は Web UI の手順で利用しますのでメモをしておいてください。

bash
Outputs:
MCPMCP.RuntimeARN = arn:aws:bedrock-agentcore:リージョン名:アカウント名:runtime/MCPMCPAgentRuntime-XXXXX
MCPMCP.McpUserPoolDomainNameXXXXXXXX = mcpmcp
MCPMCP.IdentityPoolID = リージョン名:xxxx-xxxx-xxxx-xxxx
MCPMCP.UserPoolClientID = xxxxxxxxxxxxxx
MCPMCP.UserPoolId = リージョン名_xxxxxxx

2. AWS IoT Greengrass のインストーラーを作成

サンプルコードの advanced/gginstaller には、複数の Raspberry Pi に AWS IoT Greengrass を簡単にセットアップする際に必要なインストーラーを作成します。このインストーラーは、Fleet Provisioning という仕組みを利用し、初回起動時に自動で AWS IoT Greengrass に Core デバイスとして登録を行います。この仕組み自体を別の用途で再利用しやすいように、CDK ではなく、boto3 を利用したスクリプトでセットアップするサンプルを含めています。

zipunzip コマンドを利用しますので、実行環境で使えるか事前に確認してください。uv コマンドを利用しますので、実行環境にない場合は インストール を行なってください。

インストーラー作成のコマンド

bash
cd mcp-mcp/advanced/gginstaller
uv run bash scripts/installer_builder.sh

実行完了

実行が完了すると greengrass-assets.zip というファイルが出力されます。このファイルには、 AWS IoT Greengrass をデバイス上でセットアップするために必要なファイルが含まれています。出力されたログに Component bucket: ggmcp-アカウント名-リージョン名 と出力されます。この Amazon S3 バケット名は、コンポーネントのデプロイで必要となります。

AWS IoT Greengrassのプロビジョニングについて詳しく知りたい場合は、 AWS IoT Greengrass 運用編【AWS Black Belt】もご覧ください。

注意 : このインストーラーには証明書を発行するために利用される claim 証明書を含みますので、流出しないように気をつけてください。よりセキュアにする場合は、pre-provigioning hookの利用や証明書登録のモニタリング を行なってください。

3. Minecraft を操作する為のコンポーネントを登録

Minecraft を操作するのは、AWS IoT Greengrass のコンポーネントとして作成したアプリケーションとなります。サンプルの advanced/components/com.example.mcpmcp に移動します。コンポーネントの開発では AWS IoT Greengrass Development Kit (GDK)が利用でき、このサンプルでも利用しています。 以下のコマンドでコンポーネントを作成し、AWS IoT Greengrassのサービスに登録します。リージョン は利用しているリージョンを指定してください。コンポーネントのバケット名 はインストーラーの作成時にComponent bucket: へ出力されたバケット名を指定します。

bash
uv run gdk component publish -r リージョン -b コンポーネントのバケット名

AWS マネジメントコンソールを開いて確認

これで、AWS IoT Greengrass のコンポーネントの登録ができました。マネジメントコンソール を開いて確認しましょう。

 

Missing alt text value

デプロイメントを作成

登録されているのが確認できましたね。次に、このコンポーネントをRaspberry Pi 上で動作する AWS IoT Greengrass に自動的にデプロイされるように、デプロイメントの作成を行います。

左側のメニューで deployment を選択し、右上の Create をクリックします。

Missing alt text value

デプロイメントの設定

Name に何かわかりやすい名前を指定します。このサンプルでは RpiMCP と入力しています。Deployment target では Thing Groupを選んで RpiMCP を選択します。これは、このThing Groupに登録されたGreengrass Coreデバイス全てを対象にするという意味となります。入力したら右下の Next をクリックします。

Missing alt text value

デプロイメント作成の完了

次の画面では特に設定を変更しないため右下の Next で次の画面に進み、さらに Next でレビューの画面まで進んだら Deploy をクリックして、デプロイメントの作成を完了します。これで、Thing Groupに新しいGreengrass Coreデバイスが追加されると、自動的にコンポーネントがデプロイされるようになりました。

Missing alt text value

4. Raspberry Pi に作成したインストーラーをセットアップ

前の手順で作成した greengrass-assets.zip をRaspberry Pi 上にコピーし、以下のコマンドを実行して配置します。

bash
unzip greengrass-assets.zip
cd installer/
chmod +x device-setup.sh
sudo ./device-setup.sh
sudo rm -rf /opt/greengrass-setup/provisioned

このインストーラーは、インストール用のサービス ggsetup.service を Raspberry Pi に登録します。このサービスは、 Raspberry Pi の起動時に実行され、 /opt/greengrass-setup/provisioned というファイルがなければ、 AWS IoT Greengrass ソフトウエアのセットアップを実行します。 AWS IoT Greengrass の Core の名称には uname -n で取得した値が利用されます。

補足

大量の Raspberry Pi に AWS IoT Greengrass をセットアップする場合は、1台ずつ手動で行うと非常に非効率となります。そこでよく利用される手段としては、ゴールデンイメージと呼ばれるものを作成し、作成したイメージをデバイスに書き込みます。Raspberry Pi の場合は SD カードがストレージになりますので、必要なソフトウエアを一通りインストールし終わったら、 SD カードのイメージを取得します。上記のインストーラーを含むゴールデンイメージが書き込まれたデバイスは、起動時に自動で AWS IoT Greengrass のセットアップが実行されます。

AWS IoT Greengrassゴールデンイメージを使用した大規模デバイス製造 という記事も併せてご覧ください。

SD カードのコピーを作成

同じ構成の Raspberry Pi を作成したい場合は、この状態で SD カードのコピーを作成して利用します。 今回の手順では 1 台の Raspberry Pi で進めるため、インストーラーを以下のコマンドで実行して、プロビジョニングをすぐ始めます。

bash
sudo systemctl restart ggsetup.service

インストールの開始

インストール用のサービスを再起動することで、インストールが始まりますので、しばらくすると マネジメントコンソール 上に Core デバイスとして登録されます。


Missing alt text value

登録確認

登録されてるのが確認できたかと思います。
デプロイの状況を見てみましょう。左側のメニューで Deployments を選択し、先ほど作成したデプロイメント RpiMcp を選択します。

Missing alt text value

デプロイメントの完了確認

少し待つと以下のように、完了するのが確認できるかと思います。
これで、Raspberry Piの準備ができました。Raspberry Pi 上でMinecraft のアプリを開き、Creative modeのワールドを開きます。

Missing alt text value

5.Amazon Cognito にユーザーを追加

Minecraft を操作するための Web UI は認証に Amazon Cognito を利用しています。最初の手順で Cognito のリソースは作成されていますので、以下の手順を参考に マネジメントコンソール からユーザープールにユーザーを追加してください。

  1. Amazon Cognito を開き、左側のメニューから User pools を選択します
  2. WebAppUserPool で始まるユーザープールをクリックします
  3. Users のタブを選択し、Create User を選択します
  4. UsernamePassword を入力してください (パスワードを忘れないようにお願いいたします)
    a. その他の項目はデフォルトのまま
    b. don't send an invitation を選択
    c. Email address は受信可能なメールアドレスを指定します、Mark email as verified のチェックをつける
    d. Phone Number は未入力、Mark phone number as verified のチェックは無し
Missing alt text value

6. Web UI の実行

Minecraft を操作するための Web UI は advanced/webapp/ にあります。React のWeb アプリケーションとして作成されています。 advanced/webapp/.env という名前のファイル作成して、中身を以下のようにします。 各値は CDK のデプロイ後に表示された情報で書き換えます。

bash
VITE_APP_AWS_REGION=利用しているリージョンを指定
VITE_APP_COGNITO_USER_POOL_ID=UserPoolIdの値
VITE_APP_COGNITO_USER_POOL_CLIENT_ID=UserPoolClientIDの値
VITE_APP_COGNITO_IDENTITY_POOL_ID=IdentityPoolIDの値
VITE_AGENTCORE_ENDPOINT_ARN=RuntimeARNの値

ライブラリをインストール

書き換えができたら advanced/webapp/ で以下のコマンドで必要なライブラリをインストールします。

bash
npm install

ライブラリを実行

インストールが終わったら、実行します。

bash
npm run dev

Minecraft にサインイン

http://localhost:5173/ をブラウザで開くとUIが表示されます。前の手順で作成したユーザーの認証情報を利用してサインインしてください。初回はパスワードの変更を求められます。
サインインするとチャットの画面が表示されるので、 何ができますか と入力して 送信 をクリックすると結果を確認することができます。

デモ動画のようにやりたい内容をチャットから指定して動かして、複数台の Raspberry Pi 上で建築をして子供に自慢しましょう!
 

Missing alt text value

まとめ

今回の記事を通して、以下の内容について学ぶことができたかと思います。

  • Amazon Bedrock の AgentCore を利用して、Agent や MCP サーバーをホスティングする方法
  • AWS IoT Core と AWS IoT Greengrass を使って、リモートにあるデバイスに対して生成AIから制御する方法
  • 大量のデバイスに AWS IoT Greengrass をプロビジョニングする方法

生成 AI は文書の要約や、ナレッジベースの利用から、Agentの活用と広がっており、さらにはデバイスの操作も今後行なっていくと思われます。この記事をきっかけに、IoT デバイスと生成 AI の連携に興味を持っていただければと思います。

筆者プロフィール

市川 純
アマゾン ウェブ サービス ジャパン合同会社
AWS Prototyping Team シニア プロトタイピング ソリューションアーキテクト

2018年 に AWS へ入社し、主にIoTに関連するプロトタイピングを提供しています。Web サービスから家のデッキ作りまで、モノを作るという事であれば何でも好きな DIY おじさんです。ここ最近の趣味は新しいバイクを手に入れたので、カスタムしたりツーリングに行ったりすることです。

An AWS employee wearing a branded shirt smiles while standing in an office with a wooden wall and large text in the background.