mcpField
P
pbirb-mcp

pbirb-mcp

本地服务
github.com/mafaq229数据与分析617 周前更新

关于 pbirb-mcp

pbirb-mcp 让 MCP 客户端检查和编辑 `.rdl` 格式的 Power BI Report Builder 分页报表。其工具覆盖报表结构与布局,并通过验证和原子写入避免文件只保存一部分。

主要功能

  1. 01检查报表内容与结构
  2. 02编辑数据源、数据集和参数
  3. 03调整 tablix 分组、筛选和布局
  4. 04创建并设置图表与报表项样式
  5. 05配置页面设置和分页
  6. 06验证并原子保存报表文件

适用场景

  1. 01更新现有报表中的数据集和参数
  2. 02调整 tablix 分组、筛选或格式
  3. 03在 RDL 报表中添加图表、页眉或嵌入图片

MCP 相关

它通过 stdio 上的 JSON-RPC 2.0 向 MCP 客户端提供报表检查、编辑和验证工具。客户端可打开 `.rdl` 文件、修改内容并原子保存。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"mafaq229-pbirb": {
"command": "uvx",
"args": [
"pbirb-mcp"
]
}
}
}
启动命令uvx pbirb-mcp

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypipbirb-mcp0.4.1

工具

143

收录的工具列表 · 更新于 2 周前

参数类型必填说明
pathstring是要读取的 .rdl 文件的绝对路径。

详细介绍

pbirb-mcp

CI PyPI Python versions License: MIT

用于通过 Claude(桌面版、CLI 或任何 MCP 客户端)编辑 Power BI Report Builder 分页报表(.rdl)的 MCP 服务。140 多种工具涵盖了原本需要手动编写 XML 的各种操作:创建报表、数据源和数据集、计算字段、数据集和 tablix 筛选器、分组(行、列、矩阵)、排序、图表、页眉和页脚、主体内容编排、布局容器、定位、样式、页面设置、分页、高级参数、嵌入图像、交互功能(操作、工具提示、文档地图)、事务和验证。

该服务通过 stdio 使用 JSON-RPC 2.0。它会从磁盘打开 .rdl,通过 lxml 就地修改、验证结构并以原子方式写入——保存失败不会留下写了一半的报表,也不会清除原始文件。

稳定性

尚未达到 1.0 版本。工具接口——工具名称、inputSchema、输出格式和错误语义——构成契约。在 0.x 阶段,MINOR 版本可能包含小幅破坏性变更,并在 CHANGELOG.md 中附上迁移说明;v1.0 之后,破坏性变更必须提升 MAJOR 版本。完整的版本升级规则请参阅 CONTRIBUTING.md,这些规则是针对 MCP 工具接口调整后的 SemVer 规则。

在 0.x 阶段,如果提示词依赖特定的工具名称或架构,请固定使用某个 MINOR 版本(例如 pbirb-mcp~=0.1)。


快速开始

1. 安装

最简单的方式是使用 uv + PyPI——无需克隆、无需 venv,也无需安装步骤:

uvx pbirb-mcp

uvx 会将软件包提取到临时环境中,运行 pbirb-mcp 控制台脚本,然后退出。MCP 服务通过 stdio 使用 JSON-RPC,因此任何 MCP 客户端(Claude Desktop、Claude Code 等)都可以直接启动它。

如果要在此代码库上进行本地开发:

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

验证二进制文件是否正常工作:

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

你应该会看到一条 JSON-RPC 响应,其中包含 protocolVersion、capabilities.tools 和 serverInfo.name = "pbirb-mcp"。

2. 接入 Claude Desktop

编辑 ~/Library/Application Support/Claude/claude_desktop_config.json(macOS)或 %APPDATA%\Claude\claude_desktop_config.json(Windows):

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

重启 Claude Desktop。锤子图标应显示 pbirb,并列出下方的 140 多种工具。

如需启用文件日志,请添加 env 块,但路径必须符合对应平台的格式。PBIRB_MCP_LOG_FILE 接受操作系统原生路径:类似 /tmp/pbirb-mcp.log 的 Unix 路径仅适用于 macOS/Linux。在 Windows 上,请使用 Windows 路径(例如 %TEMP%\\pbirb-mcp.log)。请参阅日志记录。未设置时,日志会写入 stderr;所有平台上的 Claude Desktop 都会在其 MCP 调试面板中捕获这些日志。

