mcp-powerbi-desktop
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-powerbi-desktoplist all measures in the model"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Power BI Desktop Companion MCP Server
A Model Context Protocol (MCP) server that acts as a local companion tool for actively running Power BI Desktop (.pbix) sessions. It attaches to the live in-memory Analysis Services engine on the local machine (similar to DAX Studio or Tabular Editor).
This companion tool is designed ONLY for local running Power BI Desktop instances. It communicates using Windows PowerShell interop to run OLE DB queries and Tabular Object Model (TOM) mutations.
Architecture & Features
Windows PowerShell OLE DB / TOM Bridge: Executes native OLE DB commands (using the MSOLAP provider) and Tabular Object Model (TOM) scripts directly against the host machine's Analysis Services engine.
Dynamic Host Instance Discovery: Scans host processes to locate the dynamic ports, PIDs, database catalog GUIDs, table counts, and measure counts of all open
.pbixfiles.Case-Insensitive Metadata Parsing: Robust schema extraction from system DMVs, filtering out internal tables (
LocalDateTable_*,DateTableTemplate_*) to present clean models.Live Model Mutations: Directly creates or updates measures in the active
.pbixsession in-memory, committing changes using TOM'sSaveChanges().Stateful Connection Management: Retains connection info (selected port and database catalog) in-memory across MCP requests, auto-selecting if only one instance is active.
Related MCP server: powerbi-mcp-local
Tools Exposed
list_instances: Lists active local Power BI Desktop instances and their ports.select_instance(port): Connects the MCP server session to a specific port.get_model_metadata: Returns a token-efficient summary of tables and measures.list_measures: Returns all measure names, expressions, and parent tables.get_measure(name): Retrieves the DAX formula for a specific measure.create_measure(table, name, dax): Creates a new measure in a table.update_measure(table, name, dax): Updates an existing measure's formula.create_or_update_measure(table, name, dax): Unified tool to create or update a measure.run_tmsl(script): Runs Tabular Model Scripting Language (TMSL) scripts.get_relationships(table): Retrieves relationships in the semantic model with columns, types, and cross-filtering direction.
📦 Container Setup & Build with Podman
1. Build the Image
To build the Podman container image natively from the Dockerfile, run:
podman build -t power-bi-mcp:latest .2. Verify the Image Exists
Confirm the image has been successfully created and registered in Podman:
podman imagesExpected output:
REPOSITORY TAG IMAGE ID CREATED SIZE
localhost/power-bi-mcp latest e5b030e749ee 1 minute ago 627 MB🚀 Running the Container (WSL2 / Linux)
Because local Analysis Services runs on the Windows host and requires host execution interop, the container must be started with host network namespace access, a mount of the /mnt/c drive, and access to the WSL interop sockets.
Ephemeral Mode (Interactive / stdio)
To run the server dynamically for standard I/O communication (e.g. connected to OpenWebUI or an agent):
podman run --rm -i \
--network=host \
--pid=host \
-v /init:/init:ro \
-v /mnt/c:/mnt/c \
-v /run/WSL:/run/WSL \
-e WSL_INTEROP=$WSL_INTEROP \
-e PATH="/mnt/c/Windows/System32/WindowsPowerShell/v1.0:$PATH" \
power-bi-mcp:latestDetached Mode (Background proxy / testing)
If running a background daemon/test container:
podman run --rm -d \
--name power-bi-mcp-bg \
--network=host \
--pid=host \
-v /init:/init:ro \
-v /mnt/c:/mnt/c \
-v /run/WSL:/run/WSL \
-e WSL_INTEROP=$WSL_INTEROP \
-e PATH="/mnt/c/Windows/System32/WindowsPowerShell/v1.0:$PATH" \
power-bi-mcp:latestAccessing the Running Instance
If direct interactive shell access is required in the container for debugging:
podman exec -it <container_id> /bin/bash🔍 Validation of MCP Functionality
You can validate the containerized MCP service programmatically using the validation script test_container.py. This script initiates the JSON-RPC stdio handshake and invokes the new relationship retrieval tool:
poetry run python test_container.pyExpected Output Structure (JSON-RPC)
When the validation script queries relationships for a table (e.g., dim_colab), the output will resemble:
---> SENT JSON-RPC:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "get_relationships",
"arguments": {
"table": "dim_colab"
}
}
}
<--- RECEIVED JSON-RPC:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"content": [
{
"type": "text",
"text": "Relationships involving table: dim_colab\n========================================\n\n* dim_colab[CC_INDEX] -> dim_novo_ccusto[MASCARA] (many to 1, direction: Single)\n* dim_colab[codcoligada] -> ajuste_vt[codcoligada] (many to 1, direction: Single)"
}
],
"isError": false
}
}🛠️ Troubleshooting
1. FileNotFoundError: [Errno 2] No such file or directory: 'powershell.exe'
Cause: The kernel inside the container was unable to locate or execute
powershell.exe.Fix: Ensure
/mnt/cis mounted in the container at/mnt/c, and add/mnt/c/Windows/System32/WindowsPowerShell/v1.0to the container'sPATH.
2. WSL UtilBindVsockAnyPort: socket failed or PE binary: Invalid argument
Cause: Rootless Podman isolates the vsock driver sockets (
/dev/vsock) and namespaces.Fix: Run the container using standard Docker Desktop (which configures WSL interop permissions natively), or run the command with
--privilegedand/initmounted (-v /init:/init:ro). Alternatively, execute the server natively on the WSL host usingpoetry run python mcp_server.py.
🔄 Updating the Image for Future Versions
Follow these guidelines to update and deploy new versions of the MCP container:
1. Version Tagging Strategy
Always tag your builds semantically to keep tracks of changes and avoid deploying broken setups:
latest: Matches the current bleeding-edge stable build.v1,v2: Major versions matching major database schema support iterations.vX.Y.Z: Granular releases (e.g.,v0.1.0for early feature builds).
To retag an image:
podman tag power-bi-mcp:latest power-bi-mcp:v1.0.02. Updating Dependencies
When dependencies in pyproject.toml are modified:
Update lock file:
poetry updateRebuild the image:
podman build --no-cache -t power-bi-mcp:latest .
3. Safely Replacing Running Services
If the MCP service is integrated into a workflow client (e.g. OpenWebUI):
Build and tag the new container version:
podman build -t power-bi-mcp:v2 .Stop the active detached container (if running):
podman stop power-bi-mcp-bgUpdate the client config (such as OpenWebUI configuration block) to point to the new version tag if necessary.
4. CI/CD Integration
Configure pipelines to automatically run
poetry run python -m unitteston code pushes.Trigger container builds on successful test runs, tagging them with the repository commit SHA before rolling them out to the user's host environment.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/jborgesecon/mcp-powerbi-desktop'
If you have feedback or need assistance with the MCP directory API, please join our Discord server