datasecops-cli 0.4.9__tar.gz → 0.5.2__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.
- datasecops_cli-0.5.2/.github/workflows/test.yml +28 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/CHANGELOG.md +49 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/PKG-INFO +55 -5
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/README.md +54 -4
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/docs/getting-started.md +18 -15
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/docs/git-operations.md +7 -4
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/docs/mcp-server.md +49 -9
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/mcp-servers.json +10 -2
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/pyproject.toml +1 -1
- datasecops_cli-0.5.2/src/datasecops_cli/__init__.py +1 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/config.py +7 -1
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/main.py +54 -41
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/menus/configuration.py +16 -51
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/menus/development.py +24 -3
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/menus/downloads.py +20 -53
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/menus/git_operations.py +14 -7
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/models/project_config.py +15 -2
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/linting_service.py +29 -1
- datasecops_cli-0.5.2/src/datasecops_cli/utilities/mcp.py +74 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_mcp/connection.py +19 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_mcp/server.py +109 -5
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/tests/test_models.py +1 -2
- datasecops_cli-0.4.9/src/datasecops_cli/__init__.py +0 -1
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/.github/workflows/auto-tag.yml +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/.github/workflows/publish-cli.yml +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/.gitignore +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/DEVELOPMENT.md +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/LICENSE +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/docs/legacy.md +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/docs/legacy_plan_of_action.md +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/setup.ps1 +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/setup.sh +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/menus/__init__.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/models/__init__.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/models/git_helpers.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/__init__.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/bootstrap_service.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/dbt_project_generator.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/dbt_runner.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/directory_scaffolder.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/download_service.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/git_service.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/skill_service.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/snowflake_service.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/services/upstream_service.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/utilities/__init__.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/utilities/display.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/utilities/file_utils.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_cli/utilities/yaml_utils.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_mcp/__init__.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/src/datasecops_mcp/__main__.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/tests/__init__.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/tests/test_config.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/tests/test_file_utils.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/tests/test_main.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/tests/test_version.py +0 -0
- {datasecops_cli-0.4.9 → datasecops_cli-0.5.2}/tests/test_yaml_utils.py +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [main]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
test:
|
|
9
|
+
name: Test (Python ${{ matrix.python-version }})
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
strategy:
|
|
12
|
+
matrix:
|
|
13
|
+
python-version: ['3.11', '3.12', '3.13']
|
|
14
|
+
|
|
15
|
+
steps:
|
|
16
|
+
- name: Checkout repository
|
|
17
|
+
uses: actions/checkout@v4
|
|
18
|
+
|
|
19
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
20
|
+
uses: actions/setup-python@v5
|
|
21
|
+
with:
|
|
22
|
+
python-version: ${{ matrix.python-version }}
|
|
23
|
+
|
|
24
|
+
- name: Install package with test dependencies
|
|
25
|
+
run: pip install -e ".[test]"
|
|
26
|
+
|
|
27
|
+
- name: Run tests
|
|
28
|
+
run: pytest --tb=short
|
|
@@ -2,6 +2,55 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to the DataSecOps CLI are documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.5.2] - 2026-06-05
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **`get_sqlfluff_config` MCP tool** — exposes the rendered `.sqlfluff` INI config file from the native app, allowing AI tools to retrieve the exact linting configuration without needing a local `.sqlfluff` file.
|
|
10
|
+
- **`get_documentation` MCP tool** — exposes framework documentation topics (model development, data governance, deployment, etc.) so AI tools can reference framework conventions directly.
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- **Cortex Code MCP config is now project-level** — MCP server registration for Cortex Code now writes `.snowflake/cortex/mcp.json` in the project root instead of calling `cortex mcp add`. This enables project-scoped MCP servers in Cortex Code Desktop and removes the dependency on the `cortex` binary being installed.
|
|
15
|
+
- **All MCP servers included in Cortex Code config** — the datasecops-framework, GitHub, Azure DevOps, and dbt MCP servers are all written to the project-level config file with `"type": "stdio"` field.
|
|
16
|
+
- **Cortex Code always available as an AI tool option** — removed the `shutil.which("cortex")` check since we no longer need the cortex binary for MCP configuration.
|
|
17
|
+
- **Expanded `_ALLOWED_PROCEDURES`** — added `get_sqlfluff_config_file` and `get_documentation` to the MCP connection allowlist.
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- **Linting now installs dbt-snowflake at framework-pinned version** — the CLI lint menu fetches both SQLFluff and dbt requirements from the native app and ensures all packages (including `dbt-core` and `dbt-snowflake`) are installed at the correct versions before linting.
|
|
22
|
+
- **Linting runs `dbt deps` if packages are missing** — if `packages.yml` exists but `dbt_packages/` is empty, `dbt deps` is run automatically before linting to satisfy the sqlfluff dbt templater.
|
|
23
|
+
- **Default `.sqlfluffignore` created on first lint** — excludes `target/`, `dbt_packages/`, `dbt_modules/`, `logs/`, `macros/`, `models/cortex/agents`, `models/cortex/semantic_views`, `objects/stages/config/`, and `objects/file_formats/config/`.
|
|
24
|
+
- **MCP linting tools check for dbt-snowflake** — the MCP server lint/fix tools now verify `dbt-snowflake` is installed (and install it if missing) before running SQLFluff.
|
|
25
|
+
|
|
26
|
+
## [0.5.1] - 2026-06-04
|
|
27
|
+
|
|
28
|
+
### Added
|
|
29
|
+
|
|
30
|
+
- **MCP server CLI arguments** — `datasecops-mcp` now accepts `--connection-name` and `--app-database` arguments, eliminating the dependency on `.datasecops.yml` being in the working directory. This fixes connection failures when AI tools (Cortex Code, Cursor, etc.) launch the MCP server from a different working directory.
|
|
31
|
+
- **`init_snowflake_service()` function** — new public API in `datasecops_mcp.connection` to pre-initialize the Snowflake service singleton with explicit parameters.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **MCP registration passes connection details** — all CLI paths that register the MCP server (setup, configuration menu, downloads menu) now pass `--connection-name` and `--app-database` to the registration command and `mcp.json` args.
|
|
36
|
+
- **`DownloadsMenu` accepts `datasecops_config`** — the downloads menu now receives the `DatasecopsConfig` so it can pass connection details during MCP server registration.
|
|
37
|
+
|
|
38
|
+
## [0.5.0] - 2026-05-21
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- **Work Items MCP tool** — new `get_work_items_config` tool in the MCP server returns the configured ticket system (Azure DevOps, Jira, or GitHub Issues), whether ticket numbers are required, and system-specific connection details. Used by the `new-branch` skill.
|
|
43
|
+
- **WorkItems model** — new `WorkItems` model in `project_config.py` stores ticket system configuration separately from source control.
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- **`ticket_number_required` moved from Source Control to Work Items** — the ticket requirement is now part of the WORK_ITEMS configuration (separate from SOURCE_CONTROL). The `get_branching_rules` MCP tool no longer includes this field; use `get_work_items_config` instead.
|
|
48
|
+
- **Branch format default updated** — default branch format changed from `{branch_type}/{branch_name}` to `{branch_type}/{ticket_name}_{name}` with explicit placeholders for ticket and description.
|
|
49
|
+
- **Branch creation uses `str.replace()` instead of `str.format()`** — supports the new `{ticket_name}` and `{name}` placeholders in branch format without breaking on missing keys.
|
|
50
|
+
- **`validate_branch_name` reads ticket requirement from WORK_ITEMS** — the MCP validation tool now queries the WORK_ITEMS config for `ticket_number_required` instead of SOURCE_CONTROL.
|
|
51
|
+
- **Config class loads WORK_ITEMS** — `Config.load_from_native_app()` now also fetches the WORK_ITEMS configuration.
|
|
52
|
+
- **Git operations menu accepts work_items** — `GitOperationsMenu` now receives `WorkItems` to determine ticket enforcement during branch creation.
|
|
53
|
+
|
|
5
54
|
## [0.4.9] - 2026-05-21
|
|
6
55
|
|
|
7
56
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datasecops-cli
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.2
|
|
4
4
|
Summary: DataSecOps Framework CLI for Snowflake Native App
|
|
5
5
|
License-Expression: MIT
|
|
6
6
|
License-File: LICENSE
|
|
@@ -158,10 +158,60 @@ The package includes an MCP (Model Context Protocol) server that exposes your fr
|
|
|
158
158
|
|
|
159
159
|
### Setup for AI Tools
|
|
160
160
|
|
|
161
|
-
**Cortex Code
|
|
161
|
+
**Cortex Code** — add to `.snowflake/cortex/mcp.json` in your project root:
|
|
162
162
|
|
|
163
|
-
```
|
|
164
|
-
|
|
163
|
+
```json
|
|
164
|
+
{
|
|
165
|
+
"mcpServers": {
|
|
166
|
+
"datasecops-framework": {
|
|
167
|
+
"type": "stdio",
|
|
168
|
+
"command": "datasecops-mcp",
|
|
169
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
170
|
+
},
|
|
171
|
+
"github": {
|
|
172
|
+
"type": "stdio",
|
|
173
|
+
"command": "npx",
|
|
174
|
+
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
175
|
+
"env": {
|
|
176
|
+
"GITHUB_PERSONAL_ACCESS_TOKEN": "<your-github-pat>"
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
"dbt": {
|
|
180
|
+
"type": "stdio",
|
|
181
|
+
"command": "uvx",
|
|
182
|
+
"args": ["dbt-mcp"]
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
For Azure DevOps instead of GitHub:
|
|
189
|
+
|
|
190
|
+
```json
|
|
191
|
+
{
|
|
192
|
+
"mcpServers": {
|
|
193
|
+
"datasecops-framework": {
|
|
194
|
+
"type": "stdio",
|
|
195
|
+
"command": "datasecops-mcp",
|
|
196
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
197
|
+
},
|
|
198
|
+
"azure-devops": {
|
|
199
|
+
"type": "stdio",
|
|
200
|
+
"command": "npx",
|
|
201
|
+
"args": ["-y", "@tiberriver256/mcp-server-azure-devops"],
|
|
202
|
+
"env": {
|
|
203
|
+
"AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/<your-org>",
|
|
204
|
+
"AZURE_DEVOPS_AUTH_METHOD": "pat",
|
|
205
|
+
"AZURE_DEVOPS_PAT": "<your-azure-pat>"
|
|
206
|
+
}
|
|
207
|
+
},
|
|
208
|
+
"dbt": {
|
|
209
|
+
"type": "stdio",
|
|
210
|
+
"command": "uvx",
|
|
211
|
+
"args": ["dbt-mcp"]
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
165
215
|
```
|
|
166
216
|
|
|
167
217
|
**VS Code / Cursor** — add to `.vscode/mcp.json` or `.cursor/mcp.json`:
|
|
@@ -171,7 +221,7 @@ cortex mcp add datasecops-framework -- datasecops-mcp
|
|
|
171
221
|
"mcpServers": {
|
|
172
222
|
"datasecops-framework": {
|
|
173
223
|
"command": "datasecops-mcp",
|
|
174
|
-
"args": []
|
|
224
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
175
225
|
}
|
|
176
226
|
}
|
|
177
227
|
}
|
|
@@ -139,10 +139,60 @@ The package includes an MCP (Model Context Protocol) server that exposes your fr
|
|
|
139
139
|
|
|
140
140
|
### Setup for AI Tools
|
|
141
141
|
|
|
142
|
-
**Cortex Code
|
|
142
|
+
**Cortex Code** — add to `.snowflake/cortex/mcp.json` in your project root:
|
|
143
143
|
|
|
144
|
-
```
|
|
145
|
-
|
|
144
|
+
```json
|
|
145
|
+
{
|
|
146
|
+
"mcpServers": {
|
|
147
|
+
"datasecops-framework": {
|
|
148
|
+
"type": "stdio",
|
|
149
|
+
"command": "datasecops-mcp",
|
|
150
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
151
|
+
},
|
|
152
|
+
"github": {
|
|
153
|
+
"type": "stdio",
|
|
154
|
+
"command": "npx",
|
|
155
|
+
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
156
|
+
"env": {
|
|
157
|
+
"GITHUB_PERSONAL_ACCESS_TOKEN": "<your-github-pat>"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"dbt": {
|
|
161
|
+
"type": "stdio",
|
|
162
|
+
"command": "uvx",
|
|
163
|
+
"args": ["dbt-mcp"]
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
For Azure DevOps instead of GitHub:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"mcpServers": {
|
|
174
|
+
"datasecops-framework": {
|
|
175
|
+
"type": "stdio",
|
|
176
|
+
"command": "datasecops-mcp",
|
|
177
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
178
|
+
},
|
|
179
|
+
"azure-devops": {
|
|
180
|
+
"type": "stdio",
|
|
181
|
+
"command": "npx",
|
|
182
|
+
"args": ["-y", "@tiberriver256/mcp-server-azure-devops"],
|
|
183
|
+
"env": {
|
|
184
|
+
"AZURE_DEVOPS_ORG_URL": "https://dev.azure.com/<your-org>",
|
|
185
|
+
"AZURE_DEVOPS_AUTH_METHOD": "pat",
|
|
186
|
+
"AZURE_DEVOPS_PAT": "<your-azure-pat>"
|
|
187
|
+
}
|
|
188
|
+
},
|
|
189
|
+
"dbt": {
|
|
190
|
+
"type": "stdio",
|
|
191
|
+
"command": "uvx",
|
|
192
|
+
"args": ["dbt-mcp"]
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
146
196
|
```
|
|
147
197
|
|
|
148
198
|
**VS Code / Cursor** — add to `.vscode/mcp.json` or `.cursor/mcp.json`:
|
|
@@ -152,7 +202,7 @@ cortex mcp add datasecops-framework -- datasecops-mcp
|
|
|
152
202
|
"mcpServers": {
|
|
153
203
|
"datasecops-framework": {
|
|
154
204
|
"command": "datasecops-mcp",
|
|
155
|
-
"args": []
|
|
205
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
156
206
|
}
|
|
157
207
|
}
|
|
158
208
|
}
|
|
@@ -156,7 +156,7 @@ Create `.vscode/mcp.json` in your project root:
|
|
|
156
156
|
"mcpServers": {
|
|
157
157
|
"datasecops-framework": {
|
|
158
158
|
"command": "datasecops-mcp",
|
|
159
|
-
"args": []
|
|
159
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
160
160
|
},
|
|
161
161
|
"dbt": {
|
|
162
162
|
"command": "uvx",
|
|
@@ -185,7 +185,7 @@ For Azure DevOps instead of GitHub:
|
|
|
185
185
|
"mcpServers": {
|
|
186
186
|
"datasecops-framework": {
|
|
187
187
|
"command": "datasecops-mcp",
|
|
188
|
-
"args": []
|
|
188
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
189
189
|
},
|
|
190
190
|
"dbt": {
|
|
191
191
|
"command": "uvx",
|
|
@@ -215,20 +215,23 @@ Create `.cursor/mcp.json` in your project root with the same format as above.
|
|
|
215
215
|
|
|
216
216
|
### Cortex Code (CoCo)
|
|
217
217
|
|
|
218
|
-
|
|
218
|
+
Create `.snowflake/cortex/mcp.json` in your project root:
|
|
219
219
|
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
220
|
+
```json
|
|
221
|
+
{
|
|
222
|
+
"mcpServers": {
|
|
223
|
+
"datasecops-framework": {
|
|
224
|
+
"type": "stdio",
|
|
225
|
+
"command": "datasecops-mcp",
|
|
226
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
227
|
+
},
|
|
228
|
+
"dbt": {
|
|
229
|
+
"type": "stdio",
|
|
230
|
+
"command": "uvx",
|
|
231
|
+
"args": ["dbt-mcp"]
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
232
235
|
```
|
|
233
236
|
|
|
234
237
|
Verify all servers are connected:
|
|
@@ -50,12 +50,15 @@ Submenu for branch management operations.
|
|
|
50
50
|
|
|
51
51
|
#### New Branch
|
|
52
52
|
|
|
53
|
-
Creates a branch using the
|
|
54
|
-
- Prompts for branch type (feature, bugfix, hotfix — or configured types)
|
|
55
|
-
- Prompts for ticket number (required or optional based on config)
|
|
56
|
-
- Prompts for branch name
|
|
53
|
+
Creates a branch using the configured `branch_format` (default: `{branch_type}/{ticket_name}_{name}`):
|
|
54
|
+
- Prompts for branch type (feature, bugfix, hotfix — or configured types from Source Control settings)
|
|
55
|
+
- Prompts for ticket number (required or optional based on Work Items config `ticket_number_required`)
|
|
56
|
+
- Prompts for branch name (description)
|
|
57
|
+
- Builds the full name using `format_map` with placeholders: `{branch_type}`, `{ticket_name}`, `{name}`, `{branch_name}` (legacy)
|
|
57
58
|
- Creates from `origin/main`, checks out, and pushes with upstream tracking
|
|
58
59
|
|
|
60
|
+
> **Tip:** Use the `new-branch` Cortex Code skill instead of the CLI menu for an AI-assisted workflow that also fetches ticket details and creates a plan document.
|
|
61
|
+
|
|
59
62
|
#### Delete Branch
|
|
60
63
|
|
|
61
64
|
- Cannot delete the current branch
|
|
@@ -13,23 +13,26 @@ pip install datasecops-cli[mcp]
|
|
|
13
13
|
Run the server:
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
|
-
datasecops-mcp
|
|
16
|
+
datasecops-mcp --connection-name <CONNECTION> --app-database <APP_DB>
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
The server communicates via stdio transport and is designed to be launched by an MCP client (not run interactively).
|
|
20
20
|
|
|
21
|
+
If `--connection-name` and `--app-database` are not provided, the server falls back to reading `.datasecops.yml` from the current working directory.
|
|
22
|
+
|
|
21
23
|
## Configuring Your AI Tool
|
|
22
24
|
|
|
23
25
|
### Cortex Code
|
|
24
26
|
|
|
25
|
-
|
|
27
|
+
Create `.snowflake/cortex/mcp.json` in your project root:
|
|
26
28
|
|
|
27
29
|
```json
|
|
28
30
|
{
|
|
29
31
|
"mcpServers": {
|
|
30
32
|
"datasecops-framework": {
|
|
33
|
+
"type": "stdio",
|
|
31
34
|
"command": "datasecops-mcp",
|
|
32
|
-
"args": []
|
|
35
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
}
|
|
@@ -38,7 +41,7 @@ Add to your Cortex Code MCP configuration:
|
|
|
38
41
|
### Claude Code
|
|
39
42
|
|
|
40
43
|
```bash
|
|
41
|
-
claude mcp add datasecops-framework datasecops-mcp
|
|
44
|
+
claude mcp add datasecops-framework datasecops-mcp -- --connection-name <CONNECTION> --app-database <APP_DB>
|
|
42
45
|
```
|
|
43
46
|
|
|
44
47
|
### Cursor / VS Code
|
|
@@ -50,7 +53,7 @@ Add to `.cursor/mcp.json` or your IDE's MCP settings:
|
|
|
50
53
|
"mcpServers": {
|
|
51
54
|
"datasecops-framework": {
|
|
52
55
|
"command": "datasecops-mcp",
|
|
53
|
-
"args": []
|
|
56
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
54
57
|
}
|
|
55
58
|
}
|
|
56
59
|
}
|
|
@@ -58,7 +61,7 @@ Add to `.cursor/mcp.json` or your IDE's MCP settings:
|
|
|
58
61
|
|
|
59
62
|
## Prerequisites
|
|
60
63
|
|
|
61
|
-
The MCP server
|
|
64
|
+
The MCP server connects to Snowflake using the connection name specified via CLI arguments (or from `.datasecops.yml`):
|
|
62
65
|
|
|
63
66
|
```yaml
|
|
64
67
|
connection_name: my_snowflake_connection
|
|
@@ -74,7 +77,8 @@ It uses your Snowflake connection from `~/.snowflake/connections.toml` to authen
|
|
|
74
77
|
|
|
75
78
|
| Tool | Description |
|
|
76
79
|
|------|-------------|
|
|
77
|
-
| `get_branching_rules` | Branch types, naming conventions,
|
|
80
|
+
| `get_branching_rules` | Branch types, naming conventions, environment branches, merge strategies |
|
|
81
|
+
| `get_work_items_config` | Work item system (Azure DevOps / Jira / GitHub Issues), ticket requirement, connection details |
|
|
78
82
|
| `get_linting_rules` | SQLFluff rules (dialect, indentation, enabled rule codes) |
|
|
79
83
|
| `get_dbt_packages` | Approved packages with pinned versions |
|
|
80
84
|
| `get_pipeline_config` | CI/CD pipeline YAML templates (GitHub Actions or Azure DevOps) |
|
|
@@ -110,6 +114,11 @@ The MCP server works transparently in the background. When you ask your AI assis
|
|
|
110
114
|
|
|
111
115
|
### Example Interactions
|
|
112
116
|
|
|
117
|
+
**Starting work on a ticket (using the `new-branch` skill):**
|
|
118
|
+
> "Start work on ticket JIRA-456"
|
|
119
|
+
|
|
120
|
+
The AI calls `get_branching_rules` for branch format and types, `get_work_items_config` for the ticket system, fetches the ticket details via the platform MCP server (Azure DevOps / Atlassian / GitHub), creates a branch like `feature/JIRA-456_add-customer-dim`, and saves the ticket details to a plan document.
|
|
121
|
+
|
|
113
122
|
**Creating a branch:**
|
|
114
123
|
> "Create a new branch for ticket JIRA-456 to add a customer dimension model"
|
|
115
124
|
|
|
@@ -166,7 +175,7 @@ For full platform integration (PR creation, CI status, issue tracking), add the
|
|
|
166
175
|
"mcpServers": {
|
|
167
176
|
"datasecops-framework": {
|
|
168
177
|
"command": "datasecops-mcp",
|
|
169
|
-
"args": []
|
|
178
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
170
179
|
},
|
|
171
180
|
"github": {
|
|
172
181
|
"command": "npx",
|
|
@@ -193,7 +202,7 @@ This enables:
|
|
|
193
202
|
"mcpServers": {
|
|
194
203
|
"datasecops-framework": {
|
|
195
204
|
"command": "datasecops-mcp",
|
|
196
|
-
"args": []
|
|
205
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
197
206
|
},
|
|
198
207
|
"azure-devops": {
|
|
199
208
|
"command": "npx",
|
|
@@ -212,8 +221,39 @@ This enables:
|
|
|
212
221
|
- Creating pull requests with templates
|
|
213
222
|
- Checking build pipeline status
|
|
214
223
|
- Linking to work items
|
|
224
|
+
- Managing and updating work items
|
|
215
225
|
- Managing boards and sprints
|
|
216
226
|
|
|
227
|
+
### Atlassian (Jira)
|
|
228
|
+
|
|
229
|
+
The Atlassian Rovo MCP Server provides access to Jira, Confluence, and Compass. Authentication is handled via OAuth 2.1 (browser flow) or API token — no local credentials needed.
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"mcpServers": {
|
|
234
|
+
"datasecops-framework": {
|
|
235
|
+
"command": "datasecops-mcp",
|
|
236
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"]
|
|
237
|
+
},
|
|
238
|
+
"atlassian": {
|
|
239
|
+
"url": "https://mcp.atlassian.com/v1/mcp/authv2"
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
Or via CLI:
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
cortex mcp add atlassian https://mcp.atlassian.com/v1/mcp/authv2 --transport http
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
This enables:
|
|
252
|
+
- Searching, creating, and updating Jira issues
|
|
253
|
+
- Reading Confluence pages for context
|
|
254
|
+
- Querying Compass components and dependencies
|
|
255
|
+
- Linking tickets to branches and PRs
|
|
256
|
+
|
|
217
257
|
## Combined Workflow Example
|
|
218
258
|
|
|
219
259
|
With both the framework MCP server and GitHub MCP server configured, a developer can say:
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"mcpServers": {
|
|
3
3
|
"datasecops-framework": {
|
|
4
|
+
"type": "stdio",
|
|
4
5
|
"command": "datasecops-mcp",
|
|
5
|
-
"args": [],
|
|
6
|
-
"env": {},
|
|
6
|
+
"args": ["--connection-name", "<CONNECTION>", "--app-database", "<APP_DB>"],
|
|
7
7
|
"description": "DataSecOps Framework governance rules, branching conventions, linting config, and project profiles from your Snowflake Native App"
|
|
8
8
|
},
|
|
9
9
|
"github": {
|
|
10
|
+
"type": "stdio",
|
|
10
11
|
"command": "npx",
|
|
11
12
|
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
12
13
|
"env": {
|
|
@@ -15,6 +16,7 @@
|
|
|
15
16
|
"description": "GitHub API access for PRs, issues, checks, and repository management"
|
|
16
17
|
},
|
|
17
18
|
"azure-devops": {
|
|
19
|
+
"type": "stdio",
|
|
18
20
|
"command": "npx",
|
|
19
21
|
"args": ["-y", "@tiberriver256/mcp-server-azure-devops"],
|
|
20
22
|
"env": {
|
|
@@ -23,6 +25,12 @@
|
|
|
23
25
|
"AZURE_DEVOPS_PAT": "<your-azure-pat>"
|
|
24
26
|
},
|
|
25
27
|
"description": "Azure DevOps API access for PRs, pipelines, work items, and boards"
|
|
28
|
+
},
|
|
29
|
+
"dbt": {
|
|
30
|
+
"type": "stdio",
|
|
31
|
+
"command": "uvx",
|
|
32
|
+
"args": ["dbt-mcp"],
|
|
33
|
+
"description": "dbt lineage, model discovery, codegen, and semantic layer"
|
|
26
34
|
}
|
|
27
35
|
}
|
|
28
36
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.5.2"
|
|
@@ -2,7 +2,7 @@ from pathlib import Path
|
|
|
2
2
|
from typing import Optional
|
|
3
3
|
|
|
4
4
|
from datasecops_cli.models.project_config import (
|
|
5
|
-
DatasecopsConfig, ProjectSettings, SourceControl, ProjectProfile, DbtTarget
|
|
5
|
+
DatasecopsConfig, ProjectSettings, SourceControl, WorkItems, ProjectProfile, DbtTarget
|
|
6
6
|
)
|
|
7
7
|
from datasecops_cli.utilities.yaml_utils import read_datasecops_config, read_dbt_project
|
|
8
8
|
from datasecops_cli.utilities.display import error_line, info_line
|
|
@@ -15,6 +15,7 @@ class Config:
|
|
|
15
15
|
self.datasecops: DatasecopsConfig = DatasecopsConfig()
|
|
16
16
|
self.project_settings: ProjectSettings = ProjectSettings()
|
|
17
17
|
self.source_control: SourceControl = SourceControl()
|
|
18
|
+
self.work_items: WorkItems = WorkItems()
|
|
18
19
|
self.profile: Optional[ProjectProfile] = None
|
|
19
20
|
self.all_profiles: list[ProjectProfile] = []
|
|
20
21
|
self.project_dir: Path = Path.cwd()
|
|
@@ -77,6 +78,11 @@ class Config:
|
|
|
77
78
|
if raw:
|
|
78
79
|
self.source_control = SourceControl(**{k: v for k, v in raw.items() if k in SourceControl.model_fields})
|
|
79
80
|
|
|
81
|
+
# Load work items
|
|
82
|
+
raw = snowflake_service.get_framework_config("WORK_ITEMS")
|
|
83
|
+
if raw:
|
|
84
|
+
self.work_items = WorkItems(**{k: v for k, v in raw.items() if k in WorkItems.model_fields})
|
|
85
|
+
|
|
80
86
|
# Load project profiles
|
|
81
87
|
profiles_data = snowflake_service.get_project_profiles()
|
|
82
88
|
if profiles_data:
|