pbi-cli-tool 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. pbi_cli_tool-0.1.0/LICENSE +21 -0
  2. pbi_cli_tool-0.1.0/PKG-INFO +244 -0
  3. pbi_cli_tool-0.1.0/README.md +206 -0
  4. pbi_cli_tool-0.1.0/pyproject.toml +76 -0
  5. pbi_cli_tool-0.1.0/setup.cfg +4 -0
  6. pbi_cli_tool-0.1.0/src/pbi_cli/__init__.py +3 -0
  7. pbi_cli_tool-0.1.0/src/pbi_cli/__main__.py +6 -0
  8. pbi_cli_tool-0.1.0/src/pbi_cli/commands/__init__.py +1 -0
  9. pbi_cli_tool-0.1.0/src/pbi_cli/commands/_helpers.py +50 -0
  10. pbi_cli_tool-0.1.0/src/pbi_cli/commands/advanced.py +135 -0
  11. pbi_cli_tool-0.1.0/src/pbi_cli/commands/calc_group.py +69 -0
  12. pbi_cli_tool-0.1.0/src/pbi_cli/commands/calendar.py +42 -0
  13. pbi_cli_tool-0.1.0/src/pbi_cli/commands/column.py +104 -0
  14. pbi_cli_tool-0.1.0/src/pbi_cli/commands/connection.py +211 -0
  15. pbi_cli_tool-0.1.0/src/pbi_cli/commands/database.py +68 -0
  16. pbi_cli_tool-0.1.0/src/pbi_cli/commands/dax.py +131 -0
  17. pbi_cli_tool-0.1.0/src/pbi_cli/commands/expression.py +64 -0
  18. pbi_cli_tool-0.1.0/src/pbi_cli/commands/hierarchy.py +56 -0
  19. pbi_cli_tool-0.1.0/src/pbi_cli/commands/measure.py +169 -0
  20. pbi_cli_tool-0.1.0/src/pbi_cli/commands/model.py +50 -0
  21. pbi_cli_tool-0.1.0/src/pbi_cli/commands/partition.py +54 -0
  22. pbi_cli_tool-0.1.0/src/pbi_cli/commands/perspective.py +38 -0
  23. pbi_cli_tool-0.1.0/src/pbi_cli/commands/relationship.py +104 -0
  24. pbi_cli_tool-0.1.0/src/pbi_cli/commands/repl_cmd.py +21 -0
  25. pbi_cli_tool-0.1.0/src/pbi_cli/commands/security.py +57 -0
  26. pbi_cli_tool-0.1.0/src/pbi_cli/commands/setup_cmd.py +75 -0
  27. pbi_cli_tool-0.1.0/src/pbi_cli/commands/skills_cmd.py +116 -0
  28. pbi_cli_tool-0.1.0/src/pbi_cli/commands/table.py +135 -0
  29. pbi_cli_tool-0.1.0/src/pbi_cli/commands/trace.py +42 -0
  30. pbi_cli_tool-0.1.0/src/pbi_cli/commands/transaction.py +42 -0
  31. pbi_cli_tool-0.1.0/src/pbi_cli/core/__init__.py +1 -0
  32. pbi_cli_tool-0.1.0/src/pbi_cli/core/binary_manager.py +247 -0
  33. pbi_cli_tool-0.1.0/src/pbi_cli/core/config.py +60 -0
  34. pbi_cli_tool-0.1.0/src/pbi_cli/core/connection_store.py +87 -0
  35. pbi_cli_tool-0.1.0/src/pbi_cli/core/errors.py +42 -0
  36. pbi_cli_tool-0.1.0/src/pbi_cli/core/mcp_client.py +252 -0
  37. pbi_cli_tool-0.1.0/src/pbi_cli/core/output.py +87 -0
  38. pbi_cli_tool-0.1.0/src/pbi_cli/main.py +94 -0
  39. pbi_cli_tool-0.1.0/src/pbi_cli/skills/__init__.py +1 -0
  40. pbi_cli_tool-0.1.0/src/pbi_cli/skills/power-bi-dax/SKILL.md +172 -0
  41. pbi_cli_tool-0.1.0/src/pbi_cli/skills/power-bi-deployment/SKILL.md +152 -0
  42. pbi_cli_tool-0.1.0/src/pbi_cli/skills/power-bi-docs/SKILL.md +148 -0
  43. pbi_cli_tool-0.1.0/src/pbi_cli/skills/power-bi-modeling/SKILL.md +128 -0
  44. pbi_cli_tool-0.1.0/src/pbi_cli/skills/power-bi-security/SKILL.md +116 -0
  45. pbi_cli_tool-0.1.0/src/pbi_cli/utils/__init__.py +1 -0
  46. pbi_cli_tool-0.1.0/src/pbi_cli/utils/platform.py +81 -0
  47. pbi_cli_tool-0.1.0/src/pbi_cli/utils/repl.py +157 -0
  48. pbi_cli_tool-0.1.0/src/pbi_cli_tool.egg-info/PKG-INFO +244 -0
  49. pbi_cli_tool-0.1.0/src/pbi_cli_tool.egg-info/SOURCES.txt +60 -0
  50. pbi_cli_tool-0.1.0/src/pbi_cli_tool.egg-info/dependency_links.txt +1 -0
  51. pbi_cli_tool-0.1.0/src/pbi_cli_tool.egg-info/entry_points.txt +2 -0
  52. pbi_cli_tool-0.1.0/src/pbi_cli_tool.egg-info/requires.txt +12 -0
  53. pbi_cli_tool-0.1.0/src/pbi_cli_tool.egg-info/top_level.txt +1 -0
  54. pbi_cli_tool-0.1.0/tests/test_binary_manager.py +92 -0
  55. pbi_cli_tool-0.1.0/tests/test_config.py +63 -0
  56. pbi_cli_tool-0.1.0/tests/test_connection_store.py +106 -0
  57. pbi_cli_tool-0.1.0/tests/test_e2e.py +50 -0
  58. pbi_cli_tool-0.1.0/tests/test_errors.py +36 -0
  59. pbi_cli_tool-0.1.0/tests/test_helpers.py +94 -0
  60. pbi_cli_tool-0.1.0/tests/test_mcp_client.py +86 -0
  61. pbi_cli_tool-0.1.0/tests/test_output.py +73 -0
  62. pbi_cli_tool-0.1.0/tests/test_platform.py +91 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 pbi-cli contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,244 @@
