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. 03tablixのグループ・フィルター・レイアウト変更
  4. 04グラフとレポート項目の作成・スタイル設定
  5. 05ページ設定とページ分割の構成
  6. 06レポートファイルの検証とアトミック保存

活用シーン

  1. 01既存レポートのデータセットやパラメーターを更新
  2. 02tablixのグループ化、フィルター、書式を調整
  3. 03RDLレポートにグラフ、ヘッダー、埋め込み画像を追加

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 サーバーです。通常なら手作業で XML を記述せざるを得ない部分を補う 140 以上のツールを備えています。レポートの作成、データソースとデータセット、計算フィールド、データセットとテーブル/マトリックスのフィルター、グループ化(行、列、マトリックス)、並べ替え、グラフ、ヘッダーとフッター、本文の構成、レイアウトコンテナー、配置、スタイル、ページ設定、ページ分割、詳細なパラメーター、埋め込み画像、インタラクティブ機能(アクション、ツールヒント、ドキュメントマップ)、トランザクション、検証に対応しています。

このサーバーは stdio を介して JSON-RPC 2.0 を使用します。ディスクから .rdl を開き、lxml を使ってその場で変更し、構造を検証してからアトミックに書き込みます。保存に失敗しても、レポートが中途半端に書き込まれたり、元のファイルが消去されたりすることはありません。

安定性

1.0 より前のバージョンです。ツール名、inputSchema、出力形式、エラーの意味など、ツールの仕様が契約となります。0.x の間は、MINOR リリースに小規模な互換性を損なう変更が含まれる場合があります。その場合は CHANGELOG.md に移行方法を記載します。v1.0 以降、互換性を損なう変更には MAJOR リリースが必要です。MCP ツールの仕様に合わせて SemVer を適用した完全なバージョン更新ルールは、CONTRIBUTING.md を参照してください。

プロンプトが特定のツール名やスキーマに依存する場合は、0.x の間は MINOR バージョンに固定してください(例:pbirb-mcp~=0.1)。


クイックスタート

1. インストール

最も簡単なのは uv と PyPI を使う方法です。リポジトリのクローン、仮想環境の作成、インストール作業は不要です。

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

