Acai Code MCP Server
Servidor MCP (Model Context Protocol) para Acai que permite a Claude y otros agentes IA acceder y manipular el código, módulos, tablas y registros de proyectos Acai.
📋 Contenido
- Instalación Local
- Docker (Producción)
- Configuración de Clientes
- Desarrollo
- Estructura del Proyecto
- Troubleshooting
🚀 Instalación Local
Requisitos
- Node.js >= 16
- npm o yarn
Pasos
- Instalar dependencias
cd server
npm install
- Iniciar el servidor en modo desarrollo
npm start
El servidor estará disponible en http://localhost:3000/sse
- Iniciar con watch mode (recarga automática)
npm run dev
- Verificar que funciona
curl http://localhost:3000/health
Deberías ver:
{
"status": "ok",
"activeSessions": 0,
"mode": "sse"
}
🐳 Docker (Producción)
Requisitos
- Docker instalado
- Docker Compose (opcional pero recomendado)
Construcción de la imagen
# Desde la carpeta server/
docker build -t acai-mcp-server .
Ejecución
Opción 1: Docker Compose (Recomendado)
docker-compose up -d
Esto inicia:
- Servidor MCP en puerto 3000
- Monitor UI en puerto 4545 (opcional)
- Auto-restart habilitado
Detener:
docker-compose down
Opción 2: Docker directo
docker run -d \
--name acai-mcp-server \
--restart unless-stopped \
-p 3000:3000 \
acai-mcp-server
Ver logs
docker logs acai-mcp-server -f
Parar/Reiniciar
docker stop acai-mcp-server
docker start acai-mcp-server
docker restart acai-mcp-server
🔧 Configuración de Clientes
Claude Code (Recomendado)
Crea el archivo .mcp.json en la raíz de tu proyecto:
Opción A: Con X-User-Token (Simple)
{
"mcpServers": {
"acai-code": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:3000/sse",
"--header",
"X-User-Token: {TU_TOKEN_AQUI}"
]
}
}
}
Opción B: Con X-Acai-Token (Completo)
{
"mcpServers": {
"acai-code": {
"command": "npx",
"args": [
"mcp-remote",
"http://localhost:3000/sse",
"--header",
"X-Acai-Token: {TU_TOKEN_AQUI}",
"--header",
"X-Acai-Token-Hash: {TU_TOKEN_HASH_AQUI}",
"--header",
"X-Acai-Website: {TU_DOMINIO_AQUI}"
]
}
}
}
Obtener credenciales
- Abre
https://cms.acaisuite.com/admin.php?debug=1 - Busca en la consola o en los Network headers:
- X-User-Token: Token único (contiene el dominio automáticamente)
- X-Acai-Token: Token de sesión
- X-Acai-Token-Hash: Hash de validación
- X-Acai-Website: Tu dominio
Servidor remoto
Si el Docker está en otra máquina:
{
"mcpServers": {
"acai-code": {
"command": "npx",
"args": [
"mcp-remote",
"http://192.168.1.100:3000/sse",
"--header",
"X-User-Token: {TU_TOKEN_AQUI}"
]
}
}
}
👨💻 Desarrollo
Estructura
server/
├── tools/
│ ├── modules/ # Herramientas para módulos
│ ├── tables/ # Herramientas para tablas
│ ├── records/ # Herramientas para registros
│ ├── files/ # Herramientas para archivos
│ ├── media/ # Herramientas para media
│ ├── auth/ # Herramientas de autenticación
│ └── helpers/ # Utilidades compartidas
├── auth/
│ ├── apiClient.js # Cliente HTTP con auto-login
│ ├── credentials.js # Gestión de credenciales
│ └── index.js # Exportaciones
├── utils/
│ ├── moduleParser.js # Parser de componentes Acai
│ └── remoteParser.js # Parser remoto (appParser)
├── resources/ # Guías y documentación
├── server.js # Punto de entrada principal
├── httpServer.js # Servidor HTTP/SSE
└── package.json
Agregar una nueva herramienta
- Crear archivo
tools/category/toolname.js:
import { z } from "zod";
import { withAuth, getSessionCredentials, getApiClient } from "../../auth/index.js";
import { handleToolError, validateRequired, handleApiResponse } from "../helpers/errorHandler.js";
export function registerMyToolTool(server) {
server.tool(
"my_tool",
"Descripción de la herramienta",
{
param1: z.string().describe("Descripción del parámetro"),
},
withAuth(async ({ param1 }, extra) => {
try {
const credentials = getSessionCredentials(extra.sessionId);
const client = await getApiClient(extra.sessionId);
// Tu lógica aquí
const response = await client.post("/endpoint", {
action_ws: "mi_accion",
});
return {
content: [{ type: "text", text: JSON.stringify(response.data, null, 2) }],
};
} catch (error) {
return handleToolError(error, 'my_tool', { param1 });
}
})
);
}
- Registrar en
tools/category/index.js:
import { registerMyToolTool } from './toolname.js';
export function registerCategoryTools(server) {
// ... otras herramientas
registerMyToolTool(server);
}
- Probar
npm run dev
Scripts disponibles
npm start # Iniciar servidor
npm run dev # Desarrollo con watch
npm test # Ejecutar tests
npm run lint # Verificar linting
📚 Herramientas Disponibles
Módulos (6)
list_modules- Listar módulosget_module- Obtener contenidosave_module- Crear/actualizarcheck_module- Validar sintaxischeck_module_usage- Ver dónde se usadelete_module- Eliminar
Tablas (6)
list_tables- Listar tablasget_table_schema- Ver estructuracreate_table- Crear tablaedit_table_field- Editar campodelete_table_field- Eliminar campoget_table_templates- Obtener templates
Registros (5)
list_records- Listar registrosget_record- Obtener unocreate_record- Crearupdate_record- Actualizardelete_record- Eliminar
Archivos (4)
list_files- Listar archivosread_file- Leer contenidowrite_file- Crear/actualizardelete_file- Eliminar
Media (3)
list_media- Listar mediaupload_media- Subir archivodelete_media- Eliminar
Auth (1)
get_session_info- Info de sesión
🔐 Autenticación
X-User-Token (Recomendado)
- Token único por usuario
- Incluye automáticamente el dominio
- Simplifica la configuración
- Trigger auto-login en primera petición
X-Acai-Token + X-Acai-Token-Hash + X-Acai-Website
- Más flexible
- Permite cambiar dominio
- Requiere 3 headers
- Más control
Auto-login
Si solo envías X-User-Token:
- Se detecta en la conexión SSE
- En la primera petición a una herramienta, se hace login
- Las credenciales se cachean en la sesión
- Las peticiones posteriores usan el token cacheado
🐛 Troubleshooting
Puerto 3000 en uso
# Encontrar proceso en puerto 3000
lsof -i :3000
# Matar proceso
kill -9 <PID>
# O cambiar puerto
MCP_PORT=3001 npm start
Error: "Token no válido" (403)
- Verifica que el token no ha expirado
- Obtén uno nuevo desde
https://cms.acaisuite.com/admin.php?debug=1 - Revisa los logs:
docker logs acai-mcp-server -f
Error: "window is not defined"
- Asegúrate de pasar
listTablesaparseComponents() - Revisa que
remoteParser.jstiene las variables seteadas correctamente
Conexión rechazada
# Verifica que está corriendo
curl http://localhost:3000/health
# Ver logs
npm run dev
# o
docker logs acai-mcp-server -f
Tools no disponibles
- Verifica headers en
.mcp.json - Comprueba que el token es válido
- Revisa los logs del servidor
📝 Variables de entorno
MCP_PORT=3000 # Puerto del servidor MCP
MCP_MONITOR_PORT=4545 # Puerto del Monitor UI
MCP_MONITOR_DISABLED=0 # Desactivar Monitor UI
ACAI_TOKEN=... # Token por defecto (no recomendado)
ACAI_WEBSITE=... # Dominio por defecto
ACAI_TOKEN_HASH=... # Hash por defecto
🔄 Actualizar
Versión local
git pull origin main
npm install
npm start
Docker
# Reconstruir imagen
docker build -t acai-mcp-server .
# Reiniciar contenedor
docker restart acai-mcp-server
📖 Recursos
- Guía Acai:
resources/guia-programacion-acai.md - Atributos:
resources/guia-atributos-acai.md - Twig Filters:
resources/guia-twig-filters.md - Builder Vars:
resources/guia-builder-vars.md - PHP Hooks:
resources/guia-php-hooks.md
🤝 Contribuir
- Fork el proyecto
- Crea una rama:
git checkout -b feature/nueva-herramienta - Haz commit:
git commit -am 'Agregar nueva herramienta' - Push:
git push origin feature/nueva-herramienta - Abre un Pull Request
📞 Soporte
Para problemas o preguntas:
- Revisa los logs:
docker logs acai-mcp-server -f - Verifica la configuración en
.mcp.json - Abre un issue en el repositorio
📄 Licencia
Igual que el proyecto principal de Acai.
Última actualización: Diciembre 2025