Skip to main content
Glama

savia-mcp

MCP Server en Python para integrar la app web SAVIA (savia4.com.ar) con Claude Desktop, usando Playwright para operar el navegador.

In English — An MCP server that exposes a legacy travel-industry ERP as tools an AI assistant can use. The ERP has no public API: network analysis showed all traffic goes through the framework's internal AJAX protocol with server-regenerated widget UUIDs, so a browser is the only viable integration path. The interesting parts are documented below: why HTTP was ruled out, how interactive elements are detected in a DOM with no semantic elements, and how server-side sessions are handled. Written as interoperability tooling for an account I own — read-only by design.

⚠️ SOLO LECTURA. Este MCP es exclusivamente para extraer información (capturas, texto, tablas). Aunque savia_click, savia_escribir y savia_presionar_enter son genéricos y técnicamente podrían usarse para crear o modificar expedientes, órdenes, comprobantes, etc., eso está prohibido por decisión explícita del dueño de la cuenta. Cualquier tarea que requiera crear/modificar algo en SAVIA se hace manualmente, no con este MCP.

Qué es SAVIA (importante para entender el diseño)

SAVIA corre sobre ZK Framework 6.5 (Java, AJAX, ~2012). Esto tiene dos consecuencias:

  • Los IDs del DOM se regeneran en cada carga de página y no son estables entre sesiones (ej. rH8Qk0). Por eso el login se ubica por placeholder del campo (fijo en el servidor), no por ID ni CSS frágil.

  • Las pantallas internas (post-login: reservas, facturación, etc.) no vienen mapeadas de antemano en este proyecto — no había forma de inspeccionarlas sin credenciales válidas. Por eso los tools no son scrapers fijos por pantalla, sino un set de herramientas genéricas (captura de pantalla, texto visible, listar elementos clicables, click por texto, extracción de grillas ZK) para que Claude pueda explorar y operar cualquier pantalla de SAVIA de forma interactiva, viendo lo mismo que ve el usuario.

El flujo de login (usuario + ID de empresa → luego contraseña, en dos pasos) está probado en vivo y funciona contra una cuenta propia. El popup de error de SAVIA usa la clase ZK .z-window-modal (confirmado forzando un error real) — es genérico, sirve para detectar cualquier alerta en cualquier pantalla, no solo el login.

El dashboard post-login (index.zul) ya se conoce: 8 menús superiores (Página Principal, Perfil Empresarial, Tarifarios y Cupos, Proveedores y Egresos, Clientes e Ingresos, Caja y Otros Medios, Contabilidad y Reportes, Soporte y Mesa de Ayuda) y accesos directos como Cotizaciones, Expedientes, Clientes, Órdenes de Ingreso/Egreso, Cronogramas de Salidas, Cajas, Comisiones y Comprobantes. Lo que falta mapear es el detalle de cada pantalla puntual (columnas de cada listado, formularios), por eso los tools siguen siendo genéricos hasta que se elija una pantalla concreta para automatizar.

¿Por qué no hablarle directo por HTTP en vez de un navegador? Se inspeccionó el tráfico real (Network) durante login y navegación: todo pasa por POST /savia/zkau con el protocolo interno de ZK ("AU requests"), cuyo payload referencia UUIDs de widgets que el servidor regenera en cada sesión (uuid_0=c5yPr0, etc.), atados al árbol de componentes vivo en el servidor. No hay ningún endpoint REST/JSON paralelo (se confirmó navegando por varias secciones: 0 requests XHR/fetch fuera de /zkau, un solo dominio). Replicar esto sin navegador implicaría reimplementar buena parte del protocolo cliente de ZK a mano — fragil y se rompe con cualquier update de SAVIA. Por eso el diseño usa Playwright: deja que el navegador real haga esa sincronización.

Related MCP server: MCP Playwright Server

Estructura

savia-mcp/
├── savia_mcp/
│   ├── __init__.py
│   ├── browser.py      # Sesión de Playwright (login, screenshot, ciclo de vida)
│   ├── extractors.py   # Scraping genérico: texto, clicables, grillas ZK
│   └── server.py       # Servidor MCP (stdio) y definición de tools
├── .env.example
├── .env                 # (git-ignored) tus credenciales reales
├── pyproject.toml
├── setup.ps1
└── README.md

Instalación (Windows)

cd "savia-mcp"
.\setup.ps1

Esto crea un entorno virtual .venv, instala dependencias, descarga Chromium para Playwright y genera .env a partir de .env.example.