如需基于本地检出版本进行开发,请将 args 替换为 ["--from", "/absolute/path/to/pbirb-mcp", "pbirb-mcp"],这样 uvx 就会运行你的工作树,而不是已发布的版本。

3. 接入 Claude Code
claude mcp add pbirb -- uvx pbirb-mcp

或者,将以下内容添加到工作区根目录下的 .mcp.json:

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

或者将其安装为 Claude Code 插件——只需运行一条命令,无需手动编辑配置(它会为你接入相同的 uvx pbirb-mcp 服务):

/plugin marketplace add mafaq229/pbirb-mcp
/plugin install pbirb-mcp@pbirb
4. 冒烟测试

在任意聊天中,向模型提问:

打开 ~/path/to/some-report.rdl,告诉我其中有哪些数据集和参数。

模型应该会调用 describe_report、get_datasets 和 get_parameters,并总结结果。如果没有调用,你的客户端可能尚未加载该服务——请检查客户端的 MCP 调试日志。


使用报表

建议的流程是先读取,再按名称编辑。每个会修改内容的工具都通过 RDL 的 Name 属性定位元素(Tablix 名称、Textbox 名称、ReportParameter 名称、DataSet 名称),而不是通过索引。多步编辑时,索引可能会变化。

典型会话:

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] <= @DateTo)")
        → add_query_parameter(dataset_name="MainDataset",
              name="DateFrom",
              value_expression="=Parameters!DateFrom.Value")
        → add_query_parameter(dataset_name="MainDataset",
              name="DateTo",
              value_expression="=Parameters!DateTo.Value")
        → add_embedded_image(name="Logo",
              mime_type="image/png", image_path="~/brand/logo.png")
        → set_page_header(height="0.75in",
              print_on_first_page=True, print_on_last_page=True)
        → add_header_image(name="HeaderLogo",
              image_source="Embedded", value="Logo",
              top="0in", left="0in", width="1in", height="0.5in")
        → add_header_textbox(name="DateLine",
              text='="From: " & Parameters!DateFrom.Value & "  To: "
                    & Parameters!DateTo.Value',
              top="0.1in", left="1.2in", width="4in", height="0.25in")

在 Report Builder 中打开生成的 .rdl;更改会显示在设计器中,并且会在预览中使用绑定的数据集进行呈现。


工具参考

共有 143 个工具,按 RDL 涉及的内容分组。下表列出各组的重点工具;权威且始终最新的完整列表及其架构,见服务器的 tools/list 输出,LLM 可在注册时查看。每个工具都接受一个 path 参数(.rdl 的绝对路径)。

大多数会修改内容的工具也接受可选的 transaction_id,以便将多步编辑批量处理为一次原子保存——参见 事务 和 docs/TRANSACTIONS.md。

只读清单

用于查看“此报表中有哪些内容?”的工具。规划多步编辑时,始终先调用这些工具。

