ECS Express Mode statt App Runner / klassisches Fargate fuer eigene Hosted-MCPs
Kontext
Mit der Migration nach AWS (aws-multi-account-strategie) und dem Start der MCP-Hosting-Pipeline (_index) musste eine Compute-Plattform fuer den ersten hosted MCP (gsuite-hosted) gewaehlt werden. Anforderungsprofil:
- Eu-central-1 (DSGVO)
- HTTP/HTTPS-Workload, persistent (nicht event-driven)
- Niedrige Last in Phase 1 (nur Marvin selbst), Skalierung in Phase 2/3
- TLS-Cert auf eigener Domain via Cloudflare-Proxy
- Multi-Service-faehig (perspektivisch papierkram-hosted, ticketpay-hosted, m365-hosted parallel)
- Wenig Boilerplate-Code, weil das Pattern fuer kuenftige MCPs wiederholbar bleiben muss
Bis April 2026 waere AWS App Runner der naheliegende Default gewesen — single-CLI-Deploy auf Fargate-Underbau, AWS-managed ALB+TLS. Aber: App Runner ist seit April 2026 closed for new customers (AWS-Announcement). Bestehende Kunden duerfen weiter nutzen, neu anlegen geht nicht. Damit faellt der primaere Kandidat raus.
Optionen
Option A — Klassisches ECS Fargate + ALB + ACM (selbst gebaut)
Standard-Pattern: eigener FargateService + ApplicationLoadBalancer + Certificate mit DNS-Validation + Listener mit HTTPS-Redirect + Target Group + Security Groups + ggf. eigene VPC.
Pro:
- Maximale Kontrolle ueber jede Schicht
- Reife CDK-L2-Konstrukte (
aws-cdk-lib/aws-ecs/FargateService,aws-cdk-lib/aws-elasticloadbalancingv2) - Etabliert seit Jahren, viel Doku, viele Beispiele
Contra:
- ~14 CFN-Resourcen pro Service zu pflegen (Cluster, Task-Def, Service, ALB, TG, Listener-HTTPS, Listener-HTTP-Redirect, ACM-Cert, SG-ALB, SG-Service, Log-Group, Cluster-Container-Insights, Output-DNSName, Output-ServiceArn)
- ACM-Cert braucht DNS-Validation → Henne-Ei-Problem mit Cloudflare-DNS-Setup waehrend des Deploys
- Pro neuem MCP wird der ALB neu angelegt — keine Sharing-Optimierung „out of the box”
Option B — ECS Express Mode (AWS::ECS::ExpressGatewayService)
Neue CFN-Resource (GA April 2026, Doku) die AWS-managed ALB+TLS+AutoScaling+LogGroup+SGs in einer Resource zusammenfasst. Service-URL ist <service>.ecs.<region>.on.aws mit AWS-vergebenem Cert.
Pro:
- 8 statt 14 CFN-Resourcen (ECR + Secret + 3 IAM-Rollen + Service)
- ALB wird ueber bis zu 25 Express-Services in derselben Region+VPC geteilt — der zweite hosted MCP zahlt keinen extra ALB-Posten (~25 USD/Monat eingespart pro zusaetzlichem Service)
- Auto-Provisioning ALB + TLS-Cert + Auto-Scaling + Log-Group + SGs — keine manuellen Glue-Resourcen
- TLS-Cert AWS-managed, kein DNS-Validation-Henne-Ei
- Nutzt darunter weiterhin Fargate — gleicher Underbau wie Option A, gleiche Reife
- 5xx-Rollback-Alarme + Canary-Deploys eingebaut
Contra:
- Nur CDK L1 (
CfnExpressGatewayService) — Properties als Strings statt Enums (cpu: '1'stattCpu.ONE_VCPU). L2 wird nachgerueckt aber Stand 2026-05 nicht da, tracking issue - Custom-Domain via Cloudflare-Proxy noetig (Endpoint ist AWS-DNS, eigene Domain ist Cloudflare-CNAME) — gleicher Setup wie bei Option A, aber expliziter Schritt
- Neuere Tech, vereinzelt Doku-Luecken (z.B. genaue IAM-Role-Trust-Topology nur in Tutorials, nicht in Standard-Reference)
- AWS-vergebene Default-DNS-Endpunkte sind nicht mit Verbots-Filtern wie „nur eigene Domain darf draufzeigen” kombinierbar
Option C — Lambda + API Gateway
Pro:
- Scale-to-zero (kein Idle-Cost)
- Kein VPC / kein Container-Build / kein ALB
- Sehr billig fuer geringe Last
Contra:
- Cold-Starts (5-10 Sekunden bei Container-Lambda mit Python+grosser Package-Liste) — unbrauchbar fuer interaktive MCP-Tool-Calls in claude.ai
- 15-Minuten-Maximum pro Aufruf — okay fuer MCP-Tool-Calls, aber stdio-Subprocess-Lifecycle macht Kontainer-Reuse schwierig
- Keine persistent stdio-Subprocesses (gsuite-Sub-MCP startet stdio neu pro Call)
- Pricing-Modell nicht praedikatabel bei wachsender Nutzung — bei 50 Customers eher teurer als ECS Fargate
Option D — Status-quo: Railway weiter nutzen
Pro:
- Bestehender mcp-vf-hosted laeuft dort produktiv (mcp-vf-hosted)
- DX exzellent (
git pushdeployed)
Contra:
- Komplette Begruendungs-Linie aus aws-multi-account-strategie greift hier — fuer Compliance-Pfad nicht weiterfuehrbar
- Multi-Tenancy nicht so sauber wie AWS-Account-Trennung
- Kein OAuth-Server-Hosting (Scalekit muss extern bleiben → bei AWS koennte das spaeter inhouse als Cognito o.ae. wandern)
Entscheidung
ECS Express Mode (Option B) in eu-central-1, deployed via CDK L1 in av-production (Account 425924867359).
Begruendung:
-
Boilerplate-Reduktion ist der wichtigste Faktor — das Pattern muss wiederholbar bleiben fuer kuenftige MCPs. 8 vs 14 Resourcen ist nicht nur weniger Code, sondern weniger Failure-Surface beim Deploy und weniger zu verstehen fuer den naechsten Agent-Lauf.
-
ALB-Sharing macht den Stack ab dem zweiten MCP signifikant guenstiger. Bei der „MCP-as-a-Service”-Vision (mcp-as-a-service-vision) ist das ein dickes Argument — wir wollen 5-8 hosted MCPs parallel betreiben.
-
AWS-managed Cert loest das DNS-Validation-Problem mit Cloudflare elegant — Cloudflare ist eh als TLS-Edge geplant, der AWS-Origin braucht „nur” einen gueltigen Cert auf seiner eigenen DNS-Identity. ACM-Validation-CNAMEs in Cloudflare zu setzen waere unnoetiger Schritt.
-
L1-Only-Constraint ist ein vertretbarer Tradeoff — der Stack wird einmal geschrieben und kopiert, nicht haendisch jeden Tag editiert. L2 kommt bei AWS gewohnt nach 6-12 Monaten nach.
-
App Runner haette das gleiche geliefert ohne L1-Constraint, ist aber nicht mehr verfuegbar — daher kein Vergleichspunkt fuer Neubauten.
-
Lambda+APIGW wurde wegen Cold-Start-Latenz verworfen — interaktive MCP-Tool-Calls vertragen keine 5-10s Latenz beim ersten Aufruf nach Idle.
-
Railway wurde durch aws-multi-account-strategie schon allgemein abgeloest, hier nur Bestaetigung der Konsistenz.
Konsequenzen
Sofort:
- CDK-Stack fuer gsuite-hosted nutzt
ecs.CfnExpressGatewayService(L1) — siehe phase-1 und mcp-hosting-aws-ecs-express - Pattern-File haelt fest: 3-Rollen-IAM (Exec / Infra / Task), Trust-Principal-Verwechslung als haeufigster Fehler dokumentiert
- Cost-Modell: ~50-65 USD/Monat fuer ersten Service (Default-Sizing 1 vCPU/2 GB), ab dem zweiten Service ~25 USD/Monat weniger durch ALB-Sharing
- mcp-vf-hosted bleibt vorerst auf Railway — Migration auf AWS-Variante des Patterns ist Phase 4 / wenn ein neuer Kunde reinkommt, nicht jetzt
Mittelfristig:
- Wenn AWS L2 fuer ECS Express Mode shippt, Stack auf L2 migrieren (Diff-only, Funktionalitaet bleibt)
- Wenn Last hochkommt: Container-Sizing von Default
1/2auf0.25/0.5runter testen — ECS Express akzeptiert beide laut Doku-Standard-Sizes - Phase 2 fuegt DynamoDB + KMS-Customer-Key zur Multi-Tenant-Isolation hinzu — orthogonal zur Compute-Wahl, ECS Express bleibt
- Phase 3 mit Composio-Hybrid: Composio-Endpoint als Sub-MCP einklinken, sonst gleiche Architektur
Risiken:
- ECS Express ist neu, vereinzelt Doku-Luecken — bei Bug-Reports gegen AWS-Support schreiben statt monatelang selber suchen. Workaround-Pfad: bei wirklichem Blocker auf klassisches Fargate (Option A) ausweichen, gleicher Underbau, mehr Boilerplate aber bewaehrt
- L1-Properties sind String-typed — Tippfehler werden erst beim Deploy gefangen, nicht beim
tsc. Mitigation: gut getestetes Template-Repo, Diffs ueber bestehende Stacks - AWS-Endpoint-DNS (
<svc>.ecs.<region>.on.aws) ist oeffentlich — wenn der Cloudflare-Proxy umgangen wird, geht ein Request am WAF vorbei. Mitigation: Origin-Auth via Cloudflare-Header oder spaeter via WAF-on-AWS-Side, in Phase 1 akzeptiert weil Scalekit-JWT die echte Auth-Boundary ist
Related
- aws-multi-account-strategie — uebergeordnete Hosting-Entscheidung (warum AWS, nicht Railway)
- mcp-hosting-aws-ecs-express — Wie-Pattern (Architektur, IAM, Cost-Modell, Lessons-Learned, Stolperer-Cheatsheet)
- _index — Pipeline-Projekt (Status pro Phase, Decision-Points)
- AWS Doku: ECS Express Mode
- AWS Doku: App Runner Migration
- GitHub: aws/aws-cdk#36234 — L2-Construct-Tracking-Issue