Skip to content

MCP Server — Thiết kế hạ tầng

MụcNội dung
Trạng thái🟡 Đang thiết kế
Case liên quan#13 MCP Server (Thiết lập mới)
Tài liệu chaMCP Server (Tổng thể)
Design liên quanDB (audit log) / DB (OAuth)

1. Mục đích tài liệu

Chốt cấu hình hosting MCP Server trên AWS.

  • Tích hợp vào hạ tầng GMAC hiện có (VPC vpc-0b4c742f84f3b2d9d, region ap-northeast-1)
  • Vận hành container (ECS Fargate)
  • Store quản lý trạng thái auth・OAuth
  • Network・Security
  • Giám sát・Alert
  • Cấu hình chung cho cả 2 phương án stack (Python / TypeScript)

2. Phương châm tận dụng hạ tầng hiện có

2.1 Tái sử dụng

MụcResource hiện cóPhương châm
VPCvpc-0b4c742f84f3b2d9d (10.0.0.0/16)Dùng nguyên si
Private subnetsubnet-095de9e00c1894a0c (1a), subnet-0f38ab1dce252e375 (1c)Nơi đặt MCP ECS task
Public subnetsubnet-0ff23c0ce66750053 (1a), subnet-0ebe6abb3572271e8 (1c)Nơi đặt ALB riêng MCP
RDSh2t-db (MySQL 8.0)Thêm bảng MCP vào mappy DB
ECRThêm repo mới h2t-mappy-mcpTheo quy tắc đặt tên hiện có
S3Bucket hiện cóNguyên tắc không tạo bucket mới
CloudWatchTheo cấu hình log group hiện cóThêm log group mới
Route 53Hosted zone hiện cóThêm subdomain mcp.mappy.<existing-domain>
AWS Account635388747933Cùng account

2.2 Thêm mới

MụcLý do
ALBMCP chạy trên domain độc lập (tách khỏi ALB hiện có)
ElastiCache (Redis)OAuth code・session・counter rate limit
Secrets ManagerJWT signing key・OAuth client secret
ECS Serviceh2t-mcp-server Fargate
Security Grouph2t-sg-mcp, h2t-sg-mcp-redis
ACM Certificatemcp.mappy.example.com (tạm)
WAFTăng cường DDoS / rate limit (tùy chọn)

3. Sơ đồ tổng thể

4. Cấu hình container (ECS Fargate)

4.1 Task definition

MụcGiá trị
Task definition familyh2t-mcp-server
Loại khởi độngFargate
Platform versionLATEST
CPU0.5 vCPU (Phase 1) / 1 vCPU (từ Phase 2)
Memory1 GB (Phase 1) / 2 GB (từ Phase 2)
Network modeawsvpc
Task roleh2t-mcp-task-role
Execution roleh2t-mcp-execution-role
Log driverawslogs
Log group/ecs/h2t-mcp-server

4.2 Container definition

MụcGiá trị
Image635388747933.dkr.ecr.ap-northeast-1.amazonaws.com/h2t-mappy-mcp:<tag>
Port8000 (trong container) → forward HTTP từ ALB
Health checkGET /health (interval 30 giây, timeout 5 giây, retry 3 lần)
Stop timeout30 giây (graceful shutdown của Streamable HTTP)
Env variableXem "Env・Secret" dưới

4.3 Service definition

MụcGiá trị
Tên serviceh2t-mcp-server
Clusterh2t-cluster (hiện có) hoặc mới h2t-mcp-cluster
Số task mong muốnPhase 1: 2 / Phase 2: 4 / Phase 3: 6
Số task tối thiểu2
Số task tối đa10
Loại deployRolling Update (minimum healthy 50%, maximum 200%)
Auto ScalingTarget Tracking (CPU 70%, số request 100/phút)
Load balancerTarget group h2t-mcp-tg của h2t-mcp-alb
Service discoveryTùy chọn

Sticky session của Streamable HTTP

Session Streamable HTTP của MCP là long-lived. Cần thiết lập sticky session của ALB (cùng client tới cùng task). Hoặc thiết kế tập trung trạng thái session ở Redis để stateless. Design này áp dụng quản lý tập trung Redis (stateless).

5. Load balancer (ALB)

5.1 Cấu hình

MụcGiá trị
Tên ALBh2t-mcp-alb
Schemeinternet-facing
Subneth2t-public-1a, h2t-public-1c
Security grouph2t-sg-mcp-alb (mới)
Idle timeout600 giây (đối phó kết nối long-lived của Streamable HTTP)
HTTP/2Bật
Attach WAFoptional (xem xét từ Phase 2)