工具返回内容
describe_report顶层清单:数据源、数据集、参数、tablix、页面设置
get_datasets / get_dataset完整的 DAX 命令文本、字段、查询参数、数据集筛选器(全部或按名称指定一个)
list_data_sources / get_data_source数据源清单;一个数据源的连接详细信息
get_parameters报表参数,包括数据类型、提示词和标志(多值、隐藏、可空、允许空白)
get_tablixesTablix 布局:列、行/列组、排序表达式、筛选器、可见性
list_tablix_filters / list_dataset_filters按文档顺序排列并带有稳定索引的筛选器
list_body_items / list_header_items / list_footer_items各区域中已命名的报表项
get_textbox / get_image / get_rectangle / get_chart已命名报表项的完整属性
list_embedded_images / get_embedded_image_data嵌入式图像名称和 MIME 类型;其中一个图像的 base64 字节
get_expression_reference常见 RDL 表达式模式速查表(count_where、sum_where、iif_format 辅助工具会构建这些模式)
数据源与数据集
工具编辑内容
set_datasource_connection将 <DataSource> 重定向到 Power BI XMLA 终结点。DataProvider=SQL(AS 提供程序 ID)。
add_data_source / remove_data_source / rename_data_source管理 <DataSource> 元素
update_dataset_query将 <DataSet>/<Query>/<CommandText> 替换为 DAX 表达式
add_query_parameter添加 <QueryParameter>(例如 =Parameters!DateFrom.Value)
update_query_parameter更改现有查询参数的值表达式
remove_query_parameter删除查询参数(并清理空的 <QueryParameters>)
add_dataset_field / remove_dataset_field管理数据集上的 <Field> 条目
add_calculated_field / remove_calculated_field管理由 <Value> 提供值的计算字段
refresh_dataset_fields根据查询的列元数据重新生成 <Fields> 列表
add_dataset_filter / remove_dataset_filter应用于数据集级别(而非 tablix)的筛选器
Tablix
工具编辑内容
add_tablix_filter追加一个 <Filter>。运算符:Equal、NotEqual、GreaterThan、In、Between、Like、TopN、...
remove_tablix_filter根据 list_tablix_filters 返回的序号索引移除
add_row_group / remove_row_group用新的外层组和标题行包裹行层次结构(以及反向操作)
add_column_group / remove_column_group对列轴执行相同操作
convert_to_matrix将表格转换为矩阵(行组 + 列组)——参见 docs/MATRIX-cookbook.md
set_tablix_corner设置矩阵角单元格文本/表达式
set_group_sort / set_column_group_sort替换组上的 <SortExpressions>
set_group_visibility / set_column_group_visibility设置组的 TablixMember 上的 <Visibility>
set_detail_row_visibility设置 Details 组上的 <Visibility>
add_tablix_column / remove_tablix_column在 tablix 网格中添加/删除列
add_static_row / add_static_column插入非分组行/列
add_subtotal_row / add_subtotal_column在组上插入汇总行/列
set_cell_span设置单元格的 RowSpan / ColSpan
set_column_width / set_row_height设置第 N 列/行的 <Width> / <Height>
set_tablix_size设置 tablix 的整体 <Width> / <Height>
页面
工具编辑内容
set_page_setup页面尺寸、边距、分栏。所有字段均为可选。
set_page_orientation调整 PageHeight/PageWidth,以匹配 Portrait 或 Landscape。可重复执行而不改变结果。
页眉和页脚

每个区域都支持同一组操作,并且每项操作都接受命名项, 以避免后续编辑时索引发生偏移。

工具编辑内容
set_page_header / set_page_footer区域高度 + PrintOnFirstPage / PrintOnLastPage
add_header_textbox / add_footer_textbox追加一个 Textbox(静态文本或 =expression)
add_header_image / add_footer_image追加一个 Image(外部 URL、嵌入名称或 Database 表达式)
remove_header_item / remove_footer_item按名称移除;清理空的 <ReportItems>
主体内容编排
工具编辑内容
add_body_textbox将一个 Textbox 追加到 <Body>/<ReportItems>
add_body_image在主体中追加一个 Image
remove_body_item从主体中移除命名的 Textbox / Image / Tablix
片段模板

通过单次调用插入常用报表项,以编程方式构建并 追加到主体中。

工具构建内容
insert_tablix_from_template基本 Tablix,形状与样例一致——标题行以列名作为静态标签,明细行绑定到 =Fields!<column>.Value。每个请求的字段对应一列。
insert_chart_from_template基本柱形图:单个类别轴按 category_field 分组,单个 Y 系列为 =Sum(Fields!<value_field>.Value)。插入后可更改 <Type>(Bar / Line / Pie / 等)。
图表

在 insert_chart_from_template 之后(或针对任何现有的 <Chart>)优化图表。

