MCP Server
Gestiona el contenido de un workspace de Cmssy desde agentes de IA con `@cmssy/mcp-server` — un puente MCP que expone herramientas de páginas, bloques, formularios y medios por stdio.
Resumen
@cmssy/mcp-server es un servidor de Model Context Protocol que conecta agentes de IA (Claude Code, Claude Desktop, cualquier herramienta compatible con MCP) con un workspace de Cmssy. Una vez configurado, el agente puede listar y editar páginas, añadir o quitar bloques, publicar borradores, gestionar formularios y más — sin salir nunca de su editor.
Se distribuye por npm y habla stdio, así que no ejecutas un servidor de larga duración: el agente lo lanza bajo demanda vía npx.
En qué se diferencia de la API HTTP
- Acotado al workspace — un único par token + ID de workspace, todo se aplica en el servidor
- Herramientas de alto nivel —
add_block_to_page,publish_page,patch_block_content, no GraphQL crudo - Aislamiento de tenants integrado — cada consulta se filtra por tu workspace; no puedes tocar accidentalmente otro tenant
Configuración
1. Crea un token de API
Workspace Settings → API Tokens → Create token. Copia el valor cs_… inmediatamente — los tokens se muestran una sola vez. El scope es solo autenticación; lo que el token puede hacer lo determinan tu rol y el flag isSuperAdmin.
2. Encuentra el ID de tu workspace
Workspace Settings → General tiene un botón de copiar junto al ID. Es el mismo workspace vinculado a tu token de API.
3. Añádelo a la config MCP de tu editor
Para Claude Code, edita .mcp.json en la raíz del proyecto (o ~/.claude/mcp.json para una instalación global):
{
"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"
]
}
}
}También se admiten equivalentes por variables de entorno: CMSSY_API_TOKEN, CMSSY_WORKSPACE_ID, CMSSY_API_URL. Útil si no quieres el token en un archivo de config commiteado.
4. Reinicia el editor
Claude Code carga el servidor en el siguiente inicio de sesión. Deberías ver una entrada MCP cmssy con la lista de herramientas disponibles.
Herramientas disponibles
Páginas
list_pages— lista todas las páginas (filtro de búsqueda opcional por name/slug/displayName)get_page— página completa con todos los bloques y contenido i18n (por slug o id)create_page/update_page_settings/delete_pagepublish_page/unpublish_page/revert_to_publishedupdate_page_blocks/update_page_layout
Bloques
add_block_to_page/remove_block_from_pageupdate_block_content— reescritura completa del contenido para cualquier forma de bloque (cadenas, arrays, objetos anidados)patch_block_content— parches HTML quirúrgicos sobre campos de cadena (análisis detallado más abajo)
Formularios
list_forms/get_formcreate_form/update_form/delete_formlist_form_submissions/get_form_submissionupdate_form_submission_status/delete_form_submission
Custom Data Models
Define esquemas (ModelDefinitions) y haz CRUD sobre sus registros — los agentes de IA pueden aprovisionar tipos de posts de blog, catálogos de productos, entradas de directorio y más. Los esquemas/campos siguen PropertyField de @cmssy/types; los registros se validan contra el modelo en cada escritura. Requiere los permisos de workspace MODELS_VIEW / MODELS_CREATE / MODELS_EDIT / MODELS_DELETE.
Modelos
list_models— lista todas las ModelDefinitions del workspaceget_model— obtén un modelo por id (ObjectId) o slugcreate_model— crea un modelo (name, slug, fields,statusFieldopcional para el ciclo de vida de los registros)update_model— actualiza cualquier campo de un modelo (cambiarfieldsdispara una migración de esquema en la siguiente escritura de registro)delete_model— elimina un modelo — en cascada sobre todos sus registros
Registros
list_records— lista registros con filtro estilo MongoDB (JSON), orden, paginación ypopulateopcional para relacionesget_record— obtén un registro por idcreate_record— crea un registro;dataindexado por las claves de campo del modeloupdate_record— actualiza los datos de un registro y/o transiciona su estado (validado contrastatusField.transitions)delete_record— elimina un registroimport_records— importación masiva de hasta 1000 registros; devuelve{ importedCount, errors }
Workspace y medios
get_workspace_info— nombre, plan, límites, usoget_site_config— idiomas, navegación, funciones habilitadaslist_media— recursos subidos
patch_block_content — ediciones quirúrgicas
Para ediciones puntuales sobre contenido de varios KB (artículos de docs, posts largos de blog), patch_block_content envía solo el diff — no la cadena completa. Se apoya en MongoDB findOneAndUpdate con $set + arrayFilters, acotado al tenant, atómico. Típicamente ~10× más barato en tokens que reenviar todo el HTML vía update_block_content.
Tres tipos de operación
insert_before / insert_after
Inserta HTML justo antes/después de un marcador único. El marcador DEBE coincidir exactamente con una ubicación — cero o varias coincidencias rechazan la operación con BAD_USER_INPUT.
{
"op": "insert_after",
"marker": "<h2>Pricing</h2>",
"html": "<p>Plans start at $0/month.</p>"
}replace_section
Reemplaza todo desde startMarker (inclusive) hasta endMarker (exclusivo). Ambos marcadores deben resolverse de forma única.
{
"op": "replace_section",
"startMarker": "<h2>Pricing</h2>",
"endMarker": "<h2>FAQ</h2>",
"html": "<h2>Pricing</h2><p>New plans here.</p>"
}Varias operaciones en una llamada
Las operaciones se aplican en orden sobre el resultado en curso. Cualquier fallo (marcador ausente, ambiguo, etc.) aborta el parche completo — sin estados a medio aplicar.
{
"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>"
}
]
}Cuando una operación falla
- 0 coincidencias — marcador no encontrado. Comprueba la coincidencia exacta carácter a carácter; los espacios y el orden de atributos importan.
- 2+ coincidencias — el marcador no es único. Añade HTML circundante para desambiguar. Las coincidencias solapadas cuentan (
"aa"en"aaa"cuenta como 2), así que evita marcadores ultracortos. - El campo no es una cadena — el
fieldPathobjetivo resuelve a un array u objeto. Usaupdate_block_contentpara campos estructurados. - Bloques de layout no soportados — header/footer y otros bloques de layout van por
update_block_content.
patch_block_content vs update_block_content
patch_block_content | update_block_content | |
|---|---|---|
| Cuándo usarlo | Ediciones puntuales sobre una cadena HTML | Reescritura completa del contenido, cualquier forma |
| Coste en tokens | Proporcional al diff | Proporcional al contenido completo |
| Ahorro típico | ~10× en contenido de varios KB | – |
| Tipos de campo | Solo cadenas (vía fieldPath) | Cualquiera (cadenas, arrays, objetos anidados) |
| Fallo parcial | El parche entero se aborta — sin estado a medio aplicar | La escritura entera se aplica o falla |
| Bloques de layout | No soportado | Soportado |
Regla práctica: si antes reenviabas todo el HTML para cambiar un párrafo, usa patch_block_content. En caso contrario, quédate con update_block_content.
Solución de problemas
- «Workspace not found» — el token no pertenece al
--workspace-idindicado. Los tokens están acotados a un solo workspace; comprueba el par en Workspace Settings. - «Not authenticated» — token expirado o revocado. Crea uno nuevo desde Workspace Settings → API Tokens.
- El servidor MCP no aparece en el editor — reinicia el editor tras cambiar la config. En Claude Code, revisa Settings → MCP → cmssy para los logs de arranque.
- Límites de tasa / de plan — el servidor MCP respeta los límites del plan del workspace (páginas máx., almacenamiento, tokens de IA).
get_workspace_infomuestra el uso actual frente a los límites.
Modo de respuesta (0.6.0)
Desde 0.6.0, cada herramienta de escritura acepta un parámetro opcional response: "minimal" | "full" (por defecto "minimal"). Minimal devuelve un pequeño ack JSON compacto (~100-200 bytes) con solo los IDs y el estado que necesitas para encadenar la siguiente llamada — no el recurso mutado completo.
Las sesiones típicas de edición masiva (agentes tocando la misma página de docs ~6 veces) quemaban ~170 kB de HTML devuelto por página antes de 0.6. El modo minimal lo reduce a ~1 kB en total — ~95 % de reducción del coste en tokens de respuesta.
Formas del ack minimal
- Herramientas de páginas (
create_page,update_page_blocks,update_page_settings,publish_page,unpublish_page,revert_to_published,update_page_layout) —{id, slug, hasUnpublishedChanges, updatedAt}(+publisheden publish/unpublish) - Herramientas de bloque-en-página (
add_block_to_page,update_block_content,remove_block_from_page) —{pageId, blockId, hasUnpublishedChanges, updatedAt} - Herramientas de formularios (
create_form,update_form) —{id, slug, status, updatedAt} - Herramientas de modelos (
create_model,update_model) —{id, slug, updatedAt} - Herramientas de registros (
create_record,update_record) —{id, status, updatedAt}
Cuándo optar por full
Pasa response: "full" cuando realmente necesites el recurso mutado completo en la misma llamada — p. ej. para verificar una transformación completa, leer un campo generado por el servidor o depurar. En otro caso, encadena una herramienta de lectura (get_page / get_form / get_model / get_record).
Herramientas que no aceptan response
Ya devuelven un ack compacto y no cambian: patch_block_content, todos los delete_*, update_form_submission_status, import_records.
Versión
Esta documentación describe @cmssy/mcp-server 0.6.0. El modo de respuesta minimal (ver arriba) llegó en 0.6.0; patch_block_content llegó en 0.5.0; las versiones anteriores solo tienen update_block_content. Fija @cmssy/mcp-server@latest en .mcp.json para tener siempre las herramientas más recientes.