Open-source Power BI MCP server for DAX, Desktop, PBIP, TMDL and PBIR automation with Claude, Codex and MCP clients
claude mcp add horizun-pbi-mcp -- python -m -r{
"mcpServers": {
"horizun-pbi-mcp": {
"command": "python",
"args": ["-m", "pip"]
}
}
}MCP Servers overview
# Horizun PBI MCP
**MCP** (Model Context Protocol) server for working with **local Power BI Desktop** and **`.pbip`** projects from Claude Code.
**v1.0.1** — 117 tools, 1547 tests passed (3 skipped, with their condition documented). Covers two complementary layers:
| Layer | For what | How |
|---|---|---|
| **Live** (Power BI Desktop open on `localhost:<port>`) | Query data (DAX), document the model, create/edit measures, refresh | ADOMD.NET + TOM via `pythonnet` |
| **On disk** (`.pbip` project) | Generate/arrange visuals, edit the model durably | TMDL (model) + PBIR (report), editing files |
> **Key rule:** the local endpoint **only exposes the DATA layer** (semantic model). **Visuals/pages/layout are NOT** in that endpoint or in any live API — they're edited via PBIR files. This MCP respects that separation: it doesn't try to move visuals "live".
---
## Documentation
| Document | For what |
|---|---|
| [`docs/INSTALL.md`](docs/INSTALL.md) | Install and register the server in Claude Code, Claude Desktop, Codex or a stdio client |
| [`docs/TOOL_INVENTORY.md`](docs/TOOL_INVENTORY.md) | The 34 baseline tools: domain, risk class, preconditions |
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Current architecture, structural debt and invariants |
| [`docs/CAPABILITY_MATRIX.md`](docs/CAPABILITY_MATRIX.md) | Coexistence with other Power BI MCPs, with verification levels |
| [`AGENTS.md`](AGENTS.md) | Rules for modifying this repository without breaking the contract |
| [`docs/TOOL_CATALOG.md`](docs/TOOL_CATALOG.md) | The 117 tools by block, with their risk class |
| [`docs/DUAL_MODE.md`](docs/DUAL_MODE.md) | Why `mode="both"` is blocked (R15) |
| [`docs/VALIDATION.md`](docs/VALIDATION.md) | The two PBIR validation layers and their limits |
| [`docs/RELEASE_CHECKLIST.md`](docs/RELEASE_CHECKLIST.md) | What is checked before publishing |
| [`docs/BACKLOG.md`](docs/BACKLOG.md) | What remains open, with evidence and how to check it |
| [`docs/TUTORIAL.md`](docs/TUTORIAL.md) | From installation to a dashboard, step by step |
| [`docs/SECURITY.md`](docs/SECURITY.md) | Threat model, guarantees and what it does **not** promise |
| [`docs/RECOVERY.md`](docs/RECOVERY.md) | What to do when something is left half-done |
| [`docs/PHASE_1A_DESIGN.md`](docs/PHASE_1A_DESIGN.md) | Design of the security layer |
| [`CHANGELOG.md`](CHANGELOG.md) | Version history |
| [`tests/fixtures/README.md`](tests/fixtures/README.md) | Fixture strategy: versioned synthetic + ignored local copy |
---
## What it does
- **Live DAX:** runs queries against the open model and returns columns/rows with timings.
- **Documentation:** tables, columns, measures, relationships, hierarchies, roles (RLS) and quality analysis → Markdown.
- **Measures:** create/edit/delete DAX measures in the open model (`live`), in the TMDL file (`pbip`) or in both (`both`).
- **Local refresh:** refreshes the open model in Desktop (not the Service).
- **PBIP:** open/validate projects, automatic backups.
- **`.pbix` → `.pbip` conversion:** report to PBIR (copied if the `.pbix` already carries it, translated if it keeps the legacy format) and model to TMDL, single file or batch folder.
- **PBIR visuals:** list/document visuals, create visuals (cloning real templates from the report), move/resize and arrange by layouts.
## What it does NOT do
- It doesn't move or create visuals "live" on the open canvas (Power BI Desktop doesn't expose an API for that). Visuals are edited via PBIR files with the `.pbip` project.
- It doesn't refresh or publish to the **Power BI Service** (local only).
- It doesn't extract the model from a `.pbix` without Power BI Desktop: the `DataModel` stream is a backup compressed with XPress9 that only the Analysis Services engine knows how to read. When converting, the `.pbix` is opened in Desktop to serialize the model.
- It doesn't translate **legacy** format bookmarks to PBIR: their state model is different and the conversion reports them as pending (`dropped`) instead of losing them silently. Creating new bookmarks is possible (`pbi_create_bookmark`).
- It doesn't invent fields or nonexistent measures when generating pages.
---
## Requirements
- **Windows** (Power BI Desktop is Windows-only) with **Power BI Desktop** installed.
- **Python 3.10+** (tested on 3.14).
- **.NET Framework 4.x** (comes with Windows) — used by `pythonnet`.
- Python dependencies: `mcp` (includes FastMCP), `pythonnet`, `psutil`, `python-dotenv`.
- **ADOMD.NET + TOM DLLs** (Analysis Services). Downloaded without admin rights via `scripts/fetch_libs.py` (no need to install in the GAC).
- To edit/create **visuals**: the report saved as **`.pbip` with PBIR** enabled.
- *(Optional)* Tabular Editor **is not required** — see [Technical decisions](#technical-decisions).
---
## Installation
### Direct from Codex or Claude (recommended)
You don't need to download or register a `.exe`, create `.mcp.json` or manually
locate this repository. The plugin sets up an isolated Python environment in
the client's data folder and verifies every download.
**Codex:**
```bash
codex plugin marketplace add HorizunGroup/horizun-pbi-mcp
codex plugin add horizun-pbi-mcp@horizun
```
**Claude Code:**
```bash
claude plugin marketplace add HorizunGroup/horizun-pbi-mcp
claude plugin install horizun-pbi-mcp@horizun
```
When the first session opens, the plugin runs the full setup automatically in
the background. Check `pbi_install_status`; once it finishes, restart the
client and the 117 `pbi_*` tools will be available. There are no downloads or
additional scripts the user needs to run manually.
> **Honest technical limit:** there's no dedicated executable, but you do need
> Windows, Power BI Desktop and Python 3.10+. The server must run locally:
> a remote MCP cannot access Desktop's local engine or your `.pbip` files.
### Manual installation for development
```bash
cd horizun-pbi-mcp
# 1) Python dependencies
python -m pip install -r requirements.txt
# or: python -m pip install -e .
# 2) Analysis Services DLLs (ADOMD.NET + TOM) -> libs/ folder
# Pinned version (19.84.1) and SHA-256 verified before installing.
python scripts/fetch_libs.py
# 3) Official PBIR schemas (needed to WRITE)
# Without them, every PBIR write fails with schema_unavailable.
python scripts/fetch_pbir_schemas.py
# 4) (optional, recommended) Microsoft's official PBIR validator
# Requires Node >= 20. Adds semantic validation of the full report.
python scripts/fetch_report_validator.py
# 5) (optional) configuration
copy .env.example .env # and edit it
```
Check the result at any time:
```bash
python scripts/doctor.py
```
### Verify
With **Power BI Desktop open** on a report:
```bash
python src/server.py # starts the MCP server (stdio); Ctrl+C to exit
```
For a quick test without MCP, in Python:
```python
import sys; sys.path.insert(0, "src")
from config import get_session
from powerbi import desktop_discovery, dax_runner
s = get_session()
print(desktop_discovery.discover_instances())
desktop_discovery.select_model(s)
print(dax_runner.run_dax(s, 'EVALUATE ROW("ok", 1)'))
```
---
## Registering with an MCP client
Full guide for **Claude Code, Claude Desktop, Codex and generic stdio clients**: [`docs/INSTALL.md`](docs/INSTALL.md).
Each client resolves environment variables, the working directory and the Python interpreter differently, so instead of a `${VAR}` template that fails on half of them, there's a generator that resolves the absolute paths on your machine:
```bash
python scripts/make_mcp_config.py --client all
```
It only prints. To create this repository's local `.mcp.json` (which is in `.gitignore`):
```bash
python scripts/make_mcp_config.py --client claude-code --write
```
Before registering anything, check the installation:
```bash
python scripts/doctor.py
```
Exits with code **0** if everything mandatory is fine. It distinguishes missing dependency, missing DLL, server that won't start, unexpected MCP contract, Desktop closed, stale session and multiple instances. Power BI Desktop being closed does **not** fail the base diagnostic (use `--require-desktop` if you want to require it).
### Environment variables (all optional)
| Variable | Default | Description |
|---|---|---|
| `HORIZUN_PBI_MCP_LIBS_DIR` | `./libs` | Folder with the ADOMD.NET/TOM DLLs |
| `HORIZUN_PBI_MCP_DOTNET_RUNTIME` | `netfx` | pythonnet runtime (`netfx` or `coreclr`) |
| `HORIZUN_PBI_MCP_MAX_ROWS` | `1000` | Default row limit in DAX |
| `HORIZUN_PBI_MCP_OUTPUTS_DIR` | `./outputs` | Documentation and `change_log.md` |
| `HORIZUN_PBI_MCP_BACKUPS_DIR` | `./backups` | `.pbip` backups |
| `HORIZUN_PBI_MCP_LOG_LEVEL` | `INFO` | `DEBUG`/`INFO`/`WARNING`/`ERROR` |
| `HORIZUN_PBI_MCP_DEFAULT_PBIP` | — | `.pbip` to open on startup |
---
## Available tools (117)
> Full catalog by block: [`docs/TOOL_CATALOG.md`](docs/TOOL_CATALOG.md).
> Baseline inventory with risk class and preconditions: [`docs/TOOL_INVENTORY.md`](docs/TOOL_INVENTORY.md).
> Names and signatures are frozen in `tests/golden/tools_v1.json` and verified by `tests/test_tool_contract.py`.
**Connection / DAX**
- `pbi_list_desktop_models` — lists open models (port, connection string, catalog, number of tables).
- `pbi_select_model` — sets the active model (by `port` if there are several).
- `pbi_run_dax` — runs DAX (`query`, `max_rows`).
- `pbi_test_connection` — validates the active connection.
- `pbi_validate_measures` — validates measure DAX WITHOUT modifying the model (dry-run with `DEFINE MEASURE`); useful before creating them.
- `pbi_validate_desktop_render` — opens a `.pbix`/`.pbip`, captures the exact window by PID without depending on focus and only closes Desktop if the tool itself opened it.
**Documentation (Phase 3)**
- `pbi_list_tables`, `pbi_list_measures`, `pbi_list_relationships` — with `source: live|pbip`.
- `pbi_analyze_model_quality` — typical model issues.
- `pbi_document_model` — complete documentation in Markdown to `outpuWhat people ask about horizun-pbi-mcp
What is HorizunGroup/horizun-pbi-mcp?
+
HorizunGroup/horizun-pbi-mcp is mcp servers for the Claude AI ecosystem. Open-source Power BI MCP server for DAX, Desktop, PBIP, TMDL and PBIR automation with Claude, Codex and MCP clients It has 0 GitHub stars and was last updated today.
How do I install horizun-pbi-mcp?
+
You can install horizun-pbi-mcp by cloning the repository (https://github.com/HorizunGroup/horizun-pbi-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is HorizunGroup/horizun-pbi-mcp safe to use?
+
HorizunGroup/horizun-pbi-mcp has not been audited yet by our security agent. Review the original repository on GitHub before using it in production.
Who maintains HorizunGroup/horizun-pbi-mcp?
+
HorizunGroup/horizun-pbi-mcp is maintained by HorizunGroup. The last recorded GitHub activity is from today, with 1 open issues.
Are there alternatives to horizun-pbi-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy horizun-pbi-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/horizungroup-horizun-pbi-mcp)<a href="https://claudewave.com/repo/horizungroup-horizun-pbi-mcp"><img src="https://claudewave.com/api/badge/horizungroup-horizun-pbi-mcp" alt="Featured on ClaudeWave: HorizunGroup/horizun-pbi-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!