Where we are: the journey so far
But going back to the question my customer had: "How do we make this look like us, not like default Power BI?" Same pattern as EmbedToken years ago, the beautiful part is derived from something upstream. There, the EmbedToken inherited AAD lifetimes. Here, the report inherits Figma tokens. Get the upstream right and the rest follows. This was confirmed to me the same way, by watching a designer change one token and the whole report follow.
bronze
gold
measures
functional
you are here
Data flows nightly, the model is certified, the report is correct, but still on the default theme. Designers already solved beauty in Figma. We just have to pipe it through.
Connect Figma MCP
// .vscode/mcp.json, add third server
{
"servers": {
"fabric": { "...": "Part 1" },
"powerbi": { "...": "Part 3" },
"figma": {
"type": "stdio",
"command": "npx",
"args": ["@figma/mcp-server@latest"],
"env": {
"FIGMA_ACCESS_TOKEN": "${env:FIGMA_ACCESS_TOKEN}",
"FIGMA_FILE_KEYS": "${env:FIGMA_FILE_KEYS}"
}
}
}
}
Get a token via Figma Settings to Personal Access Tokens (file:read, library:read), and copy the file key from your design-system URL.
// MCP: figma.getTeamLibraries() to Enterprise DS v3.2 (245 components)
// MCP: figma.getFileStyles(fileKey, "FILL") to 89 color styles
Found primary, success, warning, danger ramps + KPI Card variants (Default, Compact, Detailed, Alert). Ready to theme.
Tokens to Power BI theme with Copilot
{
"name": "Enterprise Design System",
"dataColors": ["#0052CC","#00875A","#FF8B00","#DE350B","#611F69","#007B83"],
"background": "#FFFFFF",
"foreground": "#172B4D",
"tableAccent": "#0052CC",
"visualStyles": {
"*": { "card": [{
"background": {"color": {"solid": {"color": "#FFFFFF"}}},
"border": {"color": {"solid": {"color": "#DFE1E6"}}, "radius": 8},
"shadow": {"color": {"solid": {"color": "#091E421A"}}, "blur": 8, "offsetY": 2}
}]}
}
}
// MCP: powerbi.applyTheme(ws, reportId, themeJson)
Theme "Enterprise Design System" applied to Sales Report
applyTheme. Design updates flow to BI automatically.
Apply + polish the report
// MCP: figma.getFrameNodes(fileKey, "Desktop - Full HD")
// MCP: powerbi.updateReportLayout(ws, reportId, "Overview", layoutSpec)
// MCP: powerbi.bindVisual(ws, reportId, "kpi-yoy", {
measure: "YoY Growth %",
conditionalFormatting: [{"> 0": "#00875A"}, {"< 0": "#DE350B"}] })
Overview now mirrors Figma: KPI row, bar + line pair, left slicer rail, all on-brand. Repeat once for Product/Customer/Store.
Publish + production checklist
Beauty without guardrails is a demo. Ship it like prod:
- PBIP validates clean; DAX measures pass 2 test cases each
- RLS tested per persona (Part 3 roles still enforced after theme change)
- Visual regression snapshots updated to themed pages
- Figma token sync Action scheduled; theme version pinned in repo
- Automation SP least-privilege; secrets in Key Vault / OIDC (local dev stays user-auth)
- Prod deploy requires approval; refresh + anomaly agents alerting
I hope this helps someone with the same lakehouse-to-report mess I had. I also want to thank the Fabric and Power BI product folks whose docs and Bridge samples made this verifiable instead of hand-wavy.
As usual, send me a note if you need to know more about this. Thank you!