Metadata-Version: 2.4
Name: pbi-cli-tool
Version: 2.1.0
Summary: CLI for Power BI semantic models - direct .NET connection for token-efficient AI agent usage
Author: pbi-cli contributors
License: MIT
Project-URL: Homepage, https://github.com/MinaSaad1/pbi-cli
Project-URL: Repository, https://github.com/MinaSaad1/pbi-cli
Project-URL: Issues, https://github.com/MinaSaad1/pbi-cli/issues
Keywords: power-bi,cli,semantic-model,dax,claude-code,tom
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Database
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: click>=8.0.0
Requires-Dist: rich>=13.0.0
Requires-Dist: prompt-toolkit>=3.0.0
Requires-Dist: pythonnet==3.1.0rc0
Requires-Dist: clr-loader>=0.2.6
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.4.0; extra == "dev"
Requires-Dist: mypy>=1.10; extra == "dev"
Dynamic: license-file

<img src="https://raw.githubusercontent.com/MinaSaad1/pbi-cli/master/assets/header.svg" alt="pbi-cli" width="800"/>

**Give Claude Code the Power BI skills it needs.**
Install once, then just ask Claude to work with your semantic models.

<a href="https://pypi.org/project/pbi-cli-tool/"><img src="https://img.shields.io/pypi/pyversions/pbi-cli-tool?style=flat-square&color=3776ab&label=Python" alt="Python"></a>
<a href="https://github.com/MinaSaad1/pbi-cli/actions"><img src="https://img.shields.io/github/actions/workflow/status/MinaSaad1/pbi-cli/ci.yml?branch=master&style=flat-square&label=CI" alt="CI"></a>
<a href="https://github.com/MinaSaad1/pbi-cli/blob/master/LICENSE"><img src="https://img.shields.io/github/license/MinaSaad1/pbi-cli?style=flat-square&color=06d6a0" alt="License"></a>