5.2 Listener

PortProtocolHành vi
80HTTPRedirect 301 sang HTTPS
443HTTPSACM certificate, forward sang target group h2t-mcp-tg

5.3 Target group

MụcGiá trị
Tênh2t-mcp-tg
ProtocolHTTP
Port8000
Health check path/health
Health check interval30 giây
Health check thresholdThành công 2 lần, thất bại 3 lần
Deregistration delay30 giây (chờ kết nối kết thúc)
Sticky sessionTắt (do quản lý tập trung Redis)

6. Data store

6.1 ElastiCache Redis (mới)

Dùng cho OAuth code・session・rate limit・cache idempotency.

MụcGiá trị
EngineRedis 7.x
Node typecache.t4g.micro (Phase 1) / cache.t4g.small (từ Phase 2)
Số node1 (Phase 1, không Multi-AZ) / Cluster Mode (xem xét ở Phase 3)
Subneth2t-private-1a, h2t-private-1c
Security grouph2t-sg-mcp-redis
Mã hóa (at-rest)Bật
Mã hóa (in-transit)Bật (TLS)
AuthRedis AUTH (quản lý qua Secrets Manager)
BackupSnapshot hàng ngày, giữ 7 ngày
Maintenance windowThứ Ba 04:00-05:00 JST

Thiết kế key

PrefixMục đíchTTL
oauth:code:<hash>Authorization code60 giây
oauth:state:<hash>Verify state5 phút
mcp:session:<id>Session Streamable HTTP30 phút (idle)
idempotency:<client_id>:<user_id>:<key>Cache idempotency24 giờ
confirm:<token>Confirm token áp dụng hàng loạt5 phút
ratelimit:<scope>:<key>Counter rate limit1 phút〜1 giờ
jwt:revoke:<jti>Danh sách revoke access token (cache Bloom Filter)Đến exp của JWT

6.2 RDS (hiện có)

Thêm nhóm bảng MCP vào mappy DB:

  • mappy_mcp_audit_logs
  • mappy_mcp_batches
  • mappy_mcp_rate_limit_logs
  • mappy_mcp_oauth_clients
  • mappy_mcp_oauth_consents
  • mappy_mcp_oauth_refresh_tokens
  • mappy_mcp_oauth_access_token_revocations

Chi tiết xem DB audit log / DB OAuth.

Update SG nguồn kết nối RDS

Thêm access 3306 từ h2t-sg-mcp mới vào inbound của h2t-sg-rds hiện có.

7. ECR・Container image

7.1 Repository

TênURI
h2t-mappy-mcp635388747933.dkr.ecr.ap-northeast-1.amazonaws.com/h2t-mappy-mcp

7.2 Quy tắc tag image

TagMục đích
latestMain branch mới nhất
v1.0.0Bản release
staging-<sha>Staging
dev-<sha>Môi trường dev

7.3 Cấu hình image

Phương án A: Python (FastMCP)

dockerfile
FROM python:3.11-slim

WORKDIR /app

COPY pyproject.toml uv.lock /app/
RUN pip install --no-cache-dir uv && \
    uv sync --frozen --no-dev

COPY src/ /app/src/

USER 1000
EXPOSE 8000

CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]

Phương án B: TypeScript

dockerfile
FROM node:20-alpine AS build

WORKDIR /app
COPY package.json pnpm-lock.yaml /app/
RUN corepack enable && pnpm install --frozen-lockfile

COPY src/ /app/src/
COPY tsconfig.json /app/
RUN pnpm build

FROM node:20-alpine AS runtime
WORKDIR /app
COPY --from=build /app/node_modules /app/node_modules
COPY --from=build /app/dist /app/dist
COPY package.json /app/

USER 1000
EXPOSE 8000

CMD ["node", "dist/main.js"]

7.4 Kích thước image dự kiến

Ngôn ngữKích thước mong đợi
Python (slim base)Khoảng 200 MB
Node.js (alpine base)Khoảng 150 MB

8. Network・Security Group

8.1 SG mới

Tên SGInboundMục đích
h2t-sg-mcp-alb80 / 443 from 0.0.0.0/0ALB
h2t-sg-mcp8000 from h2t-sg-mcp-albECS task
h2t-sg-mcp-redis6379 from h2t-sg-mcpRedis

8.2 Thêm vào SG hiện có

