Session-Prompt — mcp-replicate-hosted Live-Deploy

Copy/Paste in die naechste Claude-Code-Session am Anfang. Komplett self-contained: dieser Prompt baut alle Pre-Conditions selbst auf und fuehrt den Deploy in einem Rutsch durch (Marvin gibt nur die Go-Aheads).


Was bisher geschah (Stand 2026-05-19 Ende)

mcp-replicate-hosted ist code-side komplett ready:

  • Repo ~/source/mcps/mcp-replicate-hosted/ gebaut analog mcp-vf-hosted-Pattern. Branch main, drei Commits:
    • 068a210 — initial repo (Phase 2 design-stack-julian)
    • d22c3f5 — Security-Audit-Fixes F1+F2+F3
    • 50121f9 — Code-Review-Fixes H1+H2+M1-M5 (107/107 pytest, ruff clean, CDK-Guard verifiziert)
  • ECR-Repo mcp-replicate-hosted in av-production (425924867359 / eu-central-1) angelegt
  • Cloudflare-Tunnel mcp-replicate-hosted mit ID 1fb0eb9c-33fe-490d-a45e-9e9990a306fb angelegt (status “down” — kein Sidecar, kein Ingress)
  • Replicate-API-Token vf-hosted in 1Password Personal-Vault als Item Replicate API Token (mcp-replicate-hosted) (ubougcjqv5...), Format verifiziert (r8_..., 40 chars)
  • Spending-Cap Replicate sollte auf $100/Mo gesetzt sein — Marvin bestaetigt im ersten Schritt
  • Scalekit-MCP in ~/.claude.json registriert via claude mcp add --transport http scalekit https://mcp.scalekit.com/. OAuth-Flow bei erstem Tool-Aufruf in dieser Session

Code-Reviews: 0 HIGH-Findings offen. Phase-A komplett (gefixt im commit 50121f9). Phase-B/C im Tracker und im Code-Review-Run dokumentiert als separate PRs nach Live-Schaltung.

Ziel dieser Session

mcp-replicate-hosted live unter https://replicate.agenticventures.de/mcp mit Scalekit-OAuth schalten. Externer Smoke gegen /health muss 200 returnen mit Service-Name vf-replicate. Live-Schaltung an Julian erst nach VF-AVV-Sign — bis dahin hat nur Marvin Zugriff via eigenes JWT (Marketing-Demo OK).

Pre-Conditions Check (vor jedem Schritt)

Diese Probes bei Session-Start ausfuehren, parallel:

# 1. AWS-Profile aktiv
aws sts get-caller-identity --profile av-production --region eu-central-1
 
# 2. 1P-Sitzung aktiv + Replicate-Token greifbar
op item get "Replicate API Token (mcp-replicate-hosted)" --vault Personal --fields credential --reveal 2>&1 | head -c 4
# erwartet: "r8_"
 
# 3. Cloudflare-API-Token greifbar (fuer Tunnel/DNS-Calls)
aws secretsmanager get-secret-value --secret-id cloudflare/api-token \
  --profile av-production --region eu-central-1 --query SecretString --output text 2>&1 | head -c 8
 
# 4. Cloudflare-Tunnel existiert noch (sollte 'down' sein da kein Sidecar)
CF_TOKEN=$(aws secretsmanager get-secret-value --secret-id cloudflare/api-token \
  --profile av-production --region eu-central-1 --query SecretString --output text)
curl -sS -H "Authorization: Bearer $CF_TOKEN" \
  "https://api.cloudflare.com/client/v4/accounts/bf395d62cc6a9117564c0712fa9e3ad2/cfd_tunnel/1fb0eb9c-33fe-490d-a45e-9e9990a306fb" \
  | python3 -c "import sys, json; r=json.load(sys.stdin); print('tunnel status:', r['result']['status'], 'name:', r['result']['name'])"
 
# 5. ECR-Repo existiert
aws ecr describe-repositories --repository-names mcp-replicate-hosted \
  --profile av-production --region eu-central-1 --query 'repositories[0].repositoryUri' --output text
 
# 6. Repo pytest noch gruen (sanity nach evtl. neueren Commits)
cd ~/source/mcps/mcp-replicate-hosted && uv run pytest -q 2>&1 | tail -3

