Skip to content

MCP サーバー インフラ・実装計画(v2)

概要

項目内容
ステータス🟡 設計中
親ドキュメント案件提案書 / アーキテクチャ全体像
関連設計認証・テナンシ / ツール一覧
AWS Account881980194724
リージョン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-lambdasg-0ccad01d56a1b4327そのまま使用、Aurora との接続権限あり
RDS インバウンド既存 h2t-sg-rdsh2t-sg-lambda を許可済変更不要
Aurora MySQL(4 製品)既存(変更なし)読取のみアクセス
CloudWatch Logs既存ロググループ構成MCP 用ロググループを追加
cloudwatch-to-slack Lambda既存 Slack 通知MCP のアラート通知に流用

1.2 新規追加するリソース

項目用途
API Gateway HTTP APIMCP の 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 群と同じパターン。

#関数名配置メモリタイムアウト役割
1mcp-authorizerVPC 外512 MB10 秒OAuth 2.1 access_token 検証、scope 確認
2mcp-dispatcherVPC 外1024 MB29 秒tool ルーティング、入力検証、Data Fetcher 呼び出し、監査ログ
3mcp-oauthVPC 外512 MB10 秒OAuth エンドポイント(authorize / token / revoke / register / login)
4mcp-data-fetcherVPC 内 (h2t-private-1a)1024 MB25 秒Aurora への SQL クエリ実行、4 製品振り分け

命名規約

既存 Lambda 群(fetch_search_ranking, sync_database, checkBatchStatus 等)の命名パターンに合わせ、すべて mcp- プレフィックス + ケバブケース。

Reserved concurrency

関数reserved concurrency理由
mcp-authorizer50高頻度呼び出し想定(毎リクエスト)
mcp-dispatcher30tool 呼び出しごとに 1 回
mcp-oauth10認可フロー時のみ
mcp-data-fetcher15Aurora 接続数制御の主役(後述)

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 並列でも足りなくなったら、以下の順で対応:

  1. mcp-data-fetcher の reserved concurrency を 30 に上げる(接続上限まで余裕がある場合)
  2. それでも足りなければ RDS Proxy を導入(+$25.92/月、コードは接続先 endpoint の変更のみ)
  3. 究極は 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 Authorizermcp-authorizer を attach
CORSクライアントは MCP 公式クライアントのみ想定、CORS は不要

ルート定義

パスメソッドLambdaAuthorizer
/mcpPOSTmcp-dispatchermcp-authorizer ✅
/oauth/authorizeGETmcp-oauthなし
/oauth/loginPOSTmcp-oauthなし
/oauth/authorize/consentPOSTmcp-oauthなし(セッション Cookie 検証)
/oauth/tokenPOSTmcp-oauthなし
/oauth/revokePOSTmcp-oauthなし
/oauth/registerPOSTmcp-oauthなし
/.well-known/oauth-authorization-serverGETmcp-oauthなし
/.well-known/jwks.jsonGETmcp-oauthなし
/healthGETmcp-dispatcherなし

2.4 DynamoDB テーブル

すべてオンデマンド課金、暗号化(at-rest)有効、TTL 有効。

テーブル名主キーTTL 属性用途
mcp-oauth-clientsclient_id (PK)なしOAuth クライアント
mcp-oauth-codescode_hash (PK)expires_at認可コード(60s)
mcp-oauth-refresh-tokenstoken_hash (PK), GSI: user_id_indexexpires_atリフレッシュトークン(30d)
mcp-oauth-consentsuser_id (PK), client_id (SK)なしユーザー同意
mcp-jwt-revocationsjti (PK)expires_atJWT 失効リスト
mcp-audit-logsrequest_id (PK), GSI: user_id_created_atexpires_at (1y)監査ログ

詳細スキーマは 認証・テナンシ設計 §9 を参照。

2.5 Secrets Manager

Secret 名内容
mcp/jwt-signing-keyRSA 秘密鍵(RS256)+ kid。90 日ごとローテーション
mcp/db/gmacGMAC Aurora 接続情報(host / user / password)
mcp/db/gcorGCOR Aurora 接続情報
mcp/db/pipitPIPIT (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)
  • 以下のカスタムポリシー