工具编辑内容
add_chart_series / remove_chart_series管理 Y 轴 <ChartSeries>
set_chart_series_type为每个系列设置 Column / Bar / Line / Area / Pie / ...
set_chart_series_grouping类别/系列分组表达式
set_chart_axis类别/值轴标题、刻度、格式
set_chart_legend图例可见性和位置
set_chart_data_labels切换并设置数据标签格式
set_chart_title图表标题文本/表达式
set_chart_palette / set_series_color调色板名称;为每个系列指定颜色
样式
工具编辑内容
set_textbox_style自动将属性路由到正确的嵌套 <Style> 节点:框级(BackgroundColor、Border、VerticalAlign)、段落级(TextAlign)、文本运行级(FontFamily、FontSize、FontWeight、Color、Format)
set_textbox_style_bulk一次调用即可将一种样式应用到多个文本框
set_textbox_runs / set_textbox_value设置包含多个文本运行的富文本段落内容;或替换值
find_textboxes_by_style / find_textbox_by_value查找文本框,以便进行后续编辑
style_tablix_row一次性设置 tablix 行中每个单元格的样式(表头 / 明细 / 页脚)
set_alternating_row_color使用 BackgroundColor=IIf(RowNumber(Nothing) Mod 2, "<a>", "<b>") 为 tablix 的明细行设置斑马纹
set_conditional_row_color根据表达式设置明细行的 BackgroundColor
set_image_sizing / set_image_source设置图像 <Sizing>;切换 External / Embedded / Database 来源
可见性
工具编辑内容
set_element_visibility为任意已命名的 ReportItem(Tablix、Textbox、Image、Rectangle、Subreport、Chart)设置 <Visibility>。组 / 明细行可见性有各自专用的工具。
布局容器
工具构建内容
add_rectangle一个 <Rectangle> 容器(用于组合其他项、控制分页符)
add_list一个列表区域(单列 tablix 模板)
add_line一个 <Line> 报表项
定位与尺寸

在每个区域中移动和调整已命名项的大小。坐标采用 RDL 尺寸 ("1in"、"2.5cm" 等)。

工具编辑内容
set_body_item_position / set_header_item_position / set_footer_item_position设置已命名项的 Top / Left
set_body_item_size / set_header_item_size / set_footer_item_size设置已命名项的 Width / Height
set_body_size设置 <Body> 区域的整体高度
交互性
工具编辑内容
set_textbox_action / set_image_action / set_chart_series_action<Action>:超链接、钻取或书签
set_textbox_tooltip文本框 <ToolTip>
set_document_map_label导航窗格的 <DocumentMapLabel>
分页
工具编辑内容
set_group_page_break<Group><PageBreak>(Start / End / Between)
set_repeat_on_new_page在每页重复组表头 / 页脚
set_keep_together / set_keep_with_group设置保持在一起的呈现提示
参数(高级)
工具编辑内容
add_parameter / remove_parameter / rename_parameter管理 <ReportParameter> 元素
set_parameter_prompt / set_parameter_type提示词文本;数据类型(Boolean / DateTime / Integer / Float / Text)
set_parameter_available_values静态 <ParameterValues> 列表(字符串或 {value, label} 字典)或指向查找数据集的 <DataSetReference>
set_parameter_default_values静态 <Values> 列表或<DataSetReference>(默认值仅接受 ValueField——默认值是值,而非显示文本)
update_parameter_advanced切换四个布尔标志:multi_value、hidden、allow_null(写入 <Nullable>)、allow_blank
reorder_parameters重新排列 <ReportParameters>(控制提示词顺序)
set_parameter_layout / sync_parameter_layout在 <ReportParametersLayout> 网格中定位参数
级联参数

RDL 没有 <DependsOn> 元素——级联关系是根据查找数据集 <QueryParameters> 中对 =Parameters!X.Value 的引用推断出来的。 要设置参数 B 依赖于参数 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 会解析这些表达式来确定依赖关系图。

嵌入式图像
工具编辑内容
add_embedded_image从磁盘读取实际文件,将其编码为 base64,并存储在 <EmbeddedImages> 下
list_embedded_images名称 + MIME 类型
remove_embedded_image按名称移除;清理空的 <EmbeddedImages>

使用 add_*_image(image_source="Embedded", value="<image-name>") 引用嵌入式图像。

报表生命周期
工具功能
create_report创建一个最简有效的 .rdl 文件,供后续编辑
duplicate_report将报表复制到新路径
backup_report / restore_from_backup创建报表快照并回滚到该快照
表达式辅助工具