SG hiện cóThêm inbound
h2t-sg-rds3306 from h2t-sg-mcp

8.3 Outbound

Tất cả SG:

  • 443 to 0.0.0.0/0 (cho GBP API・external API)
  • 53 to 0.0.0.0/0 (DNS)
  • Nếu dùng VPC endpoint thì không cần

9. Env・Secret

9.1 Env (ghi trực tiếp vào task definition)

Tên biếnVí dụ
APP_ENVproduction / staging
LOG_LEVELINFO
MCP_BASE_URLhttps://mcp.mappy.example.com
OAUTH_ISSUERNhư trên
OAUTH_AUDIENCEmappy-mcp
LARAVEL_API_BASE_URLhttps://api.mappy.example.com
REDIS_HOSTh2t-mcp-redis.cache.amazonaws.com
REDIS_PORT6379
RDS_HOSTHiện có
RDS_DATABASEmappy

9.2 Secrets Manager (chỉ tham chiếu)

Tên SecretNội dung
h2t-mcp/jwt-signing-keysJWT signing key (private key RS256, nhiều kid)
h2t-mcp/redis-auth-tokenToken Redis AUTH
h2t-mcp/rds-credentialsUsername・password DB
h2t-mcp/laravel-api-tokenInternal auth token cho Laravel API
h2t-mcp/oauth-client-secretsSecret của trusted client (registry)

Gán IAM policy sau vào task role:

json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": ["secretsmanager:GetSecretValue"],
      "Resource": [
        "arn:aws:secretsmanager:ap-northeast-1:635388747933:secret:h2t-mcp/*"
      ]
    },
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": [
        "arn:aws:logs:ap-northeast-1:635388747933:log-group:/ecs/h2t-mcp-server:*"
      ]
    }
  ]
}

10. Route 53 / Domain

MụcGiá trị
Domainmcp.mappy.example.com (tạm, chốt khi review)
ALB aliash2t-mcp-alb-xxxxxxxx.ap-northeast-1.elb.amazonaws.com
Loại recordA (alias)
Health checkTùy chọn (có thể cover bằng CloudWatch)

10.1 Ứng cử viên domain

Phương ánVí dụLưu ý
Tách subdomainmcp.mappy.example.comĐề xuất. Dễ tách CORS・Cookie
Tách pathmappy.example.com/mcpKHÔNG. Long-lived của Streamable HTTP và cấu hình ALB hiện có xung đột
Domain riêngmappy-mcp.comCó thể nếu chấp nhận chi phí domain mới・không cần SEO

11. CI/CD

11.1 Theo cách hiện có

StepNội dung
Code repositoryh2t/mappy-mcp (mới) hoặc subdirectory trong h2t/mappy
Build pipelineGitLab CI (tận dụng CI hiện có)
Build targetPush từ Dockerfile lên ECR h2t-mappy-mcp
DeployUpdate ECS service (apply revision mới của task definition)
RollbackRevert về revision trước

11.2 Phân chia môi trường

Môi trườngALBECS serviceRedisRDS
Productionh2t-mcp-albh2t-mcp-serverh2t-mcp-redish2t-db
Stagingh2t-mcp-alb-stgh2t-mcp-server-stgh2t-mcp-redis-stgh2t-db-stg
Development(docker-compose local)-(Redis local)(MySQL local)

12. Giám sát・Alert

12.1 CloudWatch Metrics

MetricThresholdAction
ECS CPU usage> 80% (5 phút)Auto Scaling + thông báo
ECS Memory usage> 80% (5 phút)Thông báo
ALB tỷ lệ 5xx> 1% (5 phút)Thông báo CRITICAL
ALB Target Health< 50% healthyThông báo CRITICAL
Thời gian response ALBp99 > 3 giây (5 phút)Thông báo WARNING
Redis CPU> 70% (5 phút)Xem xét scale up
Redis memory> 80%Scale up
Số kết nối RDS> 80% max_connectionsWARNING

12.2 CloudWatch Logs

Log groupThời gian giữ
/ecs/h2t-mcp-server30 ngày
/ecs/h2t-mcp-server-access90 ngày
/ecs/h2t-mcp-server-audit1 năm

12.3 Quy ước field log

Cấu trúc dạng JSON, bắt buộc có các field sau:

json
{
  "timestamp": "2026-05-26T10:00:00Z",
  "level": "INFO",
  "service": "mcp-server",
  "request_id": "...",
  "user_id": 1435,
  "client_id": "...",
  "tool_name": "location.list",
  "elapsed_ms": 123,
  "message": "tool executed"
}

