mcp-cloud-bereitstellung — Cloud-MCP fuer Kunden
End-to-End-Workflow um den VF-Pattern (Vibe Factory, erstmals 2026-05-02 ausgerollt) auf einen neuen Kunden zu replizieren. Lessons Learned + Realitaets-Korrekturen sind hier eingefangen — die erste VF-Iteration hat ~6 Std gebraucht, mit diesem Skill und dem Repo-Template sollte ein Kunde in ~3 Std live sein (plus 1-2 Tage AVV-Wartezeit fuer Scalekit).
Source of Truth: mcp-vf-hosted — vollstaendiges Cookbook + Architektur. Plan + Threat-Model: alter Pfad ~/source/agent-agentur/runs/2026-05-02-vf-mcp-hosting-plan/plan.md (noch nicht migriert).
Wann triggert dieser Skill
- Kunde will MCP-Tools in claude.ai (nicht Claude Desktop)
- Kunde ist Single-Tenant (eine Person oder eine Org wo alle Tool-Calls als ein User laufen)
- Mehrere unserer Sub-MCPs sollen kombiniert werden (z.B. Buchhaltung + CRM + File-Storage)
- Sub-MCPs existieren schon in
~/source/mcps/(sonst zuerstmcp-eigenbau)
NICHT triggern wenn:
- Nur ein Sub-MCP + lokaler Use-Case → Claude Desktop reicht
- Multi-User mit Pro-User-Permission-Isolation noetig → Phase-6-Plan, separate Architektur (Delegated Auth)
- Ad-hoc / Workshop-Demo → Cloudflare-Tunnel auf Marvins lokalem MCP, siehe claude-custom-connector
Voraussetzungen (vom Kunden)
| Was | Wo |
|---|---|
| API-Tokens fuer alle Sub-MCPs (Papierkram, TicketPAY, M365, …) | Kunde generiert in seinen Tool-Backends, schickt per Signal/Threema |
| M365-Tenant-Admin-Zugriff | falls m365 dabei ist — Kunde oder sein Admin |
| Domain wo Subdomain hinkommt | Default mcp-<kunde>.agenticventures.de (unsere Zone) |
Vor-Entscheidungen (bevor Code-Touch)
| Entscheidung | Default |
|---|---|
| Subdomain-Name | mcp-<kunde>.agenticventures.de (<kunde> = kurzer Name, kein Bindestrich falls vermeidbar) |
| Welche Sub-MCPs? | Liste auf einer Zeile mit Kunde abstimmen — bestimmt was im Mono gemountet wird |
| M365-App: neu oder bestehend reusen? | Default: NEU — independent revocation + Audit-Trail-Trennung. Marvin gegen Bequemlichkeit |
| Mail-Permissions im M365 | Default: NICHT mit reinnehmen ausser Kunde hat klaren Use-Case. Wenn ja: ApplicationAccessPolicy ist Pflicht (Mailbox-Whitelist) |
| Production-Scalekit-Tenant? | Test-Tenant (.scalekit.dev) reicht fuer Dev-Tests. Fuer echten Kunden-Live: Production-Tenant (.scalekit.com) anlegen |
Step-by-Step
0. Vor-Klaerung mit Kunde (~30 Min Call)
- Welche Tools sollen verbunden werden?
- Welcher User ist der Connector-Nutzer? (eine Person, ihre Email)
- Bei M365: welche SharePoint-Site fuer Site-Grant? Welche Mailbox fuer Mail-Tools?
- AVV-Status: braucht der Kunde formellen AVV mit AV (wir) + Scalekit? Bei VF-grossen Kunden ja.
1. Repo-Setup (~15 Min)
# Template kopieren — mcp-vf-hosted ist Referenz
cp -r ~/source/mcps/mcp-vf-hosted ~/source/mcps/mcp-<kunde>-hosted
cd ~/source/mcps/mcp-<kunde>-hosted
# Anpassen:
# - pyproject.toml: name, description
# - src/mcp_<kunde>_hosted/main.py: _SUB_MCP_COMMANDS Dict (welche Sub-MCPs)
# - src/mcp_<kunde>_hosted/main.py: _SUB_MCP_ENV (welche ENV-Vars zu welchem Sub-MCP)
# - .env.example: alle ENV-Keys aktualisieren
# - README.md: Kunden-Name anpassen
# - Modul-Pfad: src/mcp_vf_hosted/ -> src/mcp_<kunde>_hosted/
uv sync --all-extras
uv run pytest # alle 19+ Tests muessen gruen sein2. Scalekit (~15 Min Browser + 1-2 Tage AVV parallel)
- https://app.scalekit.com → Sign up oder existierender Workspace → EU-Region
- Organisation anlegen mit Kunden-Name (z.B. “Vibe Factory”) — User werden in dieser Org verwaltet
- MCP Server anlegen (Dashboard → MCP Servers → New)
- Resource Identifier = die spaetere MCP-URL exakt:
https://mcp-<kunde>.agenticventures.de/mcp
- Resource Identifier = die spaetere MCP-URL exakt:
- Resource ID notieren (
res_...), Environment URL notieren - User fuer Kunde anlegen in der Org: per Email-Invitation. User bekommt Scalekit-Mail mit Magic-Link, setzt Passwort selbst.
- AVV anfordern bei Scalekit Sales/Legal — Email an support@scalekit.com mit Workspace-Name
- Optional: Production-Tenant
.scalekit.comanlegen wenn aus Test-Phase raus (Procedure wiederholbar)
Per API geht alles ausser Account-Anlage — Resource konfigurieren, User anlegen, etc. via REST mit Client-Credentials. Beispiel-Sequenzen in mcp-vf-hosted.
3. M365-App-Registration (wenn m365 dabei, ~30 Min)
Bei Kunden-Tenant einloggen, neue App anlegen:
- Name:
mcp-<kunde>-cloud (Agentic Ventures) - Permissions:
Sites.Selected, optionalFiles.ReadWrite.All, optionalMail.ReadWrite+Mail.Send - Admin-Consent klicken
- Client Secret erstellen, sofort speichern
Site-Grant fuer SharePoint-Site (PowerShell mit Microsoft Graph + Sites.FullControl.All Scope, Snippet in Setup-Doku §1).
ApplicationAccessPolicy wenn Mail-Permissions dabei sind (Exchange Online PowerShell, Mailbox-Whitelist — sonst hat App tenant-weit Zugriff auf alle Mailboxen, gefaehrlich). Snippet in Setup-Doku §1.
4. Mono-Repo + GitHub-Push
# Wenn nicht schon: ~/source/mcps/ ist git-init
cd ~/source/mcps
git add -A && git commit -m "Add mcp-<kunde>-hosted"
git push5. Railway-Deploy (~30 Min)
cd ~/source/mcps/mcp-<kunde>-hosted
# Project anlegen
railway init --name <kunde>-mcp-hosting
# Service mit ENV-Vars (non-secrets gehen via --variables)
railway add --service <kunde>-mcp \
--variables "SCALEKIT_ENV_URL=https://<tenant>.eu.scalekit.dev" \
--variables "SCALEKIT_RESOURCE_ID=res_..." \
--variables "PUBLIC_BASE_URL=https://mcp-<kunde>.agenticventures.de" \
--variables "LOG_LEVEL=INFO" \
--variables "RATE_LIMIT_PER_MINUTE=60" \
--variables "RATE_LIMIT_PER_HOUR=1000" \
--variables "HOST=0.0.0.0" \
--variables "PORT=8080"
# Secrets via stdin (nicht im Bash-Echo, nicht im Log)
echo "$PAPIERKRAM_TOKEN" | railway variables --set-from-stdin "PAPIERKRAM_TOKEN" --skip-deploys
echo "$TICKETPAY_API_KEY" | railway variables --set-from-stdin "TICKETPAY_API_KEY" --skip-deploys
echo "$M365_CLIENT_SECRET" | railway variables --set-from-stdin "M365_CLIENT_SECRET" --skip-deploys
# ... weitere Secrets
echo "$M365_TENANT_ID" | railway variables --set-from-stdin "M365_TENANT_ID" --skip-deploys
echo "$M365_CLIENT_ID" | railway variables --set-from-stdin "M365_CLIENT_ID" --skip-deploys
# Deploy aus lokalem Mono-Repo (Build-Context = ~/source/mcps/)
cd ~/source/mcps && railway up --ci --detach
# Custom Domain
railway domain mcp-<kunde>.agenticventures.de --port 8080
# Output enthaelt CNAME-Target — bei Domain-Hoster (Strato/INWX/...) eintragen6. DNS
Im Domain-Hoster (Strato fuer agenticventures.de):
- Type:
CNAME, Name:mcp-<kunde>, Target:<railway-cname>.up.railway.app - Propagation: meist 5 Min, manchmal 1-15 Min
- TLS-Cert via Railway/Cloudflare automatisch (kann 5-30 Min dauern, manchmal laenger)
7. Pen-Test-Checkliste (~15 Min)
Volle Liste im VF-Plan §7 (Pfad: ~/source/agent-agentur/runs/2026-05-02-vf-mcp-hosting-plan/plan.md — nicht migriert) und in mcp-vf-hosted. Quick-Checks:
URL=https://mcp-<kunde>.agenticventures.de
curl -sI $URL/health # 200
curl -sI $URL/mcp # 401 + WWW-Authenticate mit PRM-Pointer
curl $URL/.well-known/oauth-protected-resource/mcp # JSON mit Scalekit-AS
echo | openssl s_client -servername mcp-<kunde>.agenticventures.de -connect mcp-<kunde>.agenticventures.de:443 2>/dev/null | openssl x509 -noout -subject # CN matched Domain
curl -sI $URL/health | grep -i strict-transport # HSTS header da8. Kunde-Onboarding (~10 Min, davon 3 Min Kunde)
Email-Template: an Kunde mit Anleitung. Andre-Onboarding-Vorlage als Referenz: alter Pfad ~/source/agent-agentur/wiki/kunden/vibe-factory/artefakte/andre-onboarding-claude-ai-mcp.md (noch nicht nach extern/outbound/deliverables/vibe-factory/ migriert).
Wichtig in der Mail:
- Hinweis dass Scalekit eine separate Invitation-Mail schickt (Spam-Folder pruefen)
- Scalekit-Login muss VOR claude.ai-Connect gemacht werden (Passwort setzen)
- 3 Beispiel-Prompts fuer Smoke-Test
- Token-Verbrauchs-Hinweis: Mono-MCP laedt alle Tools, kann teurer werden — Tipp “spezifisch fragen”
Stolperer (Lessons aus VF-Erstausrollung)
- Domain-Schreibweise:
agenticventures.deohne Bindestrich, nichtagentic-ventures.de. Hat bei VF Domain-Korrektur und Scalekit-Resource-PATCH gekostet. - claude.ai Custom-Connector hat kein Bearer-Header-Feld — nur OAuth-Discovery via PRM. Statisches Bearer ist Anti-Pattern, war frueher im Plan, wurde verworfen.
- FastMCP v1 vs v2 API-Drift: Sub-MCPs sind v1 (
mcp.server.fastmcp.FastMCP), Mono ist v2 (fastmcppackage). Direkter Library-Mount bricht. Loesung: stdio-Subprozess +create_proxy()— bleibt unveraendert inmain.py, einfach Liste in_SUB_MCP_COMMANDSanpassen. - TicketPAY-Tools sind fett:
list_tickets(size=5)kann 2 MB JSON liefern → Anthropic Tool-Output-Limit gesprengt. Auto-Compact +count_only=True+fields=[...]sind eingebaut, vor dem Live-Gang testen ob alle Sub-MCPs aehnliche Patterns haben. - HSTS-Header brauchen ASGI-Middleware ueber
app.http_app(middleware=[...])+ uvicorn-Run-Variant. FastMCPadd_middlewareist MCP-protocol-Middleware, nicht HTTP. - Railway-Cert-Provisioning kann 5-30 Min dauern nach DNS-Propagation. Im Worst-Case 1-24h. Geduld oder Domain neu anlegen.
- Strato (rzone.de) als DNS-Hoster funktioniert sauber, kein CAA-Problem. Andere deutsche Hoster ggf. CAA-Record pruefen ob Let’s Encrypt erlaubt ist.
PUBLIC_BASE_URLmuss exakt der Domain entsprechen die im Scalekit-Resource-URI hinterlegt ist und die im claude.ai-Connector eingetragen wird. Sonst Audience-Mismatch in JWT.- Scalekit-Resource ist environment-weit, nicht org-spezifisch — Org “Kunde X” anzulegen ist nice fuer User-Grouping aber nicht zwingend. User in der Org koennen den Connector nutzen ohne Resource-Mapping.
Anti-Patterns
- URL-Path-Token als Bearer-Replacement → Token landet in Cloudflare/Railway-Logs, Browser-History. Nicht.
- Eigenbau-OAuth → Crypto-Risiko, lieber Scalekit/WorkOS/Auth0 nehmen.
- Sub-MCPs modifizieren fuer den Cloud-Use-Case → kapselt schlecht. Stattdessen Proxy-Pattern.
- Secrets im Bash-Echo oder im Chat → wenn Marvin per Signal Token schickt, NICHT in Bash-output rendern; via stdin pipen.
- Cloudflare-Account davorschalten wenn Marvin keinen hat → Plan-§3-Layer-1 sieht das vor, aber pragmatisch reicht Railway-internes Cloudflare. Eigene Cloudflare-Zone als Phase-2-Erweiterung wenn echter WAF-Bedarf.
Roadmap-Hinweise
Wenn Kunde wachst (Multi-User, Pro-User-Permissions): Phase-6-Plan im VF-Plan §14 (alter Pfad ~/source/agent-agentur/runs/2026-05-02-vf-mcp-hosting-plan/plan.md). Erfordert Delegated-Auth-Umbau in mcp-m365 + Tool-Layer-Permissions in mcp-ticketpay + Identity-Mapping. ~1-1.5 Wochen Mehraufwand.
Related
- mcp-vf-hosted — vollstaendiges Cookbook + Architektur (Source of Truth)
- claude-custom-connector — Constraints des UI
- SKILL — wenn vorher noch ein neuer Sub-MCP gebaut werden muss
- mcp-vf-hosted — Repo-Template
- VF-Plan + Threat-Model + Pen-Test-Checkliste:
~/source/agent-agentur/runs/2026-05-02-vf-mcp-hosting-plan/plan.md(noch nicht migriert) - zugriffsmodell — Multi-User-Zugriffsmodell (Phase 6)