这些工具不会修改报表,而是构建正确的 RDL 表达式字符串,供其他工具使用(文本、筛选器、条件样式)。

工具返回内容
count_where / sum_where带内联条件的 Count/Sum 聚合表达式
iif_format用于条件值/格式设置的 IIf(...) 表达式
get_expression_reference常见 RDL 表达式模式参考表
事务与验证

将多项编辑批量纳入一次原子保存,并在保存前后检查正确性。

工具功能
start_editing_transaction / commit_editing_transaction / cancel_editing_transaction开启内存事务,执行检查并保存一次,或放弃更改。参见 docs/TRANSACTIONS.md。
apply_edits在一个事务中应用一组工具调用
dry_run_edit预览编辑效果,但不写入磁盘
validate_report / verify_report结构验证(以及选择性地使用捆绑的 reportdefinition.xsd 进行 XSD 验证)
lint_report显示 Report Builder 会标记的警告/错误
原始 XML 备用方案
工具功能
raw_xml_view读取 XPath 下的 XML
raw_xml_replace替换 XPath 处的 XML——用于没有专用工具时的最后手段

Power BI 相关说明

XMLA 连接字符串

set_datasource_connection 会写入规范形式:

Data Source=powerbi://api.powerbi.com/v1.0/myorg/<workspace>;Initial Catalog=<dataset>

workspace_url 接受不带前缀的工作区名称(Finance)或完整的 powerbi:// URL——该工具会检测后者,避免重复添加前缀。 DataProvider 会设置为 SQL(RDL 用于 PBI XMLA 的 Analysis Services 提供程序 ID,尽管名称容易引起误解)。

DAX 查询

DAX 主体会原样接受——pbirb-mcp 不会解析 DAX,因此语法以用户(或预览时的 Report Builder)为准。 空主体会在一开始就被拒绝,因为 Report Builder 虽然会加载它们,但会在预览时出错;这不如在此处明确返回 ValueError。

PBI 分页报表不会为 DAX 携带 <CommandType>(不同于可设置 CommandType=StoredProcedure 的 SSRS);这些工具从不输出该元素。

提交前钩子(贡献者)

pre-commit 包含在 [dev] 额外依赖中。全新检出后:

uv pip install --python .venv/bin/python -e ".[dev]"
.venv/bin/pre-commit install                # one-time — installs the git hook
.venv/bin/pre-commit run --all-files        # one-time — clean any drift

安装钩子后,每次 git commit 都会运行 ruff format + ruff check(带 --fix)+ 快速 pytest 测试套件。如果检查或测试 失败,提交会被中止;请修复问题并重新暂存,然后再试。

要按需单独运行钩子:

.venv/bin/pre-commit run ruff --all-files
.venv/bin/pre-commit run ruff-format --all-files
.venv/bin/pre-commit run pytest-fast --all-files

完整配置位于 .pre-commit-config.yaml 中。Ruff 设置 (行长度、规则选择、按文件忽略项)位于 pyproject.toml 中的 [tool.ruff*] 下。

报表生成器安装

Power BI Report Builder 是 Microsoft 免费提供的 Windows 应用:

https://www.microsoft.com/en-us/download/details.aspx?id=105942

使用 Report Builder 直接打开 pbirb-mcp 生成的任意 .rdl 文件。“打开时没有升级提示且文件正常载入”这一检查才是真正的集成测试——单元测试会验证架构正确性,但 lxml 可能会往返处理 XML,而 Report Builder 的反序列化器仍会拒绝它(我们在图表模板开发中遇到过两次;两项修复都记录在 git 历史中)。


架构

