1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Strands Agents と Amazon Bedrock AgentCore の MCP サーバーを使って AI エージェントをデプロイ(TypeScript)

Last updated at Posted at 2025-12-05

AWS reinvent 2025 での発表内容

機能 ステータス 概要
TypeScriptサポート プレビュー Python以外の選択肢が追加
エッジデバイスサポート GA ローカルモデルで小型デバイス対応
Steering 実験的 エージェントの動作を柔軟に誘導
Evaluations プレビュー エージェントの品質検証・測定

今回は、TypeScriptがサポートされたとのことで、やってみたいと思います。

ただし、皆様凄い方が既に試されているようですので、Strands Agents と Amazon Bedrock AgentCore は MCP サーバーに任せて実装させてみたいと思います。

Amazon Bedrock AgentCore の MCP サーバーがあるのは知っていましたが、Strands Agents の MCP サーバーがあるのは↓ではじめて知りました。

スクリーンショット 2025-12-04 19.22.04.png


MCP サーバーのセットアップ

3 つ の MCP サーバーを、ClaudeCode にセットアップしておきます。

※ AWS Knowledge MCP サーバーは AWS 内のドキュメントを検索してくれるため、念のため入れております。

.mcp.json
.mcp.json
{
  "mcpServers": {
    "strands-agents": {
      "command": "uvx",
      "args": ["strands-agents-mcp-server"],
      "env": {
        "FASTMCP_LOG_LEVEL": "DEBUG"
      },
      "disabled": false,
      "autoApprove": ["search_docs", "fetch_doc"]
    },
    "bedrock-agentcore-mcp-server": {
      "command": "uvx",
      "args": ["awslabs.amazon-bedrock-agentcore-mcp-server@latest"],
      "env": {
        "FASTMCP_LOG_LEVEL": "DEBUG"
      },
      "disabled": false,
      "autoApprove": []
    },
    "aws-knowledge-mcp-server": {
      "url": "https://knowledge-mcp.global.api.aws",
      "type": "http",
      "disabled": false
    }   
  }
}

AI エージェントの作成

次のプロンプトを投げつけ、Strands Agents で AI エージェントを作成させてみます。

プロンプト
積極的にMCPサーバーを活用して、AI エージェントを作成してください。

