Skip to main content
Glama
rajdeepraoextras-dev

pbi-mcp

pbi-mcp

MCP servers for local-file Power BI Project (.pbip) automation — model (TMDL) and report (PBIR) layers. No Power BI API, no auth, no cloud: the tools read and write the on-disk project files Power BI Desktop itself uses.

Build a correctly-bound, themed, filtered, multi-page report — or bulk-author hundreds of measures — from a prompt, in minutes. 56 tools across two MCP servers; every report write is pre-flight validated against the official Fabric schemas.

Fastest path: pbi_set_project(path)pbi_scaffold_report() profiles the model and builds a themed, navigable, multi-page designed report in one call (use dry_run=true to review the proposal first). Or compose it yourself with pbi_build_designed_page, the design elements, and the theme generator.

Scope honesty. This builds structure, speed, consistency. It does not do custom Deneb/Vega visuals, AppSource visual sourcing, or replace design taste. It's a fast report builder, not an autonomous report designer.

Safety model (the part that matters)

The one unforgivable bug for a tool like this is producing a project Desktop refuses to open. Every mutation therefore goes through:

  • atomic writes (temp file + rename — a crash never leaves a half file)

  • backup-once-per-file snapshots (*.bak-<timestamp>), with pbi_list_backups / pbi_restore_backup to recover

  • surgical text edits for TMDL — the parsed model is never re-emitted, so partitions, annotations, and M source are preserved byte-for-byte

  • style preservation — each file keeps its exact line endings + BOM (Desktop mixes CRLF and LF across file types)

  • deletion fail-safes — deleting a measure that other measures, visuals, or filters depend on is refused (transitive DAX lineage + report usage); force=true overrides, dry_run=true previews

  • recoverable visual deletes — removed visuals move to Report/.pbi/mcp-trash/, which Desktop ignores

Related MCP server: PBIXRay MCP Server

Download the plugin

For the easiest install, download one of the bundles from dist/:

  • pbi-mcp-standalone-win32-amd64.plugin - self-contained Windows build; no local Python setup required.

  • pbi-mcp.plugin - source plugin bundle; requires Python 3.11+ and the package dependencies on the host.

Drag the .plugin file into a plugin-aware MCP host, then call pbi_set_project(path) first in both pbi-model and pbi-report sessions.

Quickstart

git clone <repo> && cd pbi-mcp
python -m venv .venv
.venv\Scripts\pip install -e ".[dev]"
.venv\Scripts\python -m pytest          # green suite = good to go

Register in Claude Desktop: run scripts/package.py, then merge dist/claude_desktop_config.snippet.json into your claude_desktop_config.json and restart. Or drag-drop dist/pbi-mcp.plugin into a plugin-aware host. Details: INSTALL.md inside the bundle.

Every session starts with pbi_set_project(path) — point it at a .pbip saved with Desktop's PBIP preview format (enable Power BI Project (.pbip) save option + PBIR enhanced metadata in Options → Preview features).

Tool reference

pbi-model server (semantic model / TMDL)

Tool

What it does

pbi_set_project(path)

Select the project; returns table/measure counts

pbi_get_model()

Tables, columns, measures, relationships snapshot

pbi_list_measures(table?)

Measures with DAX + format string

pbi_model_lineage(measure?)

DAX dependency graph; per-measure deps + direct/transitive dependents

pbi_create_measure(table, name, dax, format?, display_folder?)

Create (name must be unique model-wide)

pbi_update_measure(table, name, dax?, format?, display_folder?)

Partial update; omitted fields kept

pbi_delete_measure(table, name, force?, dry_run?)

Delete with lineage + report-usage guards

pbi_create_column(table, name, data_type, summarize_by?, source_column?, dax?)

Data column, or calculated column with dax

pbi_create_relationship(from_table, from_column, to_table, to_column, ...)

Endpoints validated; duplicates detected

pbi_create_calc_group(name, precedence, items)

Full calc-group table + model.tmdl registration

pbi_bulk_create_measures(measures)

Batch create; whole batch validated before any write

pbi_list_backups() / pbi_restore_backup(backup)

Recovery

pbi-report server (report / PBIR)

Tool

What it does

pbi_set_project(path)

Select the project; returns page/visual counts

pbi_list_pages()

Pages: id, name, size, visual count, hidden

