# PowerBI MCP Server [![PyPI](https://img.shields.io/pypi/v/powerbi-mcp.svg)](https://pypi.org/project/powerbi-mcp/) [![Python Versions](https://img.shields.io/pypi/pyversions/powerbi-mcp.svg)](https://pypi.org/project/powerbi-mcp/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) A Model Context Protocol (MCP) server that provides tools for interacting with PowerBI REST APIs. This server enables AI assistants like Claude to query PowerBI workspaces, datasets, and execute DAX queries. > [!WARNING] > **Security Best Practices** > - Never commit credentials to version control > - Store credentials in `.env` files (add to `.gitignore`) > - Rotate client secrets regularly in Azure AD > - Use least-privilege access (only grant necessary workspace permissions) > - This server has read/write access to PowerBI datasets - use with caution ## ✨ Features - **Query Your Data**: Run DAX queries to extract insights and analyze your PowerBI data directly through conversation - **Discover Workspaces & Datasets**: Explore what data is available across your organization's PowerBI environment - **Understand Data Models**: Get detailed schema information to know what tables, columns, and relationships exist - **Natural Language to Insights**: Ask questions about your data and get answers without opening PowerBI See all [available tools](#-available-tools) below. ## 💡 What Can You Do? | Scenario | Example Prompt | |----------|----------------| | Explore available data | "What workspaces do I have access to?" | | Discover reports | "What reports are available in my workspace?" | | Understand data schema | "Show me the schema for dataset [dataset-name]" | | Monitor data freshes | "When was this dataset last refreshed?" | | Check parameters | "What parameters does this dataset accept?" | | Query data with DAX | "Run a DAX query to get top 10 sales by region from [dataset]" | | Analyze data quality | "What tables are in the Sales dataset?" | | Extract insights | "Get the list of all measures in the Financial dataset" | ## 📋 Prerequisites - **Azure AD Service Principal**: Required for authentication. Follow the [Azure AD Configuration](#-azure-ad-configuration) steps below to set this up. ## 🔐 Azure AD Configuration Before installing the server, you need to set up an Azure AD application with PowerBI access. ### Create Azure AD App Registration 1. Go to [Azure Portal](https://portal.azure.com) 2. Navigate to **Azure Active Directory** > **App registrations** 3. Click **New registration** 4. Enter a name (e.g., "PowerBI MCP Server") 5. Click **Register** ### Get Credentials After registration, collect these values: - **Tenant ID**: Found in app Overview page (Directory ID) - **Client ID**: Found in app Overview page (Application ID) - **Client Secret**: - Go to **Certificates & secrets** - Click **New client secret** - Add description and set expiry - Copy the secret **Value** (you can only see this once!) ### Enable Service Principal in PowerBI 1. Go to [PowerBI Admin Portal](https://app.powerbi.com/admin-portal) 2. Navigate to **Tenant settings** > **Developer settings** 3. Enable **Service principals can use PowerBI APIs** 4. Add your app to the security group or enable for entire organization 5. Click **Apply** > [!NOTE] > Service principals can access workspaces where they've been granted explicit permissions (Admin, Member, or Contributor roles). ### Grant Workspace Access For each workspace you want to access: 1. Go to the workspace in PowerBI 2. Click workspace settings (⚙️) > **Access** 3. Click **Add people or groups** 4. Search for your app name 5. Assign role: **Admin**, **Member**, or **Contributor** 6. Click **Add** ## 📦 Installation ### Method 0: From PyPI (Recommended) Once published to PyPI, this is the simplest installation method. Add the following to your MCP client configuration file: **For Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS): ```json { "mcpServers": { "powerbi-mcp": { "command": "uvx", "args": ["powerbi-mcp"], "env": { "POWERBI_TENANT_ID": "your-tenant-id-here", "POWERBI_CLIENT_ID": "your-client-id-here", "POWERBI_CLIENT_SECRET": "your-client-secret-here" } } } } ``` **For Claude Code** (`./.mcp.json` in your project directory): ```json { "mcpServers": { "powerbi-mcp": { "command": "uvx", "args": ["powerbi-mcp"], "env": {} } } } ``` When using Claude Code, create a `.env` file in your project directory (where you run Claude Code from): ```env POWERBI_TENANT_ID=your-tenant-id-here POWERBI_CLIENT_ID=your-client-id-here POWERBI_CLIENT_SECRET=your-client-secret-here ``` > [!TIP] > The `.env` file should be in your working directory, not where the server is installed. **For OpenCode** (`~/.config/opencode/opencode.json`): ```json { "$schema": "https://opencode.ai/config.json", "mcp": { "powerbi-mcp": { "type": "local", "command": ["uvx", "powerbi-mcp"], "enabled": true, "env": { "POWERBI_TENANT_ID": "your-tenant-id-here", "POWERBI_CLIENT_ID": "your-client-id-here", "POWERBI_CLIENT_SECRET": "your-client-secret-here" } } } } ``` After adding the configuration, restart your MCP client. ### Method 1: Direct from GitHub (Development) This method uses `uvx` to run the server directly from GitHub without cloning the repository. Add the following to your MCP client configuration file: **For Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS): ```json { "mcpServers": { "powerbi-mcp": { "command": "uvx", "args": [ "--from", "git+https://github.com/gurvinder-dhillon/powerbi-mcp@main", "run-server" ], "env": { "POWERBI_TENANT_ID": "your-tenant-id-here", "POWERBI_CLIENT_ID": "your-client-id-here", "POWERBI_CLIENT_SECRET": "your-client-secret-here" } } } } ``` **For Claude Code** (`./.mcp.json` in your project directory): ```json { "mcpServers": { "powerbi-mcp": { "command": "uvx", "args": [ "--from", "git+https://github.com/gurvinder-dhillon/powerbi-mcp@main", "run-server" ], "env": {} } } } ``` When using Claude Code, create a `.env` file in your project directory (where you run Claude Code from): ```env POWERBI_TENANT_ID=your-tenant-id-here POWERBI_CLIENT_ID=your-client-id-here POWERBI_CLIENT_SECRET=your-client-secret-here ``` > [!TIP] > The `.env` file should be in your working directory, not where the server is installed. The server will automatically load environment variables from the `.env` file in your current working directory. **For OpenCode** (`~/.config/opencode/opencode.json`): ```json { "$schema": "https://opencode.ai/config.json", "mcp": { "powerbi-mcp": { "type": "local", "command": [ "uvx", "--from", "git+https://github.com/gurvinder-dhillon/powerbi-mcp@main", "run-server" ], "enabled": true, "env": { "POWERBI_TENANT_ID": "your-tenant-id-here", "POWERBI_CLIENT_ID": "your-client-id-here", "POWERBI_CLIENT_SECRET": "your-client-secret-here" } } } } ``` After adding the configuration, restart your MCP client. ### Method 2: Local Clone (Contributors) For contributors who want to run from a local clone: 1. Clone the repository: ```bash git clone https://github.com/gurvinder-dhillon/powerbi-mcp.git cd powerbi-mcp ``` 2. Install dependencies: ```bash uv sync ``` 3. Add to your MCP client configuration: **For Claude Desktop**: ```json { "mcpServers": { "powerbi-mcp-local": { "command": "uv", "args": [ "--directory", "/absolute/path/to/powerbi-mcp", "run", "run-server" ], "env": { "POWERBI_TENANT_ID": "your-tenant-id-here", "POWERBI_CLIENT_ID": "your-client-id-here", "POWERBI_CLIENT_SECRET": "your-client-secret-here" } } } } ``` **For Claude Code** (`./.mcp.json` in your project directory): ```json { "mcpServers": { "powerbi-mcp-local": { "command": "uv", "args": [ "--directory", "/absolute/path/to/powerbi-mcp", "run", "run-server" ], "env": {} } } } ``` **For OpenCode** (`~/.config/opencode/opencode.json`): ```json { "$schema": "https://opencode.ai/config.json", "mcp": { "powerbi-mcp-local": { "type": "local", "command": [ "uv", "--directory", "/absolute/path/to/powerbi-mcp", "run", "run-server" ], "enabled": true, "env": { "POWERBI_TENANT_ID": "your-tenant-id-here", "POWERBI_CLIENT_ID": "your-client-id-here", "POWERBI_CLIENT_SECRET": "your-client-secret-here" } } } } ``` Replace `/absolute/path/to/powerbi-mcp` with the actual path to your cloned repository. When using Claude Code or OpenCode, create a `.env` file in your project directory with your credentials (see Method 1 Claude Code section above for the format). ## 🚀 Quick Start Once installed, try these steps to get started: 1. **Verify Connection**: Ask Claude "What PowerBI workspaces do I have access to?" 2. **Explore Data**: "Show me the datasets in workspace [workspace-name]" 3. **View Schema**: "What tables are in dataset [dataset-name]?" 4. **Run a Query**: "Execute this DAX query on [dataset-name]: EVALUATE TOPN(10, Sales)" ## 🛠️ Available Tools | Tool | Description | Key Parameters | |------|-------------|----------------| | `get_workspaces` | List accessible PowerBI workspaces | `top`, `detail` | | `get_datasets` | Get datasets from workspace or "My workspace" | `workspace_id`, `detail` | | `get_dataset` | Get detailed dataset info including schema | `dataset_id`, `workspace_id`, `detail` | | `get_reports` | List PowerBI reports in workspace | `workspace_id`, `format`, `detail` | | `get_refresh_history` | Get dataset refresh history with status/timestamps | `dataset_id`, `workspace_id`, `top`, `format` | | `get_parameters` | List dataset parameters and their current values | `dataset_id`, `workspace_id`, `format`, `detail` | | `query_dataset` | Execute DAX queries against dataset | `dataset_id`, `dax_query`, `workspace_id` | ### Tool Details #### 1. get_workspaces List PowerBI workspaces accessible to the service principal. **Parameters:** - `top` (optional): Number of workspaces to return (default: 100, max: 5000) - `detail` (optional): Level of detail - "concise", "normal", or "full" (default: "normal") #### 2. get_datasets Get list of datasets from a workspace or "My workspace". **Parameters:** - `workspace_id` (optional): Workspace ID (omit for "My workspace") - `detail` (optional): Level of detail - "concise", "normal", or "full" (default: "normal") #### 3. get_dataset Get detailed information about a specific dataset including schema and tables. **Parameters:** - `dataset_id` (required): Dataset ID - `workspace_id` (optional): Workspace ID (omit for "My workspace") - `detail` (optional): Level of detail - "concise", "normal", or "full" (default: "normal") #### 4. get_reports List PowerBI reports in a workspace. **Parameters:** - `workspace_id` (optional): Workspace ID (omit for "My workspace") - `format` (optional): Response format - "markdown" or "json" (default: "markdown") - `detail` (optional): Level of detail - "concise" or "normal" (default: "concise") #### 5. get_refresh_history Get refresh history for a dataset showing recent refresh operations. **Parameters:** - `dataset_id` (required): Dataset ID - `workspace_id` (optional): Workspace ID (omit for "My workspace") - `top` (optional): Number of refresh records to return (default: 5, max: 60) - `format` (optional): Response format - "markdown" or "json" (default: "markdown") #### 6. get_parameters Get parameters defined in a dataset. **Parameters:** - `dataset_id` (required): Dataset ID - `workspace_id` (optional): Workspace ID (omit for "My workspace") - `format` (optional): Response format - "markdown" or "json" (default: "markdown") - `detail` (optional): Level of detail - "concise" or "normal" (default: "normal") **Note:** Not supported for datasets with SQL, Oracle, Teradata, SAP HANA DirectQuery connections or datasets modified via XMLA endpoint. #### 7. query_dataset Execute DAX queries against a dataset. **Parameters:** - `dataset_id` (required): Dataset ID - `dax_query` (required): DAX query (must start with "EVALUATE") - `workspace_id` (optional): Workspace ID (omit for "My workspace") ### DAX Query Examples **Basic Table Scan:** ```dax EVALUATE 'Sales' ``` **Top N with Sorting:** ```dax EVALUATE TOPN(10, 'Sales', [Amount], DESC) ``` **Filtered Results:** ```dax EVALUATE FILTER('Sales', [Year] = 2024) ``` **Calculated Columns:** ```dax EVALUATE ADDCOLUMNS( 'Sales', "Profit", [Revenue] - [Cost] ) ``` **Aggregated Summary:** ```dax EVALUATE SUMMARIZE( 'Sales', 'Product'[Category], "Total Sales", SUM('Sales'[Amount]) ) ``` ## ⚠️ Troubleshooting ### Authentication Errors **Error: "Authentication failed"** - Verify your `POWERBI_TENANT_ID`, `POWERBI_CLIENT_ID`, and `POWERBI_CLIENT_SECRET` are correct - Check that the client secret hasn't expired in Azure AD - Ensure the service principal is enabled in PowerBI Admin Portal ### Permission Errors **Error: "403 Forbidden" or "Access denied"** - Verify the service principal has been granted access to the workspace - Check that the workspace role is Admin, Member, or Contributor (Viewer is not sufficient for API access) - Confirm "Service principals can use PowerBI APIs" is enabled in PowerBI Admin Portal ### Connection Issues **Server not appearing in MCP client** - Restart your MCP client after adding the configuration - Check the configuration file syntax (JSON must be valid) - For local clone, verify the absolute path is correct **Tools not working** - Ensure credentials are configured - Check the MCP client logs for detailed error messages - For Claude Code, verify `.env` file is in the current working directory ## 📚 Resources - [PowerBI REST API Reference](https://learn.microsoft.com/en-us/rest/api/power-bi/) - [Model Context Protocol](https://modelcontextprotocol.io/) - [DAX Guide](https://dax.guide/) - [Azure AD App Registration](https://learn.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) ## 💬 Feedback and Support - **Issues**: Report bugs or request features via [GitHub Issues](https://github.com/gurvinder-dhillon/powerbi-mcp/issues) - **Discussions**: Ask questions in [GitHub Discussions](https://github.com/gurvinder-dhillon/powerbi-mcp/discussions) - **Pull Requests**: Contributions welcome! See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) ## 🤝 Contributing See [DEVELOPER_GUIDE.md](DEVELOPER_GUIDE.md) for information about developing and contributing to this project. ## License This project is licensed under the MIT License.