- エージェント: AWS ReInvent 2025 の情報について教えてくれるエージェント
- フレームワーク:strands-agents
- 言語:typescript
- ツール: [aws-knowledge-mcp-server](https://github.com/awslabs/mcp/tree/main/src/aws-knowledge-mcp-server)

Strands Agents MCP サーバーのツールを呼び出して作成してくれているようです。
スクリーンショット 2025-12-04 19.40.57.png

一応こんな感じでエージェントを作成してくれました。ちなみに、モデルは先日発表になった、Amazon Nova 2 Lite(us.amazon.nova-2-lite-v1:0)を使ってみてます。

agent.ts
agent.ts
import { Agent, McpClient, BedrockModel, tool } from '@strands-agents/sdk';
import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.js';
import { z } from 'zod';

// カスタムツール: ReInvent 2025 セッション推奨
const sessionRecommender = tool({
  name: 'recommend_sessions',
  description:
    'ユーザーの興味に基づいてAWS re:Invent 2025のセッションを推奨します。',
  inputSchema: z.object({
    interests: z
      .array(z.string())
      .describe('ユーザーの興味のあるトピック(例: AI, セキュリティ, データベース)'),
    experience_level: z
      .enum(['beginner', 'intermediate', 'advanced'])
      .describe('ユーザーの経験レベル')
      .optional(),
  }),
  callback: (input) => {
    const { interests, experience_level = 'intermediate' } = input;

    // 推奨セッションのマッピング
    const recommendations: Record<string, string[]> = {
      ai: [
        'BIZ221 - Agentic AIでカスタマーエクスペリエンスを革新',
        'SEC123 - AIワークロードのセキュリティ',
        'CMP456 - Amazon Bedrockを使用したC#と.NETでのAgentic AIアプリケーション構築',
      ],
      security: [
        'SEC301 - AWS AIサービスを使用したアクティブディフェンス戦略',
        'SEC402 - 高度なAWSネットワークセキュリティ',
        'SEC215 - OWASP、MAESTRO、実践的防御戦略',
      ],
      networking: [
        'NET101 - AWS Networking Fundamentals: 接続、保護、スケール',
        'NET302 - CloudFront、WAF、Shieldでのエッジの状態',
        'NET401 - Amazon CloudFrontでの大規模ストリーミング',
      ],
      database: [
        'DAT201 - AWSでのフルスタックSQL Server最適化',
        'DAT305 - Agentic AIでのSQL Server最適化の加速',
      ],
      partner: [
        'PRT101 - パートナー成長戦略 - AWS Partner Network',
        'PRT202 - AWS Marketplaceでの販売と調達ソリューション',
      ],
    };

    let result = `\n## 📚 あなたへの推奨セッション(${experience_level}レベル)\n\n`;

    let foundRecommendations = false;
    for (const interest of interests.map((i) => i.toLowerCase())) {
      if (recommendations[interest]) {
        foundRecommendations = true;
        result += `### 🎯 ${interest.toUpperCase()}関連セッション\n\n`;
        recommendations[interest].forEach((session) => {
          result += `- ${session}\n`;
        });
        result += '\n';
      }
    }

    if (!foundRecommendations) {
      result += `指定された興味に完全に一致するセッションは見つかりませんでしたが、AWS re:Invent 2025には2,000以上のセッションがあります。\n`;
      result += `公式のre:Inventカタログで「${interests.join(', ')}」を検索することをお勧めします。\n`;
    }

    return result;
  },
});

// メインのエージェント作成関数
export function createReInventAgent() {
  // AWS Knowledge MCP Serverへの接続を設定
  const awsKnowledgeClient = new McpClient({
    applicationName: 'ReInvent 2025 Agent',
    applicationVersion: '1.0.0',
    transport: new StreamableHTTPClientTransport(
      new URL('https://knowledge-mcp.global.api.aws')
    ) as Transport,
  });

  // Amazon Nova Liteモデルを設定
  const novaLiteModel = new BedrockModel({
    modelId: 'us.amazon.nova-2-lite-v1:0',
    region: 'us-west-2',
  });

  // エージェントを作成
  const agent = new Agent({
    model: novaLiteModel,
    tools: [awsKnowledgeClient, sessionRecommender],
    systemPrompt: `あなたはAWS re:Invent 2025の専門アシスタントです。ユーザーがAWS re:Invent 2025に関する情報を見つけるのを支援することが役割です。以下の情報を提供できます:

- セッションのスケジュールと説明
- キーノートとイノベーショントーク
- ワークショップとハンズオンラボ
- パートナー向けイベントとネットワーキングの機会
- 新しいAWSサービスの発表
- セキュリティ、ネットワーキング、AI/MLセッション
- 会場情報とロジスティクス

情報を検索する際は:
- 発表や新機能については、aws___search_documentationツールでtopic 'current_awareness'を使用してください
- ユーザーが特定のトピックに興味を示したり、セッション推奨を求めた場合は、recommend_sessionsツールを使用してください

常にAWS公式ドキュメントに基づいた正確で役立つ情報を提供してください。
熱意を持って親切に対応し、分かりやすく読みやすい形式で回答をフォーマットしてください。
日本語で回答してください。`,
  });

  return agent;
}

// CLIから実行される場合のメイン関数
async function main() {
  console.log('🚀 AWS ReInvent 2025 Agent starting...\n');
  console.log('🔌 Connecting to AWS Knowledge MCP Server...');
  console.log('🤖 Using Amazon Nova Lite model...\n');

  const agent = createReInventAgent();

  console.log('✅ Agent ready!\n');
  console.log('=' .repeat(70));
  console.log('🎯 AWS ReInvent 2025 Information Agent');
  console.log('=' .repeat(70));
  console.log('\n');

  // デモクエリ
  const query = 'AWS ReInvent 2025について教えてください。いつ、どこで開催されますか?';
  console.log(`💬 Question: ${query}\n`);

  const result = await agent.invoke(query);

  console.log('\n' + '='.repeat(70));
  console.log('✨ Response:');
  console.log('='.repeat(70));
  const firstContent = result.lastMessage.content[0];
  if ('text' in firstContent) {
    console.log(firstContent.text);
  }
  console.log('\n');

  console.log('💡 他の質問例:');
  console.log('   - セキュリティに関するセッションを教えてください');
  console.log('   - AIとMLに関するセッションを推奨してください');
  console.log('   - パートナー向けのイベントはありますか?\n');
}

// このファイルが直接実行された場合のみmainを実行
if (import.meta.url === `file://${process.argv[1]}`) {
  main().catch((error) => {
    console.error('❌ Error:', error);
    process.exit(1);
  });
}

AI エージェントが作成できたら、依存関係をインストール、ビルドし、ローカルで起動しテストしておきます。

npm install
npm run build
npm start

別のターミナルからテスト用のスクリプトを実行します。

./test.sh
./test.sh
#!/bin/bash

# メッセージ(コマンドライン引数またはデフォルト)
MESSAGE="${1:-AWS ReInvent 2025について教えてください}"

echo "🧪 Testing local agent..."
echo "   Message: \"${MESSAGE}\""
echo ""

# エージェントを呼び出してレスポンスを整形
RESPONSE=$(echo "{\"prompt\": \"${MESSAGE}\"}" | \
  curl -X POST http://localhost:8080/invocations \
  -H "Content-Type: application/octet-stream" \
  --data-binary @- -s)

# jqが利用可能な場合は整形、そうでない場合はそのまま表示
if command -v jq &> /dev/null; then
  echo "💬 Agent Response:"
  echo "======================================================================"
  echo "$RESPONSE" | jq -r '.response.message'
  echo "======================================================================"
else
  # jqがない場合は、Pythonで整形
  echo "💬 Agent Response:"
  echo "======================================================================"
  echo "$RESPONSE" | python3 -c "import sys, json; print(json.load(sys.stdin)['response']['message'])"
  echo "======================================================================"
fi

echo ""
echo "✅ Test complete!"

./test.sh "AWS ReInvent 2025で発表されたAI関連のアップデート情報を教えてください 。"

スクリーンショット 2025-12-06 2.25.43.png
スクリーンショット 2025-12-06 2.25.54.png

Nova 2 Lite ひょっとして良くなっている?

Amazon Bedrock AgentCore にデプロイ

次のプロンプトを投げつけ、Amazon Bedrock AgentCore に AI エージェントをデプロイさせてみます。

プロンプト
積極的に MCP サーバーを活用して、Amazon Bedrock AgentCore にデプロイしてください。

Amazon Bedrock AgentCore MCP サーバーのツールを呼び出して作成してくれているようです。

スクリーンショット 2025-12-04 20.27.02.png

おそらく、Bedrock AgentCore Starter Toolkit が python のみのためか、CLI で実行するように指示されたので DEPLOMENT.md の指示通り実行していきます。以下 DEPLOMENT.md の抜粋です。

DEPLOMENT.md
DEPLOMENT.md
## ステップ 3: IAMロールの作成

./create-iam-role.sh

### 出力されたRole ARNを保存してください。例:arn:aws:iam::123456789012:role/BedrockAgentCoreRuntimeRole

## ステップ 4: 環境変数の設定

### AWSアカウントIDを取得
export ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text)

