About Powerbi MCP Gateway
Powerbi MCP Gateway is an MCP server published by PlainsightPro in the Other category.
The repository has 14 stars and 0 forks, with the last commit 11 days ago. Recent commit activity is the strongest signal that reported issues will get attention.
Install
git clone https://github.com/PlainsightPro/powerbi-mcp-gatewayThis server has no ConduID identity, so agent calls to it are not receipted. Pin the version you install and review the source before granting it credentials.
Ask AI
Ask AI about Powerbi MCP Gateway
Powered by Claude · Grounded in docs
Security checks
Static checks derived from the repository 7 hours ago. Heuristics on the source, not an audit.
- ✓README presentThe repository ships documentation.
- ✓License declaredUsable under a stated license.
- ✓Tests presentA test suite exists in the repository.
- ✓Dependencies pinnedA lockfile pins dependency versions.
- ✓No dynamic code executionSource scan found no eval, dynamic Function, or shell execution.
1 check has not been run yet.
Releases
README
Power BI MCP Gateway
A remote MCP server that lets any MCP client (Claude, VS Code and GitHub Copilot, Cursor, ChatGPT, your own agents) talk to Power BI semantic models as the signed-in user, with the organisation's business knowledge kept centrally on the server instead of in every client's instruction files.
It works with any Power BI semantic model in a workspace that has an XMLA endpoint, which means Premium Per User, Premium or Fabric capacity. It is independent of organisation, industry and model schema: everything domain-specific comes from a skills folder that each deployment supplies.
Why
Microsoft's hosted Power BI MCP server can run DAX for a user, but it needs a model id you have to
know, it carries no business vocabulary, and its GenerateQuery tool runs on Copilot, which needs
a Copilot licence and an F2 or P1 capacity (on Premium Per User it fails with
AI_Scenarios_SkuNotSupported). The gateway sits in front of it:
| Need | Microsoft's hosted server | Gateway |
|---|---|---|
| Which models exist | none; you must know the id | list_semantic_models: only what the user can open, curated ones with description, scope and key measures |
| Business knowledge | none | server instructions, get_business_context, one prompt per recipe, skill:// resources |
| DAX generation | GenerateQuery on Copilot: Copilot licence plus F2/P1 capacity, not Premium Per User |
generate_dax on your own Foundry (Azure OpenAI) deployment, grounded in schema, glossary and rules, with one repair round; no Copilot, no Fabric capacity |
| Client onboarding | an Entra app registration per client | OAuth proxy with dynamic client registration: paste the URL, sign in |
| Execution | schema, DAX, report metadata | the same, called with the user's on-behalf-of token, so Build permission and row-level security apply |
The gateway never calls GenerateQuery. generate_dax writes the query on the deployment's own
Foundry model and runs it through the hosted server's ExecuteQuery, which only needs Build
permission on the model and an XMLA-capable workspace. Microsoft's open-source
skills-for-fabric and
powerbi-modeling-mcp take the same route:
the client's own LLM writes the DAX, guided by skill files. There is no Microsoft library for DAX
generation; the reusable part is their DAX guideline text, which a deployment can fold into its
skill://dax-rules.
Nothing runs under a service identity. Every Power BI call carries a token issued for the signed-in user, which is also what the Premium Per User terms of use require for multi-user applications.
Architecture
MCP client (Claude, VS Code, Cursor, ChatGPT, agent code)
| Streamable HTTP + OAuth 2.1 (dynamic client registration against the gateway)
v
Gateway (Azure Container Apps) FastMCP + Azure OAuth proxy
|-- /mcp tools, prompts, resources, instructions <- skills folder, loaded at startup
|-- /authorize /token /register /auth/callback <- Microsoft Entra ID behind it
|
|-- per call: on-behalf-of token for https://api.fabric.microsoft.com
| |-- Fabric REST workspaces and semantic models the user can open
| `-- hosted Power BI MCP GetSemanticModelSchema / ExecuteQuery / GetReportMetadata
`-- managed identity -> Foundry model deployment (Responses API) for generate_dax
Tools
| Tool | Purpose |
|---|---|
list_semantic_models |
Models the user can open; curated first with description, scope, date table, key measures, recipes |
get_business_context |
The deployment's glossary: vocabulary, measures, dates, model traps, recipe index |
get_recipe |
A validated query sequence for a recurring analysis |
get_semantic_model_schema |
Tables, columns, measures with descriptions, relationships |
execute_dax |
Run 1 to 4 DAX queries as the user (default 250 rows) |
generate_dax |
Question to DAX, optionally executed; returns DAX, explanation, assumptions, rows |
get_report_metadata |
Pages, visuals and filters of a report the user can open |
recall / remember / forget |
Notes users attach to one model (a correction, a trap, the measure for a recurring question). They follow the model: visible and writable only to people Power BI lets open it, and folded into the schema notes and generate_dax grounding |
Prompts: one per recipe in the skills folder. Resources: skill://glossary, skill://dax-rules,
skill://catalog, skill://recipes/{name}. The tool contract is in
docs/connect/other-agents.md.
Skills: the part you own
skills/ in this repository is a fictional example (Contoso Retail). A deployment brings its
own folder with the same five parts and the gateway is built with it:
| File | Purpose |
|---|---|
instructions.md |
How the assistant should work with the tools; sent to every client |
glossary.md |
Business vocabulary, which measure answers which question, sign conventions, traps |
dax-rules.md |
House rules for DAX generation |
recipes/*.md |
Validated query sequences; each becomes a prompt and a resource |
catalog.yaml |
Curated models: id, workspace, scope, key measures, notes |
Nothing about a real organisation belongs in this repository. See docs/skills-authoring.md for writing a folder and docs/private-skills.md for running many deployments from this one codebase.
Deploy
Prerequisites: PowerShell 7, Azure CLI 2.78+, signed in with rights to register Entra applications and grant admin consent, and Contributor on the subscription. The tenant needs the Power BI MCP endpoint enabled (see docs/administration.md).
# try it with the example skills
.\deploy\deploy_to_azure.ps1 -AcrName <globally unique registry name>
# a real deployment: private skills + resource names from a profile, engine pinned to a release
.\deploy\deploy_to_azure.ps1 -Profile C:\deployments\<org>\deploy\profile.json
The script creates or updates, idempotently: the Entra app (confidential client, access_as_user
scope, delegated Power BI permissions, admin consent), a Foundry resource with a model deployment,
a container registry, Log Analytics, a Container Apps environment and the container app with a
managed identity. It stages only runtime code and the selected skills for the build; .env, Git
history and private notes never reach the image. Re-run after changes; -SkipFoundry skips the
model part, -SkipBuild keeps the running image.
Releases publish the engine image to ghcr.io/plainsightpro/powerbi-mcp-gateway:<version>; a
deployment profile with EngineImage layers its skills on that image instead of building the
source, which is how deployments upgrade without forking.
Connect
Users need the gateway URL, a Microsoft work account, a licence matching the workspace and Build permission on the models they query. Walkthroughs per tool, usage guidelines and troubleshooting are in docs/. In short:
claude mcp add --transport http powerbi https://<host>/mcp # then /mcp and sign in
Claude Desktop, claude.ai, ChatGPT: add a custom connector with the URL, no client id. VS Code:
{"type": "http", "url": "https://<host>/mcp"} in mcp.json; Cursor: {"url": "https://<host>/mcp"}
under mcpServers.
Local development
uv sync # .venv from uv.lock, dev tools included (ruff, pyright, pytest)
Copy-Item .env.example .env # Entra app values, Foundry endpoint, optional PBIMCP_SKILLS_DIR
uv run pytest -q
uv run python -m powerbi_mcp # http://localhost:8000/mcp
http://localhost:8000/auth/callback is registered on the Entra app by the deploy script, so a
local server runs the full sign-in. az login supplies the Foundry credential locally; the
signed-in user needs the Cognitive Services OpenAI User role on the Foundry resource, or set
PBIMCP_FOUNDRY_API_KEY for the session.
Three checks exist: python -m powerbi_mcp --check-skills <folder> validates a skills folder
offline, scripts/smoke_test.py runs the token exchange, catalog, schema, query and DAX generation
headlessly with the Azure CLI identity (the deploy script's -PreauthorizeAzureCli enables it), and
scripts/check_gateway.py https://<host>/mcp verifies a deployed gateway through the real browser
sign-in.
Known limits
- The app runs one replica. Its OAuth state (client registrations, encrypted tokens) lives in an
Azure Table, so a redeploy keeps users signed in; scaling out additionally needs
stateless_http=Trueon the server (MCP sessions are per replica). - Skills are deployment-wide, not filtered by the user's permissions; separate deployments for groups that must not share business knowledge.
generate_daxreturns one query per call; multi-step analyses follow recipes.
License
MIT. Built by Plainsight; contributions welcome.
README fetched from the repository 7 hours ago. The original is authoritative.