protocolVersion、capabilities.tools、および serverInfo.name = "pbirb-mcp" を含む JSON-RPC レスポンスが 1 つ表示されます。

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 には OS 固有のパスを指定します。/tmp/pbirb-mcp.log のような Unix パスが使用できるのは macOS/Linux のみです。Windows では Windows のパス(例:%TEMP%\\pbirb-mcp.log)を使用してください。ログ記録を参照してください。未設定の場合、ログは stderr に出力されます。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 プラグインとしてインストールできます。設定を手動で編集する代わりに、コマンドを 1 つ実行します(同じ 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")

生成された .rdl を Report Builder で開くと、変更がデザイナーに表示され、バインドされたデータセットを使ってプレビューにレンダリングされます。


ツールリファレンス

RDL の項目ごとに分類された 143 個のツールです。各グループの主なツールを以下の表に示します。正式な最新リストと完全なスキーマは、サーバーの tools/list 出力に含まれており、登録時に LLM から参照できます。すべてのツールは path 引数(.rdl の絶対パス)を受け取ります。

多くの変更を加えるツールは、複数ステップの編集を 1 回のアトミックな保存にまとめるための省略可能な transaction_id も受け取ります。トランザクション および docs/TRANSACTIONS.md を参照してください。

読み取り専用の項目一覧

「このレポートには何が含まれていますか?」を確認するツールです。複数ステップの編集を計画するときは、必ず最初に呼び出します。

ツール返される内容
describe_reportデータソース、データセット、パラメーター、tablix、ページ設定の概要
get_datasets / get_datasetDAX コマンドテキスト全体、フィールド、クエリパラメーター、データセットフィルター(すべて、または名前で指定した 1 つ)
list_data_sources / get_data_sourceデータソースの一覧。1 つのデータソースの接続詳細
get_parametersデータ型、プロンプト、フラグ(複数値、非表示、NULL 許容、空白を許可)を含むレポートパラメーター
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 タイプ、1 つの画像の 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_filterlist_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_visibilityDetails グループに <Visibility> を設定します
add_tablix_column / remove_tablix_columnTablix グリッド全体で列を追加/削除します
add_static_row / add_static_columnグループ化されていない行/列を挿入します
add_subtotal_row / add_subtotal_columnグループに集計行/列を挿入します
set_cell_spanセルの RowSpan / ColSpan を設定します
set_column_width / set_row_heightN 番目の列/行の <Width> / <Height> を設定します
set_tablix_sizeTablix 全体の <Width> / <Height> を設定します
ページ
ツール編集する内容
set_page_setupページの寸法、余白、列を設定します。すべてのフィールドは省略可能です。
set_page_orientationPortrait または Landscape に合わせて PageHeight と PageWidth を入れ替えます。何度実行しても結果は変わりません。
ページヘッダーとフッター

各領域で同じ一連の操作を行えます。各操作では名前付き項目を指定できるため、 後続の編集でインデックスがずれることはありません。

ツール編集する内容
set_page_header / set_page_footerセクションの高さと PrintOnFirstPage / PrintOnLastPage を設定します
add_header_textbox / add_footer_textboxTextbox(静的テキストまたは =expression)を追加します
add_header_image / add_footer_imageImage(外部 URL、埋め込み名、またはデータベース式)を追加します
remove_header_item / remove_footer_item名前で削除します。空の <ReportItems> も整理します
本文の構成
ツール編集する内容
add_body_textboxTextbox を <Body>/<ReportItems> に追加します
add_body_imageImage を本文に追加します
remove_body_item名前を指定して本文から Textbox / Image / Tablix を削除します
スニペットテンプレート

よく使うレポート項目をプログラムで構築し、本文に追加する一度の呼び出しでの挿入です。

ツール構築する内容
insert_tablix_from_templatefixture と同じ形状の基本的な Tablix を作成します — 列名を静的ラベルとして表示するヘッダー行と、=Fields!<column>.Value にバインドする詳細行です。要求されたフィールドごとに 1 列を作成します。
insert_chart_from_template基本的な縦棒グラフを作成します。category_field でグループ化した単一のカテゴリ軸と、=Sum(Fields!<value_field>.Value) の単一の Y 系列を使用します。挿入後に <Type> を変更できます(Bar / Line / Pie / など)。
グラフ

insert_chart_from_template の実行後(または既存の <Chart> に対して)、グラフを調整します。

ツール編集する内容
add_chart_series / remove_chart_seriesY 軸の <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_bulk1 回の呼び出しで複数のテキストボックスに同じスタイルを適用します
set_textbox_runs / set_textbox_value複数のランを含むリッチな段落コンテンツを設定するか、値を置き換えます
find_textboxes_by_style / find_textbox_by_value後続の編集対象となるテキストボックスを検索します
style_tablix_rowTablix の行のすべてのセルにスタイルを一度に適用します(ヘッダー/詳細/フッター)
set_alternating_row_colorBackgroundColor=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リスト領域(1 列の 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_advanced4 つのブール値フラグを切り替えます: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 式パターンのリファレンスシート
トランザクションと検証

複数の編集をまとめて 1 回のアトミックな保存で適用し、前後に正しさを確認できます。

ツール内容
start_editing_transaction / commit_editing_transaction / cancel_editing_transactionメモリー内トランザクションを開始し、Lint を実行して一度だけ保存するか、変更を破棄します。docs/TRANSACTIONS.md を参照してください。
apply_editsツール呼び出しのリストを 1 つのトランザクションで適用します
dry_run_editディスクに書き込まずに編集の結果をプレビューします
validate_report / verify_report構造検証(およびオプトインによる、同梱の reportdefinition.xsd に対する XSD 検証)
lint_reportReport Builder が警告/エラーとして検出する内容を表示します
生 XML のエスケープハッチ
ツール内容
raw_xml_viewXPath の下にある XML を読み取ります
raw_xml_replaceXPath の 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 に設定されます(紛らわしい名前ですが、PBI XMLA 用に RDL が使用する Analysis Services プロバイダー ID です)。

DAX クエリ

DAX 本文はそのまま受け付けられます。pbirb-mcp は DAX を解析しないため、構文の正しさはユーザー(またはプレビュー時の Report Builder)が判断します。 Report Builder は空の本文を読み込めるものの、プレビュー時にエラーになるため、明確な ValueError よりも悪い通知になります。そのため、空の本文は事前に拒否されます。

PBI ページ分割レポートでは DAX に <CommandType> を指定しません(CommandType=StoredProcedure を設定する SSRS とは異なります)。これらのツールが <CommandType> を出力することはありません。

pre-commit フック(コントリビューター向け)

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 スイートが実行されます。Lint またはテストに失敗するとコミットは中止されるため、修正してステージングし直してから再試行してください。

個別のフックをその場で実行するには、次を実行してください。

.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*] にあります。

Report Builder のインストール

Power BI Report Builder は、Microsoft が配布する無料の Windows アプリです。

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

pbirb-mcp が生成した任意の .rdl を Report Builder で直接開きます。「アップグレードの確認なしで問題なく開ける」ことの確認が、実際の統合テストです。ユニットテストではスキーマの正しさを検証しますが、lxml では、Report Builder のデシリアライザーが依然として拒否する XML もラウンドトリップできてしまいます(チャートテンプレートの作業中にこの問題に 2 回遭遇し、どちらの修正も 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
テストで強制される厳格なルール
  • まずテストを書く。 すべてのコミットで、失敗するテストを書いてから、そのテストを通します。
  • 標準ライブラリの xml.etree ではなく lxml を使う。 ラウンドトリップの忠実性は、仕上げではなく機能の一部です。Report Builder はディスク上の内容を読み込むため、書式のずれは気付かれないままデータを破損させる原因になります。
  • インデックスではなく安定した ID を使う。 ツールでは column_index: 2 ではなく、tablix_name と group_name を指定します。インデックスは複数手順にまたがる編集で変わってしまいます。
  • アトミックに保存する。 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 とは異なります)。

ロギング

ロガーは 2 つの環境変数で制御します。

変数既定値用途
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. 変更した RDL を Report Builder で開きます。

コミットごとの履歴で、実際のパターンを確認できます。


リリース

CHANGELOG.md では、Keep a Changelog 形式ですべてのリリースを記録しています。リリースは GitHub Releases と PyPI にも公開されています。

バージョンには、MCP ツールのインターフェースに合わせて調整した SemVer を採用しています。詳しくは CONTRIBUTING.md § Versioning をご覧ください。

貢献

PR を歓迎します。CONTRIBUTING.md では、開発環境のセットアップ、 厳守事項(テストファースト、lxml のみを使用、安定した ID、アトミックな保存、 バイト単位で同一のラウンドトリップ、Report Builder でのスモークテスト)、MCP 向け SemVer の バージョン更新表、PR レビューのチェックリストについて説明しています。

バグ報告やツールの提案には、 イシューテンプレートを使用してください。 セキュリティ上の問題については、SECURITY.md をご覧ください。すべての参加者は、 行動規範に従うことが求められます。


謝辞

既存の bethmaloney/rdl-mcp サーバーは MCP-over-RDL パターンを先駆けて実現しましたが、対象は SSRS に限られており、列の メタデータ、基本的なパラメーター管理、ストアドプロシージャの差し替えに対応しています。Power BI ページ分割レポートは SSRS と同じ RDL 2016 スキーマを使用しますが、次の違いがあります。

  1. データソースは SQL Server ではなく、Power BI XMLA エンドポイントです。
  2. クエリは DAX であり、上流のツールには本文編集機能がありません(ストアドプロシージャ名の差し替えのみで、ここでは役に立ちません)。
  3. Report Builder は XML のラウンドトリップに敏感です。書式のずれ、名前空間プレフィックスの欠落、認識されない MustUnderstand 属性は、サイレントな破損や「このレポートをアップグレードする必要があります」というプロンプトを引き起こします。

pbirb-mcp は lxml を中心に構築されているため、変更なしの編集ではバイト単位で同一のファイルが生成され、すべての要素はインデックスではなく安定した名前で指定されます。また、「Report Builder で問題なく開けること」を実際の統合テストとして扱います。


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

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。