Después completá tus credenciales en .env:

SAVIA_URL=https://www.savia4.com.ar:8443/savia
SAVIA_USUARIO=tu_usuario
SAVIA_EMPRESA=tu_id_de_empresa
SAVIA_PASSWORD=tu_contraseña
SAVIA_HEADLESS=false

SAVIA_HEADLESS=false deja la ventana de Chrome visible — recomendado mientras se explora la app por primera vez con Claude.

Configurar Claude Desktop

setup.ps1 imprime el snippet listo para copiar. Es de esta forma, en %APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "savia": {
      "command": "C:\\ruta\\a\\savia-mcp\\.venv\\Scripts\\python.exe",
      "args": ["C:\\ruta\\a\\savia-mcp\\savia_mcp\\server.py"]
    }
  }
}

Reiniciá Claude Desktop después de guardar.

Tools disponibles

Tool

Qué hace

savia_login

Login en SAVIA (usa .env salvo que se pasen overrides). Maneja los dos flujos reales: formulario completo (usuario+empresa→password) y el rápido "Hola <nombre>..." que aparece si el navegador ya tiene una sesión previa en el mismo proceso

savia_cerrar_sesiones_duplicadas

Si savia_login falla por límite de sesiones simultáneas de la empresa, cierra las sesiones listadas y completa el login. Desloguea a cualquiera que esté usando ese usuario en otro lado — confirmar antes con esa persona

savia_logout

Cierra la sesión en el servidor (libera el cupo de sesiones de la empresa), no solo el navegador local

savia_cerrar_navegador

Hace logout real y además apaga Chromium, liberando los recursos de Playwright

savia_estado

Sesión activa + URL actual

savia_captura

Screenshot de la pantalla actual (se ve inline en el chat)

savia_texto_pagina

Texto visible de la pantalla (o de un selector)

savia_elementos_clicables

Lista elementos clickeables visibles con su texto (SAVIA no usa <a>/<button>: detecta por cursor:pointer, la única señal confiable en ZK)

savia_click

Click por texto visible o por selector CSS

savia_escribir

Escribe en un campo (por placeholder o selector)

savia_presionar_enter

Enter en un campo — muchas acciones de ZK usan onOK (Enter) en vez de botón

savia_leer_modal

Chequea si hay un popup/alerta de SAVIA visible y devuelve su texto

savia_extraer_tabla

Extrae la primera grilla/listado ZK visible como filas/columnas

savia_navegar

Navega a una ruta relativa dentro de /savia/ (ej. index.zul)

Flujo de uso típico

  1. savia_login

  2. savia_captura para ver dónde quedó la sesión tras el login

  3. savia_elementos_clicables para ver qué se puede tocar en el menú

  4. savia_click con el texto del menú deseado, después savia_captura de nuevo para confirmar

  5. savia_extraer_tabla o savia_texto_pagina para sacar los datos de esa pantalla

Con ese ciclo (captura → clicables → click → captura) se puede mapear cualquier sección de SAVIA sin haber tenido acceso previo, y una vez que se identifica una pantalla puntual que se use seguido (ej. reservas del día), se le puede agregar una función dedicada a extractors.py.

Notas

  • La sesión de SAVIA expira tras 60 minutos de inactividad (mensaje propio de la app). Si un tool falla con error de sesión, volvé a llamar savia_login.

  • SAVIA limita cuántas sesiones simultáneas puede tener la empresa a la vez (confirmado en vivo: 8). Cerrar el navegador sin hacer logout deja la sesión "colgada" del lado del servidor y come ese cupo — por eso savia_logout/savia_cerrar_navegador ahora clickean el botón real de salir en vez de solo cerrar la pestaña. Si igual se llega al límite, savia_cerrar_sesiones_duplicadas lo resuelve (pide confirmación primero porque puede desloguear a alguien más).

  • Las credenciales nunca se hardcodean: viven solo en .env (git-ignored).

  • El navegador persiste entre llamadas a tools dentro del mismo proceso del servidor MCP — no se relanza en cada tool call.

  • No hay API REST/JSON alternativa (confirmado inspeccionando el tráfico de red real): todo pasa por el protocolo interno de ZK. Playwright es la única vía razonable para automatizar SAVIA.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

  • MCP server for AI agents to plan, verify, and deploy Cloudflare-native apps.

  • Managed LinkedIn MCP server for AI agents: search, connect, message and enrich on accounts you own.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/puchocapo95-svg/savia-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server