Power BI China(21V) MCP server & skill
中文文档
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:
npx skills add edwindigital/powerbi-cn-skill
To install only this Skill for GitHub Copilot at user level:
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:
npx skills add edwindigital/powerbi-cn-skill --list --full-depth
For project-level installation instead of user-level installation, omit --global:
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 |
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:
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:
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:
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, notuvicorn[standard], because the optionalhttptoolspackage can require native C++ build tools on Windows ARM64.
MCP endpoint:
http://127.0.0.1:8000/mcp
Health endpoint:
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:
https://analysis.chinacloudapi.cn/powerbi/api/.default
The tested Azure CLI resource value is the same scope without /.default:
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:
{
"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:
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:
$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:
$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:
https://app.powerbi.cn/groups/cffe917f-edfa-4b01-a351-3db7ab182e28/reports/21967728-b944-4786-8f8f-76af50991b45/ReportSection
Tests
$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.