Wenn eines davon failed: STOP und Marvin fragen, NICHT improvisieren.

Pre-Marvin-Aktion (5 Min am Anfang)

Marvin macht die Scalekit-Resource via dem neu installierten Scalekit-MCP — falls noch nicht erledigt. Probe ob der Scalekit-MCP da ist + Auth aktiv:

# In der Session pruefen ob mcp__scalekit__* Tools verfuegbar sind.
# Falls ja: list_organizations o.ae. probieren um OAuth-Flow zu triggern.
# Falls nein: claude mcp list pruefen, ggf. claude mcp add ... erneut.

Resource-Anlage via Scalekit-MCP (per Tool-Call statt Dashboard):

  • Resource Identifier: https://replicate.agenticventures.de/mcp
  • Resource Name: VF Replicate Image-Gen MCP
  • Environment: das EU-Tenant (analog mcp-vf-hosted-Resource, ID-Format res_...)

Resource-ID notieren — die wandert spaeter in den CDK-Stack.

Fallback wenn Scalekit-MCP unzuverlaessig: Dashboard https://agenticventures.eu.scalekit.dev → MCP → Resources → New (5 Min Klick). Beide Wege fuehren zum gleichen Resource-Identifier.

Deploy-Kette (in einem Rutsch, sobald Marvin Go gibt)

Nach Marvin’s explizitem “go” — keine Zwischenfragen mehr, jeder Schritt selbst-verifiziert, ECS-Circuit-Breaker faengt Fehler ab:

Schritt 1 — Cloudflare-Tunnel-Token holen + AWS-Secret anlegen

CF_TOKEN=$(aws secretsmanager get-secret-value --secret-id cloudflare/api-token \
  --profile av-production --region eu-central-1 --query SecretString --output text)
TUNNEL_ID="1fb0eb9c-33fe-490d-a45e-9e9990a306fb"
ACCOUNT="bf395d62cc6a9117564c0712fa9e3ad2"
 
# Tunnel-Token holen
TUNNEL_TOKEN=$(curl -sS -H "Authorization: Bearer $CF_TOKEN" \
  "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/cfd_tunnel/${TUNNEL_ID}/token" \
  | python3 -c "import sys, json; print(json.load(sys.stdin)['result'])")
 
# AWS-Secret anlegen (in den Container als TUNNEL_TOKEN env)
aws secretsmanager create-secret \
  --name mcp-replicate-hosted/cloudflared-token \
  --description "Cloudflared tunnel token (tunnel ${TUNNEL_ID})" \
  --secret-string "$TUNNEL_TOKEN" \
  --profile av-production --region eu-central-1 \
  --query ARN --output text
# ARN notieren — wandert in den Stack

Schritt 2 — Ingress-Config setzen

curl -sS -X PUT -H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" \
  "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/cfd_tunnel/${TUNNEL_ID}/configurations" \
  -d '{
    "config": {
      "ingress": [
        {"hostname": "replicate.agenticventures.de", "service": "http://localhost:8080"},
        {"service": "http_status:404"}
      ]
    }
  }' | python3 -c "import sys, json; r=json.load(sys.stdin); print('ingress_ok:', r.get('success'))"

Schritt 3 — DNS-CNAME anlegen

# Zone-ID fuer agenticventures.de holen
ZONE_ID=$(curl -sS -H "Authorization: Bearer $CF_TOKEN" \
  "https://api.cloudflare.com/client/v4/zones?name=agenticventures.de" \
  | python3 -c "import sys, json; print(json.load(sys.stdin)['result'][0]['id'])")
 
curl -sS -X POST -H "Authorization: Bearer $CF_TOKEN" -H "Content-Type: application/json" \
  "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records" \
  -d "{
    \"type\": \"CNAME\",
    \"name\": \"replicate\",
    \"content\": \"${TUNNEL_ID}.cfargotunnel.com\",
    \"proxied\": true,
    \"comment\": \"mcp-replicate-hosted tunnel, set ${`date -u +%Y-%m-%d`}\"
  }" | python3 -c "import sys, json; r=json.load(sys.stdin); print('dns_ok:', r.get('success'))"

Schritt 4 — Replicate-Token-Secret anlegen

