Skip to main content

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.queryBuilder artifacts, open directly in DAX Studio
  • Workstation session — save, list, and batch-export queries during an exploration session

Prerequisites

  1. Windows — the server uses COM/ADODB under the hood, so it's Windows-only.

  2. MSOLAP provider — the OLE DB driver that talks to Power BI semantic models. Download from Microsoft — grab the "AMO + ADOMD.NET" or "MSOLAP (OLE DB)" installer. If you already have Power BI Desktop, Excel with Power Pivot, or SSMS installed, you likely have it.

    To check: open PowerShell and run:

    (New-Object System.Data.OleDb.OleDbEnumerator).GetElements() | Where-Object { $_.SOURCES_NAME -like "*MSOLAP*" }
    

    If that returns a row, you're good.

  3. uv — Python package manager. Install with:

    winget install astral-sh.uv
    

Quick start

1. Install

From PyPI (recommended):

uvx --from dax-query-mcp dax-query-server

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": ["--from", "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_DIR lets you share one Connections/ 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. Use get_connection_context or inspect_connection for 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 OLE DB provider (see Prerequisites)
  • Python 3.12+ (handled automatically by uvx)
  • uv (winget install astral-sh.uv)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dax_query_mcp-0.2.1.tar.gz (81.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dax_query_mcp-0.2.1-py3-none-any.whl (55.1 kB view details)

Uploaded Python 3

File details

Details for the file dax_query_mcp-0.2.1.tar.gz.

File metadata

  • Download URL: dax_query_mcp-0.2.1.tar.gz
  • Upload date:
  • Size: 81.9 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

Hashes for dax_query_mcp-0.2.1.tar.gz
Algorithm Hash digest
SHA256 b04379c6510b0ef84eefb5befef209af0adb4a2bc75d629a836d4269c61d998a
MD5 7b61f628182282ad8218e985225d6c4f
BLAKE2b-256 6ca45ee9c318bdece964063ca47eaf4328f494df46112fb5a0521f47b4f3f508

See more details on using hashes here.

File details

Details for the file dax_query_mcp-0.2.1-py3-none-any.whl.

File metadata

  • Download URL: dax_query_mcp-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 55.1 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

Hashes for dax_query_mcp-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7d35b0a6c30d9da13868f5e56caf6e843d22343d028c19f2be30c9635ecd14f1
MD5 eb8c789ced1ee28d5a8f32e9f6b05f79
BLAKE2b-256 07235edea08ada323a8c4743a5e3ecba36b0573bb7b0c5c6befae028224cca63

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page