# MCP Tools — Referencia Completa Este documento es el **inventario canónico** de todas las tools MCP disponibles para el agente Acai. Está agrupado por categoría (archivos, módulos, registros, tablas, layout, librerías, hooks, media, navegación, proyecto, git, autenticación, docs) y describe para cada tool su propósito, parámetros clave, qué devuelve y cuándo usarla. Incluye además los **workflows canónicos** para las operaciones más comunes (crear módulo, editar módulo, crear funcionalidad nueva con tabla + detalle, gestionar imágenes de un módulo, editar header/footer, configurar middleware de hook). Léelo antes de cualquier tarea para elegir la secuencia correcta de tools. ## Inventario por categoría ### Archivos | Tool | Acción | Notas | |------|--------|-------| | `acai-view` | Lee un archivo (con rango de líneas opcional) | Ahorra tokens — usa `start_line`/`end_line` | | `acai-glob` | Encuentra archivos por patrón glob | `template/estandar/modulos/**/index-base.tpl` | | `acai-grep` | Busca texto/regex en archivos | Soporta filtro por glob | | `acai-write` | Crea o reescribe un archivo completo | **Editar `index-base.tpl` compila automáticamente** | | `acai-line-replace` | Reemplaza un bloque de líneas validado | Preferida sobre `acai-write` para edits puntuales | | `acai-delete` | Elimina un archivo | Destructivo — confirma primero | Reglas: - Rutas siempre relativas al proyecto. - Editar `index-base.tpl` → compila automáticamente. No necesitas llamar a `compile_module`. - **NO toques** `index.tpl`, `index-twig.tpl`, `builder.json` (autogenerados) ni los archivos de layout protegidos (ver `08-layout-and-libraries.md`). ### Módulos | Tool | Acción | Notas | |------|--------|-------| | `create_module` | Crea un módulo nuevo (carpeta + archivos + compile) | Alternativa a hacer `acai-write` manual del `index-base.tpl`. Genera `moduleId` único añadiendo sufijo aleatorio. | | `compile_module` | Recompila manualmente (rescate) | Solo si los archivos generados están desincronizados. Editar `index-base.tpl` con tools de archivo ya compila. | | `check_module` | Preview del render con datos de ejemplo | Devuelve preview (50 líneas) por defecto; `fullRender:true` para todo | | `check_module_usage` | Lista páginas que usan el módulo | **OBLIGATORIO antes de `delete_module`** | | `delete_module` | Elimina la carpeta del módulo | Destructivo. Si `inUse=true`, deniega — el usuario debe quitarlo de las páginas primero | | `set_module_example_data` | Define datos de ejemplo para preview en el editor | Pasar valores para TODAS las variables del schema | ### Registros (records) | Tool | Acción | Notas | |------|--------|-------| | `list_table_records` | Lista registros con filtros, paginación | Usa `fields` y `truncateText` para ahorrar tokens | | `get_record` | Obtiene un registro completo por `num` | Carga uploads + relations por defecto | | `create_or_update_record` | Crea o actualiza registros | Sin `recordId` → crea. Con `recordId` → actualiza. Acepta array para batch | | `delete_table_records` | Elimina registros (por IDs o `deleteAll`) | **Destructivo permanente** | | `list_page_modules` | Lista módulos colocados en una página Builder | Devuelve sectionIds, posiciones, visibilidad, configVars | | `add_module_to_record` | Añade módulo a una página Builder | Devuelve `sectionId` — úsalo en `set_module_config_vars` | | `remove_module_from_record` | Quita módulo de la página | Por `sectionId` (preferido) o `modulePosition` | | `reorder_module` | Mueve módulo a otra posición | `fromPosition` → `toPosition` | | `toggle_module_visibility` | Muestra/oculta sin borrar | Por `sectionId` | | `get_module_config_vars` | Lee valores actuales de las variables | Por `tableName` + `recordNum` + `sectionId` | | `set_module_config_vars` | Escribe variables del módulo | Devuelve `uploadFields` con `recordNum`+`fieldName` listos para subir imágenes | ### Tablas y campos (schema) Ver `05-tables-and-fields.md` para detalles. Tools: | Tool | Acción | |------|--------| | `list_tables` | Inventario de tablas (sin `cms_`) | | `get_table_schema` | Schema completo. Soporta `minimal:true` y `filterFields:"..."` para ahorrar tokens | | `create_table` | Crea tabla nueva. PREGUNTA al usuario sobre `enlace`/`seoMetas` antes | | `update_table_metadata` | Actualiza el `[meta]`. `newTableName` renombra MySQL (destructivo) | | `delete_table` | Borra tabla. Usa `dryRun:true` primero. `dropData:true` borra datos | | `reorder_tables` | Reordena sidebar admin | | `create_field` | Añade campo a tabla | | `update_field` | Actualiza props. `newFieldName` renombra columna (destructivo). Cambios de `type` pueden truncar datos — surfacea `warnings` | | `delete_field` | Borra campo. `dropColumn:true` borra datos permanentemente | | `reorder_fields` | Reordena los campos del formulario admin | | `regenerate_enlaces` | Regenera URLs de la tabla. `generateAlias:true` para preservar redirects | ### Layout global Ver `08-layout-and-libraries.md`. | Tool | Acción | |------|--------| | `get_layout_field` | Lee `style`/`javascript`/`header`/`footer` del `layout.json` | | `set_layout_field` | Escribe el campo (atómico: actualiza json + regenera tpl + compila). Destructivo | ### Librerías globales | Tool | Acción | |------|--------| | `list_global_libraries` | Lista las URLs `top` (head) y `bottom` (antes de ``) | | `add_global_library` | Añade URL idempotente | | `remove_global_library` | Quita URL idempotente | | `set_global_libraries` | Reemplaza la lista de la sección. Destructivo | ### Hooks (middleware) | Tool | Acción | |------|--------| | `get_hook_middleware` | Lee la config `middleWare` de un hook global | | `set_hook_middleware` | Configura cuándo se ejecuta automáticamente: `[]`, `["allurls"]`, `["-"]` | Ver `06-hooks-and-cmsapi.md` para uso. Crear/editar el `.php` del hook se hace con `acai-write`. ### Media | Tool | Acción | Notas | |------|--------|-------| | `generate_image` | Genera imagen con IA y la guarda en `cms/uploads/generated/` | Devuelve `dockerUrl` y `uploadUrl`/`fullUrl`. **En Forge prefiere `uploadUrl`/`fullUrl`** sobre `dockerUrl` para `upload_record_image` | | `upload_record_image` | Sube imagen a un campo de un registro | Necesita `tableName`, `recordId` (num), `fieldName` real (de relations o `uploadFields`) | | `upload_image_to_assets` | Sube imagen a `/images/` del template (assets globales) | Acepta base64, data URI, URL. Permite resize/quality/format | ### Navegación | Tool | Acción | |------|--------| | `navigate_browser` | Navega el browser preview del usuario a un `enlace` (e.g. `/servicios/`) | ### Proyecto | Tool | Acción | |------|--------| | `get_web_url` | URL del sitio en desarrollo. **OBLIGATORIO** antes de fetch/Playwright. Acuérdate de añadir `?pruebas=1` | | `save_project_styles` | Guarda resumen de estilos en `docs/project-styles.md` | ### Git | Tool | Acción | |------|--------| | `list_git_log` | Lista los últimos commits para que el usuario elija un id de rollback | | (rollback) | Tool de rescate; pide confirmación al usuario | ### Autenticación | Tool | Acción | |------|--------| | `refresh_acai_token` | Renueva el JWT cuando expira (errores 403) | ### Documentación | Tool | Acción | |------|--------| | `read_doc` | Lee un doc del knowledge base completo o por sección. Útil cuando un doc no fue cargado por relevancia o necesitas una sección puntual | | `list_docs` | Lista los docs disponibles con sus títulos y summaries | ## Workflows canónicos ### 1. Crear un módulo nuevo 1. **Estilo del proyecto**: si existe `docs/project-styles.md` léelo. Si no, explora 3-4 módulos representativos (no `custom-*`) y guarda con `save_project_styles`. 2. **Lee la doc relevante** según contenido: `01-builder-fields.md` siempre; `07-css-js-conventions.md` si lleva JS; `06-hooks-and-cmsapi.md` si lleva hook PHP; `02-twig.md` si usa filtros. 3. **`acai-write`** sobre `template/estandar/modulos/_xxxxxx/index-base.tpl` con el HTML/Twig. Si necesita CSS/JS/PHP, escribe también `style.css`, `script.js`, `hook.php`. 4. **Compilación automática** al escribir `index-base.tpl`. Si por algún motivo necesitas forzarla sin tocar el archivo: `compile_module`. 5. **`add_module_to_record`** para colocarlo en una página. Devuelve `sectionId`. 6. **`set_module_config_vars`** para rellenar variables (textos, listas, etc.). Devuelve `uploadFields` con `recordNum`+`fieldName` por cada upload. 7. **Imágenes**: `generate_image` o `upload_record_image` usando el `recordNum` y `fieldName` del paso 6. 8. **`navigate_browser`** al `enlace` de la página para que el usuario vea el resultado. ### 2. Editar un módulo existente 1. `get_module_config_vars` — leer estado actual (vars + recordNums). 2. `acai-view` — leer el rango concreto de `index-base.tpl` que vas a tocar. 3. `acai-line-replace` — modificar el bloque (compila automáticamente). Usa `acai-write` solo si el cambio es masivo. 4. Si cambian variables: `set_module_config_vars` para actualizar valores. ### 3. Gestionar imágenes de un módulo **Tras `set_module_config_vars`** (recomendado): 1. La respuesta incluye `uploadFields` con `{ fieldName, recordNum }` por cada variable upload. 2. Para multi vars con uploads: `uploadFields["records.imagen"]` es array `[{index, fieldName, recordNum}]`. 3. `upload_record_image` con `tableName: "builder_custom"`, `recordId` y `fieldName` de `uploadFields`. **Sin `set_module_config_vars` previo**: 1. `get_module_config_vars` — obtiene `recordNum` de builder_custom. 2. Lee `builder.json` del módulo para encontrar el `fieldName` real (de `vars.NOMBRE.relations.builder_custom`, ej. `image1` — **NO** uses el nombre de la variable). 3. `upload_record_image` con `tableName: "builder_custom"`, `recordId` (recordNum del paso 1), `fieldName` (de relations). Generar imagen primero: 1. `generate_image` con `prompt` + `style`. 2. Usa la URL recomendada que devuelve (`uploadUrl` o `fullUrl` en Forge; `dockerUrl` solo en local). 3. `upload_record_image` con esa URL. ### 4. Crear funcionalidad nueva con tabla + detalle Ejemplo: implementar "Vacantes". 1. **`create_table`** con `tableName: "vacantes"`, `menuType: "multi"`, `enlace: true`, `seoMetas: true`. Pregunta al usuario antes los flags. 2. **`create_field`** para cada campo: `titulo`, `descripcion` (wysiwyg), `salario_minimo` (textfield), `categoria_num` (list desde tabla), `fecha_publicacion` (date), `fecha_expiracion` (date), `visible` (checkbox), `imagen_destacada` (upload). 3. **`acai-write`** sobre `template/estandar/modulos/custom-vacantes/index-base.tpl` con el Twig que usa `thisrecord.*` (sección general que renderiza el detalle de cada registro). 4. (Opcional) **Módulo de listado** `vacantes_listado_xxxxxx` con `'vacantes' | get('visible=1', 'fecha_publicacion DESC', 20)`. 5. (Opcional) **Página índice** `/vacantes/` en `apartados` (Builder) con el módulo de listado dentro. 6. **`navigate_browser`** a un detalle creado para verificar. ### 5. Editar header / footer del sitio Ver `08-layout-and-libraries.md`. 1. `get_layout_field({ field: "header" })` — lee Twig actual. 2. Modifica localmente. 3. `set_layout_field({ field: "header", content: "..." })` — atómico. Sobrescribe `layout.json`, regenera `.tpl` y compila. **NUNCA** uses `acai-write` sobre `custom-header-twig/index-base.tpl` ni `layout.json`. ### 6. Añadir librería global (jQuery, Vue CDN, Google Fonts) 1. `list_global_libraries` — comprueba si ya existe. 2. `add_global_library({ section: "bottom", url: "..." })` para JS, o `top` para CSS/fonts. Para reordenar dependencias: `set_global_libraries` con la lista completa. ### 7. Hook con middleware (auto-ejecutar antes de páginas) 1. **`acai-write`** sobre `hooks/hooks..php` con la lógica. 2. **`get_hook_middleware`** sobre `/hooks//` para ver config actual. 3. **`set_hook_middleware`** con el nuevo `middleWare`: - `[]` → solo cuando se llama explícitamente - `["allurls"]` → antes de cada página - `["cms_apartados-2"]` → solo antes del registro num=2 de apartados ### 8. Gestionar registros de una tabla 1. `list_table_records` con `where`/`order`/`limit`/`fields` (sin `cms_`). 2. `get_record` para uno completo (`tableName`+`recordNum`). 3. `create_or_update_record` para crear/actualizar. Antes consulta el schema con `get_table_schema`. 4. `delete_table_records` para borrar (destructivo permanente). ### 9. Explorar el sitio - `list_table_records` sobre `apartados` para ver páginas. - `list_page_modules` sobre una página para ver módulos. - `get_module_config_vars` para ver datos de un módulo. - `check_module` para preview con datos custom. ### 10. Consultar la documentación bajo demanda Si el knowledge_base no cargó un doc relevante (lo verás en "Other Available Docs") o necesitas una sección puntual con detalle: ``` list_docs() // todos los docs con summary read_doc({ name: "05-tables-and-fields" }) // doc completo read_doc({ name: "06-hooks-and-cmsapi", section: "Hook middleware" }) // sección por heading H2 ``` ## Reglas globales para todas las tools 1. **`tableName` siempre SIN prefijo `cms_`** (excepto en `queryDB` Twig y en el `middleWare` de `set_hook_middleware`). 2. **PK siempre `num`**, nunca `id`. Foreign keys con sufijo `_num`. 3. **Upload fields son arrays** — accede con `[0].urlPath`. 4. **`fieldName` para imágenes** viene de `builder.json` → `vars.NOMBRE.relations.builder_custom` (ej. `image1`), NO del nombre de la variable. 5. **`recordId` para imágenes de módulo** es el `num` de `builder_custom`, NO el `sectionId`. 6. Tras `set_module_config_vars`, **TODAS** las variables (incluidos uploads) reciben `recordNum`+`fieldName` en `uploadFields`. 7. Si un token JWT expira (error 403): `refresh_acai_token` y reintentar. 8. Al pedir URLs del sitio: `get_web_url` SIEMPRE primero. Añade `?pruebas=1` para modo desarrollo. Nunca uses dominios de producción ni `localhost:8080`. 9. Antes de crear archivos, **lee la doc** relevante (`read_doc` si no está en el KB cargado). 10. Operaciones destructivas (`delete_*`, `dropColumn`, `dropData`, `dropTable`, `newTableName`, `newFieldName`, `regenerate_enlaces` sin alias, `set_global_libraries`, `set_layout_field`): **pide confirmación al usuario** si no es trivial.