MCP Server
Gérez le contenu d'un workspace Cmssy depuis des agents IA avec `@cmssy/mcp-server` — un pont MCP exposant des outils pages, blocs, formulaires et médias via stdio.
Aperçu
@cmssy/mcp-server est un serveur Model Context Protocol qui relie les agents IA (Claude Code, Claude Desktop, tout outil compatible MCP) à un workspace Cmssy. Une fois configuré, l'agent peut lister et modifier des pages, ajouter ou retirer des blocs, publier des brouillons, gérer des formulaires et plus encore — sans jamais quitter son éditeur.
Il est distribué sur npm et communique en stdio : vous ne faites donc pas tourner de serveur permanent, l'agent le lance à la demande via npx.
Ce qui le distingue de l'API HTTP
- Limité au workspace — une seule paire token + ID de workspace, tout est appliqué côté serveur
- Outils de haut niveau —
add_block_to_page,publish_page,patch_block_content, pas de GraphQL brut - Isolation des tenants intégrée — chaque requête est filtrée par votre workspace ; impossible de toucher accidentellement un autre tenant
Installation
1. Créez un token API
Workspace Settings → API Tokens → Create token. Copiez la valeur cs_… immédiatement — les tokens ne sont affichés qu'une seule fois. Le scope ne couvre que l'authentification ; ce que le token peut faire dépend de votre rôle et du flag isSuperAdmin.
2. Trouvez l'ID de votre workspace
Workspace Settings → General propose un bouton de copie à côté de l'ID. C'est le même workspace que celui lié à votre token API.
3. Ajoutez-le à la config MCP de votre éditeur
Pour Claude Code, éditez .mcp.json à la racine du projet (ou ~/.claude/mcp.json pour une installation globale) :
{
"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"
]
}
}
}Les équivalents en variables d'environnement sont aussi pris en charge : CMSSY_API_TOKEN, CMSSY_WORKSPACE_ID, CMSSY_API_URL. Utile si vous ne voulez pas du token dans un fichier de config commité.
4. Redémarrez l'éditeur
Claude Code charge le serveur au prochain démarrage de session. Vous devriez voir une entrée MCP cmssy avec la liste des outils disponibles.
Outils disponibles
La 0.50.2 expose 81 outils. Ils partagent une forme de nommage - list_* et get_* pour lire, create_* / update_* / delete_* pour écrire, plus des verbes pour les transitions d'état - si bien que le groupe compte plus que le nom pris isolément.
Pages et blocs
list_pages,get_page- l'arborescence et une page avec tous ses blocs et ses langues. La recherche plein textesearch_contentest définie dans le noyau d'outils partagé mais n'est pas exposée par le serveur MCP ; elle est accessible depuis l'assistant dans l'admin.create_page,update_page_settings,delete_page.update_page_settingsdéplace aussi une page viaparentId, ce qui recalcule le slug de tout le sous-arbre.publish_page,unpublish_page,revert_to_published.add_block_to_page,update_block_content,patch_block_content,remove_block_from_page,update_page_blocks,update_page_layout.list_block_types- les types de blocs que votre site enregistre réellement, lus depuis le manifeste stocké par la poignée de main de l'éditeur. Appelez-le avant d'ajouter un bloc : c'est ainsi que vous savez ce que le frontend peut afficher.list_page_types,create_page_type.
Modèles et enregistrements
list_models,get_model,create_model,update_model,delete_model- supprimer un modèle supprime en cascade tous ses enregistrements.list_records,get_record,create_record,update_record,delete_record,import_records(jusqu'à 1000 par appel).
delete_record refuse tant qu'un bloc utilise l'enregistrement, et répond avec les pages concernées. Passez force: true pour supprimer quand même.
Médias
list_media,upload_media,move_media.list_media_folders,create_media_folder,update_media_folder,delete_media_folder.
Formulaires
list_forms,get_form,create_form,update_form,delete_form.list_form_submissions,get_form_submission,update_form_submission_status,delete_form_submission.
Commerce
- Commandes -
list_orders,get_order,create_manual_order,edit_order,update_order_details,mark_order_paid,record_order_payment,record_order_invoice,refund_order,cancel_order,transition_order_fulfillment,get_order_pipeline,set_order_pipeline_stage. - Produits -
list_products,bulk_update_products,bulk_delete_products,set_product_tiers. - Paniers et remises -
list_carts,update_cart_config,clear_cart_config,list_discounts,get_discount,create_discount,update_discount,set_discount_enabled.
Webhooks
list_webhooks,create_webhook,update_webhook,delete_webhook,rotate_webhook_secret,list_webhook_deliveries.list_webhook_event_types- la liste blanche faisant autorité des événements abonnables. Lisez-la plutôt que de deviner un nom d'événement.
Le secret de signature est renvoyé une seule fois, à la création et à la rotation, jamais ensuite.
Espace de travail
get_workspace_info- nom, offre, limites et consommation.get_site_config- langues, navigation, fonctionnalités activées, réglages du panier.list_members,list_roles- lecture seule.
Rien dans cet ensemble ne touche à votre code. Aucun outil n'écrit un fichier, ne modifie un composant ni n'ouvre une pull request : l'IA édite du contenu, et les schémas de blocs restent dans votre dépôt, sous revue.
Brouillons de développement : un bloc pas encore déployé
Chaque outil d'écriture accepte un target optionnel. "draft" (par défaut) modifie le brouillon partagé de la page ; "devDraft" modifie votre propre calque, par utilisateur, qui part de la page actuelle et ne change l'aperçu de personne d'autre.
C'est ce qui permet de composer une page autour d'un type de bloc qui n'existe encore que sur votre machine. Une fois le bloc déployé, promote_dev_draft bascule votre calque sur le brouillon partagé. get_page avec target: "devDraft" renvoie le calque à côté du brouillon partagé, ou null si vous n'en avez pas.
patch_block_content — éditions chirurgicales
Pour des modifications ciblées sur du contenu de plusieurs Ko (articles de docs, longs billets de blog), patch_block_content n'envoie que le diff — pas la chaîne complète. Il s'appuie sur MongoDB findOneAndUpdate avec $set + arrayFilters, limité au tenant, atomique. Typiquement ~10× moins cher en tokens que renvoyer tout le HTML via update_block_content.
Trois types d'opérations
insert_before / insert_after
Insérez du HTML juste avant/après un marqueur unique. Le marqueur DOIT correspondre à exactement un emplacement — zéro ou plusieurs occurrences rejettent l'opération avec BAD_USER_INPUT.
{
"op": "insert_after",
"marker": "<h2>Pricing</h2>",
"html": "<p>Plans start at $0/month.</p>"
}replace_section
Remplace tout depuis startMarker (inclus) jusqu'à endMarker (exclu). Les deux marqueurs doivent se résoudre de façon unique.
{
"op": "replace_section",
"startMarker": "<h2>Pricing</h2>",
"endMarker": "<h2>FAQ</h2>",
"html": "<h2>Pricing</h2><p>New plans here.</p>"
}Plusieurs opérations en un appel
Les opérations s'appliquent dans l'ordre sur le résultat courant. Tout échec (marqueur manquant, ambigu, etc.) annule le patch entier — pas d'état à moitié appliqué.
{
"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>"
}
]
}Quand une opération échoue
- 0 correspondance — marqueur introuvable. Vérifiez la correspondance exacte au caractère près ; les espaces et l'ordre des attributs comptent.
- 2+ correspondances — le marqueur n'est pas unique. Ajoutez du HTML environnant pour lever l'ambiguïté. Les correspondances qui se chevauchent comptent (
"aa"dans"aaa"compte pour 2), évitez donc les marqueurs ultra-courts. - Le champ n'est pas une chaîne — le
fieldPathciblé résout vers un tableau ou un objet. Utilisezupdate_block_contentpour les champs structurés. - Blocs de layout non pris en charge — header/footer et autres blocs de layout passent par
update_block_content.
patch_block_content vs update_block_content
patch_block_content | update_block_content | |
|---|---|---|
| Quand l'utiliser | Éditions ciblées sur une chaîne HTML | Réécriture complète du contenu, toute forme |
| Coût en tokens | Proportionnel au diff | Proportionnel au contenu complet |
| Gain typique | ~10× sur du contenu de plusieurs Ko | – |
| Types de champs | Chaîne uniquement (via fieldPath) | Tous (chaînes, tableaux, objets imbriqués) |
| Échec partiel | Le patch entier est annulé — pas d'état à moitié appliqué | L'écriture entière réussit ou échoue |
| Blocs de layout | Non pris en charge | Pris en charge |
Règle simple : si vous renvoyiez auparavant tout le HTML pour changer un seul paragraphe, utilisez patch_block_content. Sinon, restez sur update_block_content.
Dépannage
- « Workspace not found » — la personne derrière le token n'est pas membre du
--workspace-idindiqué, ou l'identifiant est faux. Un token authentifie une personne ; ce qu'il permet vient du rôle de cette personne dans cet espace. Vérifiez la paire dans Workspace Settings. - « Not authenticated » — token expiré ou révoqué. Créez-en un nouveau depuis Workspace Settings → API Tokens.
- Serveur MCP invisible dans l'éditeur — redémarrez l'éditeur après un changement de config. Dans Claude Code, consultez Settings → MCP → cmssy pour les logs de démarrage.
- Limites de débit / de plan — le serveur MCP respecte les limites du plan du workspace (pages max, stockage, tokens IA).
get_workspace_infomontre l'utilisation actuelle vs les limites.
Mode de réponse
Depuis la 0.6.0, chaque outil d'écriture accepte un paramètre optionnel response: "minimal" | "full" (défaut "minimal"). Minimal renvoie un petit ack JSON compact (~100-200 octets) avec juste les IDs et l'état nécessaires pour enchaîner l'appel suivant — pas la ressource mutée complète.
Les sessions d'édition en masse typiques (agents touchant la même page de docs ~6 fois) brûlaient ~170 Ko de HTML renvoyé par page avant la 0.6. Le mode minimal ramène cela à ~1 Ko au total — ~95 % de réduction du coût en tokens de réponse.
Formes d'ack minimal
- Outils de pages (
create_page,update_page_blocks,update_page_settings,publish_page,unpublish_page,revert_to_published,update_page_layout) —{id, slug, hasUnpublishedChanges, updatedAt}(+publishedpour publish/unpublish) - Outils bloc-sur-page (
add_block_to_page,update_block_content,remove_block_from_page) —{pageId, blockId, hasUnpublishedChanges, updatedAt} - Outils de formulaires (
create_form,update_form) —{id, slug, status, updatedAt} - Outils de modèles (
create_model,update_model) —{id, slug, updatedAt} - Outils d'enregistrements (
create_record,update_record) —{id, status, updatedAt}
Quand opter pour full
Passez response: "full" quand vous avez réellement besoin de la ressource mutée complète dans le même appel — p. ex. pour vérifier une transformation complète, lire un champ généré côté serveur ou déboguer. Sinon, enchaînez avec un outil de lecture (get_page / get_form / get_model / get_record).
Outils sans response
Ils renvoient déjà un ack compact et restent inchangés : patch_block_content, tous les delete_*, update_form_submission_status, import_records.
Version
Cette documentation décrit @cmssy/mcp-server 0.50.2, qui expose 81 outils issus de @cmssy/ai-tools 0.34.0. Repères utiles : patch_block_content en 0.5.0, les réponses minimales en 0.6.0, list_block_types en 0.45.0, le target brouillon de développement en 0.48.0 - promote_dev_draft lui-même n'ayant été exposé qu'en 0.50.2, la suppression sûre d'enregistrements avec force en 0.48.0, les outils de dossiers médias en 0.49.2, clear_cart_config en 0.50.1. Épinglez @cmssy/mcp-server@latest dans .mcp.json pour toujours disposer des outils les plus récents.