pbi_list_visuals(page_id)

Visuals with type, position, title, bindings

pbi_get_visual(page_id, visual_id)

Full config incl. raw visual.json

pbi_model_usage()

Classify every field direct / indirect / unused — the deletion fail-safe

pbi_create_page(name, width?, height?)

New page, registered in pages.json

pbi_add_visual(page_id, visuals[])

Batch add; buckets + model refs validated before any write

pbi_build_page(name, visuals[])

One call: page + visuals + auto-layout (KPI row, 2-col grid)

pbi_update_bindings(page_id, visual_id, bindings)

Rebind; formatting/position preserved

pbi_move_visual(page_id, visual_id, x?, y?, width?, height?)

Partial move/resize

pbi_delete_visual(page_id, visual_id)

Recoverable delete (→ .pbi/mcp-trash)

pbi_format_visual(page_id, visual_id, target, objects)

container (title/background/border) or visual (labels/legend/axes); plain values auto-encoded

pbi_set_report_theme(theme)

Install + activate a standard PBI theme JSON

pbi_add_filter(scope, field, ...)

Categorical / Advanced / TopN / RelativeDate at report, page, or visual scope

pbi-report — design, intelligence & lifecycle (v2)

Tool

What it does

pbi_capabilities()

Machine-readable spec: visual types, buckets, filters, examples

pbi_scaffold_report(...)

Autopilot: profile the model → themed multi-page designed report (dry_run to review)

pbi_profile_model()

Classify fact/dimension/date tables, measure roles, grouping columns

pbi_build_designed_page(...)

Header band + KPI strip on backplates + chart grid, one call

pbi_generate_theme(brand, mode)

Brand color → coherent theme (palette, text classes, light/dark)

pbi_add_text / pbi_add_image / pbi_add_shape

Design elements: titles, logos, backplates, dividers

pbi_style_page(page_id, ...)

Canvas background + wallpaper

pbi_group_visuals / pbi_add_visual_raw

Group as one block; raw escape hatch for any visual

pbi_sort_visual / pbi_add_nav_button

Sort; page-navigation buttons

pbi_set_page_role / pbi_set_visual_interactions

Drillthrough/tooltip pages; cross-filter control

pbi_create_bookmark

Capture page + filter state

pbi_rename/hide/reorder/delete/duplicate_page

Page lifecycle (delete is recoverable)

pbi_list_filters / pbi_remove_filter / pbi_list_trash / pbi_restore_visual

Filter + trash management

pbi_validate_project() / pbi_lint_page(id)

Schema validation + design lint

pbi_project_diff(other) / pbi_project_summary()

Diff vs another project/backup; overview

Binding format

Bindings are {bucket: ["Table.Field", ...]}. Measures vs columns are resolved automatically. Bucket names are per-visual-type and validated from core/visual_specs.py, whose contents were surveyed from real Desktop exports (150+ visuals) — notably: the Legend bucket is Series, combo charts use Y + Y2, donut charts have no Category.

// a bar chart spec for pbi_add_visual / pbi_build_page
{
  "visual_type": "clusteredBarChart",
  "bindings": {"Category": ["Date.Year"], "Y": ["Sales.Net Revenue"]},
  "title": "Revenue by Year",
  "position": {"x": 40, "y": 40, "width": 600, "height": 360}  // optional
}

Layout

pbi-mcp/
  core/            # PbipProject + TMDL/PBIR read-write, specs, lineage,
                   # usage classifier, formatting/filter builders, safe I/O
  model_server/    # MCP server: pbi-model
  report_server/   # MCP server: pbi-report
  scripts/         # smoke test, M5 demo, packager
  tests/           # 220+ tests; fixtures/ (synthetic + real, gitignored)

Testing

Fixture-based + golden files + fuzz. The suite runs against a synthetic PBIP project (committed) and any real exports dropped under tests/fixtures/real/ (auto-discovered, never committed). Golden snapshots of emitted visual.json live in tests/goldens/ (regenerate deliberately with PBI_MCP_REGEN_GOLDENS=1). A seeded 60-op fuzz storm asserts the project always reloads parseable. The reopen-in-Desktop check stays a manual gate before each release.

License

MIT.

Install Server
A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/rajdeepraoextras-dev/PBI-MCP-Server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server