1
+ Metadata-Version: 2.4
2
+ Name: pbi-cli-tool
3
+ Version: 0.1.0
4
+ Summary: CLI for Power BI semantic models - wraps the Power BI MCP server for token-efficient AI agent usage
5
+ Author: pbi-cli contributors
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/MinaSaad1/pbi-cli
8
+ Project-URL: Repository, https://github.com/MinaSaad1/pbi-cli
9
+ Project-URL: Issues, https://github.com/MinaSaad1/pbi-cli/issues
10
+ Keywords: power-bi,cli,mcp,semantic-model,dax,claude-code
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Topic :: Database
22
+ Classifier: Topic :: Software Development :: Libraries
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ License-File: LICENSE
26
+ Requires-Dist: click>=8.0.0
27
+ Requires-Dist: mcp>=1.20.0
28
+ Requires-Dist: rich>=13.0.0
29
+ Requires-Dist: httpx>=0.24.0
30
+ Requires-Dist: prompt-toolkit>=3.0.0
31
+ Provides-Extra: dev
32
+ Requires-Dist: pytest>=7.0; extra == "dev"
33
+ Requires-Dist: pytest-cov>=4.0; extra == "dev"
34
+ Requires-Dist: pytest-asyncio>=0.21; extra == "dev"
35
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
36
+ Requires-Dist: mypy>=1.10; extra == "dev"
37
+ Dynamic: license-file
38
+
39
+ # pbi-cli
40
+
41
+ **Token-efficient CLI for Power BI semantic models.**
42
+
43
+ pbi-cli wraps Microsoft's Power BI MCP server so you can manage semantic models from the terminal. MCP tool schemas consume ~4,000+ tokens in an AI agent's context window; a `pbi` command uses ~30. One install, no separate MCP server configuration required.
44
+
45
+ ```
46
+ pip install pbi-cli-tool
47
+ pbi setup
48
+ pbi connect --data-source localhost:54321
49
+ pbi measure list
50
+ ```
51
+
52
+ ## Why pbi-cli?
53
+
54
+ | Approach | Context cost | Setup |
55
+ |----------|-------------|-------|
56
+ | Raw MCP server | ~4,000 tokens per tool schema | Manual config per project |
57
+ | **pbi-cli** | **~30 tokens per command** | **`pip install pbi-cli-tool`** |
58
+
59
+ Designed for Claude Code and other AI agents, but works great for humans too. Use `--json` for machine-readable output or enjoy Rich-formatted tables by default.
60
+
61
+ ## Installation
62
+
63
+ ```bash
64
+ pip install pbi-cli-tool
65
+ ```
66
+
67
+ ### Prerequisites
68
+
69
+ - Python 3.10+
70
+ - Power BI Desktop (for local development) or a Fabric workspace
71
+
72
+ ### First-time setup
73
+
74
+ Download the Power BI MCP binary:
75
+
76
+ ```bash
77
+ pbi setup
78
+ ```
79
+
80
+ This downloads the official Microsoft binary from the VS Code Marketplace to `~/.pbi-cli/bin/`. You can also point to an existing binary:
81
+
82
+ ```bash
83
+ export PBI_MCP_BINARY=/path/to/powerbi-modeling-mcp
84
+ ```
85
+
86
+ ## Quick Start
87
+
88
+ ### Connect to Power BI Desktop
89
+
90
+ ```bash
91
+ # Connect to a local Power BI Desktop instance
92
+ pbi connect --data-source localhost:54321
93
+
94
+ # Connect to a Fabric workspace model
95
+ pbi connect-fabric --workspace "My Workspace" --model "Sales Model"
96
+ ```
97
+
98
+ ### Run DAX queries
99
+
100
+ ```bash
101
+ pbi dax execute "EVALUATE TOPN(10, Sales)"
102
+ pbi dax execute --file query.dax
103
+ cat query.dax | pbi dax execute -
104
+ ```
105
+
106
+ ### Manage measures
107
+
108
+ ```bash
109
+ pbi measure list
110
+ pbi measure create "Total Revenue" --expression "SUM(Sales[Revenue])" --table Sales
111
+ pbi measure get "Total Revenue" --table Sales
112
+ ```
113
+
114
+ ### Export and import models
115
+
116
+ ```bash
117
+ pbi database export-tmdl ./my-model/
118
+ pbi database import-tmdl ./my-model/
119
+ ```
120
+
121
+ ## Command Reference
122
+
123
+ | Group | Description | Examples |
124
+ |-------|-------------|---------|
125
+ | `setup` | Download and manage the MCP binary | `pbi setup`, `pbi setup --check` |
126
+ | `connect` | Connect to Power BI via data source | `pbi connect -d localhost:54321` |
127
+ | `connect-fabric` | Connect to Fabric workspace | `pbi connect-fabric -w "WS" -m "Model"` |
128
+ | `disconnect` | Disconnect from active connection | `pbi disconnect` |
129
+ | `connections` | Manage saved connections | `pbi connections list` |
130
+ | `dax` | Execute and validate DAX queries | `pbi dax execute "EVALUATE Sales"` |
131
+ | `measure` | CRUD for measures | `pbi measure list`, `pbi measure create` |
132
+ | `table` | CRUD for tables | `pbi table list`, `pbi table get Sales` |
133
+ | `column` | CRUD for columns | `pbi column list --table Sales` |
134
+ | `relationship` | Manage relationships | `pbi relationship list` |
135
+ | `model` | Model metadata and refresh | `pbi model get`, `pbi model refresh` |
136
+ | `database` | Import/export TMDL and TMSL | `pbi database export-tmdl ./out/` |
137
+ | `security-role` | Row-level security roles | `pbi security-role list` |
138
+ | `calc-group` | Calculation groups and items | `pbi calc-group list` |
139
+ | `partition` | Table partitions | `pbi partition list --table Sales` |
140
+ | `perspective` | Model perspectives | `pbi perspective list` |
141
+ | `hierarchy` | User hierarchies | `pbi hierarchy list --table Date` |
142
+ | `expression` | Named expressions | `pbi expression list` |
143
+ | `calendar` | Calendar table management | `pbi calendar list` |
144
+ | `trace` | Diagnostic traces | `pbi trace start` |
145
+ | `transaction` | Explicit transactions | `pbi transaction begin` |
146
+ | `advanced` | Cultures, translations, functions | `pbi advanced culture list` |
147
+ | `repl` | Interactive REPL session | `pbi repl` |
148
+
149
+ Run `pbi <command> --help` for full option details.
150
+
151
+ ## REPL Mode
152
+
153
+ The interactive REPL keeps the MCP server process alive across commands, avoiding the 2-3 second startup cost on each invocation:
154
+
155
+ ```
156
+ $ pbi repl
157
+ pbi-cli interactive mode. Type 'exit' or Ctrl+D to quit.
158
+ pbi> connect --data-source localhost:54321
159
+ Connected: localhost-54321 (localhost:54321)
160
+ pbi(localhost-54321)> measure list
161
+ ...
162
+ pbi(localhost-54321)> dax execute "EVALUATE Sales"
163
+ ...
164
+ pbi(localhost-54321)> exit
165
+ Goodbye.
166
+ ```
167
+
168
+ Features:
169
+ - Persistent MCP server connection (no restart between commands)
170
+ - Command history (stored at `~/.pbi-cli/repl_history`)
171
+ - Tab completion for commands and subcommands
172
+ - Dynamic prompt showing active connection name
173
+
174
+ ## For AI Agents
175
+
176
+ Use `--json` before the subcommand for machine-readable JSON output:
177
+
178
+ ```bash
179
+ pbi --json measure list
180
+ pbi --json dax execute "EVALUATE Sales"
181
+ pbi --json model get
182
+ ```
183
+
184
+ JSON output goes to stdout. Status messages go to stderr. This makes piping and parsing straightforward.
185
+
186
+ ### Named connections
187
+
188
+ Use `-c` to target a specific named connection:
189
+
190
+ ```bash
191
+ pbi -c my-conn measure list
192
+ pbi -c prod-model dax execute "EVALUATE Sales"
193
+ ```
194
+
195
+ ## Configuration
196
+
197
+ pbi-cli stores its configuration in `~/.pbi-cli/`:
198
+
199
+ ```
200
+ ~/.pbi-cli/
201
+ config.json # Binary version, path, args
202
+ connections.json # Named connections
203
+ repl_history # REPL command history
204
+ bin/
205
+ {version}/
206
+ powerbi-modeling-mcp[.exe]
207
+ ```
208
+
209
+ ### Binary resolution order
210
+
211
+ 1. `PBI_MCP_BINARY` environment variable (explicit override)
212
+ 2. `~/.pbi-cli/bin/{version}/` (managed by `pbi setup`)
213
+ 3. VS Code extension fallback (`~/.vscode/extensions/analysis-services.powerbi-modeling-mcp-*/server/`)
214
+
215
+ ## Development
216
+
217
+ ```bash
218
+ git clone https://github.com/pbi-cli/pbi-cli.git
219
+ cd pbi-cli
220
+ pip install -e ".[dev]"
221
+
222
+ # Lint
223
+ ruff check src/ tests/
224
+
225
+ # Type check
226
+ mypy src/
227
+
228
+ # Test
229
+ pytest -m "not e2e"
230
+ ```
231
+
232
+ ## Contributing
233
+
234
+ Contributions are welcome! Please open an issue first to discuss what you would like to change.
235
+
236
+ 1. Fork the repository
237
+ 2. Create a feature branch (`git checkout -b feature/my-change`)
238
+ 3. Make your changes with tests
239
+ 4. Run `ruff check` and `mypy` before submitting
240
+ 5. Open a pull request
241
+
242
+ ## License
243
+
244
+ [MIT](LICENSE)
@@ -0,0 +1,206 @@
1
+ # pbi-cli
2
+
3
+ **Token-efficient CLI for Power BI semantic models.**
4
+
5
+ pbi-cli wraps Microsoft's Power BI MCP server so you can manage semantic models from the terminal. MCP tool schemas consume ~4,000+ tokens in an AI agent's context window; a `pbi` command uses ~30. One install, no separate MCP server configuration required.
6
+
7
+ ```
8
+ pip install pbi-cli-tool
9
+ pbi setup
10
+ pbi connect --data-source localhost:54321
11
+ pbi measure list
12
+ ```
13
+
14
+ ## Why pbi-cli?
15
+
16
+ | Approach | Context cost | Setup |
17
+ |----------|-------------|-------|
18
+ | Raw MCP server | ~4,000 tokens per tool schema | Manual config per project |
19
+ | **pbi-cli** | **~30 tokens per command** | **`pip install pbi-cli-tool`** |
20
+
21
+ Designed for Claude Code and other AI agents, but works great for humans too. Use `--json` for machine-readable output or enjoy Rich-formatted tables by default.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install pbi-cli-tool
27
+ ```
28
+
29
+ ### Prerequisites
30
+
31
+ - Python 3.10+
32
+ - Power BI Desktop (for local development) or a Fabric workspace
33
+
34
+ ### First-time setup
35
+
36
+ Download the Power BI MCP binary:
37
+
38
+ ```bash
39
+ pbi setup
40
+ ```
41
+
42
+ This downloads the official Microsoft binary from the VS Code Marketplace to `~/.pbi-cli/bin/`. You can also point to an existing binary:
43
+
44
+ ```bash
45
+ export PBI_MCP_BINARY=/path/to/powerbi-modeling-mcp
46
+ ```
47
+
48
+ ## Quick Start
49
+
50
+ ### Connect to Power BI Desktop
51
+
52
+ ```bash
53
+ # Connect to a local Power BI Desktop instance
54
+ pbi connect --data-source localhost:54321
55
+
56
+ # Connect to a Fabric workspace model
57
+ pbi connect-fabric --workspace "My Workspace" --model "Sales Model"
58
+ ```
59
+
60
+ ### Run DAX queries
61
+
62
+ ```bash
63
+ pbi dax execute "EVALUATE TOPN(10, Sales)"
64
+ pbi dax execute --file query.dax
65
+ cat query.dax | pbi dax execute -
66
+ ```
67
+
68
+ ### Manage measures
69
+
70
+ ```bash
71
+ pbi measure list
72
+ pbi measure create "Total Revenue" --expression "SUM(Sales[Revenue])" --table Sales
73
+ pbi measure get "Total Revenue" --table Sales
74
+ ```
75
+
76
+ ### Export and import models
77
+
78
+ ```bash
79
+ pbi database export-tmdl ./my-model/
80
+ pbi database import-tmdl ./my-model/
81
+ ```
82
+
83
+ ## Command Reference
84
+
85
+ | Group | Description | Examples |
86
+ |-------|-------------|---------|
87
+ | `setup` | Download and manage the MCP binary | `pbi setup`, `pbi setup --check` |
88
+ | `connect` | Connect to Power BI via data source | `pbi connect -d localhost:54321` |
89
+ | `connect-fabric` | Connect to Fabric workspace | `pbi connect-fabric -w "WS" -m "Model"` |
90
+ | `disconnect` | Disconnect from active connection | `pbi disconnect` |
91
+ | `connections` | Manage saved connections | `pbi connections list` |
92
+ | `dax` | Execute and validate DAX queries | `pbi dax execute "EVALUATE Sales"` |
93
+ | `measure` | CRUD for measures | `pbi measure list`, `pbi measure create` |
94
+ | `table` | CRUD for tables | `pbi table list`, `pbi table get Sales` |
95
+ | `column` | CRUD for columns | `pbi column list --table Sales` |
96
+ | `relationship` | Manage relationships | `pbi relationship list` |
97
+ | `model` | Model metadata and refresh | `pbi model get`, `pbi model refresh` |
98
+ | `database` | Import/export TMDL and TMSL | `pbi database export-tmdl ./out/` |
99
+ | `security-role` | Row-level security roles | `pbi security-role list` |
100
+ | `calc-group` | Calculation groups and items | `pbi calc-group list` |
101
+ | `partition` | Table partitions | `pbi partition list --table Sales` |
102
+ | `perspective` | Model perspectives | `pbi perspective list` |
103
+ | `hierarchy` | User hierarchies | `pbi hierarchy list --table Date` |
104
+ | `expression` | Named expressions | `pbi expression list` |
105
+ | `calendar` | Calendar table management | `pbi calendar list` |
106
+ | `trace` | Diagnostic traces | `pbi trace start` |
107
+ | `transaction` | Explicit transactions | `pbi transaction begin` |
108
+ | `advanced` | Cultures, translations, functions | `pbi advanced culture list` |
109
+ | `repl` | Interactive REPL session | `pbi repl` |
110
+
111
+ Run `pbi <command> --help` for full option details.
112
+
113
+ ## REPL Mode
114
+
115
+ The interactive REPL keeps the MCP server process alive across commands, avoiding the 2-3 second startup cost on each invocation:
116
+
117
+ ```
118
+ $ pbi repl
119
+ pbi-cli interactive mode. Type 'exit' or Ctrl+D to quit.
120
+ pbi> connect --data-source localhost:54321
121
+ Connected: localhost-54321 (localhost:54321)
122
+ pbi(localhost-54321)> measure list
123
+ ...
124
+ pbi(localhost-54321)> dax execute "EVALUATE Sales"
125
+ ...
126
+ pbi(localhost-54321)> exit
127
+ Goodbye.
128
+ ```
129
+
130
+ Features:
131
+ - Persistent MCP server connection (no restart between commands)
132
+ - Command history (stored at `~/.pbi-cli/repl_history`)
133
+ - Tab completion for commands and subcommands
134
+ - Dynamic prompt showing active connection name
135
+
136
+ ## For AI Agents
137
+
138
+ Use `--json` before the subcommand for machine-readable JSON output:
139
+
140
+ ```bash
141
+ pbi --json measure list
142
+ pbi --json dax execute "EVALUATE Sales"
143
+ pbi --json model get
144
+ ```
145
+
146
+ JSON output goes to stdout. Status messages go to stderr. This makes piping and parsing straightforward.
147
+
148
+ ### Named connections
149
+
150
+ Use `-c` to target a specific named connection:
151
+
152
+ ```bash
153
+ pbi -c my-conn measure list
154
+ pbi -c prod-model dax execute "EVALUATE Sales"
155
+ ```
156
+
157
+ ## Configuration
158
+
159
+ pbi-cli stores its configuration in `~/.pbi-cli/`:
160
+
161
+ ```
162
+ ~/.pbi-cli/
163
+ config.json # Binary version, path, args
164
+ connections.json # Named connections
165
+ repl_history # REPL command history
166
+ bin/
167
+ {version}/
168
+ powerbi-modeling-mcp[.exe]
169
+ ```
170
+
171
+ ### Binary resolution order
172
+
173
+ 1. `PBI_MCP_BINARY` environment variable (explicit override)
174
+ 2. `~/.pbi-cli/bin/{version}/` (managed by `pbi setup`)
175
+ 3. VS Code extension fallback (`~/.vscode/extensions/analysis-services.powerbi-modeling-mcp-*/server/`)
176
+
177
+ ## Development
178
+
179
+ ```bash
180
+ git clone https://github.com/pbi-cli/pbi-cli.git
181
+ cd pbi-cli
182
+ pip install -e ".[dev]"
183
+
184
+ # Lint
185
+ ruff check src/ tests/
186
+
187
+ # Type check
188
+ mypy src/
189
+
190
+ # Test
191
+ pytest -m "not e2e"
192
+ ```
193
+
194
+ ## Contributing
195
+
196
+ Contributions are welcome! Please open an issue first to discuss what you would like to change.
197
+
198
+ 1. Fork the repository
199
+ 2. Create a feature branch (`git checkout -b feature/my-change`)
200
+ 3. Make your changes with tests
201
+ 4. Run `ruff check` and `mypy` before submitting
202
+ 5. Open a pull request
203
+
204
+ ## License
205
+
206
+ [MIT](LICENSE)
@@ -0,0 +1,76 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68.0", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pbi-cli-tool"
7
+ version = "0.1.0"
8
+ description = "CLI for Power BI semantic models - wraps the Power BI MCP server for token-efficient AI agent usage"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.10"
12
+ authors = [
13
+ {name = "pbi-cli contributors"},
14
+ ]
15
+ keywords = ["power-bi", "cli", "mcp", "semantic-model", "dax", "claude-code"]
16
+ classifiers = [
17
+ "Development Status :: 3 - Alpha",
18
+ "Environment :: Console",
19
+ "Intended Audience :: Developers",
20
+ "License :: OSI Approved :: MIT License",
21
+ "Operating System :: OS Independent",
22
+ "Programming Language :: Python :: 3",
23
+ "Programming Language :: Python :: 3.10",
24
+ "Programming Language :: Python :: 3.11",
25
+ "Programming Language :: Python :: 3.12",
26
+ "Programming Language :: Python :: 3.13",
27
+ "Topic :: Database",
28
+ "Topic :: Software Development :: Libraries",
29
+ ]
30
+ dependencies = [
31
+ "click>=8.0.0",
32
+ "mcp>=1.20.0",
33
+ "rich>=13.0.0",
34
+ "httpx>=0.24.0",
35
+ "prompt-toolkit>=3.0.0",
36
+ ]
37
+
38
+ [project.scripts]
39
+ pbi = "pbi_cli.main:cli"
40
+
41
+ [project.urls]
42
+ Homepage = "https://github.com/MinaSaad1/pbi-cli"
43
+ Repository = "https://github.com/MinaSaad1/pbi-cli"
44
+ Issues = "https://github.com/MinaSaad1/pbi-cli/issues"
45
+
46
+ [project.optional-dependencies]
47
+ dev = [
48
+ "pytest>=7.0",
49
+ "pytest-cov>=4.0",
50
+ "pytest-asyncio>=0.21",
51
+ "ruff>=0.4.0",
52
+ "mypy>=1.10",
53
+ ]
54
+
55
+ [tool.setuptools.packages.find]
56
+ where = ["src"]
57
+
58
+ [tool.setuptools.package-data]
59
+ "pbi_cli.skills" = ["**/*.md"]
60
+
61
+ [tool.ruff]
62
+ target-version = "py310"
63
+ line-length = 100
64
+
65
+ [tool.ruff.lint]
66
+ select = ["E", "F", "I", "N", "W", "UP"]
67
+
68
+ [tool.pytest.ini_options]
69
+ testpaths = ["tests"]
70
+ markers = [
71
+ "e2e: end-to-end tests requiring real Power BI binary",
72
+ ]
73
+
74
+ [tool.mypy]
75
+ python_version = "3.10"
76
+ strict = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,3 @@
1
+ """pbi-cli: CLI for Power BI semantic models via MCP server."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,6 @@
1
+ """Allow running pbi-cli as: python -m pbi_cli"""
2
+
3
+ from pbi_cli.main import cli
4
+
5
+ if __name__ == "__main__":
6
+ cli()
@@ -0,0 +1 @@
1
+ """CLI command groups for pbi-cli."""
@@ -0,0 +1,50 @@
1
+ """Shared helpers for CLI commands to reduce boilerplate."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from pbi_cli.core.errors import McpToolError
8
+ from pbi_cli.core.mcp_client import get_client
9
+ from pbi_cli.core.output import format_mcp_result, print_error
10
+ from pbi_cli.main import PbiContext
11
+
12
+
13
+ def run_tool(
14
+ ctx: PbiContext,
15
+ tool_name: str,
16
+ request: dict[str, Any],
17
+ ) -> Any:
18
+ """Execute an MCP tool call with standard error handling.
19
+
20
+ Adds connectionName from context if available. Formats output based
21
+ on --json flag. Returns the result or exits on error.
22
+
23
+ In REPL mode the shared client is reused and never stopped.
24
+ """
25
+ if ctx.connection:
26
+ request.setdefault("connectionName", ctx.connection)
27
+
28
+ client = get_client(repl_mode=ctx.repl_mode)
29
+ try:
30
+ result = client.call_tool(tool_name, request)
31
+ format_mcp_result(result, ctx.json_output)
32
+ return result
33
+ except Exception as e:
34
+ print_error(str(e))
35
+ raise McpToolError(tool_name, str(e))
36
+ finally:
37
+ if not ctx.repl_mode:
38
+ client.stop()
39
+
40
+
41
+ def build_definition(
42
+ required: dict[str, Any],
43
+ optional: dict[str, Any],
44
+ ) -> dict[str, Any]:
45
+ """Build a definition dict, including only non-None optional values."""
46
+ definition = dict(required)
47
+ for key, value in optional.items():
48
+ if value is not None:
49
+ definition[key] = value
50
+ return definition