[Get Started](#get-started) &bull; [Skills](#skills) &bull; [All Commands](#all-commands) &bull; [REPL Mode](#repl-mode) &bull; [Contributing](#contributing)

---

## What is this?

pbi-cli gives **Claude Code** (and other AI agents) the ability to manage Power BI semantic models. It ships with 7 skills that Claude discovers automatically. You ask in plain English, Claude uses the right `pbi` commands.

```
You                        Claude Code              pbi-cli              Power BI
 "Add a YTD measure   --->  Uses Power BI    --->   CLI commands   --->  Desktop
  to the Sales table"       skills
```

---

## Get Started

**Fastest way:** Just give Claude the repo URL and let it handle everything:

```
Install and set up pbi-cli from https://github.com/MinaSaad1/pbi-cli.git
```

**Or install manually (two commands):**

```bash
pipx install pbi-cli-tool    # 1. Install (handles PATH automatically)
pbi connect                  # 2. Auto-detects Power BI Desktop and installs skills
```

That's it. Open Power BI Desktop with a `.pbix` file, run `pbi connect`, and everything is set up automatically. Open Claude Code and start asking.

You can also specify the port manually: `pbi connect -d localhost:54321`

> **Requires:** Windows with Python 3.10+ and Power BI Desktop running.

<details>
<summary><b>Using pip instead of pipx?</b></summary>

```bash
pip install pbi-cli-tool
```

On Windows, `pip install` often places the `pbi` command in a directory that isn't on your PATH.

**Fix: Add the Scripts directory to PATH**

Find the directory:
```bash
python -c "import site; print(site.getusersitepackages().replace('site-packages','Scripts'))"
```

Add the printed path to your system PATH:
```cmd
setx PATH "%PATH%;C:\Users\YourName\AppData\Roaming\Python\PythonXXX\Scripts"
```

Then **restart your terminal**. We recommend `pipx` instead to avoid this entirely.

</details>

---

## Skills

After running `pbi connect`, Claude Code discovers **7 Power BI skills**. Each skill teaches Claude a different area of Power BI development. You don't need to memorize commands. Just describe what you want.

```
You: "Set up RLS for regional managers"
  |
  v
Claude Code --> Picks the right skill
                  |
                  +-- Modeling
                  +-- DAX
                  +-- Deployment
                  +-- Security
                  +-- Documentation
                  +-- Diagnostics
                  +-- Partitions
```

### Modeling

> *"Create a star schema with Sales, Products, and Calendar tables"*

Claude creates the tables, sets up relationships, marks the date table, and adds formatted measures. Covers tables, columns, measures, relationships, hierarchies, and calculation groups.

<details>
<summary>Example: what Claude runs behind the scenes</summary>

```bash
pbi table create Sales --mode Import
pbi table create Products --mode Import
pbi table create Calendar --mode Import
pbi relationship create --from-table Sales --from-column ProductKey --to-table Products --to-column ProductKey
pbi relationship create --from-table Sales --from-column DateKey --to-table Calendar --to-column DateKey
pbi table mark-date Calendar --date-column Date
pbi measure create "Total Revenue" -e "SUM(Sales[Revenue])" -t Sales --format-string "$#,##0"
```
</details>

### DAX

> *"What are the top 10 products by revenue this year?"*

Claude writes and executes DAX queries, validates syntax, and creates measures with time intelligence patterns like YTD, previous year, and rolling averages.

<details>
<summary>Example: what Claude runs behind the scenes</summary>

```bash
pbi dax execute "
EVALUATE
TOPN(
    10,
    ADDCOLUMNS(VALUES(Products[Name]), \"Revenue\", CALCULATE(SUM(Sales[Amount]))),
    [Revenue], DESC
)
"
```
</details>

### Deployment

> *"Export the model to Git for version control"*

Claude exports your model as TMDL files for version control and imports them back. Handles transactions for safe multi-step changes.

<details>
<summary>Example: what Claude runs behind the scenes</summary>

```bash
pbi database export-tmdl ./model/
# ... you commit to git ...
pbi database import-tmdl ./model/
```
</details>

### Security

> *"Set up row-level security so regional managers only see their region"*

Claude creates RLS roles with descriptions, sets up perspectives for different user groups, and exports the model for version control.

<details>
<summary>Example: what Claude runs behind the scenes</summary>

```bash
pbi security-role create "Regional Manager" --description "Users see only their region's data"
pbi perspective create "Executive Dashboard"
pbi perspective create "Regional Detail"
pbi database export-tmdl ./model-backup/
```
</details>

### Documentation

> *"Document everything in this model"*

Claude catalogs every table, measure, column, and relationship. Generates data dictionaries, measure inventories, and can export the full model as TMDL for human-readable reference.

<details>
<summary>Example: what Claude runs behind the scenes</summary>

```bash
pbi --json model get
pbi --json model stats
pbi --json table list
pbi --json measure list
pbi --json relationship list
pbi database export-tmdl ./model-docs/
```
</details>

### Diagnostics

> *"Why is this DAX query so slow?"*

Claude traces query execution, clears caches for clean benchmarks, checks model health, and verifies the environment.

<details>
<summary>Example: what Claude runs behind the scenes</summary>

```bash
pbi dax clear-cache
pbi trace start
pbi dax execute "EVALUATE SUMMARIZECOLUMNS(...)" --timeout 300
pbi trace stop
pbi trace export ./trace.json
```
</details>

### Partitions & Expressions

> *"Set up partitions for incremental refresh on the Sales table"*

Claude manages table partitions, shared M/Power Query expressions, and calendar table configuration.

<details>
<summary>Example: what Claude runs behind the scenes</summary>

```bash
pbi partition list --table Sales
pbi partition create "Sales_2024" --table Sales --expression "..." --mode Import
pbi expression create "ServerURL" --expression '"https://api.example.com"'
pbi calendar mark Calendar --date-column Date
```
</details>

---

## All Commands

22 command groups covering the full Power BI Tabular Object Model. You rarely need these directly when using Claude Code, but they're available for scripting, CI/CD, or manual use.

| Category | Commands |
|----------|----------|
| **Queries** | `dax execute`, `dax validate`, `dax clear-cache` |
| **Model** | `table`, `column`, `measure`, `relationship`, `hierarchy`, `calc-group` |
| **Deploy** | `database export-tmdl`, `database import-tmdl`, `database export-tmsl`, `transaction` |
| **Security** | `security-role`, `perspective` |
| **Connect** | `connect`, `disconnect`, `connections list`, `connections last` |
| **Data** | `partition`, `expression`, `calendar`, `advanced culture` |
| **Diagnostics** | `trace start`, `trace stop`, `trace fetch`, `trace export`, `model stats` |
| **Tools** | `setup`, `repl`, `skills install`, `skills list` |

Use `--json` for machine-readable output (for scripts and AI agents):

```bash
pbi --json measure list
pbi --json dax execute "EVALUATE Sales"
```

Run `pbi <command> --help` for full options.

---

## REPL Mode

For interactive work, the REPL keeps a persistent connection alive between commands:

```
$ pbi repl

pbi> connect --data-source localhost:54321
Connected: localhost-54321

pbi(localhost-54321)> measure list
pbi(localhost-54321)> dax execute "EVALUATE TOPN(5, Sales)"
pbi(localhost-54321)> exit
```

Tab completion, command history, and a dynamic prompt showing your active connection.

---

## How It Works

pbi-cli connects directly to Power BI Desktop's Analysis Services engine via pythonnet and the .NET Tabular Object Model (TOM). No external binaries or MCP servers needed. Everything runs in-process for sub-second command execution.

```
+------------------+         +---------------------+         +------------------+
|     pbi-cli      |         |   Bundled TOM DLLs  |         |    Power BI      |
|   (Python CLI)   | pythnet |  (.NET in-process)  |  XMLA   |     Desktop      |
|  Click commands  |-------->|  TOM / ADOMD.NET    |-------->|   msmdsrv.exe    |
+------------------+         +---------------------+         +------------------+
```

**Why a CLI?** When an AI agent uses an MCP server directly, the tool schemas consume ~4,000+ tokens per tool in the context window. A `pbi` command costs ~30 tokens. Same capabilities, 100x less context.

<details>
<summary><b>Configuration details</b></summary>

All config lives in `~/.pbi-cli/`:

```
~/.pbi-cli/
  config.json          # Default connection preference
  connections.json     # Named connections
  repl_history         # REPL command history
```

Bundled DLLs ship inside the Python package (`pbi_cli/dlls/`):
- Microsoft.AnalysisServices.Tabular.dll
- Microsoft.AnalysisServices.AdomdClient.dll
- Microsoft.AnalysisServices.Core.dll
- Microsoft.AnalysisServices.Tabular.Json.dll
- Microsoft.AnalysisServices.dll

</details>

---

## Development

```bash
git clone https://github.com/MinaSaad1/pbi-cli.git
cd pbi-cli
pip install -e ".[dev]"
```

```bash
ruff check src/ tests/         # Lint
mypy src/                      # Type check
pytest -m "not e2e"            # Run tests
```

---

## Contributing

Contributions are welcome! Please open an issue first to discuss what you'd like to change.

1. Fork the repository
2. Create a feature branch
3. Make your changes with tests
4. Open a pull request

---

<p align="center">
  <a href="https://github.com/MinaSaad1/pbi-cli"><img src="https://img.shields.io/badge/GitHub-pbi--cli-1a1a2e?style=flat-square&logo=github" alt="GitHub"></a>
  <a href="https://pypi.org/project/pbi-cli-tool/"><img src="https://img.shields.io/badge/PyPI-pbi--cli--tool-f2c811?style=flat-square&logo=pypi&logoColor=white" alt="PyPI"></a>
</p>

<p align="center">
  <sub>MIT License</sub>
</p>
