Build a full Power BI project from a Solid semantic model without modeling in Power BI or dragging fields onto a canvas. Cursor talks to the Solid MCP, grounds metrics in certified SQL (text2sql), and writes human-readable TMDL (semantic model) + PBIR (report). A small Python toolkit assembles a Desktop-ready .pbip you can open against live Snowflake—or push to Fabric when you’re ready.
No manual semantic model in Power BI. No canvas click-ops. The model you certified in Solid becomes the model in Power BI.
Solid semantic model (tables, metrics, relationships)
│
├─ YAML export ──► adapter ──► TMDL
└─ Solid MCP ────► grounded SQL / glossary / asset metadata
│
▼
Agent writes DAX + PBIR JSON
│
▼
reports/<slug>/…Desktop-style .pbip
│
┌───────────────┴───────────────┐
▼ ▼
Power BI Desktop Fabric / XMLA (optional)
open .pbip, live Snowflake deploy or Git-sync to workspace
- Start from the model — A Solid semantic model for your domain (tables, columns, metrics, relationships).
- Ground with the Solid MCP — Cursor invokes
text2sql(and related tools) so joins, filters, and metric logic come from the certified model—not guesses. - Translate SQL → DAX — Grounded SQL informs TMDL measures and relationships.
- Build the report — The agent scaffolds PBIR pages/visuals and binds them to the model; scripts assemble a
.pbip. - Open in Power BI — Drop the project into Desktop (or deploy to the cloud). Keep editing in Cursor anytime.
Skill files and validation scripts under .cursor/rules/ and docs/specs/ encode PBIR/TMDL landmines (schema URLs, theme packages, relationship forests, and so on) so the project opens on the first try more often than not.
You need a Solid environment with a semantic model you trust, plus MCP access:
- Solid workspace / environment with your semantic model built and certified.
- Management key with MCP enabled, and the Semantic Layer ID (UUID) for that model.
- Configure Cursor (or your IDE) for Solid’s streamable-http MCP at
https://mcp.production.soliddata.io/mcp— see Getting Started with the Solid MCP Server. - Export the model as Solid YAML into
schemas/(example checked in:schemas/retail_sales.yaml).
For scripted MCP calls from this repo, copy .env.example → .env and set:
SOLIDDATA_MANAGEMENT_KEY=…
SEMANTIC_LAYER_ID=…Scripts authenticate with the x-solid-management-key header (powerbi_middleware.solid_client). There is no in-process LLM API key—the IDE agent is the model.
- Power BI Desktop with the PBIR preview enabled (required to open generated projects).
- Snowflake connectivity from the machine that opens Desktop (DirectQuery).
- Python 3.10+ for the assemble/validate scripts.
If you want XMLA deploy or Fabric Git Integration instead of (or after) Desktop:
- Power BI Premium Per User (PPU) or a Fabric F SKU
- Entra ID app registration with admin consent for scopes such as
Dataset.ReadWrite.AllandReport.ReadWrite.All - Env vars in
.envfor Entra +FABRIC_WORKSPACE_ID(andGIT_REPO_PATHif using--push)
macOS / Linux:
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"Windows (use a real python.org install—not the Microsoft Store stub). Prefer the venv explicitly:
powershell -File scripts\bootstrap.ps1
.\.venv\Scripts\python.exe -c "import powerbi_middleware"See Windows Python notes if bare python fails in Cursor terminals.
# Use your export, or the sample retail model
python scripts/e2e_local_pbip.py \
--schema-path schemas/retail_sales.yaml \
--output-slug demo \
--name DemoWindows:
.\.venv\Scripts\python.exe scripts\e2e_local_pbip.py `
--schema-path schemas/retail_sales.yaml `
--output-slug demo `
--name Demo
# or: scripts\e2e_local_pbip.cmd --schema-path schemas/retail_sales.yaml --output-slug demo --name DemoOpen reports/demo/Demo.pbip in Power BI Desktop against live Snowflake DirectQuery.
If the connection fails: fix it once in Desktop, copy non-secret partition/M snippets into templates/snowflake-connection/, regenerate with --connection-template templates/snowflake-connection, and confirm reopen works. Never commit passwords or *.pbi/localSettings.json / cache.json.
- Point Cursor at this repo with Solid MCP connected.
- Ask for a dashboard / pages from a use case (the agent should pick the right Solid model via MCP, ground metrics, write TMDL + PBIR).
- Optionally validate with middleware
pbir_validate, then reopen the.pbipin Desktop. - Commit (no secrets, no Desktop cache files).
Example prompt shape (adapt to your domain):
Build a new Power BI report dashboard + relevant raw table pages from scratch
with the correct Solid model and the right visuals for:
<your use case bullets>
Same artifacts; use when the workspace has Fabric/PPU and XMLA (or Fabric Git Integration).
python scripts/e2e_solid_to_git.py \
--schema-path schemas/retail_sales.yaml \
--report-path /path/to/pbir/report \
--output-path .e2e_out \
--layout fabricOptional flags: --deploy (XMLA; requires Entra credentials) and --push (requires GIT_REPO_PATH and a remote connected to the Fabric workspace).
| Path | When | Output |
|---|---|---|
| Desktop (default) | Power BI Desktop, no Fabric API | reports/<slug>/ with .pbip |
| Fabric | PPU / Fabric + XMLA or Git | layout="fabric"; optional --deploy / --push |
schemas/ # Solid YAML exports
reports/<slug>/ # <Name>.pbip, <Name>.SemanticModel/, <Name>.Report/
templates/snowflake-connection/ # optional Desktop-seeded non-secret snippets
src/powerbi_middleware/ # YAML → TMDL, PBIR scaffold/rebind, assemble, validate
.cursor/rules/ # agent skill rules for PBIR/TMDL + Solid→PBIP
docs/specs/ # PBIP/PBIR schema reference (canonical for agents)
- PBIR / PBIP are in public preview — behavior and APIs may change before GA. See Microsoft’s PBIR considerations (export, subscriptions, Embedded, size limits, etc.).
- Not every metric maps 1:1 to tidy DAX — simple aggregates translate cleanly; window / share-of-total style logic may be flagged for review rather than emitted broken.
- Desktop is the final judge — structural validation catches many issues; opening the
.pbipin Power BI Desktop is the real test. - Agents sometimes stumble — expect occasional self-correction on script or format errors; re-run or nudge if needed.
| Risk | Mitigation |
|---|---|
| Preview churn (PBIR/TMDL / Fabric Git) | Track Microsoft Learn; validate in Desktop after format changes |
| Generated Snowflake connection won’t open | Desktop escape hatch; commit non-secret snippets under templates/snowflake-connection/ |
| Entra API consent (Fabric path) | Obtain admin consent before --deploy; document scopes in .env.example |
| Invalid PBIR after agent edits | pbir_validate; reopen in Desktop before commit |
| Schema shape drift | Solid YAML adapter + fixture; update adapter with real exports |
- Load schema (
load_schemadetects Solid vs normalized YAML). - Generate TMDL (
generate_tmdl); optional--connection-templatemerge. - Optionally deploy via XMLA (
xmla_deploy) when Entra credentials exist.
- Scaffold minimal PBIR (
pbir_scaffold) or rebind field refs (pbir_rebind— deterministic map, no LLM). - Day-to-day layout/measure edits: Cursor (or similar) under
reports/, grounded by Solid MCP.
- Desktop: Open the
.pbipand confirm visuals query Snowflake. - Fabric (optional): After Git sync or XMLA deploy, confirm model + report in the workspace.
PBIR visual constraints for agent/human design input: docs/wireframe-pbir-checklist.md.
pytest tests/ -v- Auth / Entra errors: Ensure admin consent for required scopes; check Entra vars in
.env. - Schema not found / unexpected shape: Use
--schema-path. Normalized format:tableswithname,columns,measures. Solid-style exports are auto-adapted; if a real export fails, updatesolid_yaml_adapter+ fixture together. - Snowflake won’t connect in Desktop: Use the escape hatch; merge non-secret templates only.
- Validation failures: Check PBIR-supported visuals; see wireframe checklist.
- Git remote not set (
--push): Configure remote on the Fabric-connected repo. - Windows:
pythonis a 0-byte stub: Use.\.venv\Scripts\python.exeorscripts\e2e_local_pbip.cmd(see below).
Cursor agent terminals often omit User PATH entries, so bare python / python3 resolve to the Microsoft Store stub (WindowsApps\python.exe, 0 bytes) and py may be missing.
- Install Python 3.12 from python.org and enable Add python.exe to PATH.
- Disable Store aliases: Settings → Apps → Advanced app settings → App execution aliases → turn OFF
python.exeandpython3.exe. - Bootstrap:
powershell -File scripts\bootstrap.ps1 - Always run via the venv:
.\.venv\Scripts\python.exe scripts\…orscripts\e2e_local_pbip.cmd
- Solid MCP: Getting Started with the Solid MCP Server
- Design / plan: local PBIR Desktop design, implementation plan
- PBIP / PBIR schema reference (agents): docs/specs/2026-07-10-pbip-pbir-schema-reference.md
- PBIR format: Power BI Desktop project report folder – PBIR
- PBIR JSON schemas: fabric/item/report/definition
- Semantic model / TMDL: Power BI Desktop project semantic model folder, TMDL overview
- Fabric Git: Git integration overview, source code format