MCP Server
Verwalte Cmssy-Workspace-Content aus KI-Agenten mit `@cmssy/mcp-server` — einer MCP-Bridge, die Tools für Seiten, Blöcke, Formulare und Medien über stdio bereitstellt.
Überblick
@cmssy/mcp-server ist ein Model-Context-Protocol-Server, der KI-Agenten (Claude Code, Claude Desktop, jedes MCP-fähige Tool) mit einem Cmssy-Workspace verbindet. Einmal konfiguriert, kann der Agent Seiten auflisten und bearbeiten, Blöcke hinzufügen oder entfernen, Entwürfe veröffentlichen, Formulare verwalten und mehr — ohne je den Editor zu verlassen.
Er wird über npm ausgeliefert und spricht stdio, du betreibst also keinen langlebigen Server: Der Agent startet ihn bei Bedarf über npx.
Was ihn vom HTTP-API unterscheidet
- Workspace-scoped — ein einziges Paar aus Token + Workspace-ID, alles serverseitig durchgesetzt
- High-Level-Tools —
add_block_to_page,publish_page,patch_block_content, kein rohes GraphQL - Tenant-Isolation eingebaut — jede Query wird nach deinem Workspace gefiltert; du kannst nicht versehentlich einen anderen Tenant anfassen
Setup
1. Erstelle ein API-Token
Workspace Settings → API Tokens → Create token. Kopiere den cs_…-Wert sofort — Tokens werden nur einmal angezeigt. Der Scope ist reine Authentifizierung; was das Token darf, bestimmen deine Rolle und das isSuperAdmin-Flag.
2. Finde deine Workspace-ID
Workspace Settings → General hat einen Kopier-Button neben der ID. Es ist derselbe Workspace, an den dein API-Token gebunden ist.
3. Trage ihn in die MCP-Config deines Editors ein
Für Claude Code bearbeite .mcp.json im Projekt-Root (oder ~/.claude/mcp.json für eine globale Installation):
{
"mcpServers": {
"cmssy": {
"command": "npx",
"args": [
"-y",
"@cmssy/mcp-server@latest",
"--token", "cs_your_token_here",
"--workspace-id", "507f1f77bcf86cd799439011",
"--api-url", "https://api.cmssy.io/graphql"
]
}
}
}Umgebungsvariablen-Äquivalente werden ebenfalls unterstützt: CMSSY_API_TOKEN, CMSSY_WORKSPACE_ID, CMSSY_API_URL. Nützlich, wenn du das Token nicht in einer committeten Config-Datei haben willst.
4. Editor neu starten
Claude Code lädt den Server beim nächsten Sessionstart. Du solltest einen cmssy-MCP-Eintrag mit den verfügbaren Tools sehen.
Verfügbare Tools
Seiten
list_pages— alle Seiten auflisten (optionaler Suchfilter auf name/slug/displayName)get_page— vollständige Seite mit allen Blöcken und i18n-Content (per Slug oder ID)create_page/update_page_settings/delete_pagepublish_page/unpublish_page/revert_to_publishedupdate_page_blocks/update_page_layout
Blöcke
add_block_to_page/remove_block_from_pageupdate_block_content— vollständiger Content-Rewrite für jede Blockform (Strings, Arrays, verschachtelte Objekte)patch_block_content— chirurgische HTML-Patches auf String-Feldern (Deep Dive unten)
Formulare
list_forms/get_formcreate_form/update_form/delete_formlist_form_submissions/get_form_submissionupdate_form_submission_status/delete_form_submission
Custom Data Models
Definiere Schemas (ModelDefinitions) und führe CRUD auf ihren Records aus — KI-Agenten können Blogpost-Typen, Produktkataloge, Verzeichniseinträge und mehr provisionieren. Schema/Felder folgen PropertyField aus @cmssy/types; Records werden bei jedem Schreibvorgang gegen das Modell validiert. Erfordert die Workspace-Berechtigungen MODELS_VIEW / MODELS_CREATE / MODELS_EDIT / MODELS_DELETE.
Modelle
list_models— alle ModelDefinitions im Workspace auflistenget_model— ein Modell per id (ObjectId) oder Slug holencreate_model— ein Modell erstellen (name, slug, fields, optionalstatusFieldfür den Record-Lifecycle)update_model— beliebige Felder eines Modells aktualisieren (eine Änderung anfieldslöst beim nächsten Record-Write eine Schema-Migration aus)delete_model— ein Modell löschen — kaskadiert auf alle seine Records
Records
list_records— Records mit MongoDB-artigem Filter (JSON), Sortierung, Pagination und optionalempopulatefür Relationen auflistenget_record— einen einzelnen Record per ID holencreate_record— einen Record erstellen;datanach den Field-Keys des Modells gekeytupdate_record— die Daten eines Records aktualisieren und/oder seinen Status überführen (validiert gegenstatusField.transitions)delete_record— einen Record löschenimport_records— Bulk-Import von bis zu 1000 Records; gibt{ importedCount, errors }zurück
Workspace & Medien
get_workspace_info— Name, Plan, Limits, Nutzungget_site_config— Sprachen, Navigation, aktivierte Featureslist_media— hochgeladene Assets
patch_block_content — chirurgische Edits
Für gezielte Edits an Multi-KB-Content (Docs-Artikel, lange Blogposts) sendet patch_block_content nur den Diff — nicht den ganzen String. Dahinter steckt MongoDB findOneAndUpdate mit $set + arrayFilters, tenant-scoped, atomar. Typischerweise ~10× günstiger in Tokens, als das ganze HTML über update_block_content erneut zu senden.
Drei Operationstypen
insert_before / insert_after
Füge HTML direkt vor/nach einem eindeutigen Marker ein. Der Marker MUSS genau eine Stelle treffen — null oder mehrere Treffer lehnen die Operation mit BAD_USER_INPUT ab.
{
"op": "insert_after",
"marker": "<h2>Pricing</h2>",
"html": "<p>Plans start at $0/month.</p>"
}replace_section
Ersetze alles von startMarker (inklusive) bis endMarker (exklusive). Beide Marker müssen sich eindeutig auflösen lassen.
{
"op": "replace_section",
"startMarker": "<h2>Pricing</h2>",
"endMarker": "<h2>FAQ</h2>",
"html": "<h2>Pricing</h2><p>New plans here.</p>"
}Mehrere Ops in einem Aufruf
Operationen werden der Reihe nach auf das laufende Ergebnis angewendet. Jeder Fehler (fehlender Marker, mehrdeutig usw.) bricht den gesamten Patch ab — kein halb angewendeter Zustand.
{
"pageId": "...",
"blockId": "...",
"locale": "en",
"operations": [
{
"op": "insert_before",
"marker": "<h2>Appendix</h2>",
"html": "<h2>New Section</h2><p>…</p>"
},
{
"op": "replace_section",
"startMarker": "<h2>Pricing</h2>",
"endMarker": "<h2>FAQ</h2>",
"html": "<h2>Pricing</h2><p>Updated.</p>"
}
]
}Wenn eine Operation fehlschlägt
- 0 Treffer — Marker nicht gefunden. Prüfe auf exakte zeichengenaue Übereinstimmung; Whitespace und Attributreihenfolge zählen.
- 2+ Treffer — der Marker ist nicht eindeutig. Füge umgebendes HTML zur Disambiguierung hinzu. Überlappende Treffer zählen (
"aa"in"aaa"zählt als 2), vermeide also ultrakurze Marker. - Feld ist kein String — der anvisierte
fieldPathlöst zu einem Array oder Objekt auf. Nutzeupdate_block_contentfür strukturierte Felder. - Layout-Blöcke nicht unterstützt — Header/Footer und andere Layout-Blöcke laufen über
update_block_content.
patch_block_content vs update_block_content
patch_block_content | update_block_content | |
|---|---|---|
| Wann nutzen | Gezielte Edits an einem HTML-String | Vollständiger Content-Rewrite, beliebige Form |
| Token-Kosten | Proportional zum Diff | Proportional zum gesamten Content |
| Typische Ersparnis | ~10× bei Multi-KB-Content | – |
| Feldtypen | Nur Strings (über fieldPath) | Beliebig (Strings, Arrays, verschachtelte Objekte) |
| Teilweises Scheitern | Ganzer Patch bricht ab — kein halb angewendeter Zustand | Ganzer Write gelingt oder scheitert |
| Layout-Blöcke | Nicht unterstützt | Unterstützt |
Faustregel: Wenn du früher das gesamte HTML erneut geschickt hättest, um einen Absatz zu ändern, nimm patch_block_content. Sonst bleib bei update_block_content.
Troubleshooting
- „Workspace not found“ — das Token gehört nicht zur angegebenen
--workspace-id. Tokens sind auf einen einzigen Workspace gescoped; prüfe das Paar in den Workspace Settings. - „Not authenticated“ — Token abgelaufen oder widerrufen. Erstelle ein neues unter Workspace Settings → API Tokens.
- MCP-Server im Editor nicht sichtbar — starte den Editor nach Config-Änderungen neu. In Claude Code findest du unter Settings → MCP → cmssy die Startup-Logs.
- Rate-Limits / Plan-Limits — der MCP-Server respektiert die Plan-Limits des Workspace (max. Seiten, Storage, KI-Tokens).
get_workspace_infozeigt die aktuelle Nutzung vs. Limits.
Response-Modus (0.6.0)
Seit 0.6.0 akzeptiert jedes Write-Tool einen optionalen Parameter response: "minimal" | "full" (Default "minimal"). Minimal gibt ein kleines Compact-JSON-Ack (~100-200 Bytes) zurück, nur mit den IDs und dem Zustand, den du zum Verketten des nächsten Aufrufs brauchst — nicht die volle mutierte Ressource.
Typische Bulk-Edit-Sessions (Agenten, die dieselbe Docs-Seite ~6-mal anfassen) verbrannten vor 0.6 ~170 kB an zurückgeschicktem HTML pro Seite. Der Minimal-Modus drückt das auf insgesamt ~1 kB — ~95 % weniger Response-Token-Kosten.
Minimal-Ack-Formen
- Seiten-Tools (
create_page,update_page_blocks,update_page_settings,publish_page,unpublish_page,revert_to_published,update_page_layout) —{id, slug, hasUnpublishedChanges, updatedAt}(+publishedbei publish/unpublish) - Block-on-Page-Tools (
add_block_to_page,update_block_content,remove_block_from_page) —{pageId, blockId, hasUnpublishedChanges, updatedAt} - Formular-Tools (
create_form,update_form) —{id, slug, status, updatedAt} - Modell-Tools (
create_model,update_model) —{id, slug, updatedAt} - Record-Tools (
create_record,update_record) —{id, status, updatedAt}
Wann du full wählen solltest
Übergib response: "full", wenn du die volle mutierte Ressource wirklich im selben Aufruf brauchst — z. B. um eine komplette Transformation zu verifizieren, ein servergeneriertes Feld zu lesen oder zu debuggen. Andernfalls hänge einen Lese-Tool-Aufruf an (get_page / get_form / get_model / get_record).
Tools ohne response
Geben bereits ein kompaktes Ack zurück und bleiben unverändert: patch_block_content, alle delete_*, update_form_submission_status, import_records.
Version
Diese Docs beschreiben @cmssy/mcp-server 0.6.0. Der Minimal-Response-Modus (siehe oben) kam mit 0.6.0; patch_block_content kam mit 0.5.0; frühere Versionen haben nur update_block_content. Pinne @cmssy/mcp-server@latest in .mcp.json, um immer die neuesten Tools zu bekommen.