Windows-first DAX and MCP toolkit for Power BI semantic models
Project description
dax-query-mcp
MCP server for running DAX queries against Power BI semantic models.
Check out making use of skills and extensions for getting better results since the MCP can't do it all
Features
- Connection-centric MCP server — discover models, query with DAX, inspect schemas
- Curated context — teach the LLM your model via markdown docs (no admin privileges needed)
- Fuzzy search — search columns and measures across tables by name or description
- Export anywhere — CSV, clipboard, Power Query M code, Streamlit apps, standalone Python projects
- Query builder — save
.dax+.dax.queryBuilderartifacts, open directly in DAX Studio - Workstation session — save, list, and batch-export queries during an exploration session
Quick start
1. Install
From PyPI (recommended):
uv pip install dax-query-mcp
From source (for development or latest changes):
git clone https://github.com/wes-stone/dax-query-mcp.git
cd dax-query-mcp
uv sync
2. Add a connection
Create Connections/my_model.yaml:
connection_string: |
Provider=MSOLAP.8;
Data Source=powerbi://api.powerbi.com/v1.0/myorg/MyWorkspace?readonly;
Initial Catalog=MySemanticModel
description: "My semantic model"
command_timeout_seconds: 1800
Optionally add Connections/my_model.md alongside it to document tables, measures, and common filters for the LLM.
3. Wire up MCP
Add to .copilot/mcp.json (or your MCP client config):
Using PyPI (via uvx):
{
"mcpServers": {
"dax-query-server": {
"command": "uvx",
"args": ["dax-query-mcp", "dax-query-server"],
"env": {
"DAX_QUERY_MCP_CONNECTIONS_DIR": "C:\\absolute\\path\\to\\Connections"
}
}
}
}
Using a local clone:
{
"mcpServers": {
"dax-query-server": {
"command": "uv",
"args": ["run", "--directory", "C:\\path\\to\\dax-query-mcp", "dax-query-server"],
"env": {
"DAX_QUERY_MCP_CONNECTIONS_DIR": "C:\\absolute\\path\\to\\Connections"
}
}
}
}
Tip:
DAX_QUERY_MCP_CONNECTIONS_DIRlets you share oneConnections/folder across workspaces.
4. Run your first query
Ask Copilot (or any MCP client):
"List connections, then run a DAX query against my model."
The server returns plain markdown — results render as tables directly in chat.
Connection YAML
connection_string: "..." # required — MSOLAP connection string
description: "..." # human-readable label
command_timeout_seconds: 1800 # DAX query timeout
connection_timeout_seconds: 300 # connection open timeout
max_rows: null # row cap (null = unlimited)
suggested_skill: "..." # optional — hint an MCP client toward a specific skill
suggested_skill_reason: "..." # optional — why that skill is relevant
MCP tools
| Tool | Purpose |
|---|---|
| Discovery | |
list_connections |
Discover available connections |
get_connection_context |
Curated markdown context (tables, columns, measures) |
search_connection_context |
Search context docs for specific terms |
inspect_connection |
Live schema via safe MDSCHEMA rowsets |
| Querying | |
run_connection_query |
Run DAX against a named connection |
run_ad_hoc_query |
Run DAX against a raw connection string |
| Search | |
search_columns |
Fuzzy-search columns across tables |
search_measures |
Fuzzy-search measures by name or expression |
| Export | |
export_to_csv |
Export results to a timestamped CSV |
copy_to_clipboard |
Copy results to clipboard (TSV or markdown) |
scaffold_power_query |
Generate Power Query M code for Excel |
scaffold_streamlit_app |
Generate a Streamlit visualization app |
scaffold_dax_workspace |
Scaffold a standalone Python project |
quick_chart |
Render a bar/line/pie chart as PNG |
| Query builder | |
save_query_builder |
Save .dax + .dax.queryBuilder artifacts |
get_query_builder |
Load a saved query builder definition |
get_query_builder_schema |
Get the expected JSON payload shape |
| Workstation | |
save_to_workstation |
Save a query to the session workstation |
list_workstation |
List saved workstation queries |
export_workstation |
Batch-export workstation as scaffold or .dax files |
Admin queries are blocked.
INFO.*()and$SYSTEM.DISCOVER_*require server admin rights. Useget_connection_contextorinspect_connectionfor metadata.
CLI usage
# List configured queries
dax-query --list --config-dir queries
# Run a query
dax-query --query my_query --preview --config-dir queries
# Inspect a connection schema
dax-query --inspect-connection my_model --connections-dir Connections
# Save a query builder artifact
dax-query-builder --save-query-builder-from builder.json --config-dir queries
Saved .dax files open directly in DAX Studio. See docs/ for detailed CLI documentation.
Copilot guard hook
A pre-commit hook reviews staged changes for private content (real workspace URIs, local paths, non-sample connection files).
# Install
powershell -ExecutionPolicy Bypass -File .\scripts\install-git-hooks.ps1
# Runs automatically on commit:
dax-query-guard --mode staged
Add repo-specific patterns via .copilot-guard.local.json:
{
"blocked_content_patterns": [
{
"pattern": "PrivateWorkspace|InternalDataset",
"reason": "Internal identifiers"
}
]
}
Fails closed by default. Set COPILOT_GUARD_FAIL_OPEN=1 to allow commits when Copilot CLI is unavailable.
Requirements
- Windows (COM/ADODB used for DAX execution)
- MSOLAP / Analysis Services client libraries
- Python 3.12+
- uv
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dax_query_mcp-0.2.0.tar.gz.
File metadata
- Download URL: dax_query_mcp-0.2.0.tar.gz
- Upload date:
- Size: 81.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4641290940735d27c39cd300fb04d2c91ebc7d55b15771598f879bbf61b6a80e
|
|
| MD5 |
9bd8b723c1bf3eb570620793b549d105
|
|
| BLAKE2b-256 |
012b169da3bc38889bed1d2fd1380beae9abaa6f93c686b6abcf6440ca2bd0b6
|
File details
Details for the file dax_query_mcp-0.2.0-py3-none-any.whl.
File metadata
- Download URL: dax_query_mcp-0.2.0-py3-none-any.whl
- Upload date:
- Size: 54.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.10.4 {"installer":{"name":"uv","version":"0.10.4","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":null,"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
575cd3f23e24ed82f31a5b6380324762b10b8527c8262464b75a6392ce3acf32
|
|
| MD5 |
25144aa64a56a88bb42d25f3797cd177
|
|
| BLAKE2b-256 |
0b45b46bcae78b1bcff095d29ff8e20d16489b288c54dba94ccf389c5e377a44
|