クラウドを利用して、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) が動くラズパイに対してクラウド経由で遠隔から操作したいと呉さんに、どのようなイメージかをホワイトボードに書いてもらいました。その時の図がこちらとなります。この図を元にどのように実現するかを考えてみることにしました。
ご注意
本記事で紹介する 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 を利用して部屋の状態を変えるといった使い方も考えられるかなと思います。
コードに定義
今回のコードでは、以下のように advanced/cdk/lib/agent/agent.py に定義しています。
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 に指定します。
@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 の以下の部分です。
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 サーバーのホスティング設定
@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 のリソースを構築する為のコードが含まれています。
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 の手順で利用しますのでメモをしておいてください。
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 を利用したスクリプトでセットアップするサンプルを含めています。
zip と unzip コマンドを利用しますので、実行環境で使えるか事前に確認してください。uv コマンドを利用しますので、実行環境にない場合は インストール を行なってください。
インストーラー作成のコマンド
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: へ出力されたバケット名を指定します。
uv run gdk component publish -r リージョン -b コンポーネントのバケット名
AWS マネジメントコンソールを開いて確認
これで、AWS IoT Greengrass のコンポーネントの登録ができました。マネジメントコンソール を開いて確認しましょう。
デプロイメントを作成
登録されているのが確認できましたね。次に、このコンポーネントをRaspberry Pi 上で動作する AWS IoT Greengrass に自動的にデプロイされるように、デプロイメントの作成を行います。
左側のメニューで deployment を選択し、右上の Create をクリックします。
デプロイメントの設定
Name に何かわかりやすい名前を指定します。このサンプルでは RpiMCP と入力しています。Deployment target では Thing Groupを選んで RpiMCP を選択します。これは、このThing Groupに登録されたGreengrass Coreデバイス全てを対象にするという意味となります。入力したら右下の Next をクリックします。
デプロイメント作成の完了
次の画面では特に設定を変更しないため右下の Next で次の画面に進み、さらに Next でレビューの画面まで進んだら Deploy をクリックして、デプロイメントの作成を完了します。これで、Thing Groupに新しいGreengrass Coreデバイスが追加されると、自動的にコンポーネントがデプロイされるようになりました。
4. Raspberry Pi に作成したインストーラーをセットアップ
前の手順で作成した greengrass-assets.zip をRaspberry Pi 上にコピーし、以下のコマンドを実行して配置します。
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 で進めるため、インストーラーを以下のコマンドで実行して、プロビジョニングをすぐ始めます。
sudo systemctl restart ggsetup.service
インストールの開始
インストール用のサービスを再起動することで、インストールが始まりますので、しばらくすると マネジメントコンソール 上に Core デバイスとして登録されます。
登録確認
登録されてるのが確認できたかと思います。
デプロイの状況を見てみましょう。左側のメニューで Deployments を選択し、先ほど作成したデプロイメント RpiMcp を選択します。
デプロイメントの完了確認
少し待つと以下のように、完了するのが確認できるかと思います。
これで、Raspberry Piの準備ができました。Raspberry Pi 上でMinecraft のアプリを開き、Creative modeのワールドを開きます。
5.Amazon Cognito にユーザーを追加
Minecraft を操作するための Web UI は認証に Amazon Cognito を利用しています。最初の手順で Cognito のリソースは作成されていますので、以下の手順を参考に マネジメントコンソール からユーザープールにユーザーを追加してください。
- Amazon Cognito を開き、左側のメニューから User pools を選択します
- WebAppUserPool で始まるユーザープールをクリックします
- Users のタブを選択し、Create User を選択します
- Username、Password を入力してください (パスワードを忘れないようにお願いいたします)
a. その他の項目はデフォルトのまま
b. don't send an invitation を選択
c. Email address は受信可能なメールアドレスを指定します、Mark email as verified のチェックをつける
d. Phone Number は未入力、Mark phone number as verified のチェックは無し
6. Web UI の実行
Minecraft を操作するための Web UI は advanced/webapp/ にあります。React のWeb アプリケーションとして作成されています。 advanced/webapp/.env という名前のファイル作成して、中身を以下のようにします。 各値は CDK のデプロイ後に表示された情報で書き換えます。
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/ で以下のコマンドで必要なライブラリをインストールします。
npm install
ライブラリを実行
インストールが終わったら、実行します。
npm run dev
Minecraft にサインイン
http://localhost:5173/ をブラウザで開くとUIが表示されます。前の手順で作成したユーザーの認証情報を利用してサインインしてください。初回はパスワードの変更を求められます。
サインインするとチャットの画面が表示されるので、 何ができますか と入力して 送信 をクリックすると結果を確認することができます。
デモ動画のようにやりたい内容をチャットから指定して動かして、複数台の Raspberry Pi 上で建築をして子供に自慢しましょう!
まとめ
今回の記事を通して、以下の内容について学ぶことができたかと思います。
- 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 おじさんです。ここ最近の趣味は新しいバイクを手に入れたので、カスタムしたりツーリングに行ったりすることです。