pbirb-mcp/
├── pbirb_mcp_server.py         # Entry point (logging + main())
├── pbirb_mcp/
│   ├── server.py               # JSON-RPC stdio dispatch
│   ├── tools.py                # Tool registry — wires ops into the server
│   ├── core/
│   │   ├── document.py         # RDLDocument: open/save (lxml), atomic write
│   │   ├── xpath.py            # Namespace-aware XPath helpers
│   │   ├── ids.py              # Stable element addressing
│   │   ├── encoding.py         # XML declaration / self-closing-tag fidelity
│   │   ├── transactions.py     # In-memory transaction registry
│   │   └── schema.py           # Structural + opt-in XSD validation
│   ├── ops/                    # One module per RDL concern; wired into tools.py
│   │   ├── reader.py           # describe / get_datasets / get_params / get_tablixes
│   │   ├── datasource.py       # PBI XMLA connection + data-source management
│   │   ├── dataset.py          # DAX body, query params, fields, calc fields, filters
│   │   ├── tablix.py           # Row/column groups, sort, visibility, matrix
│   │   ├── tablix_columns.py   # Add/remove tablix columns
│   │   ├── tablix_cells.py     # Cell span
│   │   ├── tablix_static.py    # Static rows / columns
│   │   ├── tablix_subtotals.py # Subtotal rows / columns
│   │   ├── chart.py            # Chart series, axes, legend, labels, palette
│   │   ├── page.py             # Page setup + orientation
│   │   ├── layout.py           # Pagination (page breaks, keep-together, repeat)
│   │   ├── header_footer.py    # Page header / footer authoring
│   │   ├── body.py             # Body textboxes / images / containers / removal
│   │   ├── positioning.py      # Move / resize named items per region
│   │   ├── templates.py        # Chart + tablix snippet builders
│   │   ├── styling.py          # Textbox styles, runs, bulk, row styling, find
│   │   ├── images.py           # Image sizing / source
│   │   ├── actions.py          # Actions, tooltips, document-map labels
│   │   ├── visibility.py       # Element-level visibility
│   │   ├── parameters.py       # Lifecycle, values, advanced flags, layout
│   │   ├── embedded_images.py  # Base64 image embedding
│   │   ├── expressions.py      # Expression-builder helpers (count/sum/iif)
│   │   ├── filter_types.py     # Filter operator definitions
│   │   ├── clone.py            # duplicate_report
│   │   ├── scratch.py          # create_report
│   │   ├── snapshot.py         # backup / restore
│   │   ├── transactions.py     # start/commit/cancel + apply_edits
│   │   ├── dry_run.py          # dry_run_edit
│   │   ├── validate.py         # validate / verify
│   │   ├── lint.py             # lint_report
│   │   └── escape.py           # raw_xml_view / raw_xml_replace
│   └── schemas/                # Bundled RDL 2016 XSD (reportdefinition.xsd) for opt-in validation
└── tests/
    ├── fixtures/
    │   └── pbi_paginated_minimal.rdl  # Hand-tuned to match Report Builder's emitted style
    └── test_*.py               # 1188 tests — every tool plus round-trip invariants
强制规则(由测试执行)
  • 测试优先。 每次提交都先编写失败的测试,再让测试通过。
  • 使用 lxml,而不是标准库 xml.etree。 保持往返保真度是一项功能,而非锦上添花。Report Builder 会读取磁盘上的内容;格式漂移会导致静默损坏。
  • 使用稳定 ID,绝不使用索引。 工具接收 tablix_name + group_name,而不是 column_index: 2。索引在多步编辑中会失效。
  • 原子保存。 RDLDocument.save_as 会先写入 <path>.tmp,然后再重命名。写入过程中发生故障,也不会留下只写入一半的报表。
  • 通过 tests/test_document.py 中的 test_round_trip_byte_identical_to_fixture 强制检查往返字节一致性。 空操作的打开 → 保存 → 重新打开流程会生成字节完全一致的文件。
