PowerBI MCP Server
# PowerBI MCP Server
[](https://pypi.org/project/powerbi-mcp/)
[](https://pypi.org/project/powerbi-mcp/)
[](https://opensource.org/licenses/MIT)
<!-- mcp-name: io.github.gurvinder-dhillon/powerbi-mcp -->
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.
TDQS
Scored across 7 tools
Each tool has a clearly distinct purpose: singular vs list retrieval for datasets, separate tools for parameters, refresh history, reports, workspaces, and querying. No overlaps.
All tools follow a consistent verb_noun pattern, e.g., get_dataset, get_datasets, get_parameters. query_dataset uses 'query' instead of 'get' but still matches the pattern, maintaining overall consistency.
With 7 tools covering dataset, report, workspace, parameter, refresh history, and query operations, the count is well-scoped for a focused PowerBI data retrieval server.
The server covers read operations comprehensively (list, get, query) but lacks any write capabilities (e.g., create, update, delete, refresh). This is a notable gap for full lifecycle management, though it may be sufficient for a read-only analysis tool.