REPLICATE_TOKEN=$(op item get "Replicate API Token (mcp-replicate-hosted)" \
  --vault Personal --fields credential --reveal)
 
aws secretsmanager create-secret \
  --name mcp-replicate-hosted/upstream-tokens \
  --description "Replicate API Token (vf-hosted) for Fargate container. Spending-cap \$100/Mo." \
  --secret-string "{\"REPLICATE_API_TOKEN\":\"${REPLICATE_TOKEN}\"}" \
  --profile av-production --region eu-central-1 \
  --query ARN --output text
# ARN notieren — wandert in den Stack

Schritt 5 — Stack-PLACEHOLDERs ersetzen

In ~/source/mcps/mcp-replicate-hosted/infra/lib/mcp-replicate-hosted-stack.ts drei Strings ersetzen:

  1. arn:aws:secretsmanager:eu-central-1:425924867359:secret:mcp-replicate-hosted/upstream-tokens-PLACEHOLDER → echter ARN aus Schritt 4 (mit dem 6-char-Suffix nach -PLACEHOLDER — also Suffix ersetzen)
  2. arn:aws:secretsmanager:eu-central-1:425924867359:secret:mcp-replicate-hosted/cloudflared-token-PLACEHOLDER → echter ARN aus Schritt 1
  3. res_PLACEHOLDER_REPLACE_AFTER_SCALEKIT_PROVISION → die Scalekit-Resource-ID aus der Pre-Marvin-Aktion

Image-Digest (sha256:PLACEHOLDER_DIGEST_REPLACE_AFTER_FIRST_PUSH) wird in Schritt 7 ersetzt, nicht hier.

npx cdk synth --quiet 2>&1 | tail -5 — sollte jetzt DURCHLAUFEN (Pre-Synth-Guard requireNoPlaceholder() greift nicht mehr fuer Stellen 1-3, schlaegt aber noch wegen Image-Digest fehl. Das ist erwartet.)

Schritt 6 — Docker-Build + ECR-Push (~10 Min)

# ECR-Login
aws ecr get-login-password --region eu-central-1 --profile av-production \
  | docker login --username AWS --password-stdin \
    425924867359.dkr.ecr.eu-central-1.amazonaws.com
 
# Build linux/amd64 (mcp-replicate als sibling im Build-Context, daher cd zu mcps/)
cd ~/source/mcps
docker buildx build --platform linux/amd64 \
  -f mcp-replicate-hosted/Dockerfile \
  -t 425924867359.dkr.ecr.eu-central-1.amazonaws.com/mcp-replicate-hosted:latest \
  --push .

Schritt 7 — Image-Digest pinnen

IMAGE_DIGEST=$(aws ecr describe-images \
  --repository-name mcp-replicate-hosted --image-ids imageTag=latest \
  --query 'imageDetails[0].imageDigest' --output text \
  --profile av-production --region eu-central-1)
echo "Image digest: $IMAGE_DIGEST"

In infra/lib/mcp-replicate-hosted-stack.ts: sha256:PLACEHOLDER_DIGEST_REPLACE_AFTER_FIRST_PUSH$IMAGE_DIGEST

Schritt 8 — CDK Deploy

cd ~/source/mcps/mcp-replicate-hosted/infra
[ -d node_modules ] || npm install
npx cdk synth --quiet 2>&1 | tail -3  # Final-Check, sollte clean sein
npx cdk deploy --profile av-production --require-approval never

Erwartet: 3-5 Min Deploy-Zeit, CloudFormation-Stack McpReplicateHosted neu, Output mit ServiceName, EcrUri, LogGroupName, DashboardUrl.

Schritt 9 — Smoke-Tests

# 9.1 Health intern (Container) — via aws ecs execute-command? Skip; warten auf extern
sleep 30  # warte bis Tunnel sich verbindet
 
# 9.2 Tunnel-Status: jetzt 'healthy' mit 4 QUIC-Connections
curl -sS -H "Authorization: Bearer $CF_TOKEN" \
  "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT}/cfd_tunnel/${TUNNEL_ID}" \
  | python3 -c "import sys, json; r=json.load(sys.stdin); print('status:', r['result']['status'], 'conns:', len(r['result'].get('connections',[])))"
 
