pbirb-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| PBIRB_MCP_LOG_FILE | No | Path to a log file; otherwise logs go to stderr. | stderr |
| PBIRB_MCP_LOG_LEVEL | No | Log level. DEBUG, INFO, WARNING, or ERROR. | WARNING |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| describe_reportA | Top-level inventory of an RDL: data sources, datasets, parameters, tablixes, charts, and page setup. Always the first call when planning edits. v0.4: |
| get_datasetsB | Full DAX command text, fields, query parameters, and dataset-level filters for every DataSet in the report. |
| get_parametersC | Report parameter declarations: name, data type, prompt, flags. |
| get_tablixesA | Tablix layout with stable IDs: columns, row/column groups, sort expressions, filters, visibility. Required input for any tablix edit. |
| update_dataset_queryA | Replace the DAX command text of a named dataset. The full DAX expression is accepted verbatim; empty bodies are rejected. Optional alias_strategy='preserve_field_names' positionally rewrites cells to the new DAX columns while keeping existing identifiers — so Fields!X.Value references in expressions keep resolving. |
| add_query_parameterA | Add a binding to a dataset's query. Use to wire report parameters into DAX (e.g. =Parameters!DateFrom.Value). PBIDATASET parameter naming rule: in DAX/, write @MyParam (with @). In , write MyParam (no @). SQL/MDX use @ in both places. This tool detects the dataset's provider and AUTO-STRIPS a leading @ from |
| update_query_parameterB | Change the value expression of an existing query parameter. Same PBIDATASET @-prefix normalisation as add_query_parameter applies on lookup; legacy Name='@X' parameters that already exist on disk are addressable via either @X or X. |
| set_datasource_connectionA | Repoint a DataSource at a Power BI XMLA endpoint. workspace_url accepts a bare workspace name or a full powerbi:// URL; DataProvider is set to SQL (the AS provider id in RDL). |
| list_data_sourcesA | Return a rich list of every in the report — name, data_provider, connect_string, integrated_security, shared_reference, security_type, data_source_id. describe_report.data_sources returns names only; this tool is the authoring-friendly read. |
| get_data_sourceA | Single-DataSource read-back (parity with get_textbox / get_image / get_rectangle / get_chart). Returns the same shape as one entry of list_data_sources. |
| add_data_sourceA | Create a new for a Power BI XMLA endpoint. workspace_url accepts a bare workspace name or a full powerbi:// URL. Generates a fresh rd:DataSourceID GUID. Refuses if a DataSource of the same name already exists. provider='sql' (default) emits the legacy DataProvider=SQL + powerbi:// ConnectString + rd:SecurityType shape; provider='pbidataset' emits the modern PBI Desktop shape — DataProvider=PBIDATASET, pbiazure:// ConnectString with ClaimsToken auth, plus rd:PowerBIWorkspaceName / rd:PowerBIDatasetName siblings, no rd:SecurityType. |
| remove_data_sourceA | Remove a named . Refuses by default if any DataSet/Query/DataSourceName or DataSource/DataSourceReference still references it; the error lists the offending locators. Pass force=True to remove anyway. |
| rename_data_sourceA | Rename a and rewrite every reference: DataSet/Query/DataSourceName entries AND any DataSource/DataSourceReference shared-source links. Atomic: stages all matches before committing. Errors if new_name already exists or equals old_name. |
| list_dataset_filtersA | List dataset-level filters in document order. Returns [{expression, operator, values}]; index in the list is the stable handle for remove_dataset_filter. DataSet filters apply to every consumer of the dataset (every Tablix / Chart bound to it); use list_tablix_filters for per-tablix filtering. |
| add_dataset_filterA | Append a to the named dataset's block. operator ∈ Equal / NotEqual / GreaterThan / LessThan / GreaterThanOrEqual / LessThanOrEqual / Like / In / Between / TopN / BottomN / TopPercent / BottomPercent. values must be non-empty (single-value filters use a one-element list). Returns the new filter's index for later removal. Optional field_format wraps the expression as Format(, fmt) to coerce typed fields for string-parameter comparison. Response includes warnings for field/parameter type mismatches detected via best-effort cross-check. |
| remove_dataset_filterA | Remove a dataset-level filter by its 0-based document-order index. Cleans up the empty block when removing the last entry. |
| get_datasetB | Single-DataSet read-back (parity with get_textbox / get_image / get_rectangle / get_chart / get_data_source). Returns dataset name, data_source, command_text, fields (with both data_field and value), query_parameters, filters, and designer_state_present. |
| add_calculated_fieldA | Append a calculated to the named dataset. Calculated fields carry an expression () instead of a column reference (); use them for derived fields like Total = Amount * Quantity that aren't in the source query but should be available via Fields!Name.Value. Refuses if a field of the same name already exists. |
| remove_calculated_fieldA | Remove a calculated by name. Refuses if the field is data-bound (carries instead of ) — those reflect the source query's columns. Drop a data-bound field via remove_dataset_field, or rewrite the dataset query via update_dataset_query. |
| remove_dataset_fieldA | Remove a data-bound by name (one with ). Symmetric counterpart to remove_calculated_field. Refuses on calculated fields (use remove_calculated_field instead) and on still-referenced fields (any expression containing Fields!.Value / .IsMissing / .Count). Pass force=True to delete anyway. Closes the cookbook flow: refresh_dataset_fields lists orphans, remove_dataset_field drops them. Returns {dataset, removed, kind: 'DataBoundField'}. |
| add_dataset_fieldA | Append a data-bound to a dataset's block. Writes data_field (and optional rd:TypeNametype_name). Distinct from add_calculated_field which writes for derived fields. Use after rewriting the DAX to declare a new column that came back from the query but isn't yet in . Refuses on duplicate field name. |
| refresh_dataset_fieldsA | Sync a dataset's block against the shape detected in its DAX . Eliminates the manual 'open Report Builder → right-click → Refresh Fields' step after a query rewrite. Recognises SELECTCOLUMNS aliases and Table[Col] tokens (SUMMARIZECOLUMNS / ad-hoc). Adds missing fields; lists orphans without auto-removing (caller decides what to drop). Returns {added, orphans, unchanged, warnings}. Cheap regex-based detection — bare EVALUATE 'Table' returns a warning. |
| set_image_sizingA | Set / on a named Image. sizing ∈ AutoSize / Fit / FitProportional / Clip. AutoSize renders at native size (box grows to fit); Fit stretches to fill (ignores aspect ratio); FitProportional preserves aspect ratio; Clip renders at native size, clipped to the box. Idempotent: same value → {changed: false}, no save. |
| set_image_sourceA | Repoint an existing at a different embedded image entry without delete-and-readd. Sets Source=Embedded and rewrites to embedded_name. Refuses with a clear error if embedded_name isn't in — leaving a dangling reference would render as a broken image. Add the image first via add_embedded_image. Idempotent: same (Source, Value) pair → {changed: false}, no save. Returns {name, kind, changed: bool}. |
| set_column_widthA | Set on a tablix's body column. column accepts a 0-based integer index OR a textbox name living in any cell of that column (mirrors how set_cell_span / add_subtotal_row address columns). width is an RDL size ('1.5in', '4cm', '80pt'). Idempotent: same width → {changed: false}, no save. |
| set_tablix_sizeA | Resize a tablix by writing and / or directly. Each arg independently optional. Use after adding header / footer rows that change the body's natural height — v0.2's positioning tools only cover top/left, not size. Both values are RDL size strings. Returns {tablix, kind, changed: list[str]} — empty list when inputs match existing. |
| reorder_parametersA | Reorder children to match the supplied names list. names MUST be a permutation of every existing parameter — no missing, no duplicates, no unknown names. When a exists, its CellDefinition entries are reordered in lockstep so the parameter pane shows fields in the new declaration order. RowIndex / ColumnIndex are not recomputed (RB's layout grid is independent of declaration order). Returns {order, kind, changed: bool}; same order → no save. |
| set_parameter_layoutA | Author / explicitly. Writes + ; rewrites so each name in parameter_order lands at (row=index // columns, col=index % columns). Strict permutation check (every existing parameter exactly once). rows*columns must be ≥ parameter count. Auto-creates the layout block when absent. Idempotent: same grid + order → no save. Complements reorder_parameters (declaration order) and sync_parameter_layout (gap-filling). Returns {rows, columns, order, kind, changed}. |
| duplicate_reportA | Clone an .rdl to a new path. When regenerate_ids=true (default), every rd:DataSourceID and any rd:ReportID is rewritten to a fresh uuid4() so Power BI Report Builder doesn't refuse to load the duplicate due to identity collision. Atomic-write convention from RDLDocument.save_as. Refuses if dst_path already exists. Returns {src, dst, regenerated_ids: list[str]}. |
| get_embedded_image_dataA | Read an embedded image's base64 for porting it to another report without re-reading from disk. Returns {name, mime_type, base64, byte_size}. base64 is the raw text of the ImageData element; byte_size is the decoded size for sanity-checking. Refuses with ElementNotFoundError if the named entry isn't in . |
| validate_reportA | Run schema/structural validation against an .rdl. Returns {valid, errors, xsd_used}. Structural checks always run (root element + required top-level sections). The Microsoft RDL 2016/01 XSD is bundled by default since v0.3.1 — when it's loaded, xsd_used is True and the schema-conformance bug class Power BI Report Builder rejects on load gets caught here. If the bundled XSD is missing (source-build without package-data) a {severity:warning, rule:'xsd-not-bundled'} issue surfaces instead of silent skip. Each issue is {severity, rule, location, message, suggestion?}; valid is True iff no severity='error' issue. |
| verify_reportA | One-shot static check: union of validate_report and lint_report. Returns {valid, issues, xsd_used} where valid is True iff no issue has severity='error'. Warnings (including 'xsd-not-bundled' when the schema file is missing) don't invalidate the report. Use this as the single 'is the report OK?' tool, or set PBIRB_MCP_AUTO_VERIFY=1 to have it run after every mutating call. |
| lint_reportA | Run static-analysis lint rules against an .rdl. Sixteen rules cover the v0.2/v0.3 sweep bug classes (multi-value-eq, missing-field-reference, dangling-embedded-image, pbidataset-at-prefix, parameter-layout-out-of-sync, double-encoded-entities, stale-designer-state, tablix-span-misplaced, dataset-fields-out-of-sync, etc.). Returns {issues, rules_run} with each issue {severity, rule, location, message, suggestion?}. Optional |
| dry_run_editA | Apply a list of {tool, args} ops to a tempfile clone of the report; return the unified diff and a verify (validate + lint) report. The original file is NEVER modified. The harness auto-injects |
| start_editing_transactionA | Open the report and start an editing transaction. Returns {transaction_id, path, expires_at}. Pass transaction_id to subsequent edit tools to mutate the live in-memory tree WITHOUT touching disk between calls — eliminates the per-edit parse+serialize round-trip. The transaction times out after PBIRB_MCP_TRANSACTION_TIMEOUT_S seconds (default 600); call commit_editing_transaction to flush or cancel_editing_transaction to discard. Refuses if an active transaction already owns this path. |
| commit_editing_transactionA | Lint the in-memory tree, save to disk once (atomic .tmp + rename), and deregister. Aborts (saved=False) if lint surfaces any severity='error' issue — the transaction stays OPEN so the caller can fix the offending state and re-commit. Returns {transaction_id, path, saved, verify}. |
| cancel_editing_transactionA | Discard a transaction. The in-memory tree is dropped; the on-disk file is unchanged from when the transaction was started. Returns {transaction_id, path, discarded}. |
| apply_editsA | Atomic batch: open once → apply ops → lint → save once. Opens an internal transaction against path, dispatches each {tool, args} op through the JSON-RPC tools/call path with transaction_id injected, and commits at the end. On any op failure or lint-error at commit, rolls back — disk is byte-identical to its pre-call state. Compare with dry_run_edit (clones to tempfile, never touches the real file): use dry_run_edit to preview a plan, apply_edits to land it. Returns {applied: [{tool, ok, result|error}], verify, committed}. |
| create_reportA | Emit a minimal valid RDL from scratch at |
| get_expression_referenceA | Return a static cheat-sheet of common RDL expression patterns: globals, parameters, fields, aggregates, conditionals, strings, dates. Each entry is {name, syntax, example, description}. Call this when authoring a textbox value or filter expression instead of guessing — and note the explicit encoding hint for the |
| count_whereA | Emit =Sum(IIf(, 1, 0)) — the SSRS conditional-count idiom. condition is an RDL expression body (no leading '='). Returns a complete top-level expression suitable for set_textbox_value or any RDL sink. |
| sum_whereA | Emit =Sum(IIf(, , 0)) — the SSRS conditional-sum idiom. Both args are expression bodies (no leading '='). |
| iif_formatA | Emit =IIf(, , ). All three args are expression bodies (no leading '='); string literals must already be quoted, e.g. true_value='"Yes"'. |
| set_group_page_breakA | Set on a tablix group's page-break rule. location ∈ {None, Start, End, StartAndEnd, Between}. Passing 'None' removes the element (the canonical 'no break' shape). Idempotent. Returns {tablix, group, kind: 'Group', location, changed}. |
| set_repeat_on_new_pageB | Set / on the member that wraps the named group. Most common use: repeat a group header row at the top of every page the group spans. Setting repeat=False removes the element (False is default). Returns {tablix, group, kind: 'TablixMember', repeat, changed}. |
| set_keep_togetherA | Set on a named Tablix / Rectangle / Chart / Textbox / Map / Gauge. Tells the renderer 'don't split this across pages if you can help it'. Best-effort — items larger than a page are still split. keep=False removes the element. Refuses for Image / Line / Subreport and other kinds where the RDL XSD doesn't allow it. |
| set_keep_with_groupA | Set / on the member that wraps the named group. value ∈ {None, Before, After}. Typical use: a column-header row's member with 'After' to glue it to the data rows that follow. value='None' removes the element. |
| add_rectangleA | Add a to /. With no contained_items the rectangle is empty (a visual frame). With contained_items=[name1, name2, ...], each named body item is MOVED into the rectangle's and its / recalculated so the on-screen position is preserved. Refuses on duplicate name or if any contained_item isn't in /. Returns {name, kind: 'Rectangle', moved}. |
| add_listA | Add a List (single-cell repeating Tablix) bound to a dataset. RDL has no distinct element — Report Builder's List is a Tablix with one column, one detail row, and a Rectangle inside the cell. Items placed in the rectangle repeat once per dataset row. The inner rectangle is named '_Rect' for subsequent lookup. Returns {name, kind: 'Tablix', dataset, rectangle}. |
| add_lineA | Add a to /. RDL Line semantics: top/left is the start point; width/height is the offset (vector) to the end point — horizontal line uses height='0in', vertical uses width='0in'. Optional color, line_thickness ('1pt' default), line_style (Solid/Dashed/Dotted/Double/etc.). Returns {name, kind: 'Line'}. |
| raw_xml_viewA | Read-only XPath query against the report. Returns matched elements as serialised XML strings. XPath context is (the root); 'r:' is bound to the RDL namespace, 'rd:' to the rd namespace. Examples: "r:DataSources/r:DataSource[@Name='X']" / ".//r:Textbox[@Name='X']/r:Style". Returns [] when nothing matches; raises on malformed xpath. |
| raw_xml_replaceA | Replace the single element matched by xpath with new content. content is parsed with RDL as the default namespace and 'rd:' bound, so bare names like x work without explicit xmlns. Refuses on zero matches, multiple matches, or if the xpath targets the root. Saves atomically. Returns {xpath, kind, changed}. |
| set_textbox_actionA | Set / to a Hyperlink (URL), Drillthrough (another report + optional parameters), or BookmarkLink (jump within document). target_expression accepts literal text or =expression. drillthrough_parameters is a list of {name, value} dicts wired into /. Idempotent: same action_type + target + parameters → {changed: false}, no save. |
| set_image_actionA | Same shape as set_textbox_action but operates on a named . action_type ∈ Hyperlink / Drillthrough / BookmarkLink. Returns {image, kind, action_type, changed}. |
| set_textbox_tooltipA | Set /. Literal text or =expression. Pass '' to clear. Idempotent. Returns {textbox, kind, changed: bool}. |
| set_document_map_labelA | Set on any named ReportItem (Textbox / Image / Rectangle / Chart / Tablix / etc.). Surfaces in the rendered report's navigable document-map / table-of-contents pane. Pass '' to clear. Idempotent. Returns {element, kind, changed: bool}. |
| set_chart_series_actionA | Set / to a Hyperlink (URL), Drillthrough (another report + optional parameters), or BookmarkLink. Same kwarg surface as set_textbox_action / set_image_action; the chart series is addressed by (chart_name, series_name). Schema-aware insertion respects ChartSeries child order. Idempotent on structural equality of the inner block. |
| remove_query_parameterB | Remove a query parameter from a dataset. Cleans up the empty block when removing the last one. |
| list_tablix_filtersA | List all filters on a named tablix in document order. Returns expression, operator, and values per filter; index in the list is the stable handle for remove_tablix_filter. |
| add_tablix_filterA | Append a to a tablix. Operator must be one of the RDL 2016 enumeration (Equal, NotEqual, GreaterThan, In, Between, ...). Returns the new filter's index for follow-up calls. Optional field_format wraps the expression as Format(, fmt) to coerce typed fields for string-parameter comparison. The response includes warnings for cross-checked field/parameter type mismatches. |
| add_row_groupA | Add a row group that wraps the entire current top-level row hierarchy. Inserts a matching group-header row at body row 0 with the group expression in the first cell. parent_group (nesting under an existing group) is reserved for a future commit and currently raises NotImplementedError. |
| remove_row_groupA | Inverse of add_row_group: unwraps a group's children back to its parent hierarchy and removes the matching header row at body row 0. Refuses to remove the conventional Details group. |
| convert_to_matrixA | Convert a row-grouped + column-grouped tablix into a matrix by dropping the residual Details row group and its body row. Pre-conditions (all checked): the named row_group and column_group must already exist (call add_row_group + add_column_group first); a must still be present in the row hierarchy. Refuses on second call (already a matrix). Use this after the standard insert_tablix_from_template + add_row_group + add_column_group flow to make the leaf the row group instead of Details — without this, cells render at detail granularity. Pair with set_tablix_corner (v0.4 commit 18) to author the top-left label. |
| set_tablix_cornerA | Write the block — the top-left cell of a matrix-shaped tablix that holds the row-axis caption (e.g. 'Type'). Pass |
| set_group_sortC | Replace a group's with a fresh list. Each entry is an RDL expression, e.g. =Fields!Region.Value. |
| set_group_visibilityB | Set on a group's TablixMember. Accepts a Hidden expression and an optional ToggleItem (a textbox name that toggles the group expand/collapse). |
| add_column_groupA | Add a column group that wraps the current top-level column hierarchy. Inserts a matching column at body column 0 (default 1in width) and a header cell at column 0 of every existing row with the group expression in the topmost cell. Mirrors add_row_group on the column axis. parent_group nesting is reserved for a future commit and currently raises NotImplementedError. |
| remove_column_groupA | Inverse of add_column_group: unwraps a column-axis group's children back to the top of the column hierarchy and removes the matching body column at position 0 (along with each row's first cell). Errors if group_name only exists on the row axis. |
| set_column_group_sortA | Replace a column-axis group's with a fresh list. Mirrors set_group_sort but refuses up front if group_name is on the row axis (use set_group_sort instead). |
| set_column_group_visibilityA | Set on a column-axis group's TablixMember. Accepts a Hidden expression and an optional ToggleItem (textbox name that toggles expand/collapse). Mirrors set_group_visibility but refuses up front if group_name is on the row axis. |
| add_tablix_columnA | Append (or insert) a column into a tablix. column_name is the textbox name placed in the data row's new cell — must be unique report-wide. expression goes inside that textbox's TextRun (typically =Fields!X.Value). For a tablix with >= 2 rows the first row gets header_text (default = column_name) as a literal, middle rows get blank cells, and the last row gets expression. position is 0-indexed; default appends at end. width defaults to 1in. Inserts a matching top-level TablixMember in the column hierarchy at the same index. |
| remove_tablix_columnA | Remove the tablix column whose data-row cell holds a textbox named column_name. Drops the matching TablixColumn, removes the top-level TablixMember at that column index (only if it's a leaf, never a column group wrapper), and removes the cell at that index from every TablixRow. Errors if no row contains a textbox with the given name. |
| add_subtotal_rowA | Append a subtotal row to a row-axis group. aggregates is a list of {column, expression} entries; column matches against the Details row's textbox names (the same names add_tablix_column uses as column_name — NOT field names). expression is the aggregate (e.g. =Sum(Fields!X.Value)). Columns not listed get blank cells. position='footer' (default) appends; 'header' inserts at body row 1 (right after the group-header row). Group must have been added via add_row_group. |
| add_subtotal_columnA | Column-axis mirror of add_subtotal_row. Adds a static TablixMember inside the column-group's , a new in TablixBody, and a cell at the new column index in every body row. aggregates is a list of {row, expression} entries where row is the 0-based body row index; rows not listed get blank cells. position='after' (default — canonical Grand Total slot, appends to the right of the column group) or 'before' (prepends to the group's left edge). width defaults to '1in'. Group must have been added via add_column_group. |
| set_cell_spanA | Set and/or on a tablix cell. The cell is addressed by (row_index, column_name) where column_name is the textbox name inside the cell. At least one of row_span / col_span must be supplied; both must be >= 1. Pass 1 to explicitly reset a span. Replaces existing values if present. |
| add_static_rowA | Add a static (no-group) row to a tablix. Each cell holds literal text. cells is a list of strings, one per body column (left to right); shorter list = blank trailing cells, longer list errors. Cell textboxes are named row_name (col 0) and row_name_ (others) — unique report-wide so row_name must not clash with any existing textbox. position is 0-indexed; default appends. height defaults to 0.25in. |
| add_static_columnA | Add a static (no-group) column to a tablix. Each cell holds literal text. cells is a list of strings, one per body row (top to bottom); shorter list = blank trailing cells, longer list errors. Cell textboxes are named column_name (row 0) and column_name_ (others). position is 0-indexed; default appends. width defaults to 1in. |
| set_body_item_positionA | Move an existing named ReportItem inside to (top, left). Preserves all other properties (size, style, group structure). top and left are passed through verbatim — RDL accepts any size unit (2cm, 0.75in, 108pt). Errors if no body item by that name. |
| set_header_item_positionA | Move an existing named ReportItem inside to (top, left). Errors if there is no (call set_page_header first) or no item by that name. |
| set_footer_item_positionA | Move an existing named ReportItem inside to (top, left). Errors if there is no (call set_page_footer first) or no item by that name. |
| set_body_item_sizeA | Resize an existing named ReportItem inside . At least one of width / height must be supplied; missing fields are left untouched. Same RDL size-string convention as the position tools. |
| set_header_item_sizeA | Resize a named item inside . Mirrors set_body_item_size — at least one of width / height; missing fields untouched; idempotent ({changed: false} when nothing differs). Closes the v0.2 parity gap where only the body variant existed. |
| set_footer_item_sizeB | Resize a named item inside . Same shape as set_header_item_size. |
| list_body_itemsA | List every named ReportItem at the top level of . Returns name, type (Tablix / Textbox / Image / Rectangle / Subreport / Chart / etc.), top, left, width, height. Use before set_body_item_position / set_body_item_size when you don't already know what's in the body. |
| list_header_itemsC | Same shape as list_body_items but for . |
| list_footer_itemsC | Same shape as list_body_items but for . |
| get_textboxA | Return effective state of a named Textbox: position, size, Visibility, CanGrow, CanShrink, plus a nested style dict that mirrors set_textbox_style's routing — {box: {BackgroundColor, VerticalAlign, padding, ...}, border: {Style, Color, Width}, paragraph: {TextAlign}, run: {FontFamily, FontSize, FontWeight, Color, Format, ...}}. Empty branches are dropped. runs[] entries each carry their own per-run style. Searches the entire report; tablix-cell textboxes have None for top/left/width/height. Top-level positioned items with a missing or coerce to '0in' (RDL default). |
| get_imageB | Return effective state of a named Image: position, size, Source (External / Embedded / Database), Value, Sizing (AutoSize / Fit / FitProportional / Clip), MIMEType, Style, Visibility. |
| get_rectangleB | Return effective state of a named Rectangle: position, size, names of contained ReportItems, Style, Visibility. |
| get_chartA | Return effective state of a named Chart: position, size, dataset, palette, series list (name/type/subtype/value expression/color), category groups (name/expression/label), axes (category and value), legend, title, Style, Visibility. Symmetric with get_textbox / get_image / get_rectangle. |
| backup_reportA | Copy the report to .bak.. Original is untouched. Cheap explicit checkpoint to call before a destructive batch (remove_*, rename_parameter, etc.). Returns the backup path. Set PBIRB_MCP_AUTO_BACKUP=1 to opt into automatic backups before destructive ops (off by default). |
| restore_from_backupA | Restore a backup file over its original target. target_path defaults to the path implied by the backup's .bak. filename; pass target_path explicitly when the backup name doesn't match that shape. Refuses if target mtime is newer than backup (staleness guard) — pass force=True to override. Returns {source, restored_to, bytes_restored}. |
| set_parameter_promptA | Write the text on a ReportParameter. Empty string clears the element entirely; pass a single space ' ' for blank-but-present. |
| set_parameter_typeA | Set on a ReportParameter. type ∈ {Boolean, DateTime, Integer, Float, String}. Rejects with ValueError if any existing literal default value would be incompatible with the new type — fix defaults first via set_parameter_default_values, then retry. |
| add_parameterA | Create a new ReportParameter with a minimal valid declaration. Appends to (creating it if absent). Pair with set_parameter_available_values / set_parameter_default_values afterwards for value lists. Booleans are only emitted when an explicit value is supplied. |
| remove_parameterA | Remove a ReportParameter by name. Refuses (lists offending locators) if the parameter is still referenced anywhere in the report by Parameters!.Value or .Label. Pass force=True to remove anyway. |
| rename_parameterA | Rename a ReportParameter and rewrite every textual occurrence of Parameters!.Value / .Label across the entire report. Case-sensitive. Atomic: collects all matches first, then commits. Errors if new_name already exists or equals old_name. |
| sync_parameter_layoutA | Bring // into sync with . Drops cells whose ParameterName no longer exists; appends cells for parameters that have no entry, placed at the next free (row, col) slot. add_parameter / remove_parameter / rename_parameter call this internally; the standalone tool is for repairing legacy reports authored before v0.3.0 where the layout drifted. No-op when the report has no . Returns {added, removed}. |
| set_detail_row_visibilityB | Set on the tablix's Details group, optionally with a ToggleItem textbox name. Use to hide detail rows by expression without restructuring the row hierarchy. |
| set_row_heightA | Set the Height of the Nth body row (0-indexed) in a tablix. Accepts any RDL size string ('0.25in', '1cm', '12pt'). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/mafaq229/pbirb-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server