dynamo-analytics
Levantar el MCP de Dynamo Analytics
Este MCP corre local en tu máquina, transporte
stdio — no hay deploy a Azure, no hay URL pública.
Actúa siempre como tu propio usuario (tu JWT de
sesión de Supabase Auth); nunca usa una clave de servicio. Al
final vas a poder llamar get_my_projects desde Claude
Code y ver una respuesta real de la base de datos QA.
Este manual usa comandos de Claude Code. Para
Claude Desktop el flujo de instalar/loguear/
compilar (§1-3) es idéntico — solo cambia dónde pegás el bloque
JSON final. Para Claude Mobile: no es posible,
stdio exige un proceso local que el celular no puede
correr. Detalle de los tres clientes:
Conectar desde Claude.
0. Qué necesitás antes de empezar
-
Node.js 20+ instalado — corré
node --version, debe imprimirv20.xo más. - El repo
analytics-dynamoclonado en tu máquina. - Un usuario real de Supabase Auth de este proyecto, con acceso a al menos un proyecto con analytics habilitado. Si no tenés uno, pedile a Daniel que te cree un usuario o te agregue a un proyecto.
-
El ambiente contra el que vas a apuntar. Este
manual usa QA (
bxogqotctuurtcgjakfz.supabase.co) porque es el ambiente seguro para probar — no repitas estos pasos contra PROD sin saber lo que hacés.
1. Instalar dependencias del paquete mcp/
Andá a la carpeta mcp/ del repo (NO app/,
son paquetes Node distintos):
cd analytics-dynamo/mcp
npm install
Debe terminar sin errores y crear mcp/node_modules/.
2. Generar tu sesión (npm run login)
El MCP necesita un JWT de sesión guardado en tu disco
(~/.dynamo/analytics-mcp-session.json). Exportá estas
4 variables en la misma terminal donde vas a
correr el comando (no las guardes en ningún archivo commiteado):
export SUPABASE_URL="https://bxogqotctuurtcgjakfz.supabase.co"
export ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ4b2dxb3RjdHV1cnRjZ2pha2Z6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODIxODY5OTcsImV4cCI6MjA5Nzc2Mjk5N30.IL2_oF_UWFuOMZfvD6rJ4g4f87q4f9ioROJrxGss0qg"
export DYNAMO_LOGIN_EMAIL="tu-email@ejemplo.com"
export DYNAMO_LOGIN_PASSWORD="tu-password-de-supabase-auth"
SUPABASE_URL/ANON_KEY de QA de arriba son
públicos (la anon key no es un secreto — es la
misma que ya está commiteada en app/.env.qa.example,
pensada para ir en el cliente). Para DEV/PROD, el ref y su anon key
viven en la skill db_migrations del repo / Dashboard
de Supabase de ese proyecto (Settings → API) — no están en este
manual.
Corré:
npm run login
Qué tenés que ver, una línea final como:
Sesión guardada en ~/.dynamo/analytics-mcp-session.json (permisos 600).
Si en cambio ves Login falló: Invalid login credentials,
tu email/password están mal, o tu usuario no tiene password
configurado (login solo por magic-link/OTP). En ese caso, usá el
fallback OTP:
unset DYNAMO_LOGIN_PASSWORD
export DYNAMO_LOGIN_OTP=1
npm run login
# Te llega un código de 6 dígitos al email. Corré de nuevo con el código:
export DYNAMO_LOGIN_OTP_CODE="123456"
npm run login
Verificación de este paso: corré
cat ~/.dynamo/analytics-mcp-session.json — debe
imprimir un JSON con access_token y
refresh_token. Si el archivo no existe, no sigas hasta
que exista.
3. Compilar el server
npm run build
Debe terminar sin errores y crear mcp/dist/server.js
(verificá con ls dist/server.js).
4. Configurar Claude Code (transporte stdio)
Corré esto desde la raíz del repo
(analytics-dynamo/, no desde mcp/):
claude mcp add dynamo-analytics \
--env SUPABASE_URL=https://bxogqotctuurtcgjakfz.supabase.co \
--env ANON_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ4b2dxb3RjdHV1cnRjZ2pha2Z6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODIxODY5OTcsImV4cCI6MjA5Nzc2Mjk5N30.IL2_oF_UWFuOMZfvD6rJ4g4f87q4f9ioROJrxGss0qg" \
-- node /RUTA/ABSOLUTA/A/analytics-dynamo/mcp/dist/server.js
Reemplazá /RUTA/ABSOLUTA/A/ por la ruta real de tu
clon (ej. /Users/tuusuario/dev/Dynamo/analytics-dynamo/mcp/dist/server.js).
El server no necesita DYNAMO_ACCESS_TOKEN/DYNAMO_REFRESH_TOKEN acá — lee la sesión directo del archivo del paso 2.
Equivalente en JSON (editar a mano)
{
"mcpServers": {
"dynamo-analytics": {
"command": "node",
"args": ["/RUTA/ABSOLUTA/A/analytics-dynamo/mcp/dist/server.js"],
"env": {
"SUPABASE_URL": "https://bxogqotctuurtcgjakfz.supabase.co",
"ANON_KEY": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJ4b2dxb3RjdHV1cnRjZ2pha2Z6Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3ODIxODY5OTcsImV4cCI6MjA5Nzc2Mjk5N30.IL2_oF_UWFuOMZfvD6rJ4g4f87q4f9ioROJrxGss0qg"
}
}
}
}
Claude Desktop: el mismo bloque JSON, pegado en
claude_desktop_config.json (macOS:
~/Library/Application Support/Claude/claude_desktop_config.json).
Reiniciá Claude Desktop después de guardar.
5. Verificar que responde
Reiniciá la sesión de Claude Code (o abrí una nueva) y pedile:
Usá la tool get_my_projects del MCP dynamo-analytics
Qué tenés que ver: una lista JSON con
project_id/name de los proyectos donde tu
usuario tiene acceso y analytics habilitado. Lista vacía
[] = tu usuario no tiene ningún proyecto así (no es un
error del MCP). Error mencionando
La sesión no está autenticada = volvé al paso 2.
6. session_status — el diagnóstico antes de operar
Tool sin parámetros, siempre corrible primero. Te dice quién sos
(email/user_id), contra qué ambiente estás apuntando
(dev/qa/prod/unknown, resuelto del SUPABASE_URL),
vencimiento del access token y versión del server.
Cuando el ambiente resuelto es PROD (o
UNKNOWN), session_status lo marca
explícitamente con PROD ⚠️ /
UNKNOWN ⚠️. Corré esta tool
antes de cualquier operación sensible — es el
mismo mecanismo de anon-key/ref, solo cambia la URL, y es fácil
creer que estás en QA cuando en realidad apuntás a PROD.
7. Cuando el refresh token expira
Si después de mucho tiempo sin usarlo las tools empiezan a fallar
con mensajes de sesión inválida/expirada, repetí el
paso 2 (npm run login) — no hace
falta reconfigurar Claude Code de nuevo.
8. Inventario de tools (26 total)
11 lectura + 6 write + 7 authoring de dashboard_spec +
2 del migrador PBIX. Cada una valida su input y traduce cualquier
error de la base a un mensaje legible en español — nunca se
escapa una excepción cruda.
Lectura
| Tool | Qué hace |
|---|---|
get_my_projects | Proyectos donde tenés acceso y analytics habilitado. |
list_analytics_forms | Forms con analytics habilitado de un proyecto. |
list_dashboards | Dashboards de un proyecto. |
get_form_metrics | Métricas de un form; crea el dashboard si no existe y lo pedís explícito. |
get_field_config | Config de campos visibles/orden de un dashboard. |
get_form_components | Componentes reales del form (requiere admin en el dashboard). |
get_shared_resource_columns | Columnas de un recurso compartido (requiere admin). |
get_dashboard_branding | Whitelabel — logos/colores de la org dueña. |
get_dashboard_presence_config | Config de "net presence" del dashboard. |
get_dashboard_presence_detail | Tabla Detalle de presencia (nunca lanza sin acceso — vacío). |
session_status | Diagnóstico: quién sos, ambiente, expiry, versión (§6). |
Write (requieren rol admin en el dashboard)
| Tool | Qué hace |
|---|---|
create_dashboard | Crea el dashboard de un form (requiere has_analytics). |
set_field_config | Visibilidad/orden/override de chart de un campo. |
grant_dashboard_access | Otorga rol (viewer/analyst/admin) a un usuario. |
revoke_dashboard_access | Revoca acceso de un usuario. |
invite_dashboard_by_email | Invita por email (crea acceso si ya tiene cuenta, invitación si no). |
set_presence_config | Config de identidad/evento/lugar para "net presence". |
Authoring del dashboard_spec (layout del dashboard)
| Tool | Qué hace |
|---|---|
get_spec_format | Schema completo + ejemplos válidos, sin tocar la DB. |
get_dashboard_spec | Lee el spec vigente + su spec_version. |
set_dashboard_spec | Escribe el spec completo (optimistic locking con base_version). |
edit_widget | Agrega/edita/mueve/borra un widget puntual (mismo locking). |
check_spec | Valida forma sin escribir nada (cero DB). |
generate_spec_draft | Sintetiza un draft a partir del estado real, sin escribir nada. |
delete_dashboard_spec | Restablece al diseño legacy (no borra el historial). |
Flujo de escritura: get_dashboard_spec → anotá
spec_version → set_dashboard_spec(..., base_version).
Si alguien más escribió en el medio, da
spec_version_conflict — no es un bug, es el sistema
evitando que dos escrituras se pisen. Repetí la lectura y
reintentá con la versión nueva.
Migrador PBIX (cero uploads, cero escritura en DB)
| Tool | Qué hace |
|---|---|
pbix_extract |
Lee un .pbix de tu disco (formato PBIR) y
devuelve un inventario de páginas/visuales.
|
pbix_propose_spec |
Cruza el inventario con el form real y escribe
report.md + proposed_spec.json en
disco — nunca en la base de datos.
|
No existe una tool pbix_apply: aplicar el spec
propuesto es llamar set_dashboard_spec vos mismo,
después de revisar report.md.
9. Troubleshooting rápido
-
spec_version_conflict— no es un error real, es optimistic locking. Releé el spec y reintentá. -
invalid_spec— el mensaje trae el path exacto del campo que falló. -
"Already Used"al arrancar — sesión rota; repetínpm run login.
Tabla completa de errores y causas: Troubleshooting.