MCP サーバー インフラ・実装計画(v2)
概要
| 項目 | 内容 |
|---|---|
| ステータス | 🟡 設計中 |
| 親ドキュメント | 案件提案書 / アーキテクチャ全体像 |
| 関連設計 | 認証・テナンシ / ツール一覧 |
| AWS Account | 881980194724 |
| リージョン | ap-northeast-1(東京) |
本ドキュメントは、MCP サーバーの AWS 上でのホスティング構成・実装タスク分解・検収条件を確定する。既存 AWS インフラ(既存 Lambda 群と同じ運用パターン)に乗せる方針で、新規 EC2 / ALB / Redis などは追加しない。
1. 既存インフラの活用方針
1.1 流用するリソース
| 項目 | 既存リソース | MCP での扱い |
|---|---|---|
| VPC | 既存 VPC(vpc-...) | そのまま使用 |
| プライベートサブネット | subnet-095de9e00c1894a0c(h2t-private-1a) | Lambda Data Fetcher(VPC 内 Lambda)の配置先 |
| Lambda 実行ロール(参考) | 既存 Lambda_scraper / Scraper_Role | パターンを参考に新規 MCP 用ロールを発行 |
| Lambda SG | 既存 h2t-sg-lambda(sg-0ccad01d56a1b4327) | そのまま使用、Aurora との接続権限あり |
| RDS インバウンド | 既存 h2t-sg-rds が h2t-sg-lambda を許可済 | 変更不要 |
| Aurora MySQL(4 製品) | 既存(変更なし) | 読取のみアクセス |
| CloudWatch Logs | 既存ロググループ構成 | MCP 用ロググループを追加 |
cloudwatch-to-slack Lambda | 既存 Slack 通知 | MCP のアラート通知に流用 |
1.2 新規追加するリソース
| 項目 | 用途 |
|---|---|
| API Gateway HTTP API | MCP の HTTP エンドポイント |
| Lambda 関数(4 個) | Authorizer / Dispatcher / Data Fetcher / OAuth Endpoint |
| DynamoDB テーブル(6 個) | OAuth state / 監査ログ |
| Secrets Manager(5 個) | JWT 鍵 + 4 製品の DB 接続情報 |
| IAM ロール(2 個) | VPC 外 Lambda 用 / VPC 内 Lambda 用 |
| Route 53 レコード | カスタムドメイン(mcp.h2t-products.com 等、未確定) |
| ACM 証明書 | カスタムドメインの TLS |
2. AWS リソース構成
2.1 Lambda 関数
すべて Python 3.13 + zip パッケージ。既存 Lambda 群と同じパターン。
| # | 関数名 | 配置 | メモリ | タイムアウト | 役割 |
|---|---|---|---|---|---|
| 1 | mcp-authorizer | VPC 外 | 512 MB | 10 秒 | OAuth 2.1 access_token 検証、scope 確認 |
| 2 | mcp-dispatcher | VPC 外 | 1024 MB | 29 秒 | tool ルーティング、入力検証、Data Fetcher 呼び出し、監査ログ |
| 3 | mcp-oauth | VPC 外 | 512 MB | 10 秒 | OAuth エンドポイント(authorize / token / revoke / register / login) |
| 4 | mcp-data-fetcher | VPC 内 (h2t-private-1a) | 1024 MB | 25 秒 | Aurora への SQL クエリ実行、4 製品振り分け |
命名規約
既存 Lambda 群(fetch_search_ranking, sync_database, checkBatchStatus 等)の命名パターンに合わせ、すべて mcp- プレフィックス + ケバブケース。
Reserved concurrency
| 関数 | reserved concurrency | 理由 |
|---|---|---|
mcp-authorizer | 50 | 高頻度呼び出し想定(毎リクエスト) |
mcp-dispatcher | 30 | tool 呼び出しごとに 1 回 |
mcp-oauth | 10 | 認可フロー時のみ |
mcp-data-fetcher | 15 | Aurora 接続数制御の主役(後述) |
2.2 Aurora 接続数管理(RDS Proxy 無し戦略)
mcp-data-fetcher の reserved concurrency = 15 により、Aurora への同時接続数を最大 15 に制限。
| 設定 | 値 |
|---|---|
| Aurora インスタンスクラス | db.t3.medium(2 vCPU) |
Aurora max_connections | 約 90(db.t3.medium のデフォルト) |
| MCP 由来の最大接続数 | 15(mcp-data-fetcher reserved concurrency) |
| 既存 Laravel 等の接続余地 | 75 接続(90 - 15) |
→ MCP は Aurora の接続枠の 17% しか使わず、既存 Laravel アプリケーションへの影響なし。
接続が枯渇しそうになったら
将来的にリクエスト数が増えて 15 並列でも足りなくなったら、以下の順で対応:
mcp-data-fetcherの reserved concurrency を 30 に上げる(接続上限まで余裕がある場合)- それでも足りなければ RDS Proxy を導入(+$25.92/月、コードは接続先 endpoint の変更のみ)
- 究極は Aurora インスタンスクラスを上げる(db.t3.large → max_connections 約 180)
2.3 API Gateway HTTP API
| 項目 | 値 |
|---|---|
| API 名 | mcp-api |
| API タイプ | HTTP API(v2) |
| プロトコル | HTTPS |
| カスタムドメイン | mcp.h2t-products.com(仮、未確定) |
| Lambda Authorizer | mcp-authorizer を attach |
| CORS | クライアントは MCP 公式クライアントのみ想定、CORS は不要 |
ルート定義
| パス | メソッド | Lambda | Authorizer |
|---|---|---|---|
/mcp | POST | mcp-dispatcher | mcp-authorizer ✅ |
/oauth/authorize | GET | mcp-oauth | なし |
/oauth/login | POST | mcp-oauth | なし |
/oauth/authorize/consent | POST | mcp-oauth | なし(セッション Cookie 検証) |
/oauth/token | POST | mcp-oauth | なし |
/oauth/revoke | POST | mcp-oauth | なし |
/oauth/register | POST | mcp-oauth | なし |
/.well-known/oauth-authorization-server | GET | mcp-oauth | なし |
/.well-known/jwks.json | GET | mcp-oauth | なし |
/health | GET | mcp-dispatcher | なし |
2.4 DynamoDB テーブル
すべてオンデマンド課金、暗号化(at-rest)有効、TTL 有効。
| テーブル名 | 主キー | TTL 属性 | 用途 |
|---|---|---|---|
mcp-oauth-clients | client_id (PK) | なし | OAuth クライアント |
mcp-oauth-codes | code_hash (PK) | expires_at | 認可コード(60s) |
mcp-oauth-refresh-tokens | token_hash (PK), GSI: user_id_index | expires_at | リフレッシュトークン(30d) |
mcp-oauth-consents | user_id (PK), client_id (SK) | なし | ユーザー同意 |
mcp-jwt-revocations | jti (PK) | expires_at | JWT 失効リスト |
mcp-audit-logs | request_id (PK), GSI: user_id_created_at | expires_at (1y) | 監査ログ |
詳細スキーマは 認証・テナンシ設計 §9 を参照。
2.5 Secrets Manager
| Secret 名 | 内容 |
|---|---|
mcp/jwt-signing-key | RSA 秘密鍵(RS256)+ kid。90 日ごとローテーション |
mcp/db/gmac | GMAC Aurora 接続情報(host / user / password) |
mcp/db/gcor | GCOR Aurora 接続情報 |
mcp/db/pipit | PIPIT (KingMeo) Aurora 接続情報 |
mcp/db/kuchikomi_one | 口コミONE Aurora 接続情報 |
2.6 IAM ロール
mcp-lambda-role-vpc-out(VPC 外 Lambda 用)
mcp-authorizer, mcp-dispatcher, mcp-oauth の実行ロール。
ポリシー:
AWSLambdaBasicExecutionRole(CloudWatch Logs)- 以下のカスタムポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:UpdateItem",
"dynamodb:DeleteItem", "dynamodb:Query"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:881980194724:table/mcp-*"
},
{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": "arn:aws:secretsmanager:ap-northeast-1:881980194724:secret:mcp/jwt-signing-key*"
},
{
"Effect": "Allow",
"Action": ["lambda:InvokeFunction"],
"Resource": "arn:aws:lambda:ap-northeast-1:881980194724:function:mcp-data-fetcher"
}
]
}mcp-lambda-role-vpc-in(VPC 内 Lambda 用)
mcp-data-fetcher の実行ロール。
ポリシー:
AWSLambdaBasicExecutionRoleAWSLambdaVPCAccessExecutionRole(VPC 内配置に必須)- 以下のカスタムポリシー
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["secretsmanager:GetSecretValue"],
"Resource": "arn:aws:secretsmanager:ap-northeast-1:881980194724:secret:mcp/db/*"
}
]
}→ Aurora への接続は SG 経由で許可されているため、IAM 側で RDS 認可は不要。
2.7 既存リソースとの SG 関係
| SG | 変更内容 |
|---|---|
h2t-sg-lambda | 変更なし。既に Aurora への接続権限あり、mcp-data-fetcher はこの SG に所属 |
h2t-sg-rds | 変更なし。h2t-sg-lambda からのインバウンドが既に許可されている |
つまり、MCP のために新規 SG は作らない。既存の Lambda → Aurora 接続路をそのまま使う。
2.8 Route 53 / カスタムドメイン
| 項目 | 値 |
|---|---|
| ドメイン | mcp.h2t-products.com(仮、未確定) |
| ACM 証明書 | 同ドメインに対し新規発行 |
| API Gateway カスタムドメインマッピング | mcp-api API にマッピング |
ドメインは案件確定時に最終決定。
3. CloudWatch 設定
3.1 ロググループ
| ロググループ | 保持期間 |
|---|---|
/aws/lambda/mcp-authorizer | 30 日 |
/aws/lambda/mcp-dispatcher | 30 日 |
/aws/lambda/mcp-oauth | 30 日 |
/aws/lambda/mcp-data-fetcher | 30 日 |
/aws/apigateway/mcp-api | 30 日 |
3.2 アラーム
| メトリクス | 閾値 | 通知 |
|---|---|---|
mcp-dispatcher Errors | > 5 件 / 5 分 | cloudwatch-to-slack Lambda 経由で Slack |
mcp-data-fetcher Errors | > 5 件 / 5 分 | 同上 |
mcp-authorizer Errors | > 10 件 / 5 分 | 同上 |
| API Gateway 5XX 率 | > 1% / 5 分 | 同上 |
| Lambda 平均実行時間 | p95 > 3 秒 / 10 分 | 同上 |
| DynamoDB スロットリング | 発生時 | 同上 |
3.3 構造化ログ
Lambda は JSON 形式で構造化ログを出力:
{
"timestamp": "2026-06-22T12:34:56Z",
"level": "INFO",
"service": "mcp-dispatcher",
"request_id": "01HV...",
"user_id": 1435,
"product": "gmac",
"tool_name": "location.list",
"elapsed_ms": 123,
"message": "tool executed"
}4. デプロイ構成
4.1 リポジトリ構成(提案)
新規リポジトリ h2t/mcp-server を作成(既存 h2t/mappy / h2t/scraping と並列):
mcp-server/
├ src/
│ ├ authorizer/ # mcp-authorizer Lambda
│ ├ dispatcher/ # mcp-dispatcher Lambda
│ ├ oauth/ # mcp-oauth Lambda
│ ├ data_fetcher/ # mcp-data-fetcher Lambda
│ └ shared/ # 共通モジュール(DynamoDB クライアント等)
├ tests/
├ infra/
│ └ terraform/ # 任意:IaC 化する場合
├ scripts/
│ └ deploy.sh # Lambda zip 作成 + アップロードスクリプト
├ requirements.txt
└ README.md4.2 デプロイ方式
| 環境 | デプロイ方法 |
|---|---|
| 開発(dev) | ローカルから aws lambda update-function-code で zip アップロード |
| ステージング | GitLab CI 経由(要追加設定) |
| 本番 | GitLab CI 経由、手動承認ステップあり |
初回構築は手動構築、IaC 化は Phase 2 以降
Phase 1 は AWS マネジメントコンソールでクリック構築 + デプロイスクリプトで開始し、運用が安定したら Terraform / CDK 化を検討する。早期リリースを優先。
4.3 Lambda zip パッケージング
Python 3.13 + boto3 + 必要な依存(authlib / pydantic / mysql-connector-python など)を zip にまとめる。サイズ目安:
| 関数 | zip サイズ |
|---|---|
mcp-authorizer | 約 5 MB |
mcp-dispatcher | 約 8 MB |
mcp-oauth | 約 8 MB |
mcp-data-fetcher | 約 10 MB(mysql-connector 含む) |
すべて 50 MB(Lambda zip 制限)以下に収まる。Layer は使わず単一 zip で構成(既存 Lambda 群と同じパターン)。
5. 実装タスク分解(Phase 1)
工数は AI 前提(AIリテイク回数 × レビュー時間 0.5 日/回 = 人日)。
5.1 設計フェーズ
| # | タスク | AI リテイク | 工数 | 担当 |
|---|---|---|---|---|
| 1.1 | 案件提案書作成 | 2 回 | 1.0 | 設計者 |
| 1.2 | アーキテクチャ全体像 | 3 回 | 1.5 | 設計者 |
| 1.3 | 認証・テナンシ設計 | 3 回 | 1.5 | 設計者 |
| 1.4 | ツール一覧 | 2 回 | 1.0 | 設計者 |
| 1.5 | インフラ・実装計画 | 2 回 | 1.0 | 設計者 |
| 設計小計 | 6.0 |
設計フェーズの進捗
本ドキュメントを含む 5 本の設計書は AI による作成済み。設計者のレビュー完了で 3.0 人日に短縮できる見込み(リテイク 1〜2 回相当)。
5.2 製造フェーズ
| # | タスク | AI リテイク | 工数 | 担当 |
|---|---|---|---|---|
| 2.1 | リポジトリ初期化(ディレクトリ構造・依存設定) | 1 回 | 0.5 | 製造者 |
| 2.2 | mcp-authorizer 実装(JWT 検証 + scope チェック) | 3 回 | 1.5 | 製造者 |
| 2.3 | mcp-oauth 実装(authorize/token/refresh/register/login + JWT 発行) | 4 回 | 2.0 | 製造者 |
| 2.4 | mcp-dispatcher 実装(tool ルーティング + 入力検証 + 監査ログ) | 3 回 | 1.5 | 製造者 |
| 2.5 | mcp-data-fetcher 実装(Aurora 接続 + 4 製品振り分け + 4 tool) | 3 回 | 1.5 | 製造者 |
| 2.6 | DynamoDB テーブル作成 + Secrets Manager 設定 | 2 回 | 1.0 | 製造者 |
| 2.7 | API Gateway 設定 + Route53 + ACM | 2 回 | 1.0 | 製造者 |
| 2.8 | IAM ロール作成 + Lambda デプロイ | 2 回 | 1.0 | 製造者 |
| 2.9 | 接続テスト(Claude Desktop + ChatGPT) | 2 回 | 1.0 | 製造者 |
| 2.10 | CloudWatch アラーム設定 + Slack 通知 | 1 回 | 0.5 | 製造者 |
| 製造小計 | 11.5 |
5.3 全体合計
| フェーズ | 工数 |
|---|---|
| 設計 | 3.0(残)〜 6.0(既に書いた分含む) |
| 製造 | 11.5 |
| Phase 1 合計 | 約 14.5 〜 17.5 人日 |
提案書の「11.5 人日」との差異について
提案書では「Phase 1 合計 11.5 人日」と書いたが、本設計書では設計フェーズと製造フェーズを合算して 14.5〜17.5 人日を示している。
提案書の 11.5 人日は 設計者がすでに書き終えた設計書部分を除外した「これから発生する追加工数」を試算したもの。本設計書の 14.5〜17.5 人日は 設計フェーズも含む全体の累積工数。
実際の運用としては、本設計書のレビューが終われば設計フェーズの残り工数は 3.0 人日程度。残り全体(レビュー + 製造)= 約 14.5 人日が現実的な見立て。
6. デプロイ手順(Phase 1 初回)
6.1 基盤準備
- IAM ロール作成
mcp-lambda-role-vpc-out(VPC 外用)mcp-lambda-role-vpc-in(VPC 内用)
- Secrets Manager に格納
mcp/jwt-signing-key(RSA キーペア生成)mcp/db/gmac/gcor/pipit/kuchikomi_one
- DynamoDB テーブル 6 個作成
- すべてオンデマンドキャパシティ
- TTL 有効化
- ACM 証明書発行
mcp.h2t-products.com(または最終確定ドメイン)
6.2 Lambda デプロイ
- リポジトリ初期化 + Python 依存インストール
- 各 Lambda 関数を zip パッケージ化 →
aws lambda create-functionで初回作成 - 環境変数を設定(Secrets Manager の ARN 等)
mcp-data-fetcherのみ VPC 設定(subnet, SG)追加
6.3 API Gateway 構築
- HTTP API
mcp-api作成 - ルート定義(§2.3 のテーブル通り)
- Lambda Authorizer を
/mcpルートに attach - カスタムドメイン + ACM 証明書をマッピング
- Route 53 に A レコード(alias)追加
6.4 OAuth クライアント登録
公式 MCP クライアント(Claude Desktop / ChatGPT Connectors)の OAuth クライアントを mcp-oauth-clients テーブルに事前登録:
| client_name | client_type | redirect_uris |
|---|---|---|
| Claude Desktop | public | ["https://claude.ai/api/mcp/auth_callback"] |
| Claude Code | public | ["http://localhost:*/callback"] |
| ChatGPT Connectors | public | ["https://chat.openai.com/oauth/callback"](要検証) |
6.5 動作確認
/healthで 200 OK/.well-known/oauth-authorization-serverで正しいメタデータ返却- Claude Desktop から MCP URL を設定 → OAuth ログイン → tool 一覧取得成功
tools/callでlocation.listを実行 → Aurora から実データ返却確認- CloudWatch Logs で構造化ログ確認、Slack 通知の動作確認
7. 検収条件
7.1 機能検収
- [ ] Claude Desktop に MCP サーバー追加 → OAuth ログイン → tool 一覧取得成功
- [ ] ChatGPT Connectors からの接続 → OAuth 認証 → tool 呼び出し成功
- [ ] 4 つの読取 tool(
location.list/review.list/ranking.list/insight.summary)が仕様通りの入出力で動作 - [ ] scope 不足リクエストが 403(FORBIDDEN_SCOPE)を返す
- [ ] テナンシ外の店舗(user_available_gbp_locations に無い)への要求が 403(FORBIDDEN_LOCATION)を返す
- [ ] レート制限超過時に 429(RATE_LIMITED)を返す
- [ ] refresh_token rotation が機能(再使用検出で family 全失効)
- [ ] アクセストークン失効後の呼び出しが 401 を返す
- [ ] 全 tool 呼び出しが
mcp-audit-logsに記録される
7.2 非機能検収
- [ ] 読取系 tool の p95 レスポンス時間 < 1 秒
- [ ] Lambda コールドスタートが目視で問題ない範囲(5 秒以内)
- [ ] Aurora 接続数が
max_connectionsの 30% を超えない(CloudWatch メトリクス確認) - [ ] CloudWatch アラーム発火 → Slack 通知が動作
- [ ] ステージング → 本番のデプロイがゼロダウンタイム
7.3 ドキュメント検収
- [x] 案件提案書(mcp-server-v2)
- [x] アーキテクチャ全体像(mcp-architecture-v2)
- [x] 認証・テナンシ設計(mcp-auth-v2)
- [x] ツール一覧(mcp-tools-v2)
- [x] インフラ・実装計画(本ドキュメント)
- [ ] 運用マニュアル(Phase 1 リリース時に追加作成、新規クライアント登録手順 + 障害対応手順)
8. リリース後の運用
8.1 定期メンテナンス
| タスク | 頻度 |
|---|---|
| JWT 署名鍵ローテーション | 90 日ごと |
| 期限切れ refresh_token 削除(DynamoDB TTL で自動) | 自動 |
mcp-audit-logs の古いレコード削除(TTL 自動) | 自動(1 年経過) |
| MCP 公式 SDK の最新版チェック | 月 1 回 |
| 利用状況レポート作成 | 月 1 回 |
8.2 トラブルシュート時の参照先
| 症状 | 確認するもの |
|---|---|
| ユーザーがログインできない | mcp-oauth Lambda のログ、users テーブルの該当レコード |
| tool 呼び出しが失敗する | mcp-dispatcher ログ + mcp-audit-logs の該当 request_id |
| Aurora 接続エラー | mcp-data-fetcher ログ、Aurora 接続数メトリクス、SG 設定 |
| トークン勝手に失効 | refresh_token の revoked_at / revoke_reason を DynamoDB で確認 |
9. 未確定事項(リリース前に確定)
| # | 項目 | 状態 |
|---|---|---|
| 1 | カスタムドメイン名 | mcp.h2t-products.com 等、案件確定時に決定 |
| 2 | リポジトリ構成(新規 h2t/mcp-server リポジトリ) | OK で進める想定、変更があれば再検討 |
| 3 | デプロイ承認フロー(手動 / 自動) | 本番デプロイは手動承認を推奨 |
| 4 | IaC 化のタイミング | Phase 1 は手動構築、Phase 2 以降で Terraform 化検討 |
| 5 | mcp-data-fetcher の reserved concurrency 最終値 | 15 で開始、運用フィードバックで調整 |
| 6 | Aurora の gbp_locations 等の実カラム名 | Phase 1 開始時に DB 接続して確認、本ドキュメント記載は仮 |
| 7 | カスタムドメインの ACM 検証方式 | DNS 検証推奨 |
| 8 | ChatGPT Connectors の動的クライアント登録互換性 | 製造前に検証 |