### リージョンを設定
export AWS_REGION=us-west-2

### IAMロールARNを取得
export ROLE_ARN=$(aws iam get-role \
  --role-name BedrockAgentCoreRuntimeRole \
  --query 'Role.Arn' \
  --output text)

### ECRリポジトリ名を設定
export ECR_REPO=reinvent-2025-agent

## ステップ 5: ECRリポジトリの作成

aws ecr create-repository \
  --repository-name ${ECR_REPO} \
  --region ${AWS_REGION}

## ステップ 6: Dockerイメージのビルドとプッシュ

### ECRにログイン
aws ecr get-login-password --region ${AWS_REGION} | \
  docker login --username AWS --password-stdin \
  ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

### イメージをビルド
docker build -t ${ECR_REPO} .

### タグ付け
docker tag ${ECR_REPO}:latest \
  ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO}:latest

### プッシュ
docker push ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO}:latest

## ステップ 7: AgentCore Runtimeの作成

aws bedrock-agentcore-control create-agent-runtime \
  --agent-runtime-name reinvent_2025_agent \
  --agent-runtime-artifact containerConfiguration={containerUri=${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/${ECR_REPO}:latest} \
  --role-arn ${ROLE_ARN} \
  --network-configuration networkMode=PUBLIC \
  --protocol-configuration serverProtocol=HTTP \
  --region ${AWS_REGION}

出力されたRuntime IDを保存してください。例:reinvent-2025-agent-abc123def456

## ステップ 8: デプロイの確認

### ステータスが `READY` になるまで待ちます。
aws bedrock-agentcore-control get-agent-runtime \
  --agent-runtime-id reinvent_2025_agent-wLl9oO6R0o \
  --region ${AWS_REGION} \
  --query 'status' \
  --output text
create-iam-role.sh
create-iam-role.sh
#!/bin/bash

# This script creates an IAM role for Amazon Bedrock AgentCore Runtime

set -e

ROLE_NAME="BedrockAgentCoreRuntimeRole"
POLICY_NAME="BedrockAgentCoreRuntimePolicy"

echo "Creating IAM role: ${ROLE_NAME}"

# Create trust policy document
TRUST_POLICY=$(cat <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "bedrock-agentcore-runtime.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
)

# Create the IAM role
aws iam create-role \
  --role-name ${ROLE_NAME} \
  --assume-role-policy-document "${TRUST_POLICY}" \
  --description "Role for Bedrock AgentCore Runtime" \
  || echo "Role may already exist, continuing..."

# Create permissions policy document
PERMISSIONS_POLICY=$(cat <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "bedrock:InvokeModel",
        "bedrock:InvokeModelWithResponseStream"
      ],
      "Resource": "*"
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:log-group:/aws/bedrock-agentcore/*"
    }
  ]
}
EOF
)

# Create and attach the policy
aws iam put-role-policy \
  --role-name ${ROLE_NAME} \
  --policy-name ${POLICY_NAME} \
  --policy-document "${PERMISSIONS_POLICY}"

echo "✅ IAM role created successfully!"

# Get and display the role ARN
ROLE_ARN=$(aws iam get-role --role-name ${ROLE_NAME} --query 'Role.Arn' --output text)
echo ""
echo "📋 Role ARN: ${ROLE_ARN}"
echo ""
echo "💡 Save this ARN for deployment!"
echo "   You can also retrieve it later with:"
echo "   aws iam get-role --role-name ${ROLE_NAME} --query 'Role.Arn' --output text"

では、テスト用のクライアントから実行してみます。(これは MCP サーバーではなく普通に作成しています。)

client.ts
client.ts
import { BedrockAgentCoreClient, InvokeAgentRuntimeCommand } from "@aws-sdk/client-bedrock-agentcore";

// コマンドライン引数からメッセージを取得、または デフォルトメッセージを使用
const inputText = process.argv[2] || "AWS ReInvent 2025のキーノートについて教えてください";

console.log(`🚀 Testing deployed agent...`);
console.log(`   Message: "${inputText}"\n`);

const client = new BedrockAgentCoreClient({ region: "us-west-2" });

// ランダムなセッションIDを生成(33文字以上)
const sessionId = `test-session-${Date.now()}-${Math.random().toString(36).substring(2)}`;

const input = {
  runtimeSessionId: sessionId,
  agentRuntimeArn: "arn:aws:bedrock-agentcore:us-west-2:123456789012:runtime/reinvent_2025_agent-wLl9oO6R0o",
  qualifier: "DEFAULT",
  payload: new TextEncoder().encode(JSON.stringify({ prompt: inputText })),
};

const command = new InvokeAgentRuntimeCommand(input);

try {
  const response = await client.send(command);

  // レスポンス全体の情報を表示
  console.log('📊 Response Metadata:');
  console.log(`   Session ID: ${sessionId}`);
  console.log(`   Request ID: ${response.$metadata.requestId}`);
  console.log(`   HTTP Status: ${response.$metadata.httpStatusCode}\n`);

  // ストリーミングレスポンスをパース
  const textResponse = await response.response?.transformToString();

  if (textResponse) {
    try {
      const parsedResponse = JSON.parse(textResponse);

      // レスポンスタイプとステータスを表示
      console.log('📝 Response Details:');
      console.log(`   Type: ${parsedResponse.response?.type || 'unknown'}`);
      console.log(`   Stop Reason: ${parsedResponse.response?.stopReason || 'unknown'}\n`);

      // メッセージ内容をフォーマットして表示
      if (parsedResponse.response?.message) {
        console.log('💬 Agent Response:');
        console.log('='.repeat(70));
        console.log(parsedResponse.response.message);
        console.log('='.repeat(70));
      }

      // ツール使用の情報があれば表示
      if (parsedResponse.trace) {
        console.log('\n🔧 Tool Usage Trace:');
        console.log(JSON.stringify(parsedResponse.trace, null, 2));
      }

      // デバッグ用: 完全なレスポンスを表示(--verboseフラグがある場合)
      if (process.argv.includes('--verbose')) {
        console.log('\n🔍 Full Response (Verbose):');
        console.log(JSON.stringify(parsedResponse, null, 2));
      }

    } catch (parseError) {
      console.log('⚠️  Could not parse response as JSON, showing raw output:');
      console.log(textResponse);
    }
  } else {
    console.log('❌ No response received from agent');
  }

  console.log('\n✅ Test complete!');
} catch (error) {
  console.error('❌ Error:', error);
  process.exit(1);
}
# 環境変数を設定
export RUNTIME_ID=reinvent_2025_agent-wLl9oO6R0o
export AWS_REGION=us-west-2

npx tsx client.ts "AWS Re Invent 2025 の AI の最新の情報について教えてください。"

スクリーンショット 2025-12-06 1.45.56.png
スクリーンショット 2025-12-06 1.46.16.png

一応 Amazon Bedrock のモデル呼び出しの CloudWatch ログから AWS Knowledge MCP サーバーが呼び出されているか確認しておきます。以下の通り、aws___search__documation が実行されていることが確認できます。
スクリーンショット 2025-12-06 1.39.13.png

document-skills(pptx)

最後におまけとして、冒頭にも紹介した図にある通り、PowerPoint にして資料化してみたいと思います。

セットアップは基本以下の GitHub の説明にあるとおりプラグインとしてインストールし、Claude Code を一度閉じて、再起動するだけです。

では、document-skills を使うようにして、PowerPoint で資料を作成してもらうよう指示してみます。

document-skills を使って PowerPoint で資料にして

以下の通り document-skills を使ってくれているようです。
スクリーンショット 2025-12-06 2.58.52.png

ただし、途中エラーになること多く時間がかかりすぎていたので、2 スライドぐらいまでで一ったん止めました。。。

うーん、確かに作成はしてくれますが思ったほどの感じではない印象です。
スクリーンショット 2025-12-06 3.17.54.png
スクリーンショット 2025-12-06 3.18.03.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?