# 9.3 DNS-Probe
dig +short replicate.agenticventures.de
 
# 9.4 Externer Health-Smoke
curl -sS https://replicate.agenticventures.de/health | python3 -m json.tool
# erwartet: {"ok": true, "service": "vf-replicate", "version": "0.1.0",
#           "submcps_active": ["replicate"], "model_whitelist_size": 19, "uptime_seconds": ...}

Wenn das Health-Payload service: "vf-replicate" + submcps_active: ["replicate"] zeigt: GO-LIVE erreicht. Sonst CloudWatch-Logs pruefen:

aws logs tail /aws/ecs/default/mcp-replicate-hosted --since 5m \
  --profile av-production --region eu-central-1 --follow

Schritt 10 — OAuth-Flow durchspielen (Marvin selbst)

Marvin haengt den MCP an einen Client (claude.ai Pro Custom Connector ODER Open WebUI VF Admin-UI):

  1. URL: https://replicate.agenticventures.de/mcp
  2. Type: Streamable HTTP, OAuth 2.1
  3. Marvin authentifiziert mit seinem Scalekit-Account → Token wird ausgestellt
  4. Tool-List sollte ~10 Tools zeigen (create_image, create_text_image, create_svg_logo, create_image_from_reference, create_video, search_tools, replicate_get_prediction, replicate_wait_for_prediction, replicate_cancel_prediction, replicate_list_predictions)
  5. Smoke-Tool-Call: create_image(prompt="modernes Hero-Bild fuer Sparkasse-Tasting", wait_seconds=60) → Output-URL sollte zurueckkommen, Bild mit Neongelb-Akzent
  6. Smoke F2: replicate_get_account() direkt aufrufen → muss mit serverseitig deaktiviert rejecten (Audit-Event blocked_replicate_admin_tool_attempt in CloudWatch)

Post-Deploy Updates (~10 Min)

  1. Capability-File-Status auf active aws-fargate-tunnel:
    • intern/capabilities/mcps/mcp-replicate-hosted.mdstatus: und notes: updaten, Tunnel-ID + Image-Digest + Live-Datum eintragen
  2. mcps/_index.md Hosted-Tabelle: Status auf active aws-fargate-tunnel
  3. Plan intern/projekte/openwebui-vf/plans/2026-05-19-design-stack-julian.md: Phase 2.1.e + 2.3 als done
  4. Sprint sprint-2-replicate-hosted.md status auf live
  5. Tracker intern/wissen/patterns/mcp-audit-findings-cross-repo.mdfixed_status updaten mit “live since YYYY-MM-DD”
  6. Run-Log neu intern/runs/YYYY-MM-DD-mcp-replicate-hosted-deploy/_index.md mit: was committed, Tunnel-Status nach Deploy, Smoke-Output, Welche Tools im /mcp sichtbar, AVV-Status

Decision-Forks (was zu entscheiden ist)

FrageDefaultWann anders
Tool-Whitelist in vf-nova (OWUI) erweitern um die 10 replicate.agenticventures.de-Tools?ja, gleich nach Smokenein, erst nach AVV-Sign + Julian-OAuth
VF-AVV bei Replicate parallel anstossen oder warten?parallel, JETZT (Andre + Christoph briefen)nicht warten, sonst blockiert das Julian-Live-Test
extern/shared/vibe-factory/avv-replicate.md jetzt schreiben?ja, kurz (Subprozessor-Eintrag + Datenflusswege)nicht jetzt, wenn keine Zeit — als separater Vorgang

Was schiefgehen kann (mit Fix-Pfaden)

