Android15 タブレット 8インチ 90Hzの高リフレッシュレート、TECLAST P50 Mini タブレット 8.7インチ wi-fiモデル、12GB+128GB+1TB TF拡張、8コア T7200 CPU、Widevine L1 Netflix対応+GMS+5G WIFI+5000mAh+BT5.0+GPS+OTG+無線投影+顔認識、フルメタルボディ
¥15,900 (2025年4月25日 13:05 GMT +09:00 時点 - 詳細はこちら価格および発送可能時期は表示された日付/時刻の時点のものであり、変更される場合があります。本商品の購入においては、購入の時点で当該の Amazon サイトに表示されている価格および発送可能時期の情報が適用されます。)
community.awsに投稿したこちらの記事の日本語訳です。
モデルコンテキストプロトコル(MCP)は、大規模言語モデル(LLM)アプリケーションが様々なデータソースやツールと接続できるようにする標準化されたプロトコルとして登場しました。MCP を活用することで、LLM アプリケーション開発者はデータ統合の実装に時間を費やすのではなく、ビジネスロジックとユーザーエクスペリエンスの向上に集中できます。
この記事では、AWS Lambda 上に MCP サーバーを実装するための実践的なガイドを提供します。「Streamable HTTP(セッションレス)」通信方式を使用して MCP サーバーを Lambda 関数として実装し、AWS Lambda Web Adapter を使用して効率的にデプロイすることに焦点を当てます。この組み合わせにより、スケーラブルでコスト効率の高い MCP サーバーを構築できます。
MCP の基本と AWS Lambda との互換性
MCP の役割と価値
モデルコンテキストプロトコル(MCP)は、LLM アプリケーションがデータソースやツールと対話するための共通言語として機能します。MCP は AI モデル向けの「USB-C」と考えることができます – USB-C が様々なデバイスと周辺機器を接続するための標準化された方法を提供するように、MCP は AI モデルと異なるデータソースやツールを接続するための標準化された方法を提供します。
(MCP Client)”]n S1[“MCP Server A”]n S2[“MCP Server B”]n S3[“MCP Server C”]n Host |”MCP Protocol”| S1n Host |”MCP Protocol”| S2n Host |”MCP Protocol”| S3n S1 D1[(“ローカル
データソースA”)]n S2 D2[(“ローカル
データソースB”)]n endn subgraph “インターネット”n S3 |”Web API”| D3[(“リモート
サービスC”)]n end”,”key”:”e2c080a92c90bc46c62054e0a045e154″}”>
MCP を使用する主な利点は以下の通りです:
- 統合の簡素化:事前構築された統合機能を活用して開発時間を短縮
- ベンダーロックインの回避:LLM プロバイダー間の切り替えが容易
- セキュリティの強化:データアクセスに関する標準化されたベストプラクティス
AWS Lambda が最適な理由
AWS Lambda は以下の理由から MCP サーバーの実装に特に適しています:
- スケーラビリティ:リクエスト量に基づいて自動的にスケールし、トラフィックの変動に対応
- コスト効率:使用した分だけ支払うモデルにより、低トラフィック期間のコストを抑制
- 簡単な管理:サーバーのプロビジョニングや管理が不要で、開発者はコードに集中可能
- シンプルな統合:API Gateway や他の AWS サービスとの簡単な統合
MCP 通信方式と Lambda に最適な選択
MCP は現在、クライアント-サーバー通信のための複数の標準トランスポートメカニズムを定義しています。AWS Lambda 実装では、「Streamable HTTP(セッションレス)」が特に最適です。
Streamable HTTP(セッションレス)の利点
Lambda 関数は基本的にステートレスであり、各呼び出しは独立しています。セッションレスの Streamable HTTP 通信方式は、以下の理由から Lambda に理想的です:
- ステートレス設計:Lambda の実行モデルと完全に一致
- 水平スケーリング:状態を共有する必要がなく、Lambda のスケーリング特性を最大化
- コールドスタートの最小化:セッション状態の復元が不要
- シンプルな実装:複雑なセッション管理ロジックが不要
Lambda Web Adapter の活用
AWS Lambda Web Adapter は、Express や Flask などの一般的な Web フレームワークで構築されたアプリケーションを Lambda 上で簡単に実行できるようにするツールです。MCP サーバーの実装において、Lambda Web Adapter はいくつかの重要な役割を果たします:
Lambda Web Adapter の利点
- 既存の Web フレームワークをそのまま使用:Express などの馴染みのあるフレームワークを修正なしで活用
- レスポンスストリーミングのサポート:MCP の Streamable HTTP 通信に必要なストリーミング機能をサポート
- シームレスな統合:Lambda Function URL や API Gateway との簡単な統合
- 最小限の変更:コードの変更を最小限に抑えて Lambda 上で実行
Lambda Function URL の活用
この実装では、API Gateway ではなく Lambda Function URL を使用してエンドポイントを公開します。Lambda Function URL にはいくつかの利点があります:
- シンプルな設定:API Gateway のセットアップなしで HTTP エンドポイントを簡単に作成
- レスポンスストリーミング:MCP の Streamable HTTP 通信に必要なストリーミング機能をネイティブにサポート
- 低レイテンシー:API Gateway を排除することによるレイテンシーの削減
- コスト効率:API Gateway のコストを削減
Function URL の RESPONSE_STREAM
モードは、MCP サーバーのような双方向通信を必要とするアプリケーションに特に効果的です。
実装手順
AWS Lambda 上に MCP サーバーを実装するための具体的な手順を見ていきましょう。
1. ローカル環境での MCP サーバーの実装
まず、ローカル環境で MCP サーバーを実装し、基本的な機能を確認します。
プロジェクトのセットアップ
mkdir mcp-local
cd mcp-local
npm init -y
npm install --save-dev typescript ts-node @types/node
npx tsc --init
npm install --save @modelcontextprotocol/sdk express
npm install --save-dev @types/express
サーバーの実装
src/server.ts
を作成します:
src/server.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
import express from "express";
import { z } from "zod";
// MCP サーバーを作成
const server = new McpServer({
name: "Example MCP Server",
version: "1.0.0"
});
// Express アプリケーションを作成
const app = express();
app.use(express.json());
// ツールを追加 - シンプルな計算機を実装
server.tool(
"calculate",
{ a: z.number(), b: z.number(), operation: z.enum(["add", "subtract", "multiply", "divide"]) },
async ({ a, b, operation }) => {
let result;
switch (operation) {
case "add": result = a + b; break;
case "subtract": result = a - b; break;
case "multiply": result = a * b; break;
case "divide": result = a / b; break;
}
return {
content: [{ type: "text", text: `結果: ${result}` }]
};
}
);
// Streamable HTTP トランスポート(セッションレス)を設定
const transport = new StreamableHTTPServerTransport({
sessionIdGenerator: undefined, // セッション管理を無効化
});
// ルートを設定
app.post('/mcp', async (req, res) => {
try {
await transport.handleRequest(req, res, req.body);
} catch (error) {
console.error('MCP リクエスト処理中のエラー:', error);
if (!res.headersSent) {
res.status(500).json({
jsonrpc: '2.0',
error: {
code: -32603,
message: '内部サーバーエラー',
},
id: null,
});
}
}
});
app.get('/mcp', async (req, res) => {
res.writeHead(405).end(JSON.stringify({
jsonrpc: "2.0",
error: {
code: -32000,
message: "メソッドは許可されていません。"
},
id: null
}));
});
app.delete('/mcp', async (req, res) => {
res.writeHead(405).end(JSON.stringify({
jsonrpc: "2.0",
error: {
code: -32000,
message: "メソッドは許可されていません。"
},
id: null
}));
});
// サーバーを起動
const PORT = process.env.PORT || 8080;
server.connect(transport).then(() => {
app.listen(PORT, () => {
console.log(`MCP サーバーがポート ${PORT} でリッスン中`);
});
}).catch(error => {
console.error('サーバーのセットアップに失敗しました:', error);
process.exit(1);
});
クライアントの実装
テスト用のクライアントを src/client.ts
として作成します:
src/client.ts
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
const serverUrl = process.env.MCP_SERVER_URL || "http://localhost:8080";
const transport = new StreamableHTTPClientTransport(new URL(serverUrl + "/mcp"));
const client = new Client(
{
name: "example-client",
version: "1.0.0"
}
);
async function main(): Promisevoid> {
await client.connect(transport);
// 利用可能なツールのリストを取得
const tools = await client.listTools();
console.log("利用可能なツール:", tools);
// calculate ツールを呼び出す
const toolResult = await client.callTool({
"name": "calculate",
"arguments": { "a": 1, "b": 2, "operation": "add" }
});
console.log("計算結果:", toolResult.content);
}
main().catch((error: unknown) => {
console.error('MCP クライアント実行中のエラー:', error);
process.exit(1);
});
ローカルテスト
サーバーを起動します:
npx ts-node src/server.ts
別のターミナルで、クライアントを実行します:
npx ts-node src/client.ts
すべてが正常に動作すれば、以下のような出力が表示されるはずです:
利用可能なツール: { tools: [ { name: 'calculate', inputSchema: [Object] } ] }
計算結果: [ { type: 'text', text: '結果: 3' } ]
2. AWS Lambda プロジェクトの設定
ローカルでの機能を確認した後、AWS Lambda 用のプロジェクトをセットアップしましょう。Lambda 関数のデプロイを簡素化するために AWS SAM(Serverless Application Model)を使用します。
SAM プロジェクトの作成
sam init --name mcp-lambda
--runtime nodejs22.x
--dependency-manager npm
--app-template hello-world-typescript
--no-interactive
# 不要なファイルを削除し、MCP 関数用のディレクトリを作成
rm -rf mcp-lambda/hello-world/
mkdir mcp-lambda/mcp-function
Lambda Web Adapter の設定
Lambda Web Adapter を設定します。まず、MCP サーバーを起動するシェルスクリプトを作成します:
mcp-function/run.sh
#!/bin/bash
node bundle.js
次に、Lambda Web Adapter を設定するために SAM テンプレートを修正します:
template.yaml
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
mcp-lambda
AWS Lambda 上の MCP サーバー実装
Globals:
Function:
Timeout: 60
Resources:
MCPStreamableFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: mcp-function/
Handler: run.sh
Runtime: nodejs22.x
MemorySize: 1024
Architectures:
- x86_64
Environment:
Variables:
AWS_LAMBDA_EXEC_WRAPPER: /opt/bootstrap
AWS_LWA_INVOKE_MODE: response_stream
RUST_LOG: info
PORT: 8080
Layers:
- !Sub arn:aws:lambda:${AWS::Region}:753240598075:layer:LambdaAdapterLayerX86:24
# Function URL を使用して HTTP エンドポイントを公開
# RESPONSE_STREAM モードはストリーミングレスポンスをサポート
FunctionUrlConfig:
AuthType: NONE
InvokeMode: RESPONSE_STREAM
Metadata:
BuildMethod: makefile
Outputs:
MCPStreamableFunctionUrl:
Description: "MCP Streamable HTTP 関数の Function URL"
Value: !GetAtt MCPStreamableFunctionUrl.FunctionUrl
3. Lambda 関数の実装
Lambda 関数として実行する MCP サーバーを実装します。実装は基本的にローカルバージョンと同じですが、Lambda 環境に合わせていくつかの調整を行います。
プロジェクトのセットアップ
cd mcp-lambda/mcp-function
npm init -y
npm install --save-dev typescript ts-node @types/node
npx tsc --init
npm install --save @modelcontextprotocol/sdk express
npm install --save-dev @types/express
サーバーの実装
mcp-function/src/server.ts
をローカルバージョンと同じ内容で作成します。
ビルド設定
Lambda 関数としてデプロイするには、TypeScript コードを JavaScript にコンパイルし、依存関係をバンドルする必要があります。これには esbuild を使用します:
npm install --save-dev esbuild
mcp-function/esbuild.js
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/server.js'],
bundle: true,
minify: true,
platform: 'node',
target: 'node22',
outfile: 'bundle.js',
external: ['aws-sdk', '@aws-sdk/*'], // AWS SDK は Lambda 環境に既に存在するため除外
metafile: true,
}).then(result => {
// バンドルサイズ情報を出力
const outputSize = Object.entries(result.metafile.outputs).reduce((acc, [file, data]) => {
return acc + data.bytes;
}, 0);
console.log(`バンドルサイズ: ${(outputSize / 1024 / 1024).toFixed(2)} MB`);
}).catch(() => process.exit(1));
mcp-function/Makefile
build-MCPStreamableFunction:
mkdir -p $(ARTIFACTS_DIR)
cp -r src run.sh package.json package-lock.json tsconfig.json esbuild.js $(ARTIFACTS_DIR)
cd $(ARTIFACTS_DIR) && npm ci && npx tsc && node esbuild.js
cd $(ARTIFACTS_DIR) && rm -rf src package.json package-lock.json tsconfig.json esbuild.js dist node_modules
chmod +x $(ARTIFACTS_DIR)/run.sh
4. デプロイとテスト
SAM を使用して Lambda 関数をビルドしデプロイします:
cd .. # SAM プロジェクトのルートディレクトリに移動
sam build
sam deploy --guided
デプロイが成功すると、Function URL エンドポイントが表示されます:
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Outputs
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
Key MCPStreamableFunctionUrl
Description MCP Streamable HTTP 関数の Function URL
Value https://xxxxxxxxxxxxxxxx.lambda-url.us-east-1.on.aws/
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
このエンドポイントは API Gateway を使用せずに直接 HTTP リクエストを受け付けることができる Lambda Function URL です。先ほど作成したクライアントから Lambda 上の MCP サーバーにアクセスするには、次のように実行します:
MCP_SERVER_URL=https://xxxxxxxxxxxxxxxx.lambda-url.us-east-1.on.aws npx ts-node src/client.ts
実装の洞察と最適化のヒント
Lambda Web Adapter の仕組み
Lambda Web Adapter は Lambda 関数と Web アプリケーションの間のブリッジとして機能します。その動作フローは以下の通りです:
- Lambda 関数が呼び出されると、Lambda Web Adapter が起動
- アダプターは Web アプリケーションの準備ができるのを待機(準備確認)
- アプリケーションの準備ができたら、アダプターは Lambda ランタイムを開始し、呼び出しを Web アプリケーションに転送
- Web アプリケーションからのレスポンスはアダプターによって Lambda レスポンス形式に変換
Function URL とストリーミングレスポンス
この実装では、Lambda Function URL の RESPONSE_STREAM
モードを使用しており、これには以下の利点があります:
- リアルタイム通信:ストリーミング形式でクライアントにデータを送信
- 長時間実行:最大 15 分間のレスポンスストリーミングをサポート
- アーキテクチャの簡素化:API Gateway を使用せずに HTTP エンドポイントを直接公開
このストリーミング機能は、MCP の Streamable HTTP 通信方式において重要な役割を果たします。
パフォーマンス最適化のヒント
Lambda 上で実行される MCP サーバーのパフォーマンスを最適化するためのヒントをいくつか紹介します:
-
コールドスタートの最小化
- 重要なワークロードにはプロビジョンドコンカレンシーを使用してコールドスタートを回避
- 依存関係を最小限に抑え、バンドルサイズを小さく保つ
-
メモリ設定の最適化
- CPU パワーとコストのバランスを取るために Lambda 関数のメモリ割り当てを調整
- 一般的に、MCP サーバーには少なくとも 1024MB のメモリを割り当てる
-
タイムアウト設定
- 潜在的に長時間実行されるリクエストに対応するために適切なタイムアウト値を設定
-
エラー処理の強化
- すべてのエラーケースを適切に処理し、クライアントに意味のあるエラーメッセージを返す
結論
この記事では、AWS Lambda 上にモデルコンテキストプロトコル(MCP)サーバーを実装する方法を示しました。Streamable HTTP(セッションレス)通信方式を使用して MCP サーバーを Lambda 関数として実装し、AWS Lambda Web Adapter と Lambda Function URL を使用してデプロイすることに焦点を当てました。
MCP と AWS Lambda の組み合わせには、いくつかの利点があります:
- スケーラビリティ:トラフィックに応じて自動的にスケール
- コスト効率:使用した分だけ支払い
- 簡単な管理:サーバーのプロビジョニングや管理が不要
- 高可用性:AWS インフラストラクチャの活用
- シンプルなエンドポイント公開:Lambda Function URL を使用して HTTP エンドポイントを直接公開
この実装アプローチにより、AI アプリケーション開発者はインフラストラクチャ管理ではなく、ビジネスロジックとユーザーエクスペリエンスの向上に集中できます。MCP の標準化されたインターフェースと AWS Lambda のサーバーレスアーキテクチャを組み合わせることで、LLM アプリケーションのための柔軟でスケーラブルな基盤を構築できます。