Skip to main content
Glama
EdwinDigital

Power BI China (21V) MCP Server

by EdwinDigital
README.md
# Power BI China(21V) MCP server & skill

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![skills.sh](https://skills.sh/b/edwindigital/powerbi-cn-skill)](https://skills.sh/edwindigital/powerbi-cn-skill)

[中文文档](README-CN.md)

This project implements a standalone remote HTTP MCP server for read-only analysis against Power BI China (`app.powerbi.cn`) through the China REST API (`https://api.powerbi.cn/`).

The server focuses on delegated user access, report discovery, report URL resolution, report metadata, semantic model schema discovery, and read-only DAX query execution.

## Skill

The companion agent skill lives at `skills/powerbi-cn-skill/SKILL.md`. It mirrors the Global FabricIQ and semantic-model-consumption workflow, but routes `app.powerbi.cn` artifacts to this China cloud MCP server and preserves the public API metadata limitations documented in the design plan.

### Install with skills.sh

The public GitHub repository is installable through the standard skills.sh CLI:

```powershell
npx skills add edwindigital/powerbi-cn-skill
```

To install only this Skill for GitHub Copilot at user level:

```powershell
npx skills add edwindigital/powerbi-cn-skill --skill powerbi-cn-skill --agent github-copilot --global --full-depth
```

To inspect the skills detected in the repository before installing:

```powershell
npx skills add edwindigital/powerbi-cn-skill --list --full-depth
```

For project-level installation instead of user-level installation, omit `--global`:

```powershell
npx skills add edwindigital/powerbi-cn-skill --skill powerbi-cn-skill --agent github-copilot --full-depth
```

skills.sh indexes public GitHub repositories automatically after they are installed through `npx skills add <owner/repo>`. This repository keeps the publishable Skill definition at `skills/powerbi-cn-skill/SKILL.md` and uses `skills.sh.json` to describe the repository page grouping.

## Tools

| Tool | Purpose |
|---|---|
| `list_reports` | List reports visible to the caller in a workspace, personal workspace, or accessible workspaces. |
| `resolve_report_from_url` | Parse `https://app.powerbi.cn/groups/{workspaceId|me}/reports/{reportId}` URLs. |
| `get_report_metadata` | Return report identity, dataset ID, pages, and unsupported metadata warnings. |
| `get_semantic_model_schema` | Retrieve semantic model tables, columns, measures, and relationships with DAX `INFO.VIEW.*` queries when available. |
| `execute_dax_query` | Execute a single read-only `EVALUATE` DAX query with row caps. |

## Run Locally

Clone the public GitHub repository, then install the package in editable mode:

```powershell
git clone https://github.com/EdwinDigital/powerbi-cn-skill.git
cd powerbi-cn-skill
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e .
```

If you already have the repository open locally, run the install commands from the repository root:

```powershell
python -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e .
```

For local VS Code MCP testing, use Azure CLI token acquisition inside the server:

```powershell
az cloud set --name AzureChinaCloud
az login --use-device-code
$env:AUTH_MODE = "azure_cli"
$env:AZURE_CLI_PATH = "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd"
powerbi-cn-mcp --host 127.0.0.1 --port 8000
```

`AZURE_CLI_PATH` is optional when `az` is discoverable on `PATH`; set it explicitly on Windows if the server reports that Azure CLI is not available.

For production or shared deployments, keep the default `AUTH_MODE=delegated` and require the MCP client or gateway to send an `Authorization: Bearer <Power BI China token>` header on protected tool calls.

> Note: The project depends on plain `uvicorn`, not `uvicorn[standard]`, because the optional `httptools` package can require native C++ build tools on Windows ARM64.

MCP endpoint:

```text
http://127.0.0.1:8000/mcp
```

Health endpoint:

```text
http://127.0.0.1:8000/healthz
```

## Authentication

The default mode is delegated user token pass-through. MCP clients should send an `Authorization: Bearer <token>` header for Power BI China with this scope:

```text
https://analysis.chinacloudapi.cn/powerbi/api/.default
```

The tested Azure CLI resource value is the same scope without `/.default`:

```powershell
az cloud set --name AzureChinaCloud
az login --use-device-code
az account get-access-token --resource https://analysis.chinacloudapi.cn/powerbi/api
```

Tokens are used only in memory and are forwarded to `https://api.powerbi.cn/`. Do not paste access tokens into chat or write them to disk.

### Auth Modes

| Mode | Use case | Behavior |
|---|---|---|
| `delegated` | Production/shared service default | Requires `Authorization: Bearer <token>` from the MCP client or gateway. |
| `azure_cli` | Local development in VS Code | If no Authorization header is present, runs `az account get-access-token --resource https://analysis.chinacloudapi.cn/powerbi/api` and uses that delegated token in memory. |
| `mixed` | Transitional local testing | Uses the Authorization header when present, otherwise falls back to Azure CLI token acquisition. |

## Configuration

| Variable | Default | Purpose |
|---|---|---|
| `POWERBI_CN_API_ROOT` | `https://api.powerbi.cn/` | Power BI China REST API root. |
| `POWERBI_CN_AUTHORITY` | `https://login.chinacloudapi.cn/organizations/` | China cloud authority. |
| `POWERBI_CN_SCOPE` | `https://analysis.chinacloudapi.cn/powerbi/api/.default` | Token scope. |
| `AUTH_MODE` | `delegated` | `delegated`, `azure_cli`, `mixed`, or reserved `service_principal`. |
| `AZURE_CLI_PATH` | `az` | Azure CLI executable used by `AUTH_MODE=azure_cli`, for example `C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd`. |
| `ENABLE_SERVICE_PRINCIPAL` | `false` | Reserved service principal opt-in. |
| `ALLOWED_WORKSPACES` | empty | Optional comma-separated workspace allowlist. |
| `ENABLE_PREVIEW_REPORT_METADATA` | `false` | Reserved preview metadata adapter flag. |
| `MAX_QUERY_ROWS` | `1000` | Query result cap. |
| `LOG_LEVEL` | `info` | Logging verbosity. |

## VS Code MCP Registration

For local development, start the server with `AUTH_MODE=azure_cli`, then register it as an HTTP MCP endpoint:

```json
{
  "servers": {
    "powerbi-cn-mcp": {
      "type": "http",
      "url": "http://127.0.0.1:8000/mcp"
    }
  }
}
```

If the server runs in the default `delegated` mode, the MCP client or an API gateway must attach the Power BI China bearer token to protected requests. `resolve_report_from_url` does not require authentication; `list_reports`, `get_report_metadata`, `get_semantic_model_schema`, and `execute_dax_query` do.

With `AUTH_MODE=azure_cli`, protected tools can be called without an Authorization header because the server obtains the delegated token from Azure CLI in memory.

## Verified Local Auth Flow

The following flow was validated against the test report below:

```powershell
az cloud set --name AzureChinaCloud
az login --use-device-code
$token = az account get-access-token --resource https://analysis.chinacloudapi.cn/powerbi/api --query accessToken --output tsv
```

Then call a protected MCP tool with that token:

```powershell
$headers = @{ Authorization = "Bearer $token" }
$payload = @{
  jsonrpc = "2.0"
  id = 1
  method = "tools/call"
  params = @{
    name = "get_report_metadata"
    arguments = @{
      workspaceId = "cffe917f-edfa-4b01-a351-3db7ab182e28"
      reportId = "21967728-b944-4786-8f8f-76af50991b45"
    }
  }
} | ConvertTo-Json -Depth 20

Invoke-RestMethod -Method Post -Uri http://127.0.0.1:8000/mcp -Headers $headers -ContentType "application/json" -Body $payload
```

The verified report metadata response included report `PBICopilotDemo-CN`, dataset `bfe23b67-046a-419b-a96c-08a20c0614d6`, and pages `Sales Comparison and Ranking` and `New Stores Tracking`.

The same protected call was also verified without an Authorization header after starting the server with:

```powershell
$env:AUTH_MODE = "azure_cli"
$env:AZURE_CLI_PATH = "C:\Program Files\Microsoft SDKs\Azure\CLI2\wbin\az.cmd"
```

## Test Report URL

The parser tests include this China cloud report URL:

```text
https://app.powerbi.cn/groups/cffe917f-edfa-4b01-a351-3db7ab182e28/reports/21967728-b944-4786-8f8f-76af50991b45/ReportSection
```

## Tests

```powershell
$env:PYTHONPATH = "src"
.\.venv\Scripts\python.exe -m unittest discover -s tests\unit -p "test_*.py"
```

## License

This project is licensed under the MIT License. See `LICENSE` for details.