SymptomFix
cdk synth failed mit “PLACEHOLDER” ErrorSchritt 5 oder 7 nicht komplett — alle 3 ARN/ID-Felder + Image-Digest pruefen
cdk deploy failed mit AccessDenied beim Secret-ReadSecret-ARN-Suffix im Stack stimmt nicht (das random 6-char-Suffix nach -PLACEHOLDER muss exact mit AWS-SM-Suffix uebereinstimmen). Holen via aws secretsmanager describe-secret --secret-id mcp-replicate-hosted/upstream-tokens --query ARN --output text
Container ImagePullBackOffImage-Digest im Stack falsch oder ECR-Push noch nicht durch. aws ecr describe-images ... erneut, Stack updaten, cdk deploy
Container haengt im Boot mit Scalekit-JWT-FehlerSCALEKIT_RESOURCE_ID im Stack falsch oder Scalekit-Resource nicht angelegt. CloudWatch-Logs vf-replicate-Stream pruefen
Tunnel bleibt down nach Deploycloudflared-Sidecar-Logs pruefen (aws logs tail .../mcp-replicate-hosted --filter cloudflared) — meist Token-Issue. Token aus Schritt 1 nochmal holen + AWS-Secret updaten (put-secret-value), ECS Force-Deploy
Externer curl /health 502DNS-Cache, 30s warten. Wenn weiter: Tunnel-Config-Ingress pruefen (Schritt 2 nochmal verifizieren via GET /configurations)
Externer curl /health 200 aber submcps_active: []mcp-replicate-Subprocess startet nicht im Container. Logs zeigen wahrscheinlich REPLICATE_API_TOKEN-Issue → upstream-tokens-Secret-JSON-Format pruefen
Layer-Tool-Call (z.B. create_image) wirft “model-Arg ist malformed”Code-Review-Fix H2 greift — model="flux" ohne Slash. Mit model="black-forest-labs/flux-2-pro" retry
Tool-Call zu replicate_create_model o.ae. wirft “serverseitig deaktiviert”Code-Review-Fix F2 greift wie geplant — Allow-Liste-Pattern. Audit-Event blocked_replicate_admin_tool_attempt in CloudWatch sichtbar

Anti-Scope (NICHT in dieser Session)

  • Phase-B-Refactors (main.py-Split, Pydantic-Models, Integration-Tests) — siehe Code-Review-Run §Phase-B
  • Phase-C-Hardening (Route53-Synthetic-Probe, Subject-Bucket-Fix, Audit-Spam-Throttle) — Code-Review-Run §Phase-C
  • Open WebUI vf-nova-Tool-Whitelist erweitern → erst nach AVV
  • Julian-Live-Test organisieren → separater /termin oder /email
  • mcp-vf-hosted Retrofit fuer W4 (Catalog-Cache) und W6 (CDK-PLACEHOLDER-Guard) — separater Hygiene-PR

Erfolgs-Kriterien Ende der Session

  • https://replicate.agenticventures.de/health returnt 200 mit service: "vf-replicate", submcps_active: ["replicate"], model_whitelist_size: 19
  • Cloudflare-Tunnel 1fb0eb9c-... Status healthy mit 4 QUIC-Connections
  • CloudWatch-Dashboard mcp-replicate-hosted live + zeigt RunningTaskCount=1
  • Marvin hat OAuth-Flow durchgespielt + mindestens ein create_image-Smoke gelaufen (Bild kommt zurueck)
  • F2-Block verifiziert: replicate_get_account rejected mit serverseitig deaktiviert + Audit-Event sichtbar in CloudWatch
  • Capability-File + Plan + Sprint + Tracker auf “live since YYYY-MM-DD” updated
  • Run-Log intern/runs/YYYY-MM-DD-mcp-replicate-hosted-deploy/_index.md angelegt mit Stand
  • Beide Commits (mcp-replicate-hosted Stack-Updates + Vault-Doku) durch

Live-Schaltung an Julian + AVV sind separate Vorgaenge — NICHT Teil dieser Session.

Files die ich brauchen werde

FileZweck
~/source/mcps/mcp-replicate-hosted/infra/lib/mcp-replicate-hosted-stack.tsStack-PLACEHOLDERs ersetzen + Image-Digest pinnen
~/source/mcps/mcp-replicate-hosted/README.mdDeploy-Anleitung als Referenz
mcp-replicate-hostedCapability-File status updaten
scalekitScalekit-MCP-Doku (falls Resource-Anlage hier gemacht wird)
mcp-hosting-fargate-tunnelHosting-Pattern als Referenz
reportAudit-Befunde (alle gefixt, fuer Live-Verifikation)
_indexCode-Review (alle Phase-A gefixt, fuer Live-Verifikation)
_indexAWS-Handover-Steps aus dem Build-Run als Cross-Ref
2026-05-19-design-stack-julianMaster-Plan, Phase-2-Sektion

Cross-Ref