Bridges AI assistants to both Power BI Desktop (via ADOMD) and Power BI Service (via XMLA endpoints) for natural language data queries and model management. Executes DAX queries, performs bulk table/column/measure renames, and tests row-level security roles through 34 exposed tools. The standout feature is PBIP file-based editing that handles bulk renames without breaking report visuals, solving the core limitation of Microsoft's Tabular Object Model. Includes PII detection, audit logging, and configurable access policies for enterprise use. Reach for this when you need programmatic Power BI operations beyond what the standard APIs safely allow, especially for model refactoring workflows.
An enterprise-grade Model Context Protocol server for Power BI and Microsoft Fabric.
Let AI assistants inspect, query, validate, optimize, govern, and safely refactor Power BI semantic models and reports, through natural language.
Disclaimer: This is an independent, community project. It is not affiliated with, endorsed by, or connected to Microsoft Corporation or Anthropic.
Power BI MCP Server connects an AI assistant (Claude, GitHub Copilot, any MCP client) to your Power BI content through one consistent interface. It talks to a local Power BI Desktop model, a published Power BI Service dataset, or Power BI Project (PBIP) files on disk, and wraps every operation in a security and governance layer.
It exposes 70 tools plus MCP resources, prompts, and completion, and ships with 20 assert-based test suites.
| Capability | What you get |
|---|---|
| Dual connectivity | Power BI Desktop (local) and Power BI Service (cloud) |
| Natural-language DAX | Run, validate, and optimize DAX through conversation |
| Safe refactoring | PBIP-based renames that update the model and the report visuals |
| Report authoring (preview) | Add pages, visuals, and field bindings to PBIR reports from the agent |
| DAX safety loop | Validate before committing; impact analysis; atomic transactions |
| Model quality | Best Practice Analyzer, AI-readiness scoring, VertiPaq-style storage analysis |
| Diagnostics and ops | Refresh-failure triage, unused-object detection, RLS test matrix |
| Governance | Enforced PII and column policies, tamper-evident audit, read-only mode |
| Fleet (admin) | Cross-workspace lineage, fleet refresh monitor, usage analytics |
| Modern MCP | Tool annotations, structured output, resources, prompts, completion |
This server is a bridge. On its own an AI assistant can only talk. This gives it a set of "hands" so it can reach into Power BI and actually do the work for you. You ask in plain English, the assistant picks the right tool, and you get an answer or a change.
It plugs into three places:
A few terms used below: a semantic model (dataset) is the data brain behind a report (its tables, columns, relationships, and measures). A measure is a saved calculation written in DAX (Power BI's formula language). RLS is row-level security (rules that limit which rows a user can see).
"Connect to my Power BI Desktop and summarize the model."
"What were the top 10 products by sales last quarter?"
"Create a 'Margin %' measure as profit divided by sales, formatted as a percentage."
"Rename the table 'Salesforce_Data' to 'Sales Force Data' everywhere."
"If I delete the 'Old Revenue' measure, what depends on it?"
nativeQueryRef and Sum(...) query refs Desktop itself writes).
"On the PBIP project, add an 'Overview' page with a bar chart of Sales by Region." Best Practice Analyzer (performance, DAX, naming, formatting), an AI-readiness score, storage/size analysis, and query-performance hints. "Audit this model and give me the top issues to fix before I ship."
/ instead of DIVIDE, IFERROR,
EARLIER, SUMMARIZE used for aggregation, blank-suppressing + 0, and unrecognized or
hallucinated function names) and hands back a concrete rewrite for each.
"Lint every measure in my model and suggest rewrites for the worst offenders."
"Audit naming and rename everything to Title Case without breaking the report."
"Make me a progress-bar measure for 'Margin %' against a 100% target."
.pbix file. Inspect a .pbix (it is a ZIP package): see whether it has an
imported model or a live connection, which report format it uses, and how many pages, then
extract it and get the report layout decoded to readable JSON.
"Inspect this .pbix and tell me if it has an imported model and how many pages."
"Validate our BPARules.json and tell me which rules this model is silently ignoring."
- "Connect to my Power BI Desktop model."
- "Audit it and list the worst issues."
- "What would break if I rename the 'Customer ID' column?"
- "Rename it to 'CustomerKey' across model and report."
- "Create a 'YoY Sales %' measure, validate it, and format as a percentage."
- "Export a data dictionary so the team has docs."
- "Run the pre-deploy quality gate before I publish."
Each step is one sentence; the server does the real Power BI work behind it.
Microsoft now ships official Power BI MCP servers (public preview): a remote one for chat-with-data and a local modeling one for authoring semantic models. This project is complementary. It leans into what those servers do not cover:
See docs/ARCHITECTURE.md for how it fits together.
Live connectivity (Power BI Desktop / Service): Windows 10/11, Power BI Desktop, Python 3.10+,
and the ADOMD.NET client library. Newer Power BI Desktop builds no longer ship ADOMD.NET, so
install SQL Server Management Studio (SSMS) or the Microsoft.AnalysisServices.AdomdClient
NuGet package, or point ADOMD_DLL_PATH at the folder containing
Microsoft.AnalysisServices.AdomdClient.dll. The server searches Power BI Desktop, SSMS, the
SQL Server SDK, and NuGet automatically. Cloud also needs an Azure AD service principal and,
for some operations, a Premium / PPU / Fabric capacity.
Offline subset only (PBIP editing, BPA, analysis, security): any OS, Python 3.10+, no .NET.
git clone https://github.com/sulaiman013/powerbi-mcp.git
cd powerbi-mcp
# Full install (Windows, for live connectivity)
pip install -r requirements.txt
# Or: offline / cross-platform subset only
pip install -r requirements-core.txt
# (Optional) cloud credentials, Windows
copy .env.example .env
# edit .env with your Azure AD service principal
Add to %APPDATA%\Claude\claude_desktop_config.json, then restart Claude Desktop:
{
"mcpServers": {
"powerbi": {
"command": "python",
"args": ["C:/path/to/powerbi-mcp/src/server.py"],
"env": {
"PYTHONPATH": "C:/path/to/powerbi-mcp/src"
}
}
}
}
The image runs the platform-independent tools (PBIP editing, BPA, AI-readiness, model analysis, security, resources, prompts) on any OS with no .NET. Live Desktop / XMLA / TOM connectivity still needs Windows + ADOMD.NET.
docker build -t powerbi-mcp .
docker run --rm -i -v /path/to/MyReport:/work powerbi-mcp
70 tools across the categories below. The full reference, with parameters and read / write / destructive markers, is in docs/TOOLS.md.
| Category | Count | Highlights |
|---|---|---|
| Desktop (local, ADOMD) | 7 | discover, connect, list tables/columns/measures, desktop_execute_dax, model info |
| Cloud (XMLA + REST) | 6 | workspaces, datasets, tables, columns, execute_dax, model info |
| Security and audit | 3 | security_status, security_audit_log, verify_audit_integrity |
| Row-Level Security | 3 | list roles, set role, status |
| Model writes (TOM) | 7 | create_measure, delete_measure, batch_update_measures, deprecated batch renames |
| DAX safety and transactions | 5 | validate_dax, scan_measure_dependencies, begin/commit/rollback transaction |
| Relationships | 2 | create_relationship, delete_relationship |
| PBIP safe editing | 5 | load project, get info, rename tables/columns/measures (model + report) |
| PBIP diagnostics | 4 | fix broken visuals, fix DAX quoting, scan broken refs, validate |
| Report authoring (PBIR, preview) | 4 | pbir_add_page, pbir_add_visual, pbir_bind_fields, pbir_validate_report |
| Model quality and performance | 4 | run_bpa, audit_ai_readiness, analyze_model_storage, analyze_query_performance |
| DAX quality | 2 | dax_lint (performance anti-patterns), dax_suggest_rewrite |
| Authoring helpers | 2 | generate_svg_measure (sparkline/bullet/progress/pill), audit_naming |
| PBIX onboarding | 2 | pbix_inspect, pbix_extract (crack open a real .pbix) |
| Custom BPA governance | 2 | bpa_validate_rules, bpa_audit_rule_sources |
| Documentation, diff, CI | 5 | export_data_dictionary, model_snapshot, model_diff, pre_deploy_gate, run_dax_tests |
| Diagnostics and ops | 4 | refresh_doctor, find_unused_objects, impact_analysis, rls_test_harness |
| Governance-ops fleet (admin) | 3 | cross_workspace_lineage, fleet_refresh_monitor, usage_and_orphan_analytics |
powerbi://desktop/{schema,measures,bpa,ai-readiness},
powerbi://cloud/{workspace}/{dataset}/schema,
powerbi://reference/{bpa-rules,refresh-errors}. Attach model context without a tool call.optimize_measure, explain_measure, audit_model, document_model,
plan_safe_rename, pre_deploy_review. Ready-made, tool-orchestrated playbooks.readOnlyHint, destructiveHint); key tools return typed structuredContent.Power BI stores a model layer and a report layer separately. TOM (and the official modeling MCP) can edit the model, but cannot update report visuals, so a TOM rename leaves visuals pointing at the old name. This server solves it with PBIP file editing: it rewrites the TMDL model files and the PBIR report files (visual bindings, cultures, diagram) together, so nothing breaks.
User: "Load PBIP project from C:/Projects/SalesReport"
User: "Rename table Salesforce_Data to Sales Force Data"
The rename cascade is transactional (it rolls every file back on failure) and writes atomically
(temp file plus os.replace), preserving encoding and line endings.
Always use the
pbip_rename_*tools for renames, not the deprecated TOMbatch_rename_*tools. Close Power BI Desktop before PBIP edits, then reopen.
config/policies.yaml: block, mask, hash,
redact, and numeric_mask (session-randomized scaling that hides values but preserves ratios).verify_audit_integrity.
Set POWERBI_MCP_AUDIT_KEY to switch the chain to HMAC-SHA256 (cryptographically strong against
an attacker who edits the log); without a key it is a plain SHA-256 chain that still catches
accidental edits and naive tampering.POWERBI_MCP_READONLY=true to refuse every write tool
(model/report mutations and file-writing tools like snapshots, dictionaries, and PBIX
extraction) while reads and diagnostics keep working. Ideal for shared or autonomous agent use.# config/policies.yaml (excerpt)
tables:
- name: "*"
columns:
- name: ssn
action: block
- name: card_number
action: mask
| Variable | Purpose |
|---|---|
TENANT_ID, CLIENT_ID, CLIENT_SECRET | Azure AD service principal (cloud, REST, admin) |
ADOMD_DLL_PATH | Folder (or full path) of Microsoft.AnalysisServices.AdomdClient.dll, if auto-discovery misses it |
POWERBI_MCP_READONLY | true refuses all write tools (lockdown mode) |
POWERBI_MCP_AUDIT_KEY | Secret key that switches the audit hash chain to HMAC-SHA256 (stronger tamper-resistance) |
ENABLE_PII_DETECTION, ENABLE_AUDIT, ENABLE_POLICIES | Toggle security subsystems (default true) |
LOG_LEVEL | DEBUG enables redacted argument logging |
| Doc | Contents |
|---|---|
| docs/TOOLS.md | Complete reference of all 70 tools, resources, prompts, env vars |
| docs/ARCHITECTURE.md | Components, security layer, registry pattern, verification methodology, file map |
| docs/TESTING.md | How to run the suites and what each covers |
| CHANGELOG.md | Everything that changed, by milestone |
| AGENTS.md | Agent playbook: golden rules, workflows, DAX patterns |
The suites in tests/ are assert-based scripts that run without Power BI (pure logic is tested
directly; live connectors are mocked).
python run_tests.py
See docs/TESTING.md for what each suite covers. Live Desktop, XMLA, REST, and admin paths are doc-verified against Microsoft Learn and mock-tested; end-to-end verification of those paths needs a Windows + Power BI / Fabric environment.
powerbi-mcp/
├── src/
│ ├── server.py # MCP server: 70 tools + resources/prompts/completion
│ ├── powerbi_desktop_connector.py # Desktop (ADOMD) + RLS + VertiPaq DMVs
│ ├── powerbi_xmla_connector.py # Cloud XMLA
│ ├── powerbi_rest_connector.py # REST: discovery, refresh, admin Scanner/Activity
│ ├── powerbi_tom_connector.py # TOM writes: measures, relationships, transactions
│ ├── powerbi_pbip_connector.py # PBIP/TMDL/PBIR offline editing (transactional)
│ ├── pbir_authoring.py # PBIR emitters: pages, visuals, field projections
│ ├── adomd_loader.py # Shared ADOMD.NET discovery (Desktop + XMLA)
│ ├── model_analysis.py # BPA, AI-readiness, data dictionary, diff, DAX tests
│ ├── dax_lint.py # DAX anti-pattern linter + rewrite hints (tokenizer)
│ ├── svg_measures.py # SVG micro-visual DAX measure generators
│ ├── naming_audit.py # Naming-convention audit -> rename plan
│ ├── pbix_tools.py # PBIX (.pbix ZIP) inspect/extract + layout decode
│ ├── bpa_authoring.py # Custom BPA rule validation + rule-source audit
│ ├── refresh_diagnostics.py # Refresh error classification
│ ├── governance.py # Scanner summary + activity aggregation
│ └── security/ # security_layer, access_policy, pii_detector, audit_logger
├── config/policies.yaml
├── tests/ # Assert-based suites
├── docs/ # TOOLS, ARCHITECTURE, TESTING
├── run_tests.py
├── AGENTS.md, CLAUDE.md
├── Dockerfile, requirements-core.txt
├── pyproject.toml, .editorconfig
├── CHANGELOG.md, requirements.txt
└── README.md
| Limitation | Notes |
|---|---|
| Live connectivity is Windows only | ADOMD.NET and TOM require Windows. The offline subset runs cross-platform via Docker. |
| TOM renames break visuals | Use the PBIP tools for safe renames (they update the report layer too). |
| Cloud enhanced refresh needs Premium | XMLA and enhanced refresh need PPU / Premium / Fabric capacity. Basic refresh and history work on Pro. |
| Fleet governance is admin-gated | Scanner and Activity tools need Fabric admin, or a service principal allowed to use read-only admin APIs. |
| Deep server timings | analyze_query_performance gives duration and hints; use DAX Studio for storage-vs-formula-engine timings. |
handle_list_tools, _build_tool_dispatch,
and _build_tool_annotations in src/server.py; a parity check enforces this).python run_tests.py and keep all suites green.Formatting conventions are in pyproject.toml and .editorconfig.
Sulaiman Ahmed, Data Analytics Engineer and Microsoft Certified Professional.
MIT. See LICENSE.
com.mcparmory/google-sheets
domdomegg/google-sheets-mcp
henilcalagiya/google-sheets-mcp
cct15/war-dashboard-data
moooonad/mcp-google-sheets-full
io.github.br0ski777/csv-to-json