Metadata-Version: 2.5
Name: fabric-semantic-mcp
Version: 0.1.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

<div align="center">

# fabric-semantic-mcp

### Preguntale a tus datos de Microsoft Fabric. En castellano. Sin escribir DAX.

[![CI](https://github.com/PatoSuar3z/fabric-semantic-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/PatoSuar3z/fabric-semantic-mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
![Python 3.10+](https://img.shields.io/badge/python-3.10%2B-blue.svg)
![Solo lectura](https://img.shields.io/badge/🔒-solo%20lectura-brightgreen.svg)

</div>

---

```
🧑  ¿cuanto vendimos por categoria el trimestre pasado?

🤖  Categoria A    1.240.500
    Categoria B      880.300
    Categoria C      415.900
```

Eso es todo. Conectás Claude a tu modelo semántico de Fabric y le preguntás
como le preguntarías a un analista.

<br>

## En tres frases

|   |   |
|---|---|
| 🎯 | **Usa las medidas oficiales de tu empresa.** Los mismos números que tus tableros, no un cálculo paralelo. |
| 🔒 | **No puede romper nada.** Solo lectura, y solo modelos semánticos. Nunca escribe. |
| ⚡ | **Se instala en dos minutos.** Sin registrar apps en Azure, sin pedirle permisos a TI. |

<br>

## Instalación

**1.** Iniciá sesión en Azure (una sola vez):

```bash
az login
```

**2.** Agregá el servidor a Claude Code:

```bash
claude mcp add fabric-semantic -- uvx --from git+https://github.com/PatoSuar3z/fabric-semantic-mcp fabric-semantic-mcp
```

**3.** Decile a Claude: **"conectate a Fabric"**

<details>
<summary>Otros clientes MCP (Claude Desktop, etc.)</summary>

<br>

En `claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "fabric-semantic": {
      "command": "uvx",
      "args": [
        "--from",
        "git+https://github.com/PatoSuar3z/fabric-semantic-mcp",
        "fabric-semantic-mcp"
      ]
    }
  }
}
```

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

</details>

<br>

## Cómo se usa

Claude te lleva de la mano, paso a paso:

```
 ①  ¿Tenés sesión de Azure?           →  si no, te explica cómo iniciarla
 ②  Estas son tus áreas de trabajo    →  elegís una
 ③  Estos son sus modelos semánticos  →  elegís uno
 ④  Estudiando el modelo...           →  tablas, medidas, relaciones, valores
 ▶️  Listo. Preguntá lo que quieras.
```

El paso ④ se paga **una sola vez por modelo**.

<br>

## Preguntas que puede responder

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

> *¿cómo se calcula el margen bruto?* — te muestra el DAX de la medida

> *comparame las ventas de este trimestre contra el anterior*

> *¿qué valores puede tomar la columna Estado?*

Y siempre te muestra el DAX que ejecutó, así podés auditarlo.

<br>

## 🔒 Por qué es seguro

**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.** Actúa con tu identidad y tus permisos.

**Y esta es la parte importante:**

> Solo consulta **modelos semánticos** — nunca lakehouses ni warehouses.
>
> El modelo semántico aplica **Row Level Security**. El SQL endpoint de un
> lakehouse **no**. Una herramienta que consulta lakehouses puede devolverle a
> alguien 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**.

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

<br>

---

<details>
<summary><h3>🛠️ Las 11 herramientas</h3></summary>

<br>

| 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 |
| `get_model_schema` | Esquema completo o de una tabla |
| `search_model` | Búsqueda difusa, para modelos con cientos de medidas |
| `get_measure_definition` | El DAX de una medida |
| `resolve_values` | Valores reales de una columna |
| `run_dax` | Ejecuta la consulta, solo lectura |
| `reset_session` | Volver a empezar |

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

</details>

<details>
<summary><h3>🧠 Qué aprende del modelo</h3></summary>

<br>

`learn_model` no se limita a leer nombres de columnas:

- **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.
- **Los valores reales** de las columnas de corte de baja cardinalidad.

Ese ú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.

</details>

<details>
<summary><h3>⚙️ Cómo funciona por dentro</h3></summary>

<br>

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

| | API | Para qué |
|---|---|---|
| 🔍 | `api.fabric.microsoft.com` | Descubrir workspaces, modelos, y leer el TMDL |
| ⚡ | `api.powerbi.com` | Ejecutar 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**.

</details>

<details>
<summary><h3>💾 Qué se guarda en tu equipo</h3></summary>

<br>

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
```

</details>

<details>
<summary><h3>❓ Preguntas frecuentes</h3></summary>

<br>

**¿Puede borrar o modificar mis datos?**
No. No existe ninguna tool 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: se usa la sesión de Azure CLI existente. Solo vas a necesitar
ayuda 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 — 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.

**¿Por qué la instalación es tan larga?**
Porque todavía no está publicado en PyPI. Cuando lo esté, va a ser simplemente
`uvx fabric-semantic-mcp`.

</details>

<details>
<summary><h3>⚠️ Limitaciones conocidas</h3></summary>

<br>

| Limitación | Detalle |
|---|---|
| Calidad de la documentación | Un modelo sin descripciones en sus medidas da respuestas menos confiables |
| Pensado para agregaciones | `executeQueries` permite una consulta por request y hasta 100.000 filas |
| Modelos muy grandes | Con cientos de medidas, usá `search_model` en vez de volcar el esquema entero |
| Perfilado inicial | En un modelo grande, `learn_model` puede tardar cerca de un minuto. Es una sola vez |

</details>

---

<br>

## 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
```

Leé [CONTRIBUTING.md](CONTRIBUTING.md) antes de abrir un PR — sobre todo la
sección de alcance.

<br>

<div align="center">

**MIT** · [Licencia](LICENSE) · [Seguridad](SECURITY.md) · [Changelog](CHANGELOG.md)

</div>
