Horizun PBI MCP
PYPI · HORIZUN-PBI-MCP · SCANNED SEP 21
Build, audit and repair Power BI Desktop models and PBIP reports with DAX, TMDL and PBIR.
Available components
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security100
- No malware found by supply-chain analysis.Pass
- No known CVEs affecting this package version or its production dependencies.Pass
- Runs setuptools.build_meta at install time, a recognised native-build step with no shell scripting around it. View diagnostics → Pass
- 1 of 46 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency35
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Provenance check failed: no build-provenance attestation is published. See how to fix → View diagnostics → Fail
- License check failed: no license is declared. See how to fix → Fail
- Actively maintained (last published 15 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability60
- AI-judged instruction clarity (good).Pass
- Context-footprint check failed: tool/resource definitions use about 23980 tokens (~172/item across 139 items; 139 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management87
- Stability observed for 26 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage71
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 0% of tool parameters carry a description.Fail
- Structured output schemas are declared (100% of tools); any adoption earns full credit.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- All 5 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.Pass
- An AI judge read all 139 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
How do I install the Horizun PBI MCP server?
Horizun PBI MCP runs locally as a PyPI package, launched with uvx horizun-pbi-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
pypi · horizun-pbi-mcp
claude mcp add horizungroup-horizun-pbi-mcp -- uvx horizun-pbi-mcp
{
"mcpServers": {
"horizungroup-horizun-pbi-mcp": {
"command": "uvx",
"args": [
"horizun-pbi-mcp"
]
}
}
} {
"servers": {
"horizungroup-horizun-pbi-mcp": {
"command": "uvx",
"args": [
"horizun-pbi-mcp"
]
}
}
} codex mcp add horizungroup-horizun-pbi-mcp -- uvx horizun-pbi-mcp
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"horizungroup-horizun-pbi-mcp": {
"type": "local",
"command": [
"uvx",
"horizun-pbi-mcp"
],
"enabled": true
}
}
} openclaw mcp add horizungroup-horizun-pbi-mcp --command uvx --arg horizun-pbi-mcp
mcp_servers:
horizungroup-horizun-pbi-mcp:
command: "uvx"
args: ["horizun-pbi-mcp"] {
"McpServers": {
"horizungroup-horizun-pbi-mcp": {
"Transport": "stdio",
"Command": "uvx",
"Arguments": [
"horizun-pbi-mcp"
]
}
}
} assistant mcp add horizungroup-horizun-pbi-mcp -t stdio -c uvx -a horizun-pbi-mcp
{
"mcpServers": {
"horizungroup-horizun-pbi-mcp": {
"command": "uvx",
"args": [
"horizun-pbi-mcp"
]
}
}
} Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 21 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 83 to 87. That category is still filling its 30-day observation window: 25 days of observed history at the previous scan, 26 at this one. The score rises as the window fills, whether or not the server changes.
- 19 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 77 to 80. That category is still filling its 30-day observation window: 23 days of observed history at the previous scan, 24 at this one. The score rises as the window fills, whether or not the server changes.
- 17 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 70 to 73. That category is still filling its 30-day observation window: 21 days of observed history at the previous scan, 22 at this one. The score rises as the window fills, whether or not the server changes.
- 15 Sept 26 +16
- Malware scan: unverified → pass ▲ security
- 14 Sept 26 −15
- Malware scan: pass → unverified ▼ security
- 13 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 57 to 60. That category is still filling its 30-day observation window: 17 days of observed history at the previous scan, 18 at this one. The score rises as the window fills, whether or not the server changes.
- 11 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 50 to 53. That category is still filling its 30-day observation window: 15 days of observed history at the previous scan, 16 at this one. The score rises as the window fills, whether or not the server changes.
- 8 Sept 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 21 Sept 2026 · Analysed pypi/horizun-pbi-mcp@2.1.1
Provenance No attestation
The registry publishes no build provenance for this version, so there is nothing to verify.
| Result | No attestation |
|---|---|
| Ecosystem | pypi |
Background: How many MCP packages publish verified provenance →
Install scripts 1 script
| Hook | Tier | Command |
|---|---|---|
| build_backend | allowlisted | setuptools.build_meta |
Background: Why install scripts are a supply-chain risk →
Dependencies 46 packages
| Packages resolved | 46 |
|---|---|
| Stale | 1 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
pbi_preview_page_spec ~80
Maqueta HTML del spec con las posiciones FINALES. No escribe al .pbip. Lo que muestra el preview es exactamente lo que se escribiria: tipos, titulos, campos, tamanos y posiciones salen del mismo compilado que usa la aplicacion.
| Name | Type | Req | Description |
|---|---|---|---|
| seed | string | – | – |
| spec | object | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_preview_spec_html ~80
Genera una MAQUETA HTML de una hoja propuesta (sin escribir nada al .pbip). `spec`: {page_name, canvas?, layout?, visuals:[{type,title,fields,position?}]}. Devuelve la ruta del HTML (abrelo en el navegador para revisar el diseno).
| Name | Type | Req | Description |
|---|---|---|---|
| spec | object | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_profile_data ~160
Perfila los VALORES del modelo abierto y devuelve lo que no cuadra. Complementa a pbi_audit_model, que revisa la estructura: un porcentaje que vale -800 no es un defecto del modelo sino de los datos, y solo se ve consultandolos. Detecta porcentajes fuera de 0-100, columnas vacias, columnas de un solo valor y columnas mayormente vacias. Cada hallazgo trae la consulta que lo demuestra y la consecuencia concreta sobre el tablero. Solo lectura. `tables` acota el trabajo; `max_columns` evita que un modelo grande agote el timeout y devuelva un perfil a medias.
| Name | Type | Req | Description |
|---|---|---|---|
| max_columns | integer | – | – |
| tables | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_propose_dashboard ~156
Mira el modelo y PROPONE varios diseños distintos, con su porque. A diferencia de pbi_page_building_blocks, que entrega el inventario y deja el diseño en manos de quien pregunta, esto clasifica lo que hay —que columna es un estado, cual una fecha, cuales forman una familia de metricas comparables— y devuelve paginas completas con un spec listo para aplicar. Devuelve tambien `blockers`: lo que hay que resolver ANTES de construir (p.ej. un modelo sin medidas, donde todo visual caeria en sumas implicitas), y `themes` con las paletas disponibles. Usalo para ofrecer opciones al usuario en vez de decidir por el.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_purge_backups ~163
Aplica la politica de retencion a los backups. DESTRUCTIVA. Sin `confirm` devuelve el MANIFIESTO de lo que se eliminaria, sin tocar nada. Solo se borran directorios de journal reconocibles (con su `manifest.json`) dentro de la carpeta de backups del proyecto activo: nunca un archivo suelto, ni un enlace simbolico, ni una raiz amplia. Se conserva siempre el journal mas reciente y TODOS los pendientes: un journal pendiente guarda los unicos originales de una transaccion que no llego a cerrarse.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| days | integer | – | – |
| max_journals | integer | – | – |
| request_id | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_recover_from_journal ~178
Restaura los originales guardados en un journal. DESTRUCTIVA. Sin `confirm` devuelve la VISTA PREVIA: que archivos se restaurarian, cual es su estado actual y si alguien los cambio despues. Estados: `recoverable`, `recovered`, `conflict`, `incomplete`, `corrupted`. Si un archivo cambio despues de la transaccion, se rechaza con `recovery_conflict` en vez de pisar ese trabajo; `force_conflict` lo aplica de todas formas. Cada archivo se verifica byte a byte tras restaurarlo, y se recrean los directorios padre que hubieran desaparecido.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| force_conflict | boolean | – | – |
| journal | string | yes | – |
| request_id | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_reflow_pages ~318
Reescala las paginas ya escritas al lienzo de otro sistema. El camino de vuelta que faltaba. Aplicar un sistema cambia el tema del informe, pero NO reescribe lo ya compuesto: las paginas se quedan con el lienzo anterior —visuales fuera de limites, basura invisible que si viaja al render— y con los colores que se cocieron al componerlas: un titulo compuesto en tema oscuro queda BLANCO SOBRE BLANCO al pasar a claro, sin que falle nada. Esto hace las dos cosas: reescala cada visual proporcionalmente al lienzo nuevo (acotandolo si no cabe) y recalcula el color de texto de los elementos decorativos con el tema del sistema destino. **No recompone**: no se puede saber que intencion tenia cada visual, y adivinarla seria peor. Si una pagina necesita otra estructura, recomponla con `pbi_compose_page`. Esto la deja utilizable, no optima. `pages`: subconjunto opcional (id o nombre visible); por defecto todas. `dry_run=true` (por defecto) devuelve el plan visual por visual, con cuales estaban ya fuera de limites, sin escribir nada. Escribe en el informe (PBIR): requiere el proyecto CERRADO en Desktop.
| Name | Type | Req | Description |
|---|---|---|---|
| dry_run | boolean | – | – |
| pages | – | – | – |
| request_id | string | – | – |
| system | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_refresh_model ~454
Refresca el modelo LOCAL abierto en Power BI Desktop (no el Service). `type`: full | calculate | clear_values (tambien automatic | data_only). `tables`: lista opcional de tablas a refrescar; si se omite, todo el modelo. Los errores de credenciales/origen se reportan. `timeout_seconds` (600 por defecto, `0` lo desactiva): un refresh lanzado por XMLA **no puede mostrar el dialogo de credenciales** de Desktop, asi que un origen sin credenciales guardadas deja al motor esperando para siempre y no hay ninguna ventana que cerrar. Al agotarse el plazo se pide la cancelacion al motor y se devuelve `refresh_timeout` enumerando los origenes que REQUIEREN credenciales -no si las tienen: eso Desktop no lo expone- y si la cancelacion se confirmo o el comando pudo quedar corriendo. Devuelve estado, duracion y **`rows_by_table`**: cuantas filas quedaron en cada tabla refrescada. Un refresh puede terminar en 'ok' y haber cargado CERO filas -credenciales que devuelven vacio, un filtro de fecha que no alcanza nada, un origen que cambio de esquema-, asi que las tablas vacias salen ademas en `warnings`. Si no se pudo contar, se dice; no se inventa el numero. En un proyecto **.pbip los datos NO se guardan**: viven en la sesion de Desktop y al reabrir hay que refrescar otra vez. Lo que persiste al guardar es la definicion (TMDL + PBIR). **Exige `confirm=true` desde 2.0.0.** Hasta entonces era la unica tool `destructiveHint` sin confirmacion junto con `pbi_open_and_refresh`: un agente que decide por «¿tiene `confirm`?» no veia nada que preguntar.
| Name | Type | Req | Description |
|---|---|---|---|
| confirm | boolean | – | – |
| request_id | string | – | – |
| tables | – | – | – |
| timeout_seconds | – | – | – |
| type | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_rename_measure ~253
Renombra una medida actualizando TODO lo que la referencia. Renombrar a mano rompe el informe en silencio: cualquier visual o medida que apuntara al nombre viejo abre y sale VACIO, sin error. Esta tool compila primero y escribe en UNA transaccion: la cabecera TMDL, las expresiones DAX de otras medidas que usan `[old_name]`, y los visual.json del informe. Devuelve la lista de lo tocado. Limite honesto: las referencias DAX CALIFICADAS (`Tabla[old]`) no se reescriben —pueden ser una columna homonima de otra tabla, y adivinar seria corromper—; si quedan, salen en `warnings` con su ubicacion, igual que las de bookmarks y filtros. Solo `pbip` (escribe modelo E informe a la vez: exige Desktop CERRADO). `dry_run=true` (defecto) devuelve el plan sin escribir.
| Name | Type | Req | Description |
|---|---|---|---|
| dry_run | boolean | – | – |
| new_name | string | yes | – |
| old_name | string | yes | – |
| request_id | string | – | – |
| table | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_rename_page ~49
Cambia el nombre visible de una pagina. El id interno no cambia.
| Name | Type | Req | Description |
|---|---|---|---|
| new_name | string | yes | – |
| page | string | yes | – |
| request_id | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_reorder_pages ~60
Fija el orden de las paginas del informe. Acepta ids o nombres visibles. Las paginas que no menciones quedan al final, conservando su orden relativo.
| Name | Type | Req | Description |
|---|---|---|---|
| order | array | yes | – |
| request_id | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_repair_broken_references ~116
Detecta referencias rotas en los visuales y las repara. Sin `mapping` solo diagnostica: adivinar a que campo queria apuntar un visual roto no es una decision que deba tomarse sola. Pasa `{"Tabla[Viejo]": "Tabla[Nuevo]"}` para repararlas, y el destino se valida contra el modelo antes de escribir.
| Name | Type | Req | Description |
|---|---|---|---|
| dry_run | boolean | – | – |
| mapping | – | – | – |
| request_id | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_replace_visual_field ~166
Sustituye una referencia de campo dentro de un visual. `old_ref`/`new_ref`: 'Tabla[Campo]' o '[Medida]'. Trabaja sobre las proyecciones existentes; no crea roles nuevos. Falla si el visual no referencia `old_ref`, en vez de no hacer nada en silencio. El destino se valida contra el modelo antes de escribir: si no existe, es ambiguo o es de otro tipo (medida donde va una columna), se rechaza con `field_not_found` en lugar de inventarlo.
| Name | Type | Req | Description |
|---|---|---|---|
| new_ref | string | yes | – |
| old_ref | string | yes | – |
| page | string | yes | – |
| request_id | string | – | – |
| visual_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_report_capabilities ~65
Version PBIR observada, tema, custom visuals y tipos clonables. Solo se pueden crear visuales de tipos ya presentes en el informe: se clona una estructura real en vez de inventarla. Esta tool dice cuales hay disponibles antes de intentarlo.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_run_dax ~267
Ejecuta una consulta DAX de SOLO LECTURA contra el modelo activo. Solo se admiten formas reconocidas: EVALUATE, DEFINE...EVALUATE y DMVs de $SYSTEM. Cualquier otra cosa se rechaza (politica fail-closed). `max_rows`: limite de filas. `max_bytes`: tope de tamano del resultado, para no devolver megas al cliente. `timeout_seconds`: timeout del comando. `export=true` vuelca el resultado completo a outputs/ y devuelve la ruta. Devuelve columnas, tipos observados, filas, estadisticas de ejecucion y si se trunco (y por que: filas o tamano). Los errores DAX del motor se devuelven tal cual. `query` es el unico nombre de la consulta: no hay alias `dax`, porque `query` es obligatorio en el contrato congelado y un alias no podria sustituirlo. Ejemplo: `pbi_run_dax(query="EVALUATE TOPN(5, 'Ventas')")`.
| Name | Type | Req | Description |
|---|---|---|---|
| export | boolean | – | – |
| max_bytes | – | – | – |
| max_rows | – | – | – |
| query | string | yes | – |
| timeout_seconds | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_search_model ~98
Busca objetos del modelo por nombre (y en el DAX de las medidas). `term`: texto a buscar, sin distinguir mayusculas. `kinds`: filtra por tipo — table, column, measure, hierarchy, role. Para las medidas indica si coincidio el nombre o la expresion.
| Name | Type | Req | Description |
|---|---|---|---|
| kinds | – | – | – |
| limit | integer | – | – |
| source | string | – | – |
| term | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_select_model ~110
Selecciona el modelo local activo para futuras operaciones. Si hay un solo modelo abierto no hace falta indicar nada. Si hay varios, pasa `port` **o** `connection_string` TAL CUAL lo devuelve `pbi_list_desktop_models` (`"Data Source=localhost:56057"`): lo que sale de esa tool entra en esta sin tener que extraer el puerto a mano.
| Name | Type | Req | Description |
|---|---|---|---|
| catalog | – | – | – |
| connection_string | – | – | – |
| port | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_session_info ~58
Detalle de la sesion: modelo activo, proyecto activo y su frescura. Distingue una sesion valida de una obsoleta (`stale`) o de otra que ocupo el mismo puerto (`mismatch`).
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_color_from_field ~215
Colorea un visual con el color que DEVUELVE una medida. Es el modo "valor de campo" de Power BI: la medida entrega '#D03B3B' o un nombre de color, y el visual lo aplica tal cual. Es el patron tipico de un semaforo calculado en DAX. `field`: '[Medida]' o 'Tabla[Medida]' que devuelve el color. `target`: 'background' o 'font' (tablas y matrices), 'bars' (barras, columnas y puntos). La matriz de que combinacion funciona en que tipo de visual vive en el servidor y se valida antes de escribir. `target_column`: columna proyectada a pintar; sin ella se pinta la columna del propio campo.
| Name | Type | Req | Description |
|---|---|---|---|
| field | string | yes | – |
| page | string | yes | – |
| request_id | string | – | – |
| target | string | – | – |
| target_column | – | – | – |
| visual_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_column_visibility ~167
Oculta o muestra una columna del modelo (p.ej. ocultar columnas de ID). mode='both' esta temporalmente deshabilitado bajo la politica estricta: 'live' necesita Power BI Desktop abierto y 'pbip' lo necesita cerrado, asi que una sola llamada aplicaria solo uno de los dos destinos. Elige 'live' o 'pbip', o usa 'auto' y se mira el estado para elegir. Si estas construyendo desde cero, 'auto' o 'pbip': el defecto es 'live' y exige Desktop abierto.
| Name | Type | Req | Description |
|---|---|---|---|
| column | string | yes | – |
| hidden | boolean | – | – |
| mode | string | – | – |
| request_id | string | – | – |
| table | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_conditional_format ~363
Colorea un visual segun el valor de un campo (degradado). Es lo que convierte una matriz de numeros en un mapa de calor, o unas barras planas en una escala de semaforo. `field`: 'Tabla[Campo]' o '[Medida]' de donde sale el VALOR. `target_column`: que columna del visual se pinta con ese valor; sin ella se pinta la columna del propio `field`. Debe estar proyectada en el visual (p.ej. pintar 'Resumen[semaforo]' con '[Puntaje promedio]'). `target`: 'background' o 'font' para tablas y matrices; 'bars' para barras, columnas y puntos. `mid_color`: si lo indicas, el degradado tiene tres paradas en vez de dos, util cuando hay un punto neutro. `min_value`/`mid_value`/`max_value`: anclas numericas de las paradas (sin ellas, Power BI usa el minimo y maximo observados). `null_strategy`: asZero | none | specificColor. Si el visual ya tenia una regla en ese mismo destino, se sustituye: dos degradados sobre la misma propiedad no se suman, se pisan.
| Name | Type | Req | Description |
|---|---|---|---|
| field | string | yes | – |
| max_color | string | yes | – |
| max_value | – | – | – |
| mid_color | – | – | – |
| mid_value | – | – | – |
| min_color | string | yes | – |
| min_value | – | – | – |
| null_strategy | string | – | – |
| page | string | yes | – |
| request_id | string | – | – |
| target | string | – | – |
| target_column | – | – | – |
| visual_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_relationship_direction ~180
Cambia el filtro cruzado de una relacion. `direction`: 'single' (una direccion, recomendado) o 'both' (bidireccional). OJO: cambiar a 'single' puede alterar totales que dependian de la bidireccional; verifica el informe despues. No confundir `direction='both'` (bidireccional, valido) con `mode='both'`, que esta temporalmente deshabilitado bajo la politica estricta: 'live' necesita Power BI Desktop abierto y 'pbip' lo necesita cerrado, asi que una sola llamada aplicaria solo uno de los dos destinos.
| Name | Type | Req | Description |
|---|---|---|---|
| direction | string | – | – |
| from_table | string | yes | – |
| mode | string | – | – |
| request_id | string | – | – |
| to_table | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_storage_mode ~166
Cambia el modo de almacenamiento de una tabla: import | directQuery | dual. Con directQuery el dato se consulta al origen en cada interaccion y desaparece el refresco, pero NO es un interruptor inocuo: la consulta M tiene que ser plegable al origen, las columnas y tablas calculadas dejan de estar disponibles, y cada visual pasa a ser una consulta al servidor. Devuelve el modo anterior y cuantas particiones cambiaron, para poder deshacerlo sabiendo exactamente que se toco. Escribe en TMDL: requiere el proyecto CERRADO en Power BI Desktop.
| Name | Type | Req | Description |
|---|---|---|---|
| mode | string | yes | – |
| request_id | string | – | – |
| table | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_visual_filter ~482
Filtra un visual EXISTENTE sin escribir `filterConfig` a mano. `filters`: lista de specs. Por COLUMNA, `{field: 'Tabla[Columna]', values?: [...], type?: 'Categorical' | 'Advanced' | 'TopN' | 'Range' | 'RelativeDate' | 'Passthrough', exclude?: bool, raw?: {...}, hidden?: bool, locked?: bool, display_name?: str}`. Con `values` se arma un filtro de lista (Categorical); sin `values` ni `raw` el campo queda declarado pero SIN acotar, como el panel de filtros vacio. `raw` pasa una consulta semantica ya construida, para lo que este constructor no cubre. Por MEDIDA, `{measure: 'Tabla[Medida]', condition: 'GreaterThan', value: 0}` (`condition`: Equal | NotEqual | GreaterThan | GreaterThanOrEqual | LessThan | LessThanOrEqual, o los simbolos `> >= < <= = !=`). Es la forma de ENCADENAR slicers de dimension cuando varias tablas de hechos cuelgan de las mismas dimensiones y una relacion bidireccional crearia ambiguedad. `field`/`measure` van con el NOMBRE real de la tabla. La mitad interna de la consulta usa un ALIAS (`SourceRef.Source`) que esta tool resuelve sola: escribirlo a mano ahi es el error mas comun al construir un filtro de visual, y Power BI lo ignora sin decir por que. Por defecto REEMPLAZA los filtros del visual, y una lista vacia los quita todos. **Cuidado con los slicers**: suelen traer un filtro `Categorical` donde vive la seleccion del usuario, y reemplazarlo la borra. Para anadir sin pisar, `merge=true` (ahi una lista vacia no quita nada). No comprueba el campo contra el modelo: uno que no existe se escribe igual y Power BI lo resuelve en silencio a nada.
| Name | Type | Req | Description |
|---|---|---|---|
| filters | array | yes | – |
| merge | boolean | – | – |
| page | string | yes | – |
| request_id | string | – | – |
| visual_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_visual_title ~125
Cambia u oculta el titulo de un visual PRESERVANDO su formato. `title`: el texto nuevo. `show=false`: oculta el titulo SIN borrar su texto ni formato (el rodeo de poner texto vacio dejaba la banda del titulo ocupando altura); `show=true` lo vuelve a mostrar. Se puede pasar solo uno de los dos, o ambos.
| Name | Type | Req | Description |
|---|---|---|---|
| page | string | yes | – |
| request_id | string | – | – |
| show | – | – | – |
| title | – | – | – |
| visual_id | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_set_visual_z_order ~84
Fija el orden Z de los visuales de una pagina. `order`: ids de MENOR a MAYOR z; el ultimo queda encima. Los visuales que no menciones se colocan por encima, conservando su orden relativo.
| Name | Type | Req | Description |
|---|---|---|---|
| order | array | yes | – |
| page | string | yes | – |
| request_id | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_sharepoint_download_folder ~187
Descarga una carpeta de SharePoint a outputs/ de forma todo-o-nada. Primero inventaria el lote y valida `max_files`, `max_total_mb` y el filtro opcional `extensions` (por ejemplo `['xlsx','csv']`). Luego usa URLs temporales emitidas por Graph, verifica tamano y SHA-256 y publica el directorio completo bajo `outputs/sharepoint/`. Un fallo elimina el staging y no deja una carpeta final parcial. Es una descarga de solo lectura remota: no sube, mueve ni elimina nada en SharePoint.
| Name | Type | Req | Description |
|---|---|---|---|
| extensions | – | – | – |
| folder_path | string | – | – |
| library | string | – | – |
| max_files | integer | – | – |
| max_total_mb | integer | – | – |
| recursive | boolean | – | – |
| site_url | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_sharepoint_list_folder ~172
Conecta con SharePoint Online y lista una carpeta mediante Graph. `site_url` es la URL HTTPS del sitio; `library` es el nombre o id de la biblioteca documental; `folder_path` usa `/`. Sigue la paginacion de Graph y puede recorrer subcarpetas con un limite total explicito. Autenticacion app-only: las credenciales SOLO se leen de las variables `HORIZUN_PBI_MCP_SHAREPOINT_TENANT_ID`, `_CLIENT_ID` y `_CLIENT_SECRET`. Nunca se aceptan secretos como parametros ni se devuelven tokens.
| Name | Type | Req | Description |
|---|---|---|---|
| folder_path | string | – | – |
| library | string | – | – |
| max_items | integer | – | – |
| recursive | boolean | – | – |
| site_url | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_start_here ~159
Por donde empezar. Mira el estado real y dice los siguientes pasos. Ciento treinta y dos tools con buen nombre siguen siendo ciento treinta y dos tools. Esta responde «¿y ahora que?» con tres o cuatro pasos concretos, cada uno con el nombre exacto de la tool y **por que** toca ahora: si hay proyecto activo, si tiene modelo o solo informe, si esta vacio, y si Power BI Desktop lo tiene abierto —que impide escribir el TMDL—. Devuelve tambien `common_tasks`: tareas frecuentes y la secuencia de tools que las resuelve. No escribe nada. Empieza por aqui cuando no sepas que sigue.
| Name | Type | Req | Description |
|---|---|---|---|
| request_id | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_test_connection ~22
Valida la conexion al modelo activo con una consulta trivial.
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_update_measure ~175
Actualiza una medida existente. Lo no especificado se conserva. mode='both' esta temporalmente deshabilitado bajo la politica estricta: 'live' necesita Power BI Desktop abierto y 'pbip' lo necesita cerrado, asi que una sola llamada aplicaria solo uno de los dos destinos. Elige 'live' o 'pbip', o usa 'auto' y se mira el estado para elegir. Si estas construyendo desde cero, 'auto' o 'pbip': el defecto es 'live' y exige Desktop abierto.
| Name | Type | Req | Description |
|---|---|---|---|
| description | – | – | – |
| display_folder | – | – | – |
| expression | – | – | – |
| format_string | – | – | – |
| mode | string | – | – |
| name | string | yes | – |
| request_id | string | – | – |
| table | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_update_power_query ~319
Reemplaza ENTERA la consulta M de una particion o expresion. No hay edicion parcial ni sustitucion por expresion regular: se localiza el bloque por su estructura y se cambia completo. `dry_run` viene ACTIVADO: la primera llamada enseña lo que se escribiria sin tocar el disco, sin backup y sin journal. `expected_sha256` (el que devuelve `pbi_get_power_query`) rechaza la escritura si el texto cambio desde que lo leiste, en vez de pisar el trabajo de otro. Escribe TMDL: exige proyecto .pbip y Power BI Desktop CERRADO. Va con backup, journal, transaccion, relectura y rollback; si el modelo queda con errores TMDL que antes no tenia, se revierte entero. La respuesta distingue lo comprobado de lo no comprobado: `parse_checked` y `tmdl_load_checked` dicen que el TMDL se lee y que el serializador oficial lo acepta; `m_engine_checked` y `refresh_checked` son SIEMPRE false. Que el archivo parsee no significa que la consulta cargue: eso solo lo dice un refresh.
| Name | Type | Req | Description |
|---|---|---|---|
| dry_run | boolean | – | – |
| expected_sha256 | string | – | – |
| kind | string | – | – |
| m | string | yes | – |
| name | string | – | – |
| request_id | string | – | – |
| table | string | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_update_visual_position ~76
Mueve/redimensiona un visual existente.
| Name | Type | Req | Description |
|---|---|---|---|
| height | number | yes | – |
| page | string | yes | – |
| request_id | string | – | – |
| visual_id | string | yes | – |
| width | number | yes | – |
| x | number | yes | – |
| y | number | yes | – |
| z | – | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_validate_desktop_render ~946
Abre un .pbip/.pbix y captura su ventana real sin depender del foco. Es la comprobacion visual automatizable que complementa al validador PBIR: espera el modelo, identifica la ventana por PID y hora de inicio, y la renderiza con PrintWindow directamente a ``outputs/desktop_captures``. La captura no activa ni trae Desktop al frente, por lo que no puede fotografiar por accidente otra ventana que tape el informe. `path` (o `pbip_path`, el mismo nombre que devuelve `pbi_session_info`) se puede omitir: entonces se usa el proyecto .pbip activo. **`refresh=true` es lo que hace que la captura signifique algo en un .pbip**: ese formato guarda la definicion, no los datos, asi que recien abierto el modelo viene VACIO y las tablas y matrices salen en blanco aunque el informe este perfecto. Con `refresh` se abre, se refresca, se espera a que la ventana deje de repintar y se captura. Ese es tambien el camino para fotografiar OTRA pagina con datos: `page` exige abrir el proyecto, y al abrirlo hay que volver a refrescar. Como el refresh modifica de forma irreversible el modelo en memoria, `refresh=true` exige ademas `confirm=true`. `confirm_reuse` autoriza mover una ventana que ya era del usuario; son autorizaciones distintas. Pase lo que pase, la respuesta lleva `data_loaded`: si es `false`, la captura no es representativa del informe, es la foto de un modelo sin datos. Si no se pudo comprobar, se dice; no se afirma ninguna de las dos. `page`: captura ESA pagina (id o nombre visible), no la que quedo activa. `fit_to_page` (activado por defecto): fuerza la vista "Ajustar a la pagina" para que salga el lienzo COMPLETO y no el tercio superior al zoom guardado. Con el proyecto CERRADO (.pbip) ambos se aplican como una vista temporal en disco que se restaura byte a byte al terminar. Con la ventana YA ABIERTA -que es del usuario- se hacen en la propia interfaz, pero SOLO con `confirm_reuse=true`: elegir una pestaña y cambiar el zoom mueven esa ventana, y una captura que solo debi…
| Name | Type | Req | Description |
|---|---|---|---|
| capture_timeout | integer | – | – |
| confirm | boolean | – | – |
| confirm_reuse | boolean | – | – |
| fit_to_page | boolean | – | – |
| page | – | – | – |
| path | – | – | – |
| pbip_path | – | – | – |
| project_path | – | – | – |
| refresh | boolean | – | – |
| refresh_timeout_seconds | – | – | – |
| request_id | string | – | – |
| reuse_open | boolean | – | – |
| timeout | integer | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_validate_generated_page ~59
Verifica una pagina YA escrita: referencias rotas y geometria. Se usa despues de aplicar un spec para comprobar que el resultado es valido de verdad, no solo que la escritura no fallo.
| Name | Type | Req | Description |
|---|---|---|---|
| page | string | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_validate_measures ~95
Valida DAX de medidas SIN modificar el modelo (dry-run con DEFINE MEASURE). Ideal para probar medidas ANTES de crearlas con pbi_create_measure. `measures`: lista de {"name","dax","table"(opcional)}. Las medidas pueden referenciarse entre si. Devuelve por cada una: valid, value (muestra) y error.
| Name | Type | Req | Description |
|---|---|---|---|
| measures | array | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_validate_page_spec ~69
Valida un spec: esquema, referencias contra el modelo y geometria. Los errores traen su JSON path (`$.visuals[2].fields.values[0]`) para que se puedan corregir sin adivinar. No escribe nada.
| Name | Type | Req | Description |
|---|---|---|---|
| spec | object | yes | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_validate_pbip_project ~136
Valida a fondo el proyecto .pbip activo (estructura, PBIR, TMDL). Incluye `references`: cada Measure/Column que un visual.json o su filterConfig citan, cruzada contra el TMDL real. El esquema PBIR y la sintaxis TMDL pueden pasar limpios por separado con un visual que apunta a una medida borrada -- Desktop lo resuelve en silencio a nada, sin marca visible. Solo corre si el TMDL es valido (comparar contra un modelo que no abre es ruido, no una comprobacion).
Input schema present but exposes no named parameters.
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
pbi_validate_tmdl ~279
Comprueba si un modelo TMDL abrira, sin abrir Power BI Desktop. Dos capas. Un lint estatico que caza las trampas que solo se veian al abrir (una propiedad de tabla colocada despues de sus hijos, un comentario '///' sobre una relacion, una medida que se llama como una columna de su tabla, medidas duplicadas, referencias rotas) y, si estan las DLL, un parseo con el MISMO serializador que usa Power BI. Cada hallazgo trae `rule`, `severity`, el archivo y la linea. Si el parseo no se pudo ejecutar se dice (`parse_checked: false`) en vez de darlo por bueno. Hay fallos que NINGUN analisis estatico ve porque dependen de los datos —un blanco en el lado 'uno' de una relacion, un separador decimal mal interpretado—. Salen en `limitations`: para esos hay que refrescar. `path`: carpeta `definition` del modelo, la carpeta `.SemanticModel` o el `.pbip`. Si se omite, el proyecto activo. `use_tom=False`: solo el lint estatico, sin tocar las DLL.
| Name | Type | Req | Description |
|---|---|---|---|
| path | string | – | – |
| use_tom | boolean | – | – |
| Name | Type | Req | Description |
|---|---|---|---|
| result | object | yes | – |
No examples provided.
What is the Horizun PBI MCP server?
Horizun PBI MCP is listed in the public MCP registry as io.github.HorizunGroup/horizun-pbi-mcp. Build, audit and repair Power BI Desktop models and PBIP reports with DAX, TMDL and PBIR. This page covers its PyPI package (horizun-pbi-mcp).
Is the Horizun PBI MCP server safe to use?
Horizun PBI MCP scores 76 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 21 September 2026. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the Horizun PBI MCP server expose?
Horizun PBI MCP exposes 139 tools: pbi_profile_data, pbi_audit_project, pbi_audit_report_only, pbi_plan_audit_fixes, pbi_apply_audit_fixes, and 134 more. Their descriptions and schemas cost roughly 23,980 tokens of context every time the server is loaded.
Is the Horizun PBI MCP server still maintained?
Horizun PBI MCP is still listed as active in the MCP registry. We last reached this channel on 21 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.