Are you the author? Sign in to claim
MCP server for Microsoft Power BI - list workspaces/datasets, read TMDL models, and run DAX, with MSAL/WAM auth.
A small Model Context Protocol (MCP) server for Microsoft Power BI. It lets an MCP-capable client (Claude, VS Code, etc.) discover your workspaces and datasets, read a semantic model's structure, and run DAX queries — all through the public Power BI and Microsoft Fabric REST APIs.
Authentication uses MSAL with the Windows broker (WAM): you sign in once, the token is cached locally, and the server refreshes it silently afterwards. No tokens are ever pasted by hand or stored in config.
| Tool | Description |
|---|---|
list_workspaces | List the workspaces (groups) you can access. |
list_datasets | List the datasets (semantic models) in a workspace. |
get_model_definition | Return a model's TMDL: tables, columns, measures (with DAX) and relationships. |
run_dax | Execute a DAX query and return the rows as JSON. |
git clone https://github.com/rajivdatta/powerbi-mcp.git
cd powerbi-mcp
python -m venv .venv
.venv\Scripts\activate # Windows (source .venv/bin/activate on macOS/Linux)
pip install -r requirements.txt
All configuration is optional and via environment variables — copy
.env.example to .env if you want to set any:
| Variable | Default | Purpose |
|---|---|---|
POWERBI_TENANT_ID | organizations | Pin sign-in to one Azure AD tenant. Use a GUID or domain (e.g. contoso.com). Recommended for work accounts. |
POWERBI_CLIENT_ID | Azure CLI public client | Override only if you want to use your own app registration. The default is a Microsoft first-party public client that works with the Windows broker. |
Finding your tenant ID: Azure Portal → Microsoft Entra ID → Overview → Tenant ID, or just use your email domain. Leaving it unset (
organizations) lets any work/school account sign in.
.env is git-ignored.
.venv\Scripts\activate
python server.py --login
This opens an interactive sign-in (Windows broker popup or browser) and caches a
refresh token at %LOCALAPPDATA%\powerbi-mcp\token_cache.bin. After this, the
server refreshes access tokens silently on every call — no re-login needed.
To switch accounts later, just run --login again and pick the other account.
python -c "import server; print(server.list_workspaces())"
You should get a JSON list of your workspaces (each with an id and name).
Point your client at server.py (see examples/mcp.json).
Use the venv's Python so dependencies resolve:
{
"mcpServers": {
"powerbi": {
"command": "C:\\path\\to\\powerbi-mcp\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\powerbi-mcp\\server.py"],
"env": { "POWERBI_TENANT_ID": "your-tenant-id-or-domain" }
}
}
}
Restart your MCP client, then try: "using powerbi, list my workspaces".
Claude Desktop reads its MCP servers from
claude_desktop_config.json. Open it from Settings → Developer → Edit Config
(this creates the file if it doesn't exist), or edit it directly:
%APPDATA%\Claude\claude_desktop_config.json~/Library/Application Support/Claude/claude_desktop_config.jsonAdd this server under mcpServers, using absolute paths to the venv's
Python and server.py:
{
"mcpServers": {
"powerbi": {
"command": "C:\\path\\to\\powerbi-mcp\\.venv\\Scripts\\python.exe",
"args": ["C:\\path\\to\\powerbi-mcp\\server.py"],
"env": { "POWERBI_TENANT_ID": "your-tenant-id-or-domain" }
}
}
}
On macOS the paths are POSIX, e.g. "command": "/Users/you/powerbi-mcp/.venv/bin/python".
Save the file and fully quit and reopen Claude Desktop (use Quit from the
tray/menu-bar icon — closing the window isn't enough). The server's tools then
appear in the tools (🔌) menu of a new chat. Sign in first with
python server.py --login so the token cache exists before Desktop launches it.
A typical sequence:
list_workspaces → pick a workspace idlist_datasets(workspace_id) → pick a dataset idget_model_definition(workspace_id, dataset_id) → learn table & measure namesrun_dax(workspace_id, dataset_id, "EVALUATE ...") → get resultsThe MSAL token cache (%LOCALAPPDATA%\powerbi-mcp\token_cache.bin) contains a
refresh token. Treat it like a password — it lives outside the repo and is never
committed.
MIT (c) 2026 Rajiv Datta
Run Claude Code as an MCP server so any agent can delegate coding tasks to it
Browser automation using accessibility snapshots instead of screenshots
Google's universal MCP server supporting PostgreSQL, MySQL, MongoDB, Redis, and 10+ databases
Official GitHub integration for repos, issues, PRs, and CI/CD workflows