
Pbirb Mcp
io.github.mafaq229由 GitHub 帳號 mafaq229 發布v0.4.1更新於 Oct 26, 2026
MCP server for editing Power BI Report Builder paginated reports (RDL)
概覽
用來編輯 Power BI Report Builder 分頁報表(.rdl)的 MCP 伺服器,讓助理透過 140 多個工具讀取、修改、驗證並儲存報表 XML。
- 可以做什麼
- 檢視報表:描述整體結構、資料集、資料來源、參數、Tablix、篩選條件與內嵌圖片
- 編輯資料來源與資料集:改指向 Power BI XMLA 端點,替換 DAX 查詢,管理查詢參數、欄位、計算欄位與篩選條件
- 調整 Tablix:列與欄群組、排序、可見性、轉換為矩陣、增刪欄、小計、儲存格跨距與尺寸
- 編排版面:頁面設定與方向、頁首頁尾、本文項目、矩形、清單、線條、定位與樣式
- 建立圖表、參數、內嵌圖片、動作、工具提示、分頁,以及運算式輔助工具
- 管理生命週期與安全:建立、複製、備份與還原報表,以交易批次編輯、試跑、驗證、檢查,以及讀取或取代原始 XML
- 適用情境
- 適合需要維護 Power BI 分頁報表、希望助理以結構化方式修改 .rdl 檔案而非手寫 XML 的情境,尤其是重新綁定資料集、新增群組或重設 Tablix 樣式等多步驟變更。
- 執行需求
- 以 stdio 在本機執行,通常透過 uvx 從 PyPI 啟動,因此需要 Python 與 uv。未宣告驗證、環境變數或標頭;選用的環境變數 PBIRB_MCP_LOG_FILE 可指定日誌路徑。檢視結果需另外安裝免費的 Windows 版 Report Builder。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Pbirb Mcp,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
pbirb-mcp
[CI] [PyPI] [Python versions] [License: MIT]
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; after v1.0, breaking changes require MAJOR.
See CONTRIBUTING.md 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 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:
Verify the binary works:
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):
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. 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
Or add to .mcp.json at the workspace root:
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):
4. Smoke test
In any chat, ask the model:
Open
~/path/to/some-report.rdland 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:
Open the resulting .rdl in Report Builder; the change is visible in the
designer and renders in Preview against the bound dataset.
Tool reference
143 tools, grouped by RDL concern. The highlights of each group are tabled
below; the authoritative, always-current list with full schemas is the
server's tools/list output, visible to the LLM at registration time. Every
tool takes a path argument (absolute path to the .rdl).
Most mutating tools also accept an optional transaction_id so a multi-step
edit batches into a single atomic save — see Transactions
and docs/TRANSACTIONS.md.
Read-only inventory
The "what's in this report?" tools. Always the first calls when planning a multi-step edit.
Datasource & dataset
Tablix
Page
Page header & footer
Same set of operations for each region, each accepts named items so follow-up edits don't drift on indices.
Body composition
Snippet templates
Single-call inserts of common report items, programmatically built and appended to the body.
Charts
Refine a chart after insert_chart_from_template (or any existing <Chart>).
Styling
Visibility
Layout containers
Positioning & sizing
Move and resize named items in each region. Coordinates are RDL sizes
("1in", "2.5cm", ...).
Interactivity
Pagination
Parameters (advanced)
Cascading parameters
RDL has no <DependsOn> element — cascading is inferred from
=Parameters!X.Value references in a lookup dataset's <QueryParameters>.
To wire parameter B to depend on parameter A:
set_parameter_available_values(name="B", source="query", query_dataset="LookupB", ...)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
Reference an embedded image with
add_*_image(image_source="Embedded", value="<image-name>").
Report lifecycle
Expression helpers
These don't mutate the report — they build correct RDL expression strings to pass into other tools (text, filters, conditional styling).
Transactions & validation
Batch many edits into one atomic save, and check correctness before/after.
Raw XML escape hatch
Power BI specifics
XMLA connection strings
set_datasource_connection writes the canonical form:
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 ValueError here.
PBI paginated reports do not carry <CommandType> for DAX (unlike
SSRS where you'd set CommandType=StoredProcedure); these tools never
emit it.
Pre-commit hooks (contributors)
pre-commit is in the [dev] extras. After a fresh checkout:
After the hook is installed, every git commit runs ruff format +
ruff check (with --fix) + the fast pytest suite. If lint or tests
fail the commit is aborted; fix and re-stage before retrying.
To run individual hooks ad-hoc:
The full config lives in .pre-commit-config.yaml. Ruff settings
(line length, rule selection, per-file ignores) live under
[tool.ruff*] in pyproject.toml.
Report Builder install
Power BI Report Builder is a free Microsoft-distributed Windows app:
https://www.microsoft.com/en-us/download/details.aspx?id=105942
Open any .rdl produced by pbirb-mcp directly in Report Builder. The
"opens cleanly with no upgrade prompt" check is the actual integration
test — the unit tests verify schema correctness, but lxml will
round-trip XML that Report Builder's deserialiser still rejects (we hit
this twice in the chart-template work; both fixes are documented in the
git history).
Architecture
Hard rules (enforced by tests)
- Tests first. Every commit writes failing tests, then makes them pass.
- lxml, not stdlib
xml.etree. Round-trip fidelity is a feature, not polish. Report Builder reads what's on disk; formatting drift causes silent corruption. - Stable IDs, never indices. Tools take
tablix_name+group_name, notcolumn_index: 2. Indices break across multi-step edits. - Atomic save.
RDLDocument.save_aswrites to<path>.tmpthen renames. A failure mid-write never leaves a half-written report. - Round-trip byte-identity is enforced by
tests/test_document.py'stest_round_trip_byte_identical_to_fixture. A no-op open → save → reopen produces a byte-identical file.
RDL gotchas learned the hard way
<?xml version="1.0" encoding="utf-8"?>uses double quotes, not lxml's default single quotes. Fixed inRDLDocument.save_asvia a manual declaration.- Self-closing tags use
<Tag />with a space, not<Tag/>. Fixed via a post-process regex. - The
rd:prefix (http://schemas.microsoft.com/SQLServer/reporting/reportdesigner) carries designer metadata Report Builder relies on. Don't strip it; preserve prefixes. - Do not put
MustUnderstand="df"on<Report>unless you also declarexmlns:df=.... <ChartCategoryAxes>/<ChartValueAxes>hold<ChartAxis>children directly — there is no<ChartCategoryAxis>/<ChartValueAxis>wrapper.<ChartMember>requires a<Label>child, even an empty one.- DAX queries live in
<DataSet><Query><CommandText>EVALUATE ...</CommandText></Query></DataSet>. No<CommandType>element for DAX (unlike SSRS).
Logging
Two environment variables control the logger:
Development
Running tests
The suite is fast (~1.7s for 1188 tests) so re-run on every change.
Smoke testing the live binary
For an end-to-end sanity check, drive an actual mutation against a copy of the bundled fixture:
Open the resulting file in Power BI Report Builder. Manual verification
that an .rdl opens cleanly is the actual integration test — the unit
tests catch schema-level mistakes, but only Report Builder catches
deserialiser nits.
Adding a new tool
- Write tests first under
tests/test_*.py. - Implement in the appropriate
pbirb_mcp/ops/*.pymodule (or create a new one). - Register in
pbirb_mcp/tools.pywith a cleardescriptionand strictinputSchema. - Run the full suite and a JSON-RPC smoke against the fixture.
- Open the modified RDL in Report Builder.
The commit-by-commit history shows the pattern in practice.
Releases
CHANGELOG.md tracks every release in Keep a Changelog format. Releases are also published as GitHub Releases and to PyPI.
Versions follow SemVer adapted for an MCP tool surface — see CONTRIBUTING.md § Versioning.
Contributing
PRs welcome. CONTRIBUTING.md covers dev setup, the hard rules (tests-first, lxml only, stable IDs, atomic save, byte-identity round-trip, smoke in Report Builder), the SemVer-for-MCP bump table, and the PR review checklist.
Bug reports and tool proposals: please use the issue templates. For security issues, see SECURITY.md. All participants are expected to follow the Code of Conduct.
Acknowledgments
The existing bethmaloney/rdl-mcp server pioneered the MCP-over-RDL pattern but is scoped to SSRS: column metadata, basic parameter management, stored-procedure swap. Power BI paginated reports use the same RDL 2016 schema as SSRS, but:
- Data sources are Power BI XMLA endpoints, not SQL Server.
- Queries are DAX, and the upstream tool exposes no body-edit (only stored-procedure name swap, useless here).
- Report Builder is picky about XML round-tripping — formatting drift,
namespace prefix loss, or unrecognised
MustUnderstandattributes cause silent corruption or "this report needs to be upgraded" prompts.
pbirb-mcp is built around lxml so a no-op edit produces a byte-identical
file, addresses every element by stable name (never index), and treats
"opens cleanly in Report Builder" as the actual integration test.
來源:README.md,提交 e1dbcce
工具
0版本歷史
1- v0.4.1最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分