血泪总结的 RDL 注意事项
  • <?xml version="1.0" encoding="utf-8"?> 使用双引号,而非 lxml 默认的单引号。已在 RDLDocument.save_as 中通过手动声明修复。
  • 自闭合标签使用 <Tag />,中间有空格,而不是 <Tag/>。已通过后处理正则表达式修复。
  • rd: 前缀 (http://schemas.microsoft.com/SQLServer/reporting/reportdesigner) 携带 Report Builder 依赖的设计器元数据。不要移除它; 请保留前缀。
  • 除非同时声明 xmlns:df=...,否则不要在 <Report> 上添加 MustUnderstand="df"。
  • <ChartCategoryAxes> / <ChartValueAxes> 直接包含 <ChartAxis> 子元素——不存在 <ChartCategoryAxis> / <ChartValueAxis> 包装元素。
  • <ChartMember> 必须包含 <Label> 子元素,即使它为空也一样。
  • DAX 查询位于 <DataSet><Query><CommandText>EVALUATE ...</CommandText></Query></DataSet>。 DAX 不使用 <CommandType> 元素(与 SSRS 不同)。

日志记录

以下两个环境变量用于控制日志记录器:

变量默认值用途
PBIRB_MCP_LOG_LEVELWARNINGDEBUG / INFO / WARNING / ERROR
PBIRB_MCP_LOG_FILEstderr日志文件路径;否则日志会写入 stderr(Claude Desktop 会在其 MCP 调试面板中捕获这些日志)
PBIRB_MCP_LOG_LEVEL=DEBUG PBIRB_MCP_LOG_FILE=/tmp/pbirb-mcp.log pbirb-mcp

开发

运行测试
.venv/bin/python -m pytest tests/ -v

测试套件运行很快(1188 个测试约需 1.7 秒),因此每次更改后都要重新运行。

对实时二进制文件进行冒烟测试
printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{}}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  | .venv/bin/pbirb-mcp

如需端到端健全性检查,可针对随附样例文件的副本执行实际修改:

SCRATCH=$(mktemp -d)/r.rdl
cp tests/fixtures/pbi_paginated_minimal.rdl "$SCRATCH"
.venv/bin/python -c "
from pbirb_mcp.ops.dataset import update_dataset_query
update_dataset_query(path='$SCRATCH', dataset_name='MainDataset',
    dax_body=\"EVALUATE TOPN(10, 'Sales')\")
print('Wrote', '$SCRATCH')
"

在 Power BI Report Builder 中打开生成的文件。手动验证 .rdl 能否正常打开才是真正的集成测试——单元测试能发现架构层面的错误,但只有 Report Builder 能发现反序列化器的细微要求。

添加新工具
  1. 先在 tests/test_*.py 下编写测试。
  2. 在相应的 pbirb_mcp/ops/*.py 模块中实现(或创建新模块)。
  3. 在 pbirb_mcp/tools.py 中注册,并提供清晰的 description 和严格的 inputSchema。
  4. 运行完整测试套件,并针对样例文件执行 JSON-RPC 冒烟测试。
  5. 在 Report Builder 中打开修改后的 RDL。

逐次提交的历史记录展示了实际操作模式。


发布

CHANGELOG.md 按照 Keep a Changelog 格式跟踪每个版本的变更。发布版本也会同步发布到 GitHub Releases 和 PyPI。

版本遵循针对 MCP 工具接口调整的 SemVer 规范,详见 CONTRIBUTING.md § Versioning。

贡献

欢迎提交 PR。CONTRIBUTING.md 介绍了开发环境设置、硬性规则(先写测试、仅使用 lxml、稳定 ID、原子保存、往返字节完全一致、在 Report Builder 中进行冒烟测试)、SemVer-for-MCP 版本递增表,以及 PR 审查清单。

报告 Bug 和提议工具:请使用 问题模板。 安全问题请参阅 SECURITY.md。所有参与者 都应遵守行为准则。


致谢

现有的 bethmaloney/rdl-mcp 服务开创了 MCP-over-RDL 模式,但其范围仅限于 SSRS:列 元数据、基本参数管理、存储过程替换。Power BI 分页报表使用与 SSRS 相同的 RDL 2016 架构,但:

  1. 数据源是 Power BI XMLA 终结点,而不是 SQL Server。
  2. 查询使用 DAX,且上游工具不支持编辑正文(只能 替换存储过程名称,在此处毫无用处)。
  3. Report Builder 对 XML 往返处理很挑剔——格式漂移、 命名空间前缀丢失或无法识别的 MustUnderstand 属性都会导致 静默损坏,或提示“此报表需要升级”。

pbirb-mcp 基于 lxml 构建,因此无操作编辑会生成字节完全一致的 文件;通过稳定名称(而非索引)定位每个元素,并将 “可在 Report Builder 中正常打开”作为实际集成测试。


mcp-name: io.github.mafaq229/pbirb-mcp

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。