powerbi-plus
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@powerbi-pluslist pages in my report"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
powerbi-plus
An MCP server for building and inspecting Power BI report visuals by editing the report's PBIR files on disk. It complements the model-layer MCPs (XMLA/TOM) by owning the layer they can't reach: pages, charts, slicers, cards, layout.
Why two layers
Power BI automates in two very different ways:
Layer | What | How reached |
Semantic model | tables, columns, measures, relationships, DAX | live via the Analysis Services / XMLA endpoint while Desktop is open |
Report / visuals | pages, charts, slicers, layout, formatting | file-based — no live canvas API |
This server is the report layer. It reads and edits the per-visual JSON files of a report saved in PBIR format. Changes land on disk; Power BI Desktop picks them up when the project is reopened/reloaded — there is no supported way to draw on a live session's canvas.
Related MCP server: powerbi-mcp-local
Prerequisite: save your report as PBIP with PBIR format
A classic .pbix stores the report as an opaque blob this server can't safely
edit. One-time conversion in Power BI Desktop:
File → Options and settings → Options → Preview features — enable:
Power BI Project (.pbip) save option
Store reports using enhanced metadata format (PBIR)
Restart Desktop if prompted.
File → Save as → Power BI project (.pbip).
You get a folder tree:
<Project>.pbip
<Project>.Report/
definition.pbir
definition/
report.json
pages/
pages.json
<pageName>/
page.json
visuals/
<visualName>/visual.json ← one file per visual
<Project>.SemanticModel/open_project reports the format; if it says anything other than PBIR,
finish the conversion above before inspecting/editing.
Install
cd C:\path\to\mcp-powerbi-plus
python -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txtRegister the server
Add the entry below to your MCP config, fixing the two paths to point at this
checkout's .venv python and server.py. Use double backslashes in JSON on
Windows, and write the file as UTF-8 without a BOM (a BOM breaks the JSON
parser). Restart the client afterward — MCP servers load at launch.
{
"mcpServers": {
"powerbi-plus": {
"command": "C:\\path\\to\\mcp-powerbi-plus\\.venv\\Scripts\\python.exe",
"args": [
"C:\\path\\to\\mcp-powerbi-plus\\server.py"
]
}
}
}Where the config lives, by client:
Client | Config file | Notes |
Claude Desktop |
| Merge |
Claude Code |
| Add to the top-level |
A ready-to-edit snippet is in examples/mcp.json. Once
registered, the tools appear as powerbi-plus's tools (e.g.
mcp__powerbi-plus__open_project).
Config (config.json)
Pure filesystem — no Azure auth.
Key | Meaning |
| gates future create/update/delete/theme tools. Read/inspect always work. |
| optional path used when a tool's |
Tools — read / inspect
Tool | Does |
| format (PBIR vs legacy blob), name, dataset pointer, theme, page count, active page |
| pages in order: internal name, displayName, size, visual count, active flag |
| visuals on a page: name, type, title, position, bound roles |
| one visual in full: type, title, position, field bindings per role, formatting objects, filters |
| tables / columns (+dataType) / measures from the sibling |
Tools — write (gated by "writable": true)
Tool | Does |
| create a visual on a page (type + field bindings + position + title) |
| edit an existing visual in place (type / bindings / title / position) |
| reposition / resize (x / y / width / height / z) |
| remove a visual |
| create a page and register it in |
| remove a page + its visuals, reassign active page |
| create a page and auto-lay-out a list of visuals on a column grid in one call |
| set formatting on a visual (background, title, legend, dataColors…), merging into existing objects |
| apply a custom report theme — update an existing registered theme in place, or stage a new one |
project is accepted on every tool and may be a .pbip file, the *.Report
folder, the definition folder, or a parent dir holding one *.Report. Omit it
to use default_project.
Binding shape
bindings maps a visual role to one field spec or a list of them:
{
"Category": { "entity": "DimRegion", "property": "Region" }, // column (default)
"Y": { "entity": "FactSales", "property": "Total Sales", "kind": "measure" },
"Values": { "entity": "FactSales", "property": "Amount", "aggregation": "sum" } // wraps a column
}Roles by visual: chart → Category + Y; card → Values; matrix
(pivotTable) → Rows + Columns + Values; slicer → Values.
aggregation ∈ sum / avg / min / max / count / countNonNull / median / stdev / var.
Edits land on disk. Close the report in Power BI Desktop before writing, then reopen the project to see changes — there is no live-canvas push.
generate_page layout
Items flow left-to-right across a column grid (default 12 cols) and wrap to a
new row when full; a row's height is its tallest item. Per item: colSpan
(grid width, default half), height (points). An item with an explicit
position is pinned and skips the flow. Optional layout overrides
{columns, margin, gutter, rowHeight}. The whole spec is validated and built
in memory before the page is created — an invalid spec writes nothing.
format_visual value encoding
formatting is {object: {prop: value}}. Values auto-encode to PBIR property
expressions: bool → true/false, int → whole-number literal (14L), float →
decimal (50.5D), "#RRGGBB" or a color-named prop → solid color, other text →
quoted string. Force a type with {"type":"color|text|int|number|bool","value":…}
or pass a ready node with {"raw": {…}}. target auto-routes container objects
(title/background/border/shadow/…) to visualContainerObjects and the rest to
objects; override with "objects" / "container".
apply_theme — what's actually supported
PBIR is in preview, and registering a brand-new resource by external edit is
not supported (it needs a report.json change Desktop owns). So:
Theme already registered →
apply_themeoverwrites it (or deep-merges withmerge: true). Reopen Desktop to load. ✅ supported.No theme registered yet → the file is staged under
StaticResources/RegisteredResources; register it once via Desktop View → Themes → Browse for themes, after which updates work in place. The returnedsupportedflag tells you which path ran.
list_model_fields
Reads the report's semantic model (resolved via definition.pbir byPath, or a
single sibling *.SemanticModel) and returns its tables, columns (with
dataType), and measures — so you can bind visuals to fields that actually
exist. TMDL and legacy model.bim/TMSL are both parsed; hidden fields are
excluded unless include_hidden: true. Reports on a live (byConnection)
dataset have no local model files — query those via the powerbi-modeling or
powerbi MCP instead.
Status
All 14 tools are verified against a synthetic PBIR fixture (every write
round-trips through the read layer). Not yet validated against a report
opened in Power BI Desktop — schema details like literal suffixes (L/D),
the title bucket, and theme registration should be confirmed on a real .pbip
before relying on the write tools in production.
License
MIT.
This server cannot be installed
Maintenance
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/rajivdatta/mcp-powerbi-plus'
If you have feedback or need assistance with the MCP directory API, please join our Discord server