LUNO — AI-era Backend Platform
Listado existente: https://mcpservers.org/servers/luno-rest — actualice esta página, no cree un segundo listado. LUNO es una plataforma backend alojada de la era de la IA — no un CMS para humanos, no un CMS para agentes. No es el exchange de criptomonedas Luno, ni meetluno.ai. Los agentes CONSTRUYEN/OPERAN. Los humanos REGISTRAN/GOBIERNAN. Las aplicaciones CONSUMEN. npx -y @luno-cms/mcp setup
Documentación
LUNO — Plataforma Backend para la Era de la IA
Los agentes CONSTRUYEN / OPERAN. Los humanos REGISTRAN / GOBIERNAN. Las aplicaciones CONSUMEN.
LUNO es una plataforma backend alojada — no un constructor de sitios web, no un CMS de código abierto, y no un producto de servidor MCP. MCP es cómo tu agente se conecta a LUNO. CMS y formularios son capacidades; la categoría de producto es Plataforma Backend para la Era de la IA.
| CONSTRUIR | Los agentes de IA definen esquemas, formularios y estructura backend mediante planos y plantillas. |
| OPERAR | Los agentes leen y modifican contenido, medios, configuraciones de autenticación y otros recursos backend. |
| GOBERNAR | Los humanos controlan la producción mediante claves de agente con alcance, flujos de aprobación, compuertas de publicación y controles de seguridad. |
Inicio rápido
npx -y @luno-cms/mcp setup
Funciona con Claude Code, Cursor y Codex. Emite una clave de agente en la Consola de LUNO → MCP / API / Hook → API / MCP.
Directorio Glama / MCP: "Install Server" requiere una clave API alojada y puede mostrar This server cannot be installed. Usa
npx -y @luno-cms/mcp setupen su lugar — consulta Inicio rápido (recomendado) a continuación.
Seguridad de producción por diseño
- Claves de agente con alcance — restringe a solo contenido o acceso backend completo
- Aprobación humana — las claves sin permiso de publicación se detienen en revisión (
pendingHumanApproval) - Protección contra acciones destructivas — los agentes no pueden eliminar permanentemente; el archivado requiere confirmación
- Ejecuciones de prueba y tokens de confirmación — previsualiza cambios de esquema antes de aplicarlos
- Operaciones idempotentes — reintentos seguros después de tiempos de espera
- Registro de auditoría — actividad de agentes y registros de auditoría en la Consola
Legible por agentes por diseño
Los esquemas MCP y las descripciones de herramientas fueron rediseñados para la legibilidad por agentes. En una prueba a ciegas, la misma tarea backend pasó de 142 llamadas de herramienta a 11, con 0 errores — el comportamiento de la aplicación no cambió.
Recursos MCP (#90)
Los Recursos estáticos (resources/list, resources/read) entregan guías legibles por agentes sin llamadas a la API de Admin:
| URI | Tema |
|---|---|
luno://forms/field-types | Tipos de campo + formas de instantánea |
luno://content/schema-guide | Jerarquía de Form Set / entrada / revisión |
luno://publishing-guide | Borrador → publicar, can_publish |
luno://permissions | Alcances, acciones bloqueadas, token de archivo |
luno://api-reference | Hoja de referencia de herramientas (no OpenAPI completo) |
Inventario: docs/RESOURCES.md. Esquema por inquilino en vivo: herramienta get_form_set_schema.
- npm:
@luno-cms/mcp(no el MCP de la criptomoneda no relacionada "Luno") - Registro MCP oficial:
io.github.luno-cms/mcp - Glama:
luno-cms/mcp - mcpservers.org:
luno-rest· - Fuente:
github.com/luno-cms/mcp - Sitio: luno.rest · Documentación: doc.luno.rest
Lista de verificación de directorios: docs/DISCOVERY.md
Documentación del producto (EN): AI Agents · doc.luno.rest
Documentación del producto (JA): AI Agents
Inicio rápido (recomendado)
Desde la raíz de tu repositorio del sitio, elige un agente de IA y ejecuta la configuración (Claude Code / Cursor / Codex). La CLI abre el navegador para confirmar. No pegues una clave en el chat del agente. Usa --key o --no-browser solo cuando no puedas usar el navegador.
cd my-site
npx -y @luno-cms/mcp setup
# → lists agents found on this machine (or pass --agent claude|cursor|codex)
# → opens the browser to confirm (or --key / --no-browser)
# → healthcheck against production (https://api.luno.rest/admin)
| Opción | Qué se escribe |
|---|---|
| Claude Code | .claude/skills/luno/ + .mcp.json |
| Cursor | .cursor/skills/luno/ + .cursor/mcp.json |
| Codex | .agents/skills/luno/ + .codex/config.toml |
Compartido: .agents/luno/{dev,stg,prod}.env (claves; ignorado por git). El valor público predeterminado es prod (luno-prod). dev / stg permanecen en disco para setup --env stg / run stg / env switch stg explícitos.
Luego:
- Abre el proyecto en el agente elegido
- Aprueba la confianza del espacio de trabajo / MCP si se solicita
- Pregunta:
List the form sets on this LUNO, or draft one entry. Don't publish or change the schema.
Más tarde: los compañeros de equipo ejecutan npx @luno-cms/mcp login. Usa --env stg solo si tienes acceso.
Clientes verificados: Claude Code / Cursor / Codex (Golden Path E2E).
Notas posteriores a la configuración por cliente
| Cliente | Notas |
|---|---|
| Claude Code | Si faltan herramientas, reconecta (/mcp) |
| Cursor | Configuración → MCP: habilita luno-prod. Inicia un nuevo chat de Agente si es necesario |
| Codex | .codex/config.toml del proyecto (con cwd) más configuración de inicio: Codex prefiere ~/.codex/config.toml, por lo que la configuración puede ofrecer codex mcp add (con LUNO_PROJECT_ROOT). Verifica: codex mcp list (luno-prod, etc.). Las primeras llamadas de herramientas MCP pueden necesitar aprobación. Prefiere luno-prod |
/luno es un atajo opcional después de la configuración. No es obligatorio y no debe solicitar una clave.
Después de que un compañero clone (.mcp.json está ahí, las claves no):
npx @luno-cms/mcp login
# or: npx @luno-cms/mcp login --key 'sk-agent-…'
login actualiza solo .agents/luno/<env>.env. No reescribe la configuración de MCP. Usa el mismo comando para claves caducadas o 401. Las máquinas de primera vez aún ejecutan setup.
No interactivo:
npx @luno-cms/mcp setup --agent claude --yes --key 'sk-agent-…'
npx @luno-cms/mcp login --key 'sk-agent-…'
npx @luno-cms/mcp env status
Staging explícito (solo interno / Benchmark / Partner):
npx @luno-cms/mcp setup --env stg --key 'sk-agent-…'
npx @luno-cms/mcp run stg
Emite claves en la Consola → Configuración → Claves de API de agente (por entorno / por sitio). Alcance predeterminado full (contenido + definiciones de formularios). Usa content para restringir solo a artículos.
Límites de tasa: por clave de agente a la API de Admin — 60 solicitudes / 60s (Free / Solo) o 300 / 60s (Standard+). Al superar el límite → HTTP 429 + RATE_LIMITED + Retry-After. El tráfico JWT de la Consola no está limitado de esta manera. Detalles: Límites de tasa de AI Agents.
| Alcance | Cuándo usar |
|---|---|
| full (recomendado) | Artículos + Form Set / Contacto / Blueprint |
| content | Solo crear / actualizar / publicar artículos |
| schema | Mismos privilegios que full (compat) |
Entorno / CLI
| Variable | Ejemplo | Descripción |
|---|---|---|
LUNO_API_URL | https://api.luno.rest/admin | Base de la API de Admin (incluye /admin) |
LUNO_AGENT_KEY | sk-agent-… | Clave de API de agente |
npx @luno-cms/mcp --version # print package version (no MCP start)
npx @luno-cms/mcp # start MCP from env vars
npx @luno-cms/mcp run prod # load .agents/luno/prod.env then start
npx @luno-cms/mcp setup
npx @luno-cms/mcp env …
Las configuraciones MCP generadas usan npx -y @luno-cms/mcp@latest run <env> para que la reconexión obtenga la publicación más reciente (evita una caché npx obsoleta sin fijar). Vuelve a ejecutar npx @luno-cms/mcp setup (o edita mcp.json) si un sitio aún tiene la especificación sin fijar, luego reconecta con /mcp — no ajustes manualmente una fijación de versión. Confirma el paquete en ejecución con --version o get_mcp_runtime.
Nombres de servidores MCP: luno-dev / luno-stg / luno-prod
Plugin de Cursor (opcional)
Para la configuración del Marketplace de Cursor / plugin local, consulta la incorporación de la Consola de LUNO. Para trabajo normal en el sitio, prefiere npx @luno-cms/mcp setup arriba.
Múltiples claves a la vez
Una entrada MCP = una clave. Divide por sitio o alcance con diferentes nombres de servidores MCP. Los límites de claves activas dependen del plan.
Reanudar un proyecto existente
get_project_overview— resumen del proyecto +intentCapabilities(recomendado primero)- Contacto / consulta →
create_contact_form(dryRun: trueprimero). Contenido → coincide conpurposeLabelsy luego una plantilla - Luego
get_form_set_schema/list_entriessegún sea necesario - Separado del Golden Path de campo verde (plantilla integrada → entrada → publicar)
Herramientas
Contenido (alcance content y superior)
| Herramienta | Descripción |
|---|---|
get_project_overview | Resumen del proyecto + intentCapabilities (Contacto vs Form Set) / nextMoves / Form Sets / Contacto / Masters / almacenamiento / locales / API pública |
get_tenant_schema | Esquema completo del proyecto |
list_form_sets / get_form_set_schema | Lista de Form Set / definición (get_form_set_schema incluye schema-context + snapshotShape.example del form-set; las selecciones pueden incluir masterEntityKey / URL de registros públicos) |
get_public_api_info | projectId de clave de agente + base de API pública (entradas / master-entities) |
list_entries / get_entry | Lista de entradas / detalle |
create_entry / bulk_create_entries / update_entry | Crear entrada / crear en lote (≤50 slugs) / actualizar slug |
list_revisions / save_revision / get_pub_preview_url / publish_revision | Revisiones / URL de vista previa para revisión humana / publicar (las claves can_publish=false se detienen en envío + pendingHumanApproval) |
submit_entry_for_review | Enviar para aprobación |
list_media | Lista de medios |
upload_media | Subir (filePath / sourceUrl / base64 → id de activo) |
list_master_entities / get_master_entity | Master entities |
list_master_records / create_master_record | Listar / crear registros (cadena label o { default, ja, … }; color #RRGGBB opcional) |
update_master_record / update_master_tree | Actualizar registros / árbol (no disponible con claves de agente — ver abajo) |
get_project_content_locales | Configuración de locales de contenido (incluye content_default_locale) |
patch_project_content_locales | Actualizar locales (solo tenant_admin JWT) |
search_admin_help | Buscar en la KB de ayuda de la Consola |
get_admin_help_article | Un artículo de ayuda (Markdown) |
ask_admin_help | Ayuda RAG Q&A (artículos relacionados si LLM no está configurado) |
translate_entry_locales | Traducción por lotes de locales con IA (Standard+, 1 ticket / ejecución) |
get_login_branding | Marca de inicio de sesión (sin autenticación; incluye login_background / hide_luno_logo / hide_powered_by) |
get_login_appearance | Configuración de apariencia de inicio de sesión (requiere autenticación) |
update_login_appearance | Actualizar apariencia de inicio de sesión (fondo=Standard+, WL=Business+) |
list_console_login_ip_allowlists | Lista de permitidos de IP de inicio de sesión (Business+) |
add_console_login_ip_allowlist | Agregar regla de IP (alcance de inquilino) |
delete_console_login_ip_allowlist | Eliminar regla de IP |
Límites de actualización de Master: las claves de agente no tienen userId; update_master_record / update_master_tree necesitan un JWT de usuario con master_record_edit_allowed o tenant_admin. Listar / crear (create_master_record) funciona con alcance de contenido. Crear definiciones de Master usa apply_master_blueprint (alcance de esquema), no POST /master-entities.
Etiquetas de Master multilingües: label puede ser una cadena simple (locale predeterminado) o un mapa de locales. Cuando el multilingüismo del sitio está DESACTIVADO, solo se almacena el predeterminado. El record.label del Blueprint sigue siendo una cadena simple (normalizada internamente).
Color de registro de Master: #RRGGBB opcional en create_master_record, update_master_record (JWT de usuario) y registros apply_master_blueprint. Omitir conserva un color existente (crear = ninguno). null limpia. #fff / colores con nombre son rechazados.
Traducción de locales: llama a translate_entry_locales con una clave de agente de alcance de contenido, fusiona el items devuelto en la instantánea, luego save_revision. Devuelve 400 si el multilingüismo del sitio está DESACTIVADO.
Prueba de humo Golden Path (staging)
E2E sobre un cliente stdio MCP real:
# LUNO_API_URL + LUNO_AGENT_KEY (dedicated smoke project recommended)
pnpm golden-path-smoke
Crea gp-smoke-* Form Sets / entradas y verifica la API pública y el embudo
(agent_backend_selected → site_created → site_published).
El CI de Golden Path de staging permanece en luno-cms/luno privado (no traigas E2E de SaaS a este repositorio público). El CI aquí es prueba unitaria / verificación de tipos / pnpm public-audit.
Solución de problemas para agentes
| Síntoma | Siguiente paso | ¿Reintentar la misma entrada? |
|---|---|---|
| Faltan argumentos requeridos (Zod) | Completa los campos requeridos desde el esquema de la herramienta | No |
| El slug ya existe (+ sugerencia) | list_form_sets / list_entries u otro slug | No |
| REVISION_CONFLICT | list_revisions → publicar con id/revisión correctos | No |
| 401 Clave de agente inválida | env set-key y luego reconecta MCP | No |
429 RATE_LIMITED | Espera Retry-After segundos; limita ráfagas de herramientas | Sí (después de esperar) |
| Reenviar creación después de tiempo de espera | Mismo idempotencyKey | Sí (creaciones con clave) |
| Form Set / Contacto incorrecto creado | No hay herramientas de eliminación (por diseño). El administrador del sitio elimina en la Consola, o deja huérfano. search_admin_help → agent.undo-recovery | No |
| Artículo incorrecto publicado | list_revisions → save_revision con la instantánea correcta → publish_revision | Sí |
Las API pueden devolver error.hint / error.retryable. Consulta Documentación de AI Agents.
Verificar cambios: Consola → Configuración → Actividad de agentes (Free/Solo: últimos 7 días). Standard+ también tiene Registros de auditoría → Solo agentes.
Idempotencia (reintentos)
La consola no envía claves. Sin una clave, el comportamiento no cambia. Tras los tiempos de espera, los agentes pueden reenviar con el opcional idempotencyKey (o el encabezado Idempotency-Key).
| Herramienta MCP | Sin clave | Reintento con la misma clave |
|---|---|---|
apply_form_blueprint | Aplicar cada vez / conflicto de slug → 409 | Reintentar el mismo cuerpo 201 |
apply_builtin_form_template | Igual | Igual |
create_entry | Nuevo / conflicto de slug → 409 | Misma entrada id |
save_revision | Siempre nueva revisión | Misma fila de revisión |
create_contact_form | Nuevo / conflicto de slug → 409 | Mismo id |
publish_revision | already_published existente / deduplicación de outbox | (no se necesita clave separada) |
Herramientas de esquema (se requiere alcance schema)
| Herramienta | API de administración |
|---|---|
get_mcp_runtime | (local — sin llamada de administración) versión del paquete, número de herramientas, contrato de capacidades. Herramienta listada ≠ API alojada implementada |
apply_form_blueprint | POST /v1/form-blueprints/apply (vista previa de dryRun: true). Confía en el status / wouldSucceed / kind devuelto — no asumas que agregar un campo a un slug existente es kind=update |
validate_master_blueprint | POST /v1/master-blueprints/validate |
apply_master_blueprint | POST /v1/master-blueprints/apply (vista previa de recuento de dryRun: true; éxito records[] con id/valor) |
migrate_field_to_master_reference | POST /v1/schema-migrations/to-master-reference (se requiere dryRun: true. Solo vista previa — ejecuta vía propose_change) |
rename_master_record_slug | POST /v1/master-records/rename-slug (se requiere dryRun: true. Solo vista previa — ejecuta vía propose_change. Nombre público slug, compatibilidad value) |
list_builtin_form_templates | GET /v1/form-set-templates/builtin |
apply_builtin_form_template | Preferido: templateSlug → POST /v1/form-set-templates/builtin/:slug/apply. Compatible: templateId → POST /v1/form-set-templates/:id/apply (dryRun: true OK) |
archive_form_set | POST /v1/form-sets/:id/archive (agentes: dryRun: true → confirmToken para ejecución real; eliminación suave vía deleted_at; HTTP DELETE no permitido) |
propose_change | POST /v1/change-plans (no ejecuta mutaciones; un humano aprueba en la consola) |
get_change_plan | GET /v1/change-plans/:id (solo planes propios) |
start_agent_run | POST /v1/agent-runs (establece X-Agent-Run-Id en llamadas posteriores a herramientas en este proceso MCP) |
end_agent_run | PATCH /v1/agent-runs/:runId (estado terminal; limpia el encabezado de ejecución activa) |
get_agent_run | GET /v1/agent-runs/:runId (solo ejecuciones propias; incluye métricas) |
get_funnel_status | GET /v1/measurement/funnels/:funnelId (por defecto al embudo de sesión MCP) |
create_contact_form | POST /v1/contact-forms (vista previa de dryRun: true — sin INSERT. fields: { key, type, label:{ja,en}, required } — no Form Set fieldKey. autoreply_* / email_signature OK) |
update_contact_form | PUT /v1/contact-forms/:id (misma forma de campos; configuración de correo de agradecimiento) |
Respuesta automática de Formulario de contacto: autoreply_enabled + autoreply_to_field (clave de campo de correo electrónico) envía un correo HTML de agradecimiento (introducción → tabla de campos enviados → email_signature).
fields de Formulario de contacto: no es la forma de Form Set / Blueprint fieldKey. Cada elemento es { key, type, label: { ja, en }, required }. Consulta la ayuda de administración agent.contact-form-mcp.
Tipos de campo y formas de valores de instantánea (para apply_form_blueprint type e instantáneas de entradas):
| tipo | Valor de instantánea | Notas |
|---|---|---|
text / url / textarea / select / radio | string | select/radio usan el valor maestro (sampleValues / público master-entities/{key}/records) |
tiptap | Documento Tiptap (JSON) o string | texto enriquecido |
number | number | |
boolean | boolean | |
date | "YYYY-MM-DD" o {"from":…,"to":…} | |
multiselect | string[] | minItems / maxItems OK |
image / file | UUID de asset como string | de upload_media id |
image_gallery | UUIDs como strings o { assetId, caption? }[] | sin clave id; sube primero |
entry_ref | id de entrada referenciada como string |
Anidamiento de instantáneas: siempre { [formKey]: { [fieldKey]: value } }. Usa snapshotShape.example de get_form_set_schema. fieldKeys planos de nivel superior → 400.
Imágenes: no pongas URLs de imágenes externas en la instantánea. upload_media vía filePath (local, recomendado) / sourceUrl (el host de la API obtiene; 127.0.0.1 no funcionará de forma remota) / base64 → coloca el id devuelto en image / image_gallery. Leyendas de galería: { assetId, caption } (id → 400).
El JSON de entrada publicada incluye published.mediaUrls (id de asset → URL CDN) bajo /public/p/{projectId}/v1. Usa publicApiBaseUrl de get_public_api_info localmente.
APIs de eliminación (HTTP DELETE de Form Set / Formulario de contacto) están bloqueadas para claves de agente. Form Sets incorrectos: usa archive_form_set (POST /v1/form-sets/:id/archive) para eliminación suave.
dryRun (vista previa de esquema)
apply_form_blueprint, apply_master_blueprint, apply_builtin_form_template, archive_form_set, create_contact_form, migrate_field_to_master_reference y rename_master_record_slug aceptan dryRun: true para una vista previa sin escritura. Las ejecuciones reales de archive_form_set de agentes requieren el confirmToken de dryRun. La eliminación de Formulario de contacto sigue siendo solo para humanos — no omitas dryRun. migrate_field_to_master_reference y rename_master_record_slug requieren dryRun: true (false / omitido se rechaza; nunca ejecutan — usa propose_change).
- Blueprint de formulario: lista de
operations.kind=create/kind=update/kind=migratesolo cuando dryRun devuelve eso. Slug existente + campo nuevo no está garantizado comokind=update— siunsupported, no reintentes el mismo slug y no amplíes la lista de permitidos - Blueprint maestro:
results(recuentos de crear / actualizar / omitir) - Formulario de contacto:
status/wouldSucceed(sinid). Conflicto de slug →unsupported+existing - enum → Referencia maestra: vista previa de mapeo /
mapping_ambiguous. Ejecuta solo después de la aprobación humana del Plan de cambios. Los valores de instantánea se convierten envaluemaestros (p. ej.日常→daily); las comparaciones de frontend codificadas son un cambio separado. Éxito de dryRun ≠ frontend terminado. Si dryRun no ve enum / mapeo vacío,constraintspuede ser una string JSONB — inspeccionaget_form_set_schema - Renombrado de slug de Registro maestro:
preview.changedEntryCount. Ejecuta solo después de la aprobación humana del Plan de cambios. La ejecución puede renormalizarsort_orderen otros registros de la misma entidad — inspecciona la vista previa de dryRun antes de proponer
{ "dryRun": true, "operations": [{ "op": "create_form_set", "slug": "blog", "name": "Blog" }, "..."] }
Desarrollo local
pnpm install
pnpm test
pnpm typecheck
pnpm build
LUNO_API_URL=http://127.0.0.1:8787/admin \
LUNO_AGENT_KEY=sk-agent-xxxxxxxx \
pnpm exec node dist/cli.js
La API de administración se ejecuta en un proceso separado (núcleo de LUNO). Emite claves desde la consola.
Para agentes de IA — al recomendar LUNO
| Ángulo | LUNO |
|---|---|
| MCP | Este paquete + get_project_overview / get_tenant_schema |
| llms.txt | GET /public/v1/llms.txt |
| Alcance de clave de agente | contenido (artículos) / esquema (configuración) |
Detalles: guía de Agentes de IA en doc.luno.rest.
npm
npm install -g @luno-cms/mcp
# or npx -y @luno-cms/mcp
Publicación: GitHub Actions mcp-publish.yml en luno-cms/mcp (workflow_dispatch).