Metadata-Version: 2.5
Name: fabric-semantic-mcp
Version: 0.2.0
Summary: MCP server for asking business questions to Microsoft Fabric semantic models. Read-only.
Project-URL: Homepage, https://github.com/PatoSuar3z/fabric-semantic-mcp
Project-URL: Issues, https://github.com/PatoSuar3z/fabric-semantic-mcp/issues
License: MIT
License-File: LICENSE
Keywords: analytics,dax,fabric,mcp,power-bi,semantic-model
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.2
Provides-Extra: dev
Requires-Dist: pytest>=8; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Description-Content-Type: text/markdown

# fabric-semantic-mcp

Preguntas de negocio en lenguaje natural sobre modelos semánticos de Microsoft
Fabric. Solo lectura.

[![PyPI](https://img.shields.io/pypi/v/fabric-semantic-mcp.svg)](https://pypi.org/project/fabric-semantic-mcp/)

```
> ¿cuánto vendimos por categoría el trimestre pasado?

  Categoría A    1.240.500
  Categoría B      880.300
  Categoría C      415.900
```

El DAX que se ejecutó queda siempre a la vista: la respuesta es auditable, no un
número que hay que creer.

## Por qué existe

La respuesta a *"¿cuánto vendimos de esto?"* ya está calculada. Vive en un modelo
semántico, en una medida que alguien escribió con cuidado y que alimenta los
tableros de la empresa. El problema es que consultarla fuera de un tablero
requiere saber DAX, y eso deja a la mayoría esperando que alguien tenga tiempo.

Esta herramienta le da a Claude acceso de lectura a ese modelo, con **las mismas
medidas que ya usan los informes oficiales**. No reemplaza a Power BI: usa lo que
Power BI ya tiene.

## Qué es esto, exactamente

Si ya trabajás con MCP, saltate esta sección.

Claude no puede consultar tus datos por su cuenta: no tiene acceso a tu red, a
tus credenciales ni a tu tenant. **MCP** (Model Context Protocol) es el estándar
que resuelve eso. Un *servidor MCP* es un programa que corre en tu máquina, se
conecta a un sistema que vos ya usás, y le expone a Claude un conjunto acotado de
operaciones —llamadas *tools*— que puede invocar.

Este proyecto es un servidor MCP para modelos semánticos de Fabric. Corre local,
usa tu sesión de Azure, y expone trece operaciones de lectura. Claude decide
cuáles llamar y en qué orden según lo que le preguntes; vos ves cada llamada.

Tres consecuencias que conviene tener claras:

- **Nada sale de tu equipo.** El servidor habla con las APIs de Microsoft usando
  tus credenciales. No hay un servicio intermedio.
- **Claude solo puede hacer lo que las tools permiten.** Si no existe una
  operación de escritura, no hay forma de que escriba, por más que se lo pidas.
- **Podés auditar cada paso.** Las llamadas y sus resultados se ven en la
  conversación, incluido el DAX que se ejecutó.

El paquete incluye además una *skill*: un instructivo que Claude carga al
trabajar con este servidor, y que le impone el orden correcto —inspeccionar el
esquema y verificar los valores reales antes de escribir DAX—. Sin eso, un modelo
de lenguaje inventa nombres de columnas que suenan razonables.

## Instalación

Requiere Python 3.10+, [uv](https://docs.astral.sh/uv/) y
[Azure CLI](https://learn.microsoft.com/cli/azure/install-azure-cli).

```bash
az login
claude mcp add fabric-semantic -- uvx fabric-semantic-mcp
```

No hay que registrar ninguna aplicación en Azure AD ni pedirle permisos a nadie:
se reutiliza la sesión de Azure CLI que ya tenés en tu equipo. Si podés abrir el
modelo en Power BI, podés consultarlo con esta herramienta.

### Otros clientes MCP

En `claude_desktop_config.json`, o el equivalente de tu cliente:

```json
{
  "mcpServers": {
    "fabric-semantic": {
      "command": "uvx",
      "args": ["fabric-semantic-mcp"]
    }
  }
}
```

## Conexión guiada

Pedile a Claude que se conecte a Fabric. El flujo tiene estado, así que el
asistente nunca improvisa el orden ni elige por vos:

| Paso | Qué pasa |
|------|----------|
| Sesión | Verifica Azure. Si no hay sesión, te explica cómo iniciarla |
| Área | Lista tus áreas de trabajo. Elegís por número, nombre o ID |
| Modelo | Lista los modelos semánticos del área. Elegís uno |
| Análisis | Estudia el modelo y te explica cómo está conformado |

El análisis se paga **una sola vez por modelo**: lo aprendido queda cacheado en
`~/.fabric-semantic-mcp/`.

Al terminar no te deja frente a una pantalla en blanco: te devuelve un mapa del
modelo —qué tipo de esquema es, cuál es la tabla de hechos y de qué tamaño, qué
dimensiones tiene y por qué cortes podés preguntar— para que sepas qué preguntar
antes de preguntarlo.

## Qué aprende del modelo

El análisis no se limita a leer nombres de columnas. Extrae:

- **Tablas, columnas y tipos**, descartando las tablas de fecha automáticas que
  Power BI crea por detrás y que solo son ruido.
- **Cada medida con su expresión DAX completa.** Esto permite responder *"¿cómo
  se calcula este indicador?"* sin abrir Power BI Desktop, y evita el error
  clásico de reproducir una medida a mano y obtener un número distinto al del
  tablero.
- **Las relaciones** entre tablas, con su cardinalidad y su dirección real.
- **El rol de cada tabla**: qué es un hecho, qué es una dimensión, qué está
  desconectado. Se deduce de la topología de relaciones y del tamaño de cada
  tabla, no del nombre.
- **Los valores reales** de las columnas de corte de baja cardinalidad.

El último punto es el que más cambia la calidad de las respuestas. El usuario
dice *"exportación"*, el dato dice `EX`. Sin ese perfilado, el filtro devuelve
cero filas y la respuesta es incorrecta.

## Qué se le puede preguntar

> ¿cuánto vendimos por región este año?

> ¿cómo se calcula el margen bruto?

> comparame las ventas de este trimestre contra el anterior

> ¿qué valores puede tomar la columna Estado?

La segunda merece una nota: como el análisis lee la expresión DAX de cada medida,
la herramienta puede explicar cómo está definido un indicador. Es la pregunta que
hoy obliga a abrir Power BI Desktop, y suele ser la más frecuente.

## Preguntas de modelado

Además de responder sobre los datos, la herramienta responde sobre **el modelo
mismo**: cómo está construido, qué tablas son hechos y cuáles dimensiones, cómo
se relacionan y qué se puede cruzar con qué.

> ¿cómo está armado este modelo?

> ¿cuál es la tabla de hechos y cuáles son las dimensiones?

> ¿por qué no puedo cortar las ventas por esta columna?

> ¿qué contiene la tabla de clientes y con qué se relaciona?

Esto sirve para dos cosas distintas. Para quien recién llega a un modelo, es la
forma más rápida de entenderlo sin abrir Power BI Desktop. Y para cualquiera que
vaya a preguntar por los datos, entender la estructura primero evita preguntas
mal planteadas: si una tabla está desconectada del resto, filtrar por ella no va
a cambiar ningún número, y es mejor saberlo antes que después.

La clasificación no se adivina por el nombre de las tablas. Se deduce de la
topología de relaciones —quién está del lado *muchos* y quién del lado *uno*— y
se contrasta con el tamaño real de cada tabla. Esto importa más de lo que parece:
las relaciones se pueden definir en cualquier dirección, y un modelo con
relaciones invertidas engaña a cualquier heurística que solo mire los nombres.

El análisis también señala problemas de modelado que afectan las respuestas:
tablas sin relaciones, relaciones inactivas, y filtros bidireccionales que pueden
producir resultados inesperados al combinar dimensiones.

## Seguridad

**No puede modificar nada.** No existe ninguna operación de escritura en el
servidor. Cualquier consulta que no empiece con `EVALUATE` o `DEFINE` se rechaza
antes de salir de tu computadora.

**No puede ver lo que vos no podés ver.** La autenticación es delegada: el
servidor actúa con tu identidad y tus permisos. No hay service principals ni
credenciales compartidas, y el token nunca se escribe a disco.

**Solo consulta modelos semánticos**, nunca lakehouses ni warehouses. Esa
restricción es deliberada, y es la garantía principal de la herramienta:

> El modelo semántico aplica Row Level Security. El SQL endpoint de un lakehouse
> no. Una herramienta que consulta lakehouses puede devolverle a una persona
> filas que su propio tablero le oculta. Al limitarse al modelo semántico, esta
> herramienta hereda exactamente los permisos que tu organización ya definió, y
> no puede exponer un solo dato nuevo.

Todas las herramientas declaran `readOnlyHint`, así que tu cliente MCP puede
mostrarte que este servidor no modifica nada.

## Cómo funciona

Dos APIs de Microsoft, cada una para lo que sabe hacer:

- **Fabric API** (`api.fabric.microsoft.com`) descubre áreas de trabajo y
  modelos, y devuelve la definición TMDL.
- **Power BI API** (`api.powerbi.com`) ejecuta el DAX vía `executeQueries`.

### Por qué el esquema no se lee con DAX

Lo intuitivo sería pedir la metadata con `INFO.TABLES()` e `INFO.MEASURES()`. No
funciona: `executeQueries` bloquea las funciones de metadata y las DMVs, y
devuelve el error opaco `3239575574`.

La ruta que sí funciona es `getDefinition` de la Fabric API, que devuelve el
**TMDL completo** del modelo. Sale mejor que la idea original: el TMDL trae
además la expresión DAX de cada medida, que `INFO.*` nunca hubiera dado.

No se necesita capacidad Premium ni XMLA habilitado: funciona con Power BI Pro.

## Herramientas

| Tool | Qué hace |
|------|----------|
| `check_azure_login` | Verifica la sesión y guía el login |
| `list_workspaces` · `select_workspace` | Descubrir y elegir área de trabajo |
| `list_models` · `select_model` | Descubrir y elegir modelo semántico |
| `learn_model` | Lee el TMDL y perfila el modelo |
| `setup_status` | En qué paso del flujo estás |
| `explain_model` | Cómo está conformado el modelo: hechos, dimensiones, relaciones |
| `describe_table` | Qué es una tabla, qué rol cumple y con qué se conecta |
| `get_model_schema` | Esquema completo o de una tabla |
| `search_model` | Búsqueda difusa, para modelos con cientos de medidas |
| `get_measure_definition` | La expresión DAX de una medida |
| `resolve_values` | Valores reales de una columna |
| `run_dax` | Ejecuta la consulta, solo lectura |
| `reset_session` | Volver a empezar |

## Qué se guarda en tu equipo

En `~/.fabric-semantic-mcp/`:

- `session.json` — qué área de trabajo y qué modelo elegiste.
- `models/*.json` — el esquema del modelo y los valores de sus columnas de baja
  cardinalidad.

Ese caché **contiene metadata y valores de tu modelo**. Si trabajás con
información sensible, borralo al terminar:

```bash
rm -rf ~/.fabric-semantic-mcp
```

No hay telemetría: nada sale de tu equipo más allá de las APIs de Microsoft.

## Limitaciones conocidas

| Limitación | Detalle |
|---|---|
| Documentación del modelo | Sin descripciones en las medidas, las respuestas son menos confiables. El perfilado ayuda, pero no reemplaza documentar |
| Pensado para agregaciones | `executeQueries` permite una consulta por request y hasta 100.000 filas. No es una herramienta de extracción masiva |
| Modelos grandes | Con cientos de medidas conviene buscar en el esquema en vez de volcarlo entero |
| Análisis inicial | En un modelo grande puede tardar cerca de un minuto. Es una sola vez |

## Preguntas frecuentes

**¿Puede borrar o modificar mis datos?**
No. No existe ninguna herramienta de escritura, y hay una validación que rechaza
cualquier consulta que no sea de lectura antes de enviarla.

**¿Ve datos que yo no debería ver?**
No. Actúa con tu identidad, y el modelo aplica su Row Level Security igual que
cuando abrís un informe.

**¿Necesito capacidad Premium o Fabric?**
No. Funciona con Power BI Pro, porque no usa XMLA.

**¿Tengo que pedirle algo a mi área de TI?**
En general no. Solo si tu organización bloquea las APIs de Fabric por política, o
si no tenés permiso de lectura sobre el área de trabajo.

**¿Y si quiero escribir en Fabric?**
Este proyecto nunca lo va a hacer, porque es su garantía de seguridad. Existen
otros MCP de Fabric con capacidades de escritura; la combinación correcta es
instalar los dos por separado, para que cada uno declare honestamente lo que
puede hacer.

## Contribuir

Las mejoras son bienvenidas: código, documentación, o simplemente contar cómo te
fue contra tu propio tenant. Los tests corren sin red y sin acceso a Fabric, así
que podés contribuir aunque no tengas un entorno a mano.

```bash
git clone git@github.com:PatoSuar3z/fabric-semantic-mcp.git
cd fabric-semantic-mcp
uv venv && uv pip install -e ".[dev]"
uv run pytest
```

Antes de abrir un PR, leé la sección de alcance en
[CONTRIBUTING](CONTRIBUTING.md): el proyecto no acepta operaciones de escritura
ni acceso a lakehouses, y eso no va a cambiar.

## Licencia

MIT — ver [LICENSE](LICENSE). Ver también [SECURITY](SECURITY.md) y
[CHANGELOG](CHANGELOG.md).