12.4 Thông báo alert

  • Channel Slack #h2t-mcp-alerts
  • CRITICAL thì thông báo điện thoại + email

13. Backup・DR

Đối tượngPhương phápTần suất
Data RDSAuto backup (hiện có)Hàng ngày 7 ngày
Data RedisSnapshotHàng ngày 7 ngày
Task definition ECSQuản lý version (auto)Auto
Secrets ManagerGiữ versionAuto

RTO (recovery time objective): trong 1 giờ RPO (recovery point objective): khôi phục data trong 24 giờ gần nhất

14. Ước lượng chi phí (Phase 1)

ResourceƯớc lượng tháng
ECS Fargate (2 task × 0.5 vCPU / 1 GB)Khoảng 30 USD
ALBKhoảng 25 USD
ElastiCache Redis (cache.t4g.micro)Khoảng 15 USD
ACM CertificateMiễn phí
Route 53Khoảng 1 USD
Secrets Manager (5 secret)Khoảng 2 USD
CloudWatch Logs (30 ngày × 5 GB)Khoảng 5 USD
Lưu trữ ECRKhoảng 1 USD
Truyền dataKhoảng 5 USD
TổngKhoảng 84 USD/tháng

Từ Phase 2:

  • Tăng ECS task (4 task × 1 vCPU / 2 GB) → khoảng 120 USD/tháng
  • Scale up Redis → khoảng 30 USD/tháng
  • Tổng: khoảng 180 USD/tháng

Tối ưu chi phí

  • Phase 1 dùng Fargate Spot giảm 30〜50%
  • Đồng cư trên RDS hiện có nên không phát sinh chi phí DB
  • Môi trường staging vận hành bằng Fargate Spot + node 1

15. Checklist bảo mật

MụcTrạng thái
ALB chỉ HTTPS (HTTP redirect 301)
ECS task đặt trong private subnet
Redis mã hóa in-transit + at-rest
RDS theo cấu hình hiện có (đã mã hóa)
Tham chiếu Secrets Manager giới hạn bằng IAM
WAF (xem xét từ Phase 2)🔵
Nội bộ hóa traffic AWS API qua VPC endpoint🔵 (đề xuất)
Bật GuardDuty (hiện có)
Theo dõi thay đổi resource bằng AWS ConfigTheo cấu hình hiện có
Tập trung access log vào S3🔵

16. Quy trình deploy (Phase 1 lần đầu)

  1. Chuẩn bị nền tảng

    • Tạo SG mới (h2t-sg-mcp-alb / h2t-sg-mcp / h2t-sg-mcp-redis)
    • Thêm inbound vào h2t-sg-rds hiện có
    • Tạo instance ElastiCache Redis
    • Lưu JWT key・các secret vào Secrets Manager
    • Tạo ECR repository h2t-mappy-mcp
  2. DB migration

    • Tạo bảng mappy_mcp_* (DDL của OAuth / audit log)
    • Đăng ký OAuth client khởi tạo (Claude Desktop / ChatGPT v.v.)
  3. Xây ALB

    • Phát ACM certificate (mcp.mappy.example.com)
    • Tạo ALB / target group
    • Thêm record Route 53
  4. Xây ECS

    • Cluster (tận dụng hiện có hoặc mới)
    • Task definition (IAM role, env, tham chiếu Secrets)
    • Tạo service (liên kết ALB, Auto Scaling)
  5. Deploy app lần đầu

    • Build Dockerfile & push ECR
    • Update ECS service
  6. Kiểm tra hoạt động

    • Xác nhận response /health
    • Xác nhận /.well-known/oauth-authorization-server
    • Test kết nối từ Claude Desktop / ChatGPT
  7. Cấu hình giám sát・alert

    • Tạo CloudWatch Alarm
    • Cấu hình thông báo Slack

17. Điểm chưa chốt (quyết định tại review design)

#MụcPhương án
1Domain name cho MCPmcp.mappy.example.com (tạm)
2ECS clusterTận dụng hiện có / mới
3Thời điểm đưa WAFPhase 1 / Phase 2
4Redis Multi-AZHỗ trợ Phase 1 / từ Phase 2
5Phạm vi dùng Fargate SpotToàn production / chỉ staging
6Cấu hình repositoryMới h2t/mappy-mcp / trong h2t/mappy
7Flow approve deployAuto / approve thủ công
8Đưa VPC endpointNgay / Phase 2

18. Tài liệu liên quan