Indigo
beat-mcp conecta tu asistente —Claude Code o Codex— con el sistema de la operación: el ERP de salud, Microsoft Fabric y los modelos de Power BI. Vos preguntás con palabras; él busca, convierte y ejecuta.
Beat — automatizando tu operación.
Cuatro cosas. Todas las pedís hablando normal, sin escribir código y sin abrir otra herramienta.
Conoce el ERP de salud por dentro: sus tablas, vistas y procedimientos, con la lógica de negocio y las normas colombianas que llevan adentro.
Pedile: qué guarda una tabla, qué hace un procedimiento, quién lo usa, qué se rompe si lo cambiás.Pasa consultas del SQL viejo al que entiende Fabric, sin cambiar la lógica. Si algo no se puede traducir, lo avisa en vez de inventarlo.
Pedile: convertí esta consulta, o este lote de vistas, y decime qué quedó dudoso.Crea y ejecuta notebooks y pipelines, consulta las tablas ya publicadas y ordena las carpetas del workspace.
Pedile: armá este notebook y corrélo, consultá esta tabla, ordená estas carpetas.Entra al modelo de un informe: medidas, tablas, relaciones, roles y permisos. Puede leer el DAX, ejecutarlo y compararlo con el dato de origen.
Pedile: listame las medidas, revisá las relaciones, corré este DAX y comparalo.◆ Trabaja con tu usuario, no con uno genérico
Todo lo que hace corre con tu propia cuenta de Indigo, y queda registrado a tu nombre. No hay un segundo inicio de sesión ni contraseñas que guardar.
En Fabric y Power BI eso significa que ves exactamente lo que tu cuenta ya podía ver: los workspaces y modelos donde tenés permiso, ni uno más. El catálogo del ERP funciona distinto: es compartido, así que cualquiera con acceso a la herramienta puede consultar cualquier objeto — sus columnas, sus dependencias y su definición SQL. No trae datos de pacientes, pero sí la lógica del sistema.
Se hace una sola vez y queda listo en todos tus proyectos. El servidor ya está andando — no hay nada que descargar ni levantar. Necesitás dos cosas de entrada: una cuenta @indigo.tech (el servidor autentica contra el Entra corporativo; una cuenta personal o externa no puede entrar) y tu herramienta instalada (claude --version o codex --version debe responder; si no la tenés, pedila por SOPORTE INTERNO). Elegí tu herramienta y tu sistema, y seguí sólo el camino que te queda a la vista:
Herramienta
Sistema
Claude Code · Windows · PowerShell
az version
Si no la tenés, instalala vos — probá primero sin pedirle permiso a nadie:
winget install --id Microsoft.AzureCLI --exact --accept-package-agreements --accept-source-agreements
Si winget te lo niega por permisos de instalación, ahí pedilo por SOPORTE INTERNO en el portal. Cuando termine, cerrá la terminal y abrila de nuevo: hasta que no lo hagas, az no va a aparecer aunque esté instalado.
az login
az login --scope api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user
Si te salteás el segundo, todo lo demás queda bien configurado y aun así ninguna llamada funciona: el error es AADSTS65001, que quiere decir que todavía nadie autorizó a beat-mcp a actuar en tu nombre. Se hace una sola vez.
beat-mcp-headers.bat en la carpeta .claude\scripts de tu usuario — creala si no existe:
mkdir -Force $HOME\.claude\scripts | Out-Null
Es lo que le prueba al servidor que sos vos; se renueva solo.
@echo off for /f "delims=" %%t in ('az account get-access-token --scope api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user --tenant 0ca8ab9f-b553-4b4b-a787-f03c2ccd756d --query accessToken -o tsv') do set "TOKEN=%%t" echo {"Authorization": "Bearer %TOKEN%"}
El for /f va en una sola línea, tal cual está acá. Una versión anterior de esta guía lo partía con ^ y envolvía az en powershell -Command — esa variante imprime el header vacío en algunas máquinas. Si ya la tenías guardada, reemplazá el archivo por este.
Probalo antes de seguir — tiene que imprimir {"Authorization": "Bearer eyJ... con un token largo:
& "$HOME\.claude\scripts\beat-mcp-headers.bat"
Si imprime Bearer y nada después, el problema es la sesión de az o el consentimiento — volvé al paso 2.
TU_USUARIO por el tuyo:
claude mcp add-json beat-mcp --scope user '{\"type\":\"http\",\"url\":\"https://sqlfabric-mcp.livelybay-0e37e766.eastus2.azurecontainerapps.io/mcp\",\"headersHelper\":\"C:\\Users\\TU_USUARIO\\.claude\\scripts\\beat-mcp-headers.bat\",\"headers\":{\"Authorization\":\"Bearer PLACEHOLDER\"}}'
Las barras invertidas antes de cada comilla son necesarias, y va todo en una sola línea. Sin ellas PowerShell se come las comillas y el comando responde Invalid configuration.
La palabra PLACEHOLDER es de relleno y nunca se usa: el archivito del paso anterior la reemplaza por tu credencial real en cada conexión. El valor exacto no importa (verificado) — es solo una convención legible para que el campo no quede vacío.
/mcp: tiene que aparecer beat-mcp como conectado. Listo, ya podés preguntar.Claude Code · macOS · Linux · WSL · bash
command -v az
En macOS:
brew install azure-cli
En Linux o WSL:
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
az login
az login \
--scope api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user
Si te salteás el segundo, todo lo demás queda bien configurado y aun así ninguna llamada funciona: el error es AADSTS65001, que quiere decir que todavía nadie autorizó a beat-mcp a actuar en tu nombre. Se hace una sola vez.
mkdir -p ~/.claude/scripts cat > ~/.claude/scripts/beat-mcp-headers.sh <<'SH' #!/usr/bin/env bash set -uo pipefail SCOPE='api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user' TENANT='0ca8ab9f-b553-4b4b-a787-f03c2ccd756d' token="$(az account get-access-token \ --scope "$SCOPE" \ --tenant "$TENANT" \ --query accessToken -o tsv 2>/dev/null)" || token='' if [ -z "$token" ]; then echo '{}' exit 0 fi printf '{"Authorization": "Bearer %s"}\n' "$token" SH chmod +x ~/.claude/scripts/beat-mcp-headers.sh
El chmod no es opcional: sin él Claude no puede ejecutarlo y el servidor aparece caído sin decir por qué.
$HOME lo resuelve la terminal.
claude mcp add-json beat-mcp --scope user "{\"type\":\"http\",\"url\":\"https://sqlfabric-mcp.livelybay-0e37e766.eastus2.azurecontainerapps.io/mcp\",\"headersHelper\":\"$HOME/.claude/scripts/beat-mcp-headers.sh\",\"headers\":{\"Authorization\":\"Bearer PLACEHOLDER\"}}"
Las comillas dobles de afuera importan: con comillas simples $HOME no se expande y el headersHelper queda apuntando a una ruta que no existe.
La palabra PLACEHOLDER es de relleno y nunca se usa: el archivito del paso anterior la reemplaza por tu credencial real en cada conexión. El valor exacto no importa — es solo una convención legible para que el campo no quede vacío.
/mcp: tiene que aparecer beat-mcp como conectado.Codex · Windows · PowerShell
az version
Si no la tenés, instalala vos — probá primero sin pedirle permiso a nadie:
winget install --id Microsoft.AzureCLI --exact --accept-package-agreements --accept-source-agreements
Si winget te lo niega por permisos de instalación, ahí pedilo por SOPORTE INTERNO en el portal. Cuando termine, cerrá la terminal y abrila de nuevo: hasta que no lo hagas, az no va a aparecer aunque esté instalado.
az login
az login --scope api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user
Si te salteás el segundo, todo lo demás queda bien configurado y aun así ninguna llamada funciona: el error es AADSTS65001, que quiere decir que todavía nadie autorizó a beat-mcp a actuar en tu nombre. Se hace una sola vez.
codex mcp remove beat-mcp
codex mcp add beat-mcp --url https://sqlfabric-mcp.livelybay-0e37e766.eastus2.azurecontainerapps.io/mcp --bearer-token-env-var BEAT_MCP_TOKEN
Queda guardado para todos tus proyectos en %USERPROFILE%\.codex\config.toml. Si el primer comando se queja porque no había nada registrado, seguí de largo.
if (-not (Test-Path $PROFILE)) { New-Item -ItemType File -Path $PROFILE -Force } notepad $PROFILEPegá esto al final, guardá y cerrá:
function codex-beat { $env:BEAT_MCP_TOKEN = az account get-access-token ` --scope api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user ` --tenant 0ca8ab9f-b553-4b4b-a787-f03c2ccd756d ` --query accessToken -o tsv if (-not $env:BEAT_MCP_TOKEN) { Write-Error "No se pudo obtener el token de Azure." return } codex @args }Y activalo:
. $PROFILE
Si al pegarlo PowerShell se queja de que no puede correr el perfil, corré una sola vez Set-ExecutionPolicy -Scope CurrentUser RemoteSigned.
codex mcp get beat-mcp
Va a imprimir varias líneas, con sangría y en el orden que le guste. No las cuentes: fijate que entre ellas aparezcan estos tres valores.
transport ......... streamable_http url ............... https://sqlfabric-mcp.livelybay-0e37e766.eastus2.azurecontainerapps.io/mcp bearer_token_env_var BEAT_MCP_TOKEN
if ($env:BEAT_MCP_TOKEN) { "ok, hay permiso" } else { "vacia: abri Codex con codex-beat" }
Si trabajás dentro de WSL en lugar de PowerShell, seguí el camino de macOS · Linux: ahí az y Codex son los de WSL, que son instalaciones aparte de las de Windows.
⚠ Abrí Codex siempre con codex-beat
No con codex pelado. El atajo es el que pide el permiso nuevo antes de arrancar la sesión — si abrís Codex directo, beat-mcp no va a poder conectarse.
Codex · macOS · Linux · bash
command -v az
En macOS brew install azure-cli; en Linux curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash.
az login
az login \
--scope api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user
Si te salteás el segundo, todo lo demás queda bien configurado y aun así ninguna llamada funciona: el error es AADSTS65001, que quiere decir que todavía nadie autorizó a beat-mcp a actuar en tu nombre. Se hace una sola vez.
codex mcp remove beat-mcp 2>/dev/null || true
codex mcp add beat-mcp \
--url https://sqlfabric-mcp.livelybay-0e37e766.eastus2.azurecontainerapps.io/mcp \
--bearer-token-env-var BEAT_MCP_TOKEN
Queda guardado para todos tus proyectos en ~/.codex/config.toml.
~/.bashrc: es lo que pide un permiso nuevo cada vez que abrís Codex.
codex-beat() {
export BEAT_MCP_TOKEN="$(az account get-access-token \
--scope api://87ffbc1f-29fb-4b30-9495-9d2f2a5e866b/access_as_user \
--tenant 0ca8ab9f-b553-4b4b-a787-f03c2ccd756d \
--query accessToken -o tsv)"
if [ -z "$BEAT_MCP_TOKEN" ]; then
echo "No se pudo obtener el token de Azure." >&2
return 1
fi
command codex "$@"
}
Y activalo:
source ~/.bashrc
codex mcp get beat-mcp
Va a imprimir varias líneas, con sangría y en el orden que le guste. No las cuentes: fijate que entre ellas aparezcan estos tres valores.
transport ......... streamable_http url ............... https://sqlfabric-mcp.livelybay-0e37e766.eastus2.azurecontainerapps.io/mcp bearer_token_env_var BEAT_MCP_TOKEN
[ -n "$BEAT_MCP_TOKEN" ] && echo "ok, hay permiso" || echo "vacia: abri Codex con codex-beat"
⚠ Abrí Codex siempre con codex-beat
No con codex pelado. El atajo es el que pide el permiso nuevo antes de arrancar la sesión — si abrís Codex directo, beat-mcp no va a poder conectarse.
◆ Si algo no entra, es casi siempre una comilla
El paso 3 es el que más falla, y falla parejo: PowerShell se come las comillas del JSON, el comando recibe algo que no es JSON, y contesta Invalid configuration: Invalid input — un mensaje que no menciona ni las comillas ni PowerShell. Copiá el bloque completo y en una sola línea, con las barras invertidas tal cual están. Si igual no entra, avisale a quien te compartió esta guía y pegale el comando que usaste.
La otra que no es culpa tuya: AADSTS50105 ("user is not assigned to a role") al pedir el token. Significa que tu cuenta no está asignada a la app beat-mcp en Entra — no hay nada que configurar de tu lado; pedile la asignación a quien administra Entra ID (o al DRI de beat, que lo tramita).
◆ Por qué el archivito lleva un --tenant fijo
Si trabajás con más de una cuenta de Azure — o tu terminal elige la cuenta según la carpeta en la que estés — sin ese --tenant la credencial sale de la cuenta equivocada según desde dónde abriste el editor. Y no falla de forma obvia: la credencial es válida, solo que de otra organización, así que beat-mcp la rechaza y el error no menciona en ningún momento la carpeta, que es la causa real. Con el --tenant puesto, el archivito se comporta igual desde cualquier lado. Copialo tal cual.
Si algo falla al pegar los comandos, avisale a quien te compartió esta guía.
Una sola idea, y es la que más ahorra tiempo.
◆ Conoce el sistema viejo, no lo nuevo
El catálogo que consulta es el del ERP de origen — el sistema que ya existe. Las tablas nuevas que se construyen en Fabric no están ahí, y eso es normal: son el resultado, no la fuente.
Si buscás por el nombre de una tabla nueva de Fabric, no la va a encontrar. Preguntá por el objeto original, o describí el dato que buscás y dejá que él encuentre de dónde sale.
Puede darte un resumen rápido, pero eso es una orientación. Si la decisión importa, pedile que lo confirme con el código real y que valide contra los datos. Un proceso que corrió bien no garantiza que el número esté bien.
◆ Ya sabe cómo trabajar — no se lo tenés que recordar
Apenas se conecta, el servidor le entrega sus reglas de ruteo. No dependen de tu computadora ni de que instales nada: viajan con la herramienta, así que valen igual en cualquier proyecto y en cualquier editor. Estas son las seis principales:
// lo que recibe al conectarse 1. Antes de razonar sobre una tabla, vista o procedimiento, resolverlo: graph_search → graph_info → graph_sql. Nunca deducir el significado de un nombre. 2. graph_ask es una pista sintetizada por un LLM, no la verdad. Verificar siempre con graph_sql o graph_info. 3. Para traducir SQL entre dialectos: transpile_sql. Nunca a mano. 4. Escribir SQL desde cero para algo que ya existe en el ERP es un error de ruteo: el objeto y su definición real están en el grafo. 5. Las tools de Power BI modifican un modelo existente. Para crear uno, fabric_create_item. 6. Un destino de Fabric NO está en el grafo, y esa ausencia es correcta. Leer el notebook o consultar el endpoint.
Junto con esas reglas recibe también dos avisos sobre defectos del backend y una guía de costos — por eso agrupa los pedidos de Power BI en vez de hacerlos de a uno, y por eso no te pide la definición completa de una tabla cuando alcanza con la lista.
Si aun así lo ves adivinando en vez de consultar, decíselo — es señal de que algo no le llegó.
Pegá cualquiera de estas y cambiale los nombres por los de tu sistema. Los que aparecen acá son de ejemplo: lo que importa es la forma de preguntar, no el objeto. No hace falta decirle qué herramienta usar: la elige él.
¿Qué guarda la tabla dbo.PACIENTES y qué vistas o procedimientos la usan?
¿Qué hace el procedimiento dbo.SP_FacturacionDetallada y de dónde saca los datos?
Buscá todo lo que tenga que ver con facturación y la resolución que estoy reportando.
Mostrame cómo está hecha por dentro la vista Facturacion.ViewEstadisticas.
Si cambio esta tabla, ¿qué informes o procesos se rompen?
Convertí esta consulta para que corra en Fabric y avisame si algo quedó dudoso.
Convertí este lote de vistas y hacé una lista de las que necesitan revisión manual.
Armá un notebook en Fabric con esta consulta, corrélo y decime si terminó bien.
Consultá cuántos registros distintos tiene esta tabla en Fabric.
Listame las medidas del modelo «Ventas» del workspace «Analytics» y mostrame cómo están calculadas.
Revisá las relaciones de ese modelo y decime si hay alguna mal armada.
Traeme de una sola vez las tablas, medidas y relaciones de ese modelo.
Corré esta medida y comparala con el dato del sistema de origen.
Este informe dice que los totales no cuadran. Revisá el cálculo y comprobalo con un mes real.
Este objeto ya lo migramos: comparalo con el original y decime si quedó alguna diferencia.
Funcionan igual en Claude Code y en Codex — es el mismo servidor detrás.
Para saber qué esperar sin entrar en detalle. Son 47 funciones en total, agrupadas por lo que resuelven.
El catálogo completo del ERP, la definición real de cualquier objeto, sus dependencias en las dos direcciones, las tablas ya publicadas en Fabric, y el modelo entero de un informe de Power BI.
Convertir SQL entre versiones, crear y ejecutar notebooks y pipelines, ordenar carpetas del workspace, y crear o ajustar medidas, tablas y relaciones en Power BI.
Borrar nada — ni carpetas, ni informes, ni medidas. Está deshabilitado a propósito y no hay forma de pedírselo. Tampoco inventa: si el catálogo no tiene la respuesta, lo dice en vez de improvisar.
Crear y cambiar medidas, tablas y relaciones funciona, sin pedir nada especial. Lo único apagado es borrar. Pero modifica el modelo real, el que están usando los informes: no hay copia de trabajo ni «deshacer». Antes de tocar algo productivo, confirmá que sea el modelo que querés.
Agrupado por lo que te va a pasar: primero cómo salir de un problema, después cómo no perder tiempo, y al final los detalles que confunden a todos la primera vez.
⚠ Cada tanto hay que reconectar
En Claude Code escribí /mcp y elegí reconectar; en Codex cerrá y volvé a abrir con codex-beat.
Cómo se ve. Las llamadas empiezan a fallar. En Claude Code el mensaje es este:
MCP server "beat-mcp" requires re-authorization (token expired)
No perdiste permisos y no se rompió nada tuyo: se venció tu credencial. Lo que debería renovarla sola hoy no funciona — es un defecto conocido de Claude Code, ya reportado. Reconectar es lo que la renueva.
Cuánto dura. Una credencial nueva vive entre 60 y 90 minutos. Pero tu sesión dura lo que le quede a la que ya estaba guardada en tu máquina, que pueden ser cinco minutos. Por eso a veces aguanta toda la mañana y a veces se cae enseguida: no es tu conexión ni el servidor, es cuánta vida traía la credencial que te tocó.
Y acá está lo que casi nadie sabe: reconectar NO renueva nada si la credencial todavía está viva. Te devuelve la misma que ya tenías. Solo sirve después de que venció.
Lo que sí funciona: cuando se cae, reconectá en ese momento. Ahí sí te dan una credencial nueva y arrancás con la ventana completa en vez de con la sobra. Reconectar "por precaución" antes de algo largo no sirve para nada.
Si te falta una función que deberíamos tener, o seguís viendo una que ya sacamos, es el mismo problema visto de costado: tu sesión se quedó con la lista anterior porque la reconexión falló. Reconectá y se sincroniza.
⚠ «No se pudo guardar» casi siempre es un nombre repetido
Si le pedís crear una medida y te contesta que la transacción no se pudo guardar, el mensaje no dice el motivo real. En la práctica casi siempre es un choque de nombres, y hay dos formas de chocar: la medida se llama igual que una columna de su misma tabla, o igual que otra medida del modelo — los nombres de medida no se pueden repetir en todo el modelo, aunque estén en tablas distintas.
Cambiale el nombre y entra a la primera. Si vas a crear varias de una vez, pedile que las agrupe en una tabla aparte solo para medidas: así no chocan nunca con las columnas y quedan todas juntas.
⚠ Una consulta DAX no te devuelve las filas
Es un defecto conocido de la herramienta de Microsoft, no de Beat: al ejecutar una consulta DAX la respuesta vuelve vacía aunque la consulta sea válida. Comprobado el 30/07/2026 contra un modelo de prueba: una consulta que devuelve una sola fila con un número volvió sin nada. Está reportado a Microsoft.
Por eso, para ver datos no uses Power BI: preguntale a las tablas ya publicadas en Fabric. Lo de Power BI es la estructura — qué medidas hay y cómo están calculadas. Al crear o modificar una medida ya no hace falta que verifiques nada: el servidor la vuelve a leer solo y te muestra el resultado, así que pedirle que liste de nuevo solo paga el arranque dos veces.
Reconectar no arregla todo. Para entrar a un modelo hacen falta dos permisos que no dependen de Beat: que el workspace te tenga como miembro, y que la capacidad tenga habilitada la lectura XMLA. Si el error insiste después de reconectar, pedile a quien administra el workspace que revise esas dos cosas.
⚠ Power BI es lento — pedile varias cosas juntas
Cada consulta a un modelo de Power BI tarda unos 7 segundos, aunque sea para leer una sola medida. Si necesitás ver varias cosas, pedíselas todas en un mismo mensaje («traeme tablas, medidas y relaciones») y las resuelve de una pasada, en vez de esperar 7 segundos por cada una.
Un workspace grande puede tener cientos de objetos, y pedirlos todos de una llena la conversación y la corta. Decile qué tipo buscás: «listame los notebooks», «listame los modelos semánticos».
Te dice qué medidas, tablas, columnas y relaciones tiene un modelo, y cómo están calculadas. No te trae las filas — para eso está la consulta a las tablas ya publicadas en Fabric. Preguntale «qué mide este informe», no «cuánto vendimos».
Si armás un modelo nuevo, va a tener la estructura pero ninguna fila hasta que le pidas actualizarlo. Es normal: los datos se cargan en la actualización, no en la creación.
Para cualquier cosa de Power BI hay que decirle el workspace y el modelo, siempre los dos. Podés usar el nombre visible — escrito tal cual aparece en pantalla, con mayúsculas, guiones bajos y espacios — o el identificador: los dos sirven, y si le pasás un identificador lo resuelve solo.
Y son dos cosas distintas: el workspace es la carpeta, el modelo es uno de los informes que vive adentro. Casi nunca se llaman igual. Si le pasás el mismo nombre para los dos, se queda pegado intentando conectarse a un modelo que no existe. Cuando no sepas el nombre del modelo, pedile primero que liste los modelos de ese workspace.
Algunos objetos de Fabric se piden por identificador — ese código largo con guiones. No lo busques en ningún lado: está en la dirección del navegador cuando tenés el objeto abierto. Copiá y pegá.
Cada modelo de Power BI tiene una versión interna, y los creados hace tiempo rechazan algunas funciones nuevas — por ejemplo el calendario para analizar por fecha. El aviso no aclara el motivo: dice que no pudo crearlo y nada más. Si algo que debería andar no entra, esa es la primera sospecha: pedile que te confirme la versión del modelo.
Si buscás un procedimiento por nombre y no aparece, puede que se haya renombrado al migrar. Buscá por la tabla o el dato: son mucho más estables.
Si marca algo como «requiere revisión» o «no soportado», es real. Casos con lógica compleja (ciclos, condiciones) quedan fuera de la conversión automática y hay que mirarlos a mano.
Si un reporte de negocio dice una cosa y el código dice otra, gana el código. Pedile que te muestre la parte que lo contradice.