json
{
  "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 の実行ロール。

ポリシー:

  • AWSLambdaBasicExecutionRole
  • AWSLambdaVPCAccessExecutionRole(VPC 内配置に必須)
  • 以下のカスタムポリシー
json
{
  "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-authorizer30 日
/aws/lambda/mcp-dispatcher30 日
/aws/lambda/mcp-oauth30 日
/aws/lambda/mcp-data-fetcher30 日
/aws/apigateway/mcp-api30 日

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 形式で構造化ログを出力:

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.md

4.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.2mcp-authorizer 実装(JWT 検証 + scope チェック)3 回1.5製造者
2.3mcp-oauth 実装(authorize/token/refresh/register/login + JWT 発行)4 回2.0製造者
2.4mcp-dispatcher 実装(tool ルーティング + 入力検証 + 監査ログ)3 回1.5製造者
2.5mcp-data-fetcher 実装(Aurora 接続 + 4 製品振り分け + 4 tool)3 回1.5製造者
2.6DynamoDB テーブル作成 + Secrets Manager 設定2 回1.0製造者
2.7API Gateway 設定 + Route53 + ACM2 回1.0製造者
2.8IAM ロール作成 + Lambda デプロイ2 回1.0製造者
2.9接続テスト(Claude Desktop + ChatGPT)2 回1.0製造者
2.10CloudWatch アラーム設定 + 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 基盤準備

  1. IAM ロール作成
    • mcp-lambda-role-vpc-out(VPC 外用)
    • mcp-lambda-role-vpc-in(VPC 内用)
  2. Secrets Manager に格納
    • mcp/jwt-signing-key(RSA キーペア生成)
    • mcp/db/gmac / gcor / pipit / kuchikomi_one
  3. DynamoDB テーブル 6 個作成
    • すべてオンデマンドキャパシティ
    • TTL 有効化
  4. ACM 証明書発行
    • mcp.h2t-products.com(または最終確定ドメイン)

6.2 Lambda デプロイ

  1. リポジトリ初期化 + Python 依存インストール
  2. 各 Lambda 関数を zip パッケージ化aws lambda create-function で初回作成
  3. 環境変数を設定(Secrets Manager の ARN 等)
  4. mcp-data-fetcher のみ VPC 設定(subnet, SG)追加

6.3 API Gateway 構築

  1. HTTP API mcp-api 作成
  2. ルート定義(§2.3 のテーブル通り)
  3. Lambda Authorizer を /mcp ルートに attach
  4. カスタムドメイン + ACM 証明書をマッピング
  5. Route 53 に A レコード(alias)追加

6.4 OAuth クライアント登録

公式 MCP クライアント(Claude Desktop / ChatGPT Connectors)の OAuth クライアントを mcp-oauth-clients テーブルに事前登録

client_nameclient_typeredirect_uris
Claude Desktoppublic["https://claude.ai/api/mcp/auth_callback"]
Claude Codepublic["http://localhost:*/callback"]
ChatGPT Connectorspublic["https://chat.openai.com/oauth/callback"](要検証)

6.5 動作確認

  1. /health で 200 OK
  2. /.well-known/oauth-authorization-server で正しいメタデータ返却
  3. Claude Desktop から MCP URL を設定 → OAuth ログイン → tool 一覧取得成功
  4. tools/calllocation.list を実行 → Aurora から実データ返却確認
  5. 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デプロイ承認フロー(手動 / 自動)本番デプロイは手動承認を推奨
4IaC 化のタイミングPhase 1 は手動構築、Phase 2 以降で Terraform 化検討
5mcp-data-fetcher の reserved concurrency 最終値15 で開始、運用フィードバックで調整
6Aurora の gbp_locations 等の実カラム名Phase 1 開始時に DB 接続して確認、本ドキュメント記載は仮
7カスタムドメインの ACM 検証方式DNS 検証推奨
8ChatGPT Connectors の動的クライアント登録互換性製造前に検証

10. 関連ドキュメント