CDKで始めるLambda MCP
TL;DR
AWS CDKを使ってMCP(Model Context Protocol)サーバーをLambdaにデプロイし、CursorのAIエージェントから独自のツールを呼び出せるようにする方法を解説します。
簡単な数値計算ツールを例に、一から環境構築からクリーンアップまでを説明します。
はじめに
今回は、AWS Lambda上でMCPサーバーを動かし、CursorのAIエージェントから利用する方法を実装していきます。
前提条件
以下の環境が整っていることを確認してください:
- AWS CLI設定済み: AWSアカウントの設定とクレデンシャルの設定
- Node.js: CDKの実行に必要
- Python 3.12: Lambdaのランタイム
- AWS CDK: Infrastructure as Codeツール
CDKの詳細なセットアップはAWS CDK公式ガイドを参照してください。
プロジェクト構成
今回作成するプロジェクトの構成は以下の通りです:
mcp-lambda-project/
├── lambda/ # MCPサーバーのPythonコード
│ ├── main.py
│ └── requirements.txt
└── infra/ # CDKのインフラコード
├── bin/
├── lib/
└── package.json
MCPサーバーの準備
まず、プロジェクトのルートディレクトリを作成し、Lambdaのコードを準備します。
mkdir mcp-lambda-project
cd mcp-lambda-project
mkdir lambda
cd lambda
依存関係の定義
まず、Pythonの依存関係を定義します。
touch requirements.txt
requirements.txtに以下を追加:
awslabs.mcp-lambda-handler
MCPサーバーのコード作成
main.pyを作成し、以下のコードを記述します:
from awslabs.mcp_lambda_handler import MCPLambdaHandler
# MCPハンドラーのインスタンスを作成
mcp = MCPLambdaHandler(name="mcp-lambda-server", version="1.0.0")
@mcp.tool()
def add_two_numbers(a: int, b: int) -> int:
"""Add two numbers together."""
return a + b
def lambda_handler(event, context):
"""AWS Lambda handler function."""
return mcp.handle_request(event, context)
このコードの説明:
-
MCPLambdaHandler: AWS Lambdaで動作するMCPサーバーのハンドラー -
@mcp.tool(): デコレータを使ってAIエージェントが利用できるツールを定義 -
add_two_numbers: 2つの数値を足し算する簡単なツール関数 -
lambda_handler: LambdaのエントリーポイントでMCPリクエストを処理
インフラの準備
次に、CDKを使ってAWSのインフラストラクチャを定義します。
cd .. # プロジェクトルートに戻る
mkdir infra
cd infra
npx cdk init app --language=typescript
CDKスタックの定義
infra/lib/infra-stack.tsを以下の内容に置き換えます:
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as lambda from 'aws-cdk-lib/aws-lambda';
export class InfraStack extends cdk.Stack {
constructor(scope: Construct, id: string, props?: cdk.StackProps) {
super(scope, id, props);
// Lambda関数の定義
const func = new lambda.Function(this, 'McpLambdaFunction', {
runtime: lambda.Runtime.PYTHON_3_12,
handler: 'main.lambda_handler',
code: lambda.Code.fromAsset('../lambda'),
architecture: lambda.Architecture.ARM_64,
timeout: cdk.Duration.seconds(10),
description: 'MCP Lambda server function exposed via Function URL',
});
// Function URLの作成(認証なしでパブリックアクセス可能)
const functionUrl = func.addFunctionUrl({
authType: lambda.FunctionUrlAuthType.NONE,
});
// デプロイ後にURLを出力
new cdk.CfnOutput(this, 'McpLambdaFunctionUrl', {
value: functionUrl.url,
description: 'Public Function URL for the MCP Lambda function',
});
}
}
このCDKスタックの構成要素:
- Lambda関数: Python 3.12ランタイムでMCPサーバーを実行
- Function URL: HTTPSエンドポイントを提供(認証なし)
- ARM64アーキテクチャ: コスト効率とパフォーマンスの最適化
- 10秒タイムアウト: 短時間での応答を前提とした設定
- 出力: デプロイ後にFunction URLを表示
デプロイの実行
CDKスタックをAWSにデプロイします:
npx cdk deploy
デプロイ時に以下のような確認画面が表示されます:
IAM Statement Changes
┌───┬──────────────────────────────────────┬────────┬──────────────────────────┬──────────────────────────────┬───────────┐
│ │ Resource │ Effect │ Action │ Principal │ Condition │
├───┼──────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤
│ + │ ${McpLambdaFunction.Arn} │ Allow │ lambda:InvokeFunctionUrl │ * │ │
├───┼──────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤
│ + │ ${McpLambdaFunction/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │
└───┴──────────────────────────────────────┴────────┴──────────────────────────┴──────────────────────────────┴───────────┘
IAM Policy Changes
┌───┬──────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐
│ │ Resource │ Managed Policy ARN │
├───┼──────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤
│ + │ ${McpLambdaFunction/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │
└───┴──────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘
Do you wish to deploy these changes (y/n)? y
InfraStack: deploying... [1/1]
InfraStack: creating CloudFormation changeset...
✅ InfraStack
✨ Deployment time: 48.47s
Outputs:
InfraStack.McpLambdaFunctionUrl = https://xxxxxxx.lambda-url.ap-northeast-1.on.aws/
...
yを入力してデプロイを実行すると、数十秒後にデプロイが完了し、InfraStack.McpLambdaFunctionUrlとして表示されるURLが、今回作成したMCPサーバーのエンドポイントになります。
CursorでMCPサーバーを設定
作成したMCPサーバーをCursorのAIエージェントから利用できるように設定します。
MCP設定の開き方
- Cursorで
Cmd+Shift+P(Windowsの場合はCtrl+Shift+P)を押す -
Open MCP Settingsを選択 -
New MCP Serverをクリック
設定ファイルの編集
mcp.jsonが開かれるので、以下の設定を追加します:
{
"mcpServers": {
"aws-mcp-lambda": {
"type": "streamable-http",
"url": "https://xxxxxxx.lambda-url.ap-northeast-1.on.aws/" // デプロイ時に表示されたURLに置き換え
}
}
}
接続状況の確認
設定後、Cursorの画面下部にMCP接続インジケータが表示されます。インジケータが赤色になることがありますが、ログを確認するとツールは正常に認識されています。

2025-08-11 16:34:49.686 [error] Client error for command Streamable HTTP error: Failed to open SSE stream: Bad Request
2025-08-11 16:34:49.686 [error] Client error for command Streamable HTTP error: Failed to open SSE stream: Bad Request
2025-08-11 16:34:49.704 [info] Found 1 tools and 0 prompts
2025-08-11 23:09:39.219 [info] Handling CreateClient action
2025-08-11 23:09:39.222 [info] Connected to streamableHttp server, fetching offerings
2025-08-11 23:09:39.222 [info] Connected to streamableHttp server, fetching offerings
Found 1 tools and 0 promptsの表示で、1つのツールが認識されていることが確認できます。
動作テスト
CursorのAIチャットで実際にツールが使えるかテストしてみましょう:

59+21というリクエストに対して、作成したMCPツール(addTwoNumbers)が呼び出されて結果が返されます。
正常にMCPサーバーとの連携ができていることが確認できました。
トラブルシューティング:赤いインジケータについて
現象
MCP設定後、Cursorの画面下部のインジケータが赤色になることがあります。同様の現象について、Cursorフォーラムでも報告されています。
原因の詳細
- Cursor の streamable-http クライアントは接続時にまず SSE(Server-Sent Events) を試す仕様。
- AWS Lambda(Pythonランタイム + Function URL + BUFFERED) は SSE 非対応。
- そのため初回の SSE 接続が 400 Bad Request になり、
Cursor ログにFailed to open SSE stream: Bad Requestが出る。 - その後 Cursor は通常 HTTP にフォールバックし、リクエストは成功する。
結論
この現象は特に問題はない:
- MCP のツール実行自体は正常に動作
- ログ上の SSE エラーは無害な仕様上のノイズ
- 実際の機能に影響はなし
解決策(任意)
もしエラーログを完全に消したい場合は、以下のいずれかを検討してください:
- Lambda のランタイムをNode.jsに変更し、
InvokeMode.RESPONSE_STREAMを使用
ただし、現状でも十分に動作するため、特に対応は不要。
環境のクリーンアップ
実験が完了したら、作成したAWSリソースを削除しましょう。
リソース削除ポリシーの設定
まず、infra/bin/infra.tsを開いて、リソースの強制削除を許可する設定を追加します:
import * as cdk from 'aws-cdk-lib';
import { InfraStack } from '../lib/infra-stack';
const app = new cdk.App();
new InfraStack(app, 'InfraStack', {});
// 全リソースの強制削除を許可
cdk.RemovalPolicies.of(app).destroy();
最終行にcdk.RemovalPolicies.of(app).destroy();を追加します。これにより、CloudWatchログなどの永続化リソースも含めて、全てのリソースを強制的に削除できるようになります。
スタックの削除
設定を変更したら、以下のコマンドでスタックを削除します:
npx cdk destroy
確認プロンプトでyを入力すると、作成した全てのAWSリソースが削除されます。
最後に
本記事では、AWS CDKを使ってLambda上でMCPサーバーを構築し、CursorのAIエージェントから利用する方法を実践的に学びました。
今回実現したこと
- MCPサーバーの作成: Pythonで簡単な計算ツールを実装
- AWS Lambdaへのデプロイ: CDKを使った自動化されたインフラ構築
- Cursorとの連携: AIエージェントからMCPツールの呼び出し
この基盤を使ってデータベース操作、外部API連携、ファイル処理などの高度なツールを開発できます。Lambdaの無料枠(月100万リクエスト)内であれば、ほぼ無料でAIエージェントの機能を大幅に拡張可能です。
Discussion