AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Pbirb Mcp

mcp-mafaq229-pbirb-mcp · by mafaq229

MCP server for editing Power BI Report Builder paginated reports (`.rdl`) through Claude or any MCP client. 130+ tools across charts, datasets, layout, parameters, validation. Byte-identical RDL round-trip; PBIDATASET-aware.

— No reviews yet
0 installs
30 views
0.0% view→install

Install

$ agentstack add mcp-mafaq229-pbirb-mcp

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-mafaq229-pbirb-mcp)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 3mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Pbirb Mcp? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

pbirb-mcp

[](https://github.com/mafaq229/pbirb-mcp/actions/workflows/ci.yml) [](https://pypi.org/project/pbirb-mcp/) [](https://pypi.org/project/pbirb-mcp/) [](LICENSE)

An MCP server for editing Power BI Report Builder paginated reports (.rdl) through Claude (Desktop, CLI, or any MCP client). 140+ tools cover the gaps that otherwise force hand-written XML: report creation, data sources and datasets, calculated fields, dataset and tablix filters, groupings (row, column, matrix), sorting, charts, headers and footers, body composition, layout containers, positioning, styling, page setup, pagination, advanced parameters, embedded images, interactivity (actions, tooltips, document map), transactions, and validation.

The server speaks JSON-RPC 2.0 over stdio. It opens an .rdl from disk, mutates it in place via lxml, validates structure, and writes atomically — a failed save never leaves a half-written report or scrubs the original.

Stability

Pre-1.0. The tool surface — tool names, inputSchema, output shapes, error semantics — is the contract. While on 0.x, MINOR releases may include a small breaking change with a migration note in [CHANGELOG.md](CHANGELOG.md); after v1.0, breaking changes require MAJOR. See [CONTRIBUTING.md](CONTRIBUTING.md#versioning) for the full bump rules adapted from SemVer for an MCP tool surface.

Pin to a MINOR while on 0.x (e.g. pbirb-mcp~=0.1) if your prompts depend on specific tool names or schemas.


Quick start

1. Install

The simplest path is uv + PyPI — no clone, no venv, no install step:

uvx pbirb-mcp

uvx fetches the package into a throwaway environment, runs the pbirb-mcp console script, and exits. The MCP server speaks JSON-RPC over stdio, so any MCP client (Claude Desktop, Claude Code, etc.) can spawn it directly.

For local development against this codebase instead:

git clone https://github.com/mafaq229/pbirb-mcp
cd pbirb-mcp
uv venv .venv
uv pip install --python .venv/bin/python -e ".[dev]"

Verify the binary works:

printf '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}\n' \
  | .venv/bin/pbirb-mcp

You should see a single JSON-RPC response with protocolVersion, capabilities.tools, and serverInfo.name = "pbirb-mcp".

2. Wire into Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "pbirb": {
      "command": "uvx",
      "args": ["pbirb-mcp"]
    }
  }
}

Restart Claude Desktop. The hammer icon should show pbirb and the 140+ tools listed below.

To enable file logging, add an env block — but keep it platform-appropriate. PBIRB_MCP_LOG_FILE takes an OS-native path: a Unix path like /tmp/pbirb-mcp.log only works on macOS/Linux. On Windows use a Windows path (e.g. %TEMP%\\pbirb-mcp.log). See [Logging](#logging). When unset, logs go to stderr, which Claude Desktop captures in its MCP debug pane on every platform.

For development against a local checkout, swap the args for ["--from", "/absolute/path/to/pbirb-mcp", "pbirb-mcp"] so uvx runs your working tree instead of the published version.

3. Wire into Claude Code

claude mcp add pbirb -- uvx pbirb-mcp

Or add to .mcp.json at the workspace root:

{
  "mcpServers": {
    "pbirb": {
      "command": "uvx",
      "args": ["pbirb-mcp"]
    }
  }
}

Or install it as a Claude Code plugin — one command instead of editing config by hand (it wires up the same uvx pbirb-mcp server for you):

/plugin marketplace add mafaq229/pbirb-mcp
/plugin install pbirb-mcp@pbirb

4. Smoke test

In any chat, ask the model:

> Open ~/path/to/some-report.rdl and tell me what datasets and parameters it has.

The model should call describe_report, get_datasets, and get_parameters and summarise the result. If it doesn't, your client probably hasn't loaded the server — check the client's MCP debug log.


Working with a report

The recommended flow is read first, then edit by name. Every mutating tool addresses elements by their RDL Name attribute (Tablix name, Textbox name, ReportParameter name, DataSet name) — never by index. Indices break across multi-step edits.

A typical session:

You:    Bind the existing report at ~/Reports/sales.rdl to the Finance
        workspace's "FY26 Sales" dataset, change the body DAX to a date-
        ranged query, and add a header with a logo and a parameter line.

Claude: → describe_report(path=…)
        → set_datasource_connection(name="PBIDataset",
              workspace_url="Finance", dataset_name="FY26 Sales")
        → update_dataset_query(dataset_name="MainDataset",
              dax_body="EVALUATE FILTER('Sales',
                'Sales'[OrderDate] >= @DateFrom &&
                'Sales'[OrderDate] ` at a Power BI XMLA endpoint. `DataProvider=SQL` (the AS provider id). |
| `add_data_source` / `remove_data_source` / `rename_data_source` | Manage `` elements |
| `update_dataset_query` | Replace `//` with a DAX expression |
| `add_query_parameter` | Append `` (e.g. `=Parameters!DateFrom.Value`) |
| `update_query_parameter` | Change the value expression of an existing query parameter |
| `remove_query_parameter` | Drop a query parameter (and clean up empty ``) |
| `add_dataset_field` / `remove_dataset_field` | Manage `` entries on a dataset |
| `add_calculated_field` / `remove_calculated_field` | Manage ``-backed calculated fields |
| `refresh_dataset_fields` | Re-derive the `` list from the query's column metadata |
| `add_dataset_filter` / `remove_dataset_filter` | Filters applied at the dataset level (vs. tablix) |

### Tablix

| Tool | What it edits |
|------|---------------|
| `add_tablix_filter` | Append a ``. Operators: Equal, NotEqual, GreaterThan, In, Between, Like, TopN, ... |
| `remove_tablix_filter` | Remove by ordinal index from `list_tablix_filters` |
| `add_row_group` / `remove_row_group` | Wrap the row hierarchy in a new outer group + header row (and its inverse) |
| `add_column_group` / `remove_column_group` | Same, on the column axis |
| `convert_to_matrix` | Promote a table to a matrix (row + column groups) — see [docs/MATRIX-cookbook.md](docs/MATRIX-cookbook.md) |
| `set_tablix_corner` | Set the matrix corner cell text/expression |
| `set_group_sort` / `set_column_group_sort` | Replace `` on a group |
| `set_group_visibility` / `set_column_group_visibility` | Set `` on a group's TablixMember |
| `set_detail_row_visibility` | Set `` on the Details group |
| `add_tablix_column` / `remove_tablix_column` | Add/drop a column across the tablix grid |
| `add_static_row` / `add_static_column` | Insert a non-grouped row/column |
| `add_subtotal_row` / `add_subtotal_column` | Insert an aggregate row/column on a group |
| `set_cell_span` | Set `RowSpan` / `ColSpan` on a cell |
| `set_column_width` / `set_row_height` | Set `` / `` on the Nth column/row |
| `set_tablix_size` | Set the tablix's overall `` / `` |

### Page

| Tool | What it edits |
|------|---------------|
| `set_page_setup` | Page dimensions, margins, columns. All fields optional. |
| `set_page_orientation` | Swap PageHeight/PageWidth to match `Portrait` or `Landscape`. Idempotent. |

### Page header & footer

Same set of operations for each region, each accepts named items so
follow-up edits don't drift on indices.

| Tool | What it edits |
|------|---------------|
| `set_page_header` / `set_page_footer` | Section height + `PrintOnFirstPage` / `PrintOnLastPage` |
| `add_header_textbox` / `add_footer_textbox` | Append a Textbox (static text or `=expression`) |
| `add_header_image` / `add_footer_image` | Append an Image (External URL, Embedded name, or Database expression) |
| `remove_header_item` / `remove_footer_item` | Remove by name; tidies empty `` |

### Body composition

| Tool | What it edits |
|------|---------------|
| `add_body_textbox` | Append a Textbox to `/` |
| `add_body_image` | Append an Image to the body |
| `remove_body_item` | Remove a named Textbox / Image / Tablix from the body |

### Snippet templates

Single-call inserts of common report items, programmatically built and
appended to the body.

| Tool | What it builds |
|------|----------------|
| `insert_tablix_from_template` | A basic Tablix mirroring the fixture's shape — header row with the column name as a static label, detail row binding to `=Fields!.Value`. One column per requested field. |
| `insert_chart_from_template` | A basic Column chart: single category axis grouped by `category_field`, single Y series `=Sum(Fields!.Value)`. Change `` post-insert (Bar / Line / Pie / etc.). |

### Charts

Refine a chart after `insert_chart_from_template` (or any existing ``).

| Tool | What it edits |
|------|---------------|
| `add_chart_series` / `remove_chart_series` | Manage Y-axis `` |
| `set_chart_series_type` | Column / Bar / Line / Area / Pie / ... per series |
| `set_chart_series_grouping` | Category/series grouping expression |
| `set_chart_axis` | Category / value axis title, scale, format |
| `set_chart_legend` | Legend visibility and placement |
| `set_chart_data_labels` | Toggle and format data labels |
| `set_chart_title` | Chart title text/expression |
| `set_chart_palette` / `set_series_color` | Palette name; explicit per-series color |

### Styling

| Tool | What it edits |
|------|---------------|
| `set_textbox_style` | Routes properties to the right nested `` node automatically: box-level (BackgroundColor, Border, VerticalAlign), paragraph-level (TextAlign), run-level (FontFamily, FontSize, FontWeight, Color, Format) |
| `set_textbox_style_bulk` | Apply one style to many textboxes in a single call |
| `set_textbox_runs` / `set_textbox_value` | Rich multi-run paragraph content; or replace the value |
| `find_textboxes_by_style` / `find_textbox_by_value` | Locate textboxes to target follow-up edits |
| `style_tablix_row` | Style every cell of a tablix row at once (header / detail / footer) |
| `set_alternating_row_color` | Zebra-stripe a tablix's detail row with `BackgroundColor=IIf(RowNumber(Nothing) Mod 2, "", "")` |
| `set_conditional_row_color` | Drive detail-row `BackgroundColor` from an expression |
| `set_image_sizing` / `set_image_source` | Image ``; switch External / Embedded / Database source |

### Visibility

| Tool | What it edits |
|------|---------------|
| `set_element_visibility` | Set `` on any named ReportItem (Tablix, Textbox, Image, Rectangle, Subreport, Chart). Group / detail-row visibility have their own tools. |

### Layout containers

| Tool | What it builds |
|------|----------------|
| `add_rectangle` | A `` container (group other items, control page breaks) |
| `add_list` | A list region (single-column tablix template) |
| `add_line` | A `` report item |

### Positioning & sizing

Move and resize named items in each region. Coordinates are RDL sizes
(`"1in"`, `"2.5cm"`, ...).

| Tool | What it edits |
|------|---------------|
| `set_body_item_position` / `set_header_item_position` / `set_footer_item_position` | `Top` / `Left` of a named item |
| `set_body_item_size` / `set_header_item_size` / `set_footer_item_size` | `Width` / `Height` of a named item |
| `set_body_size` | The `` region's overall height |

### Interactivity

| Tool | What it edits |
|------|---------------|
| `set_textbox_action` / `set_image_action` / `set_chart_series_action` | ``: hyperlink, drill-through, or bookmark |
| `set_textbox_tooltip` | Textbox `` |
| `set_document_map_label` | `` for the navigation pane |

### Pagination

| Tool | What it edits |
|------|---------------|
| `set_group_page_break` | `` (Start / End / Between) |
| `set_repeat_on_new_page` | Repeat a group header/footer on each page |
| `set_keep_together` / `set_keep_with_group` | Keep-together rendering hints |

### Parameters (advanced)

| Tool | What it edits |
|------|---------------|
| `add_parameter` / `remove_parameter` / `rename_parameter` | Manage `` elements |
| `set_parameter_prompt` / `set_parameter_type` | Prompt text; data type (Boolean / DateTime / Integer / Float / Text) |
| `set_parameter_available_values` | Static `` list (strings or `{value, label}` dicts) **or** `` to a lookup dataset |
| `set_parameter_default_values` | Static `` list **or** `` (defaults take ValueField only — defaults are values, not display strings) |
| `update_parameter_advanced` | Toggle the four boolean flags: `multi_value`, `hidden`, `allow_null` (writes ``), `allow_blank` |
| `reorder_parameters` | Reorder `` (controls prompt order) |
| `set_parameter_layout` / `sync_parameter_layout` | Position parameters in the `` grid |

#### Cascading parameters

RDL has no `` element — cascading is inferred from
`=Parameters!X.Value` references in a lookup dataset's ``.
To wire parameter `B` to depend on parameter `A`:

1. `set_parameter_available_values(name="B", source="query", query_dataset="LookupB", ...)`
2. `add_query_parameter(dataset_name="LookupB", name="@A", value_expression="=Parameters!A.Value")`

Report Builder figures out the dependency graph by parsing those expressions.

### Embedded images

| Tool | What it edits |
|------|---------------|
| `add_embedded_image` | Read a real file off disk, base64-encode it, store under `` |
| `list_embedded_images` | Names + MIME types |
| `remove_embedded_image` | Remove by name; tidies empty `` |

Reference an embedded image with
`add_*_image(image_source="Embedded", value="")`.

### Report lifecycle

| Tool | What it does |
|------|--------------|
| `create_report` | Scratch-create a minimal valid `.rdl` to start from |
| `duplicate_report` | Copy a report to a new path |
| `backup_report` / `restore_from_backup` | Snapshot a report and roll back to it |

### Expression helpers

These don't mutate the report — they build correct RDL expression strings to
pass into other tools (text, filters, conditional styling).

| Tool | What it returns |
|------|-----------------|
| `count_where` / `sum_where` | A `Count`/`Sum` aggregate expression with an inline condition |
| `iif_format` | An `IIf(...)` expression for conditional values/formatting |
| `get_expression_reference` | A reference sheet of common RDL expression patterns |

### Transactions & validation

Batch many edits into one atomic save, and check correctness before/after.

| Tool | What it does |
|------|--------------|
| `start_editing_transaction` / `commit_editing_transaction` / `cancel_editing_transaction` | Open an in-memory transaction, lint-and-save once, or discard. See [docs/TRANSACTIONS.md](docs/TRANSACTIONS.md). |
| `apply_edits` | Apply a list of tool calls in one transaction |
| `dry_run_edit` | Preview an edit's effect without writing to disk |
| `validate_report` / `verify_report` | Structural validation (and opt-in XSD validation against the bundled `reportdefinition.xsd`) |
| `lint_report` | Surface warnings/errors Report Builder would flag |

### Raw XML escape hatch

| Tool | What it does |
|------|--------------|
| `raw_xml_view` | Read the XML under an XPath |
| `raw_xml_replace` | Replace the XML at an XPath — last resort for anything without a dedicated tool |

---

## Power BI specifics

### XMLA connection strings

`set_datasource_connection` writes the canonical form:

Data Source=powerbi://api.powerbi.com/v1.0/myorg/;Initial Catalog=


`workspace_url` accepts a bare workspace name (`Finance`) or a full
`powerbi://` URL — the tool detects the latter and avoids double-prefixing.
`DataProvider` is set to `SQL` (the Analysis Services provider id RDL uses
for PBI XMLA, despite the misleading name).

### DAX queries

DAX bodies are accepted verbatim — `pbirb-mcp` doesn't parse DAX, so the
user (or Report Builder at preview time) is the source of truth for syntax.
Empty bodies are rejected up front because Report Builder loads them but
errors at preview, which is a worse signal than a clear `Value

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [mafaq229](https://github.com/mafaq229)
- **Source:** [mafaq229/pbirb-mcp](https://github.com/mafaq229/pbirb-mcp)
- **License:** MIT
- **Homepage:** https://pypi.org/project/pbirb-mcp/

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.