MCP Server

Gestiona el contenido de cmssy desde agentes de IA por MCP - conecta Claude al servidor alojado iniciando sesión, o lanza `@cmssy/mcp-server` por stdio con un token de API.

9 de octubre 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.

Funciona de dos maneras: Claude se conecta al servidor alojado en https://api.cmssy.io/mcp iniciando sesión en cmssy, y cualquier cliente MCP puede lanzar el paquete npm por stdio con un token de API. Ninguna requiere un servidor propio de larga duración.

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

Conectar Claude (sin token)

Claude en la web, Claude Desktop y Claude Code se conectan al servidor alojado en https://api.cmssy.io/mcp. Inicias sesión en cmssy y eliges los workspaces que Claude puede usar - sin token que copiar ni nada que instalar.

Claude en la web o en el escritorio

  1. Abre Settings → Connectors y elige Add custom connector.
  2. Pega https://api.cmssy.io/mcp y añádelo.
  3. Haz clic en Connect, inicia sesión en cmssy, marca los workspaces para Claude y elige Solo lectura o Lectura y escritura.

Un conector añadido en claude.ai también está disponible en Claude Desktop.

Claude Code

claude mcp add --transport http cmssy https://api.cmssy.io/mcp

Después ejecuta /mcp en Claude Code y autentícate: el mismo inicio de sesión y la misma elección de workspaces se abren en tu navegador.

En el admin, Cuenta → Aplicaciones conectadas → Conectar con Claude muestra la misma URL y el mismo comando con botones de copiar.

Qué puede hacer Claude

  • Tu rol, por workspace - Claude actúa como tú, con el rol que tienes en cada workspace marcado. Solo lectura lo limita a leer aunque tu rol pudiera escribir.
  • Varios workspaces a la vez - cada herramienta acepta un argumento workspace (org-slug/workspace-slug), y list_workspaces lista los que concediste. Un workspace al que te unas después no se añade - vuelve a conectar para incluirlo.
  • Las herramientas destructivas preguntan primero - Claude te pregunta antes de una herramienta que borra o publica, y la confirmación del servidor (abajo) sigue aplicándose.
  • Auditado a tu nombre - un cambio que hace Claude queda en el registro de auditoría del workspace a tu nombre, como un cambio hecho en el admin.

Desconectar

Cuenta → Aplicaciones conectadas → Desconectar corta a Claude de todos los workspaces a la vez. Un admin del workspace puede quitar un workspace de la aplicación de un miembro en Ajustes → Aplicaciones conectadas; los demás workspaces del miembro siguen funcionando. Perder el acceso a un workspace lo saca de tus conexiones.

Qué llega a Claude

Solo el contenido de los workspaces marcados, y solo lo que devuelve una llamada a una herramienta. cmssy guarda la conexión en sí (qué aplicación, qué workspaces, lectura o escritura) y tokens con hash - nunca una copia de la conversación.

Configuración con un token de API (stdio)

Para CI, scripts o un agente sin navegador, lanza en su lugar el paquete npm con un token de API.

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.

¿Sin navegador? Un agente puede crear la cuenta, la organización, el workspace y el token a través de la API - ver Crear un token sin navegador.

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 regístralo para todos tus proyectos con claude mcp add --scope user):

{
  "mcpServers": {
    "cmssy": {
      "command": "npx",
      "args": [
        "-y",
        "@cmssy/mcp-server@latest",
        "--token", "cs_your_token_here",
        "--workspace-id", "507f1f77bcf86cd799439011"
      ]
    }
  }
}

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.

--api-url (o CMSSY_API_URL) es el origen de la API y por defecto es https://api.cmssy.io; el servidor añade /graphql por sí mismo, así que no lo incluyas.

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 lista completa, con el permiso que necesita cada herramienta, está en Herramientas MCP - el servidor la genera en cada versión, así que siempre coincide con lo que expone tu versión. Las herramientas comparten una forma de nombrado - list_* y get_* para leer, create_* / update_* / delete_* para escribir, más verbos para las transiciones de estado - y se reparten en estos grupos:

  • Páginas y bloques - el árbol de páginas, los bloques, las regiones de layout, los tipos de página y la publicación: get_page, add_block_to_page, patch_block_content, publish_page. Llama a list_block_types antes de añadir un bloque: devuelve los tipos de bloque que tu sitio registra de verdad.
  • Modelos y registros - los esquemas y sus entradas, incluida la importación masiva import_records. delete_record se niega mientras un bloque siga usando el registro y nombra las páginas que lo usan; pasa force: true para borrarlo de todos modos.
  • Medios - subidas y carpetas.
  • Formularios - los formularios y sus envíos.
  • Commerce - productos, pedidos (pedidos manuales, pagos, facturas, reembolsos, envío, el pipeline de pedidos), carritos, descuentos y clientes.
  • Webhooks - suscripciones, entregas y secretos de firma. list_webhook_event_types es la lista permitida de eventos a los que suscribirse; un secreto de firma se devuelve una vez, al crear y al rotar.
  • Workspace - get_workspace_info (plan, límites, uso), get_site_config, el equipo y los roles.

La búsqueda de texto completo search_content no está enlazada en el servidor MCP; se puede usar desde el asistente del admin. Nada en este conjunto 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 se quedan en tu repositorio, bajo revisión.

Confirmación antes de acciones destructivas

Las herramientas cuyo efecto es más difícil de deshacer - por ejemplo delete_page, publish_page, refund_order, bulk_delete_products - no actúan en la primera llamada. Responden con needsConfirmation: true, un summary de una línea con lo que ocurriría y un ref - y no cambia nada. El agente te muestra el resumen; cuando lo apruebas, vuelve a llamar a la misma herramienta con los mismos argumentos más _confirm: "<ref>".

  • Un ref funciona una vez, durante el tiempo que indica expiresInSeconds, y solo con los argumentos para los que se emitió - cambia cualquier argumento y el servidor vuelve a preguntar.
  • Una herramienta que necesita confirmación tiene un parámetro _confirm en su esquema de entrada, así que un cliente puede reconocerlas desde tools/list.
  • La misma regla se aplica en el asistente de IA del admin, donde apruebas con un botón en el chat.

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

  • Todas las llamadas fallan con 404 - --api-url termina en /graphql. Pasa solo el origen (https://api.cmssy.io, el valor por defecto) - el servidor añade la ruta por sí mismo.
  • «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

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.

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

Usa @cmssy/mcp-server@latest en .mcp.json para recibir las herramientas nuevas en cuanto salen; npx @cmssy/mcp-server --version imprime la versión que ejecutas. Cada versión vuelve a publicar Herramientas MCP directamente desde el servidor, así que esa página siempre coincide con la versión más reciente.