Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Scaffold, validate, preview, and manage Power BI PBIR report projects using pbi-cli. Invoke this skill whenever the user mentions "create report", "new report", "PBIR", "scaffold", "validate report", "report structure", "preview report", "report info", "reload Desktop", "convert report", ".pbip project", "report project", or wants to understand the PBIR folder format, set up a new report from scratch, or work with the report as a whole. For specific tasks, see also: power-bi-visuals (charts, bin
.claude/skills/minasaad1-power-bi-report/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-13 | ✗→✓ | ▲ Improved | 4% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 0% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -31% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -25% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 55% | 0% |
Manage Power BI PBIR report projects at the top level -- scaffolding, validation, preview, and Desktop integration. No connection to Power BI Desktop is needed for most operations.
PBIR (Enhanced Report Format) stores reports as a folder of JSON files:
MyReport.Report/
definition.pbir # dataset reference
definition/
version.json # PBIR version
report.json # report settings, theme
pages/
pages.json # page order
page_abc123/
page.json # page settings
visuals/
visual_def456/
visual.json # visual type, position, bindingsEach file has a public JSON schema from Microsoft for validation. PBIR is GA as of January 2026 and the default format in Desktop since March 2026.
bash# Scaffold a new report project pbi report create ./MyProject --name "Sales Report" # With dataset reference pbi report create ./MyProject --name "Sales" --dataset-path "../Sales.Dataset"
This creates the full folder structure with definition.pbir, report.json, version.json, and an empty pages/ directory.
bash# Show report metadata summary (pages, theme, dataset) pbi report info pbi report info --path ./MyReport.Report # Validate report structure and JSON files pbi report validate
Validation checks:
definition.pbir, report.json, version.json)pages.json match actual page foldersStart a live HTML preview of the report layout:
bashpbi report preview
Opens a browser showing all pages with visual placeholders, types, positions, and data bindings. The preview auto-refreshes when files change.
Requires the preview optional dependency: pip install pbi-cli-tool[preview]
bash# Trigger Power BI Desktop to reload the current report pbi report reload
Power BI Desktop's Developer Mode auto-detects TMDL changes but not PBIR changes. This command saves and closes the open .pbip in Desktop, re-applies any PBIR edits that Desktop's save would overwrite, then reopens the file.
Requires the reload optional dependency (installs pywin32): pip install pbi-cli-tool[reload]
By default, every write command (add-page, delete-page, set-background, set-theme, etc.) automatically syncs Power BI Desktop after each operation. The sync closes Desktop with save and reopens the .pbip (it does not send a keyboard shortcut), so users will see Desktop close and relaunch after each write. When building a report in multiple steps, this causes Desktop to close-and-reopen after every single command.
Use --no-sync on the report command group to suppress per-command syncs, then call pbi report reload once at the end:
bash# BAD: Desktop reloads after every command pbi report add-page --display-name "Overview" --name overview pbi report set-background overview --color "#F2F2F2" # GOOD: suppress sync during build, reload once at the end pbi report --no-sync add-page --display-name "Overview" --name overview pbi report --no-sync set-background overview --color "#F2F2F2" pbi report reload
--no-sync is available on: report, visual, filters, and bookmarks command groups.
bash# Convert a .Report folder into a distributable .pbip project pbi report convert ./MyReport.Report --output ./distributable/
All report commands auto-detect the .Report folder:
pbi report --path ./MyReport.Report info*.Report/definition/.pbip: finds sibling .Report folder from .pbip fileThese constraints are not obvious but will silently crash PBI Desktop on open:
.pbip artifacts — only report is allowedThe .pbip file's artifacts array must contain ONLY a report entry. Never add a dataset entry — the schema rejects it:
json// CORRECT "artifacts": [{ "report": { "path": "MyReport.Report" } }] // WRONG — crashes on open with a schema validation error "artifacts": [ { "report": { "path": "MyReport.Report" } }, { "dataset": { "path": "MyModel.SemanticModel" } } ]
The semantic model is linked via definition.pbir, not the .pbip artifacts.
definition.pbir path — must be a non-null stringdatasetReference.byPath.path must always be a non-null string pointing to the SemanticModel folder. Setting it to null is a schema violation:
json// CORRECT "datasetReference": { "byPath": { "path": "../MyModel.SemanticModel" } } // WRONG — null is not allowed by the schema "datasetReference": { "byPath": { "path": null } }
bashpbi report validate
Run this after every structural change. It catches JSON parse errors (including trailing commas), missing required files, and broken page references before PBI Desktop sees them.
This workflow uses commands from multiple skills:
bash# 1. Scaffold report (this skill) pbi report create . --name "SalesDashboard" --dataset-path "../SalesModel.Dataset" # 2. Add pages (power-bi-pages skill) pbi report add-page --display-name "Overview" --name overview pbi report add-page --display-name "Details" --name details # 3. Add visuals (power-bi-visuals skill) pbi visual add --page overview --type card --name revenue_card pbi visual add --page overview --type bar --name sales_by_region # 4. Bind data (power-bi-visuals skill) pbi visual bind revenue_card --page overview --field "Sales[Total Revenue]" pbi visual bind sales_by_region --page overview \ --category "Geo[Region]" --value "Sales[Amount]" # 5. Apply theme (power-bi-themes skill) pbi report set-theme --file brand-colors.json # 6. Validate (this skill) pbi report validate
pbi-cli covers both the semantic model layer and the report layer:
bash# Model layer (requires pbi connect) pbi connect pbi measure create "Total Revenue" -e "SUM(Sales[Amount])" -t Sales # Report layer (no connection needed) pbi report create . --name "Sales" pbi visual add --page overview --type card --name rev_card pbi visual bind rev_card --page overview --field "Sales[Total Revenue]"
| Skill | When to use | |-------|-------------| | power-bi-visuals | Add, bind, update, delete visuals | | power-bi-pages | Add, remove, configure pages and bookmarks | | power-bi-themes | Themes, conditional formatting | | power-bi-filters | Page and visual filters |
bashpbi --json report info pbi --json report validate
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-13 | fail→pass | 13,755 | 2,962 | -78% | 1 | 1 | 0% | 2,257 | 2,342 | +4% | 0 | 0 | — |
case-01 | fail→pass | 15,815 | 2,969 | -81% | 1 | 1 | 0% | 2,403 | 2,395 | -0% | 0 | 0 | — |
case-02 | fail→pass | 20,144 | 4,105 | -80% | 1 | 1 | 0% | 3,595 | 2,471 | -31% | 0 | 0 | — |
case-03 | fail→pass | 16,969 | 2,575 | -85% | 1 | 1 | 0% | 2,897 | 2,183 | -25% | 0 | 0 | — |
case-04 | fail→pass | 8,899 | 3,426 | -62% | 1 | 1 | 0% | 1,567 | 2,426 | +55% | 0 | 0 | — |
case-05 | fail→pass | 9,164 | 2,427 | -74% | 1 | 1 | 0% | 1,709 | 2,301 | +35% | 0 | 0 | — |
case-06 | fail→pass | 14,343 | 1,987 | -86% | 1 | 1 | 0% | 2,391 | 2,120 | -11% | 0 | 0 | — |
case-07 | fail→pass | 19,760 | 2,624 | -87% | 1 | 1 | 0% | 3,282 | 2,241 | -32% | 0 | 0 | — |
case-08 | fail→pass | 12,338 | 2,915 | -76% | 1 | 1 | 0% | 1,865 | 2,297 | +23% | 0 | 0 | — |
case-09 | fail→pass | 18,295 | 1,757 | -90% | 1 | 1 | 0% | 3,161 | 2,101 | -34% | 0 | 0 | — |
case-10 | fail→pass | 15,119 | 3,877 | -74% | 1 | 1 | 0% | 2,337 | 2,481 | +6% | 0 | 0 | — |
case-11 | fail→pass | 12,670 | 3,252 | -74% | 1 | 1 | 0% | 1,862 | 2,309 | +24% | 0 | 0 | — |
case-12 | fail→pass | 19,218 | 1,634 | -91% | 1 | 1 | 0% | 3,194 | 2,071 | -35% | 0 | 0 | — |
case-14 | pass→pass | 9,642 | 3,842 | -60% | 1 | 1 | 0% | 1,684 | 2,475 | +47% | 0 | 0 | — |
case-15 | fail→pass | 12,499 | 5,207 | -58% | 1 | 1 | 0% | 1,855 | 2,644 | +43% | 0 | 0 | — |
case-16 | fail→pass | 14,157 | 4,081 | -71% | 1 | 1 | 0% | 2,063 | 2,478 | +20% | 0 | 0 | — |
case-17 | fail→pass | 8,911 | 1,906 | -79% | 1 | 1 | 0% | 1,372 | 2,053 | +50% | 0 | 0 | — |
case-18 | fail→pass | 17,145 | 2,327 | -86% | 1 | 1 | 0% | 2,822 | 2,230 | -21% | 0 | 0 | — |
case-19 | pass→pass | 11,191 | 8,836 | -21% | 1 | 1 | 0% | 2,033 | 3,313 | +63% | 0 | 0 | — |
case-20 | pass→pass | 13,286 | 10,081 | -24% | 1 | 1 | 0% | 2,140 | 3,467 | +62% | 0 | 0 | — |
case-21 | pass→pass | 12,956 | 11,080 | -14% | 1 | 1 | 0% | 2,139 | 3,762 | +76% | 0 | 0 | — |
case-22 | pass→pass | 14,826 | 8,631 | -42% | 1 | 1 | 0% | 2,458 | 3,126 | +27% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +77 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.