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.

24 de abril de 2026

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 niveladd_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

La 0.50.2 expone 81 herramientas. Comparten una forma de nombrado -list_* y get_* para leer, create_* / update_* / delete_* para escribir, más verbos para transiciones de estado-, así que importa más el grupo que el nombre suelto.

Páginas y bloques

  • list_pages, get_page: el árbol de páginas y una página con todos sus bloques e idiomas. La búsqueda de texto completo search_content está definida en el núcleo de herramientas compartido pero no la enlaza el servidor MCP; se alcanza desde el asistente del panel.
  • create_page, update_page_settings, delete_page. update_page_settings también reubica una página vía parentId, lo que recalcula el slug de todo el subárbol.
  • 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: los tipos de bloque que tu sitio registra de verdad, leídos del manifiesto que guarda el handshake del editor. Llámalo antes de añadir un bloque: es como sabes qué puede renderizar el frontend.
  • list_page_types, create_page_type.

Modelos y registros

  • list_models, get_model, create_model, update_model, delete_model: borrar un modelo arrastra en cascada todos sus registros.
  • list_records, get_record, create_record, update_record, delete_record, import_records (hasta 1000 por llamada).

delete_record se niega mientras un bloque siga usando el registro, y responde con las páginas que lo usan. Pasa force: true para borrarlo igualmente.

Medios

  • list_media, upload_media, move_media.
  • list_media_folders, create_media_folder, update_media_folder, delete_media_folder.

Formularios

  • list_forms, get_form, create_form, update_form, delete_form.
  • list_form_submissions, get_form_submission, update_form_submission_status, delete_form_submission.

Comercio

  • Pedidos: 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.
  • Productos: list_products, bulk_update_products, bulk_delete_products, set_product_tiers.
  • Carritos y descuentos: 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 lista autorizada de eventos suscribibles. Léela en vez de adivinar un nombre de evento.

El secreto de firma se devuelve una sola vez, al crear y al rotar, nunca después.

Workspace

  • get_workspace_info: nombre, plan, límites y consumo.
  • get_site_config: idiomas, navegación, funciones activas, ajustes del carrito.
  • list_members, list_roles: solo lectura.

Nada de esto toca tu código. Ninguna herramienta escribe un archivo, edita un componente ni abre un pull request: la IA edita contenido, y los esquemas de bloques siguen en tu repositorio, bajo revisión.

Borradores de desarrollo: un bloque aún sin desplegar

Cada herramienta de escritura acepta un target opcional. "draft" (por defecto) edita el borrador compartido de la página; "devDraft" edita tu propia capa por usuario, que parte de la página actual y no cambia la vista previa de nadie más.

Eso es lo que hace seguro componer una página alrededor de un tipo de bloque que por ahora solo existe en tu máquina. Cuando el bloque se despliega, promote_dev_draft lleva tu capa al borrador compartido. get_page con target: "devDraft" devuelve la capa junto al borrador compartido, o null si no tienes ninguna.

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 fieldPath objetivo resuelve a un array u objeto. Usa update_block_content para 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_contentupdate_block_content
Cuándo usarloEdiciones puntuales sobre una cadena HTMLReescritura completa del contenido, cualquier forma
Coste en tokensProporcional al diffProporcional al contenido completo
Ahorro típico~10× en contenido de varios KB
Tipos de campoSolo cadenas (vía fieldPath)Cualquiera (cadenas, arrays, objetos anidados)
Fallo parcialEl parche entero se aborta — sin estado a medio aplicarLa escritura entera se aplica o falla
Bloques de layoutNo soportadoSoportado

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» — la persona detrás del token no es miembro del --workspace-id indicado, o el id es erróneo. Un token autentica a una persona; lo que puede hacer sale del rol de esa persona en ese 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_info muestra el uso actual frente a los límites.

Modo de respuesta

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} (+published en 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.50.2, que enlaza 81 herramientas de @cmssy/ai-tools 0.34.0. Hitos útiles: patch_block_content llegó en 0.5.0, las respuestas mínimas en 0.6.0, list_block_types en 0.45.0, el target de borrador de desarrollo en 0.48.0, aunque promote_dev_draft no se enlazó hasta 0.50.2, el borrado seguro de registros con force en 0.48.0, las herramientas de carpetas de medios en 0.49.2 y clear_cart_config en 0.50.1. Fija @cmssy/mcp-server@latest en .mcp.json para tener siempre las herramientas más recientes.