drake-mcp 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 (104) hide show
  1. drake_mcp-0.1.0/PKG-INFO +30 -0
  2. drake_mcp-0.1.0/README.md +400 -0
  3. drake_mcp-0.1.0/pyproject.toml +71 -0
  4. drake_mcp-0.1.0/setup.cfg +4 -0
  5. drake_mcp-0.1.0/src/drake/__init__.py +0 -0
  6. drake_mcp-0.1.0/src/drake/ai_clustering/__init__.py +0 -0
  7. drake_mcp-0.1.0/src/drake/ai_clustering/dependency_matcher.py +160 -0
  8. drake_mcp-0.1.0/src/drake/ai_clustering/embedding_service.py +154 -0
  9. drake_mcp-0.1.0/src/drake/ai_clustering/explain.py +29 -0
  10. drake_mcp-0.1.0/src/drake/ai_clustering/graph_clustering.py +570 -0
  11. drake_mcp-0.1.0/src/drake/ai_clustering/nl_compiler.py +36 -0
  12. drake_mcp-0.1.0/src/drake/ai_clustering/ollama_service.py +96 -0
  13. drake_mcp-0.1.0/src/drake/ai_clustering/schemas/workflow.py +69 -0
  14. drake_mcp-0.1.0/src/drake/ai_clustering/workflow_naming.py +106 -0
  15. drake_mcp-0.1.0/src/drake/cli/__init__.py +3 -0
  16. drake_mcp-0.1.0/src/drake/cli/commands/__init__.py +1 -0
  17. drake_mcp-0.1.0/src/drake/cli/commands/ansible.py +63 -0
  18. drake_mcp-0.1.0/src/drake/cli/commands/audit.py +86 -0
  19. drake_mcp-0.1.0/src/drake/cli/commands/cluster.py +52 -0
  20. drake_mcp-0.1.0/src/drake/cli/commands/compatibility.py +133 -0
  21. drake_mcp-0.1.0/src/drake/cli/commands/config.py +74 -0
  22. drake_mcp-0.1.0/src/drake/cli/commands/diagnostics.py +119 -0
  23. drake_mcp-0.1.0/src/drake/cli/commands/governance.py +112 -0
  24. drake_mcp-0.1.0/src/drake/cli/commands/pipeline.py +50 -0
  25. drake_mcp-0.1.0/src/drake/cli/commands/runtime.py +108 -0
  26. drake_mcp-0.1.0/src/drake/cli/commands/server.py +36 -0
  27. drake_mcp-0.1.0/src/drake/cli/commands/system.py +45 -0
  28. drake_mcp-0.1.0/src/drake/cli/components.py +321 -0
  29. drake_mcp-0.1.0/src/drake/cli/container.py +52 -0
  30. drake_mcp-0.1.0/src/drake/cli/context.py +8 -0
  31. drake_mcp-0.1.0/src/drake/cli/exceptions.py +12 -0
  32. drake_mcp-0.1.0/src/drake/cli/main.py +179 -0
  33. drake_mcp-0.1.0/src/drake/cli/plugins/__init__.py +48 -0
  34. drake_mcp-0.1.0/src/drake/cli/services/__init__.py +23 -0
  35. drake_mcp-0.1.0/src/drake/cli/services/ansible.py +50 -0
  36. drake_mcp-0.1.0/src/drake/cli/services/audit.py +59 -0
  37. drake_mcp-0.1.0/src/drake/cli/services/bridge.py +20 -0
  38. drake_mcp-0.1.0/src/drake/cli/services/cluster.py +121 -0
  39. drake_mcp-0.1.0/src/drake/cli/services/compatibility.py +140 -0
  40. drake_mcp-0.1.0/src/drake/cli/services/config.py +94 -0
  41. drake_mcp-0.1.0/src/drake/cli/services/diagnostics.py +148 -0
  42. drake_mcp-0.1.0/src/drake/cli/services/governance.py +142 -0
  43. drake_mcp-0.1.0/src/drake/cli/services/runtime.py +75 -0
  44. drake_mcp-0.1.0/src/drake/cli/services/system.py +77 -0
  45. drake_mcp-0.1.0/src/drake/cli/theme.py +170 -0
  46. drake_mcp-0.1.0/src/drake/core/__init__.py +33 -0
  47. drake_mcp-0.1.0/src/drake/core/compatibility/ansible_enricher.py +167 -0
  48. drake_mcp-0.1.0/src/drake/core/compatibility/engine.py +664 -0
  49. drake_mcp-0.1.0/src/drake/core/compatibility/models.py +201 -0
  50. drake_mcp-0.1.0/src/drake/core/compatibility/orchestrator.py +250 -0
  51. drake_mcp-0.1.0/src/drake/core/compatibility/repository.py +386 -0
  52. drake_mcp-0.1.0/src/drake/core/compatibility/sources.py +219 -0
  53. drake_mcp-0.1.0/src/drake/core/compression.py +136 -0
  54. drake_mcp-0.1.0/src/drake/core/config.py +110 -0
  55. drake_mcp-0.1.0/src/drake/core/database.py +1064 -0
  56. drake_mcp-0.1.0/src/drake/core/env_config.py +72 -0
  57. drake_mcp-0.1.0/src/drake/core/exceptions.py +120 -0
  58. drake_mcp-0.1.0/src/drake/core/models.py +245 -0
  59. drake_mcp-0.1.0/src/drake/governance/__init__.py +1 -0
  60. drake_mcp-0.1.0/src/drake/governance/core/__init__.py +1 -0
  61. drake_mcp-0.1.0/src/drake/governance/core/policy.py +89 -0
  62. drake_mcp-0.1.0/src/drake/governance/core/risk.py +88 -0
  63. drake_mcp-0.1.0/src/drake/governance/core/validator.py +58 -0
  64. drake_mcp-0.1.0/src/drake/governance/middleware.py +89 -0
  65. drake_mcp-0.1.0/src/drake/governance/runtime/__init__.py +1 -0
  66. drake_mcp-0.1.0/src/drake/governance/runtime/interceptor.py +62 -0
  67. drake_mcp-0.1.0/src/drake/parser/__init__.py +9 -0
  68. drake_mcp-0.1.0/src/drake/parser/asyncapi_parser.py +61 -0
  69. drake_mcp-0.1.0/src/drake/parser/graphql_parser.py +65 -0
  70. drake_mcp-0.1.0/src/drake/parser/grpc_parser.py +57 -0
  71. drake_mcp-0.1.0/src/drake/parser/openapi_parser.py +378 -0
  72. drake_mcp-0.1.0/src/drake/proxy/__init__.py +0 -0
  73. drake_mcp-0.1.0/src/drake/proxy/api.py +1143 -0
  74. drake_mcp-0.1.0/src/drake/proxy/executors/__init__.py +11 -0
  75. drake_mcp-0.1.0/src/drake/proxy/executors/base.py +52 -0
  76. drake_mcp-0.1.0/src/drake/proxy/executors/dell_omsdk_executor.py +69 -0
  77. drake_mcp-0.1.0/src/drake/proxy/executors/httpx_executor.py +299 -0
  78. drake_mcp-0.1.0/src/drake/proxy/executors/workflow_execution_service.py +243 -0
  79. drake_mcp-0.1.0/src/drake/proxy/server.py +813 -0
  80. drake_mcp-0.1.0/src/drake/proxy/stdio_server.py +37 -0
  81. drake_mcp-0.1.0/src/drake_mcp.egg-info/PKG-INFO +30 -0
  82. drake_mcp-0.1.0/src/drake_mcp.egg-info/SOURCES.txt +102 -0
  83. drake_mcp-0.1.0/src/drake_mcp.egg-info/dependency_links.txt +1 -0
  84. drake_mcp-0.1.0/src/drake_mcp.egg-info/entry_points.txt +2 -0
  85. drake_mcp-0.1.0/src/drake_mcp.egg-info/requires.txt +25 -0
  86. drake_mcp-0.1.0/src/drake_mcp.egg-info/top_level.txt +1 -0
  87. drake_mcp-0.1.0/tests/test_caching_optimizer.py +130 -0
  88. drake_mcp-0.1.0/tests/test_clustering_quality.py +78 -0
  89. drake_mcp-0.1.0/tests/test_edge_concurrency.py +97 -0
  90. drake_mcp-0.1.0/tests/test_edge_resilience.py +94 -0
  91. drake_mcp-0.1.0/tests/test_edge_security.py +96 -0
  92. drake_mcp-0.1.0/tests/test_generator_bootstrap.py +97 -0
  93. drake_mcp-0.1.0/tests/test_governance_api.py +283 -0
  94. drake_mcp-0.1.0/tests/test_hierarchical_exposure.py +111 -0
  95. drake_mcp-0.1.0/tests/test_hierarchical_exposure_comprehensive.py +155 -0
  96. drake_mcp-0.1.0/tests/test_microservice.py +137 -0
  97. drake_mcp-0.1.0/tests/test_mock_api.py +34 -0
  98. drake_mcp-0.1.0/tests/test_multi_api_ingestion.py +164 -0
  99. drake_mcp-0.1.0/tests/test_nl_compiler.py +89 -0
  100. drake_mcp-0.1.0/tests/test_parser.py +61 -0
  101. drake_mcp-0.1.0/tests/test_real_world_specs.py +68 -0
  102. drake_mcp-0.1.0/tests/test_security_hardening.py +73 -0
  103. drake_mcp-0.1.0/tests/test_server.py +28 -0
  104. drake_mcp-0.1.0/tests/test_workflow_lifecycle_patterns.py +182 -0
@@ -0,0 +1,30 @@
1
+ Metadata-Version: 2.4
2
+ Name: drake-mcp
3
+ Version: 0.1.0
4
+ Summary: Dell Enterprise MCP Workflow Proxy
5
+ Requires-Python: >=3.10
6
+ Requires-Dist: fastmcp>=3.4.2
7
+ Requires-Dist: httpx>=0.28.1
8
+ Requires-Dist: instructor>=1.15.3
9
+ Requires-Dist: ollama>=0.6.2
10
+ Requires-Dist: openapi-core>=0.23.1
11
+ Requires-Dist: pydantic>=2.13.4
12
+ Requires-Dist: fastapi>=0.110.0
13
+ Requires-Dist: uvicorn>=0.30.0
14
+ Requires-Dist: networkx>=3.0
15
+ Requires-Dist: sentence-transformers>=3.0.0
16
+ Requires-Dist: scikit-learn>=1.5.0
17
+ Requires-Dist: leidenalg>=0.10.2
18
+ Requires-Dist: igraph>=0.11.0
19
+ Requires-Dist: tenacity>=9.1.4
20
+ Requires-Dist: sqlalchemy>=2.0.51
21
+ Requires-Dist: aiosqlite>=0.22.1
22
+ Requires-Dist: PyYAML>=6.0.1
23
+ Requires-Dist: mcp>=0.1.0
24
+ Requires-Dist: python-dotenv>=1.1.0
25
+ Requires-Dist: PyJWT>=2.10.0
26
+ Requires-Dist: click>=8.2.1
27
+ Requires-Dist: rich>=14.0.0
28
+ Requires-Dist: numpy>=2.0.0
29
+ Requires-Dist: typer>=0.16.0
30
+ Requires-Dist: openai>=1.84.0
@@ -0,0 +1,400 @@
1
+ # Dell Enterprise MCP Proxy - Infrastructure Command Center CLI (`drake`)
2
+
3
+ The **Infrastructure Command Center CLI (`drake`)** is the primary operational control plane and administration utility for the Dell Enterprise MCP Proxy platform.
4
+
5
+ It is designed for:
6
+ * **Infrastructure Engineers** managing bare-metal systems and server topologies.
7
+ * **Platform Reliability Engineers (PRE)** monitoring runtime states and API availability.
8
+ * **Dell PowerEdge Administrators** validating hardware compliance and firmware inventories.
9
+ * **Governance & Compliance Teams** auditing AI-generated workflows and reviewing action ledgers.
10
+
11
+ The CLI acts as a thin presentation and orchestration layer over the underlying Dell MCP services, presenting a high-performance, unified, and resilient command center experience.
12
+
13
+ ---
14
+
15
+ ## Architecture Diagram
16
+
17
+ The CLI is decoupled from the core business engines and repositories using a strict presentation layer design:
18
+
19
+ ```mermaid
20
+ flowchart TD
21
+ subgraph Presentation Layer
22
+ A[Operator Console / shell] -->|drake CLI| B[Typer Main Router src/cli/main.py]
23
+ B -->|Command Group Router src/cli/commands/*| C[CLIContainer src/cli/container.py]
24
+ C -->|Lazy Resolution| D[CLI Service Adapter src/cli/services/*]
25
+ end
26
+ subgraph Core Platform Services
27
+ D -->|Database Sync / Async Session| E[(SQLite governance.db)]
28
+ D -->|Pre-flight Verification| F[Compatibility Engine]
29
+ D -->|Playbook Enrichment| G[Ansible Exporter]
30
+ D -->|FastMCP Runtime State| H[Execution Manager]
31
+ end
32
+ ```
33
+
34
+ ### Dependency Rules
35
+ * Commands **must never** directly instantiate SQLite connections, SQLAlchemy sessions, HTTPX clients, or core logic engines.
36
+ * All operations must flow through service adapters resolved via the centralized **CLIContainer**.
37
+ * Console visual structures are decoupled from business logic.
38
+
39
+ ---
40
+
41
+ ## Installation & Requirements
42
+
43
+ ### System Requirements
44
+ * Python 3.10 or higher.
45
+ * `uv` (fast Python package installer).
46
+ * Stateful access to `data/governance.db` (seeded and active).
47
+
48
+ ### Editable Development Installation
49
+ Install the project dependencies and wire the executable script locally using `uv`:
50
+
51
+ #### 1. Install uv
52
+ ```bash
53
+ curl -LsSf https://astral.sh/uv/install.sh | sh
54
+ ```
55
+
56
+ #### 2. Install Local LLM Engine (Ollama)
57
+ You must also install and start the local LLM engine Ollama and pull/run the Llama3 model:
58
+ ```bash
59
+ # Run Ollama with Llama3 model
60
+ ollama run llama3
61
+ ```
62
+
63
+ #### 3. Environment Setup
64
+ Initialize the virtual environment and install all dependencies:
65
+ ```bash
66
+ # Sync all platform virtual environment dependencies
67
+ uv sync
68
+
69
+ # Install the drake package in editable mode
70
+ uv pip install -e .
71
+ ```
72
+
73
+ #### 4. Activate the Virtual Environment
74
+ Activate the `uv`-managed virtual environment so that `drake` resolves to the correct venv binary:
75
+ ```powershell
76
+ # Windows (PowerShell) — run once per terminal session
77
+ .venv\Scripts\Activate.ps1
78
+ ```
79
+
80
+ After activation, run bare `drake` commands directly:
81
+ ```bash
82
+ drake --help
83
+ ```
84
+
85
+ > **Alternative (no activation needed):** Prefix every command with `uv run`:
86
+ > ```bash
87
+ > uv run drake --help
88
+ > uv run drake overview
89
+ > ```
90
+
91
+ > **Environment Variable:** Ensure the following variable is defined in your `.env` file:
92
+ > `DELL_MCP_API_KEY` — used in `src/proxy/api.py` to authenticate proxy calls and administration endpoints.
93
+
94
+ ---
95
+
96
+ ## Quick Start (Automated Launch)
97
+
98
+ You can launch all required services—including environment validation, package sync, the backend FastMCP/FastAPI server, the Next.js frontend console, and checking Ollama models—with a single command:
99
+
100
+ ```powershell
101
+ # Run the PowerShell launcher script
102
+ .\start.ps1
103
+ ```
104
+
105
+ Or simply double-click the `start.bat` file in Windows Explorer, or run:
106
+ ```cmd
107
+ start.bat
108
+ ```
109
+
110
+ The launcher will verify your dependencies and launch the backend and frontend services in dedicated terminal windows.
111
+
112
+ ---
113
+
114
+ ## Quick Start (Manual Setup)
115
+
116
+ Activate the virtual environment first, then run commands:
117
+
118
+ ```powershell
119
+ # 1. Activate venv (once per terminal session)
120
+ .venv\Scripts\Activate.ps1
121
+
122
+ # 2. Print global help instructions and subcommand catalog
123
+ drake --help
124
+
125
+ # 3. Render the executive control plane dashboard overview
126
+ drake overview
127
+
128
+ # 4. Verify subsystem readiness and health assessment matrix
129
+ drake health
130
+ ```
131
+
132
+ > **Or without activation:** prefix every command with `uv run drake ...`
133
+
134
+ ---
135
+
136
+ ## Command Reference
137
+
138
+ The Command Center organizes operational tasks into specialized command groups:
139
+
140
+ ### 1. `cluster`
141
+ Manages AI clustering, OpenAPI integrations, and spec parsing.
142
+ * **`summary`**
143
+ * *Purpose*: Render clustering metrics and distribution data.
144
+ * *Syntax*: `drake cluster summary`
145
+ * *Example Output*: Prints total endpoints, Leiden clusters, and average confidence levels.
146
+ * **`graph`**
147
+ * *Purpose*: Display active relationship graphs of endpoints.
148
+ * *Syntax*: `drake cluster graph`
149
+ * **`run --spec <path>`**
150
+ * *Purpose*: Parse an OpenAPI specification file and regenerate workflow clusters.
151
+ * *Syntax*: `drake cluster run --spec openapi.json`
152
+
153
+ ### 2. `governance`
154
+ Enforces human-in-the-loop review cycles for LLM-generated workflows.
155
+ * **`pending`**
156
+ * *Purpose*: List all workflows awaiting human approval.
157
+ * *Syntax*: `drake governance pending`
158
+ * **`approved`**
159
+ * *Purpose*: List all certified/approved operational workflows.
160
+ * *Syntax*: `drake governance approved`
161
+ * **`rejected`**
162
+ * *Purpose*: List workflows blocked or rejected by operators.
163
+ * *Syntax*: `drake governance rejected`
164
+ * **`review <workflow_id>`**
165
+ * *Purpose*: Inspect a workflow's details and constituent API steps.
166
+ * *Syntax*: `drake governance review test_wf_1`
167
+ * **`approve <workflow_id>`**
168
+ * *Purpose*: Approve a pending workflow, promoting it to an executable FastMCP tool.
169
+ * *Syntax*: `drake governance approve test_wf_1`
170
+ * **`reject <workflow_id> --reason <text>`**
171
+ * *Purpose*: Reject a workflow and document the audit reason.
172
+ * *Syntax*: `drake governance reject test_wf_1 --reason "Security validation failed"`
173
+
174
+ ### 3. `compatibility`
175
+ Pre-flight verification intelligence.
176
+ * **`validate <workflow_id> --target-ip <ip>`**
177
+ * *Purpose*: Validate workflow steps against target hardware.
178
+ * *Syntax*: `drake compatibility validate test_wf_1 --target-ip 192.168.0.120`
179
+ * **`explain <workflow_id>`**
180
+ * *Purpose*: Render the DAG rules tree that evaluates the workflow.
181
+ * *Syntax*: `drake compatibility explain test_wf_1`
182
+ * **`dashboard <workflow_id> --target-ip <ip>`**
183
+ * *Purpose*: Renders the decision cockpit (see flagship section below).
184
+ * *Syntax*: `drake compatibility dashboard test_wf_1 --target-ip 192.168.0.120`
185
+ * **`rules`**
186
+ * *Purpose*: Print the active policies and compatibility rules catalog.
187
+ * *Syntax*: `drake compatibility rules`
188
+ * **`device <ip>`**
189
+ * *Purpose*: Query stateful cached specifications for a datacenter node.
190
+ * *Syntax*: `drake compatibility device 192.168.0.120`
191
+
192
+ ### 4. `runtime`
193
+ Controls the FastMCP integration hooks.
194
+ * **`tools`**
195
+ * *Purpose*: List currently exposed FastMCP tools ready for client consumption.
196
+ * *Syntax*: `drake runtime tools`
197
+ * **`reload`**
198
+ * *Purpose*: Trigger hot-reloads to refresh tool mappings from database states.
199
+ * *Syntax*: `drake runtime reload`
200
+ * **`execute <tool_name> --params <json>`**
201
+ * *Purpose*: Manually invoke a registered workflow.
202
+ * *Syntax*: `drake runtime execute test_workflow --params '{"sys_id": 1}'`
203
+
204
+ ### 5. `ansible`
205
+ Exports workflow logic to infrastructure-as-code files.
206
+ * **`preview <workflow_id>`**
207
+ * *Purpose*: Render syntax-highlighted playbook configurations directly on the console.
208
+ * *Syntax*: `drake ansible preview test_wf_1`
209
+ * **`export <workflow_id> --output <path>`**
210
+ * *Purpose*: Export enriched playbooks directly to files.
211
+ * *Syntax*: `drake ansible export test_wf_1 --output playbooks/deploy.yml`
212
+
213
+ ### 6. `audit`
214
+ Exposes the compliance history ledger.
215
+ * **`events`**
216
+ * *Purpose*: List administrative events, modifications, and approvals.
217
+ * *Syntax*: `drake audit events`
218
+ * **`executions`**
219
+ * *Purpose*: Print workflow runs, durations, status codes, and targets.
220
+ * *Syntax*: `drake audit executions`
221
+ * **`summary`**
222
+ * *Purpose*: Present compliance summaries and error trends.
223
+ * *Syntax*: `drake audit summary`
224
+
225
+ ### 7. `system`
226
+ Prints operational topology data.
227
+ * **`topology`**
228
+ * *Purpose*: Display the system dependencies tree.
229
+ * *Syntax*: `drake system topology`
230
+
231
+ ### 8. `diagnostics`
232
+ Evaluates internal health checks.
233
+ * **`db`** / **`api`** / **`compatibility`** / **`runtime`**
234
+ * *Purpose*: Troubleshoot connections to database files, REST endpoints, and facts caches.
235
+ * *Syntax*: `drake diagnostics db`
236
+
237
+ ---
238
+
239
+ ## Flagship Feature: Compatibility Cockpit
240
+
241
+ The **Compatibility Cockpit** provides a single Go/No-Go verdict before executing any workflow on target hardware:
242
+
243
+ ```bash
244
+ drake compatibility dashboard <workflow_id> --target-ip <ip>
245
+ ```
246
+
247
+ ### Cockpit Panels
248
+
249
+ 1. **Target Device**: Displays model, BIOS version, Lifecycle Controller version, and scan time.
250
+ 2. **Validation Scores**:
251
+ * *Compatibility Score*: Measures compliance with active rules catalog (0-100%).
252
+ * *Risk Score*: Computes operational risk coefficients (0-100).
253
+ * *Blast Radius*: Outlines impact boundary (e.g. `NODE`, `CHASSIS`, `RACK`, `DATACENTER`).
254
+ * *Confidence*: Quality indicator of cached/retrieved device specifications.
255
+ 3. **Violations**: Lists check failures, expected vs actual properties, and corrective remediation actions.
256
+ 4. **Prerequisites Dependencies**: Structured tree showing parent-child dependency checks.
257
+ 5. **Final Execution Verdict**: Bold colored indicator marking either `✓ SAFE TO EXECUTE` or `✗ BLOCK EXECUTION`.
258
+
259
+ ---
260
+
261
+ ## Universal JSON Mode
262
+
263
+ To support scripting, automation pipeline runs, and DevOps integration, every CLI command supports the `--json` flag:
264
+
265
+ ```bash
266
+ drake --json compatibility dashboard test_wf_1 --target-ip 192.168.0.120
267
+ ```
268
+
269
+ When `--json` is enabled:
270
+ * All styled panels, colors, tables, trees, and interactive spinners are **bypassed**.
271
+ * Only valid machine-readable JSON is written to `stdout`.
272
+ * Standard logs and non-critical warnings are redirected to `stderr`.
273
+
274
+ ---
275
+
276
+ ## Watch Mode
277
+
278
+ Monitor executive statuses or health assessment matrices in real-time using watch flags:
279
+
280
+ ```bash
281
+ drake overview --watch --interval 2
282
+ drake health --watch
283
+ ```
284
+
285
+ * **`--watch`**: Toggles live loop.
286
+ * **`--interval` (`-i`)**: Defines update frequency in seconds (default: 5).
287
+ * *Exit*: Cleanly intercepts `Ctrl+C` to terminate the loops without locking SQLite files.
288
+
289
+ ---
290
+
291
+ ## Plugin System
292
+
293
+ The Command Center includes a self-discovering plugin mechanism located in **`src/cli/plugins/`**.
294
+
295
+ ### How Plugin Discovery Works
296
+ * The CLI scans the `src/cli/plugins/` directory at startup.
297
+ * It dynamically loads modules that do not start with an underscore (`_`).
298
+ * It registers subcommands if they expose a `register_plugin(app)` function or expose a `typer.Typer()` application named `app`.
299
+
300
+ ### Authoring Custom Plugins
301
+ Create a Python module in `src/cli/plugins/network_config.py`:
302
+ ```python
303
+ import typer
304
+
305
+ app = typer.Typer(help="Manage switch network configurations")
306
+
307
+ @app.command("show")
308
+ def show_switch_status():
309
+ print("Switch connections operational.")
310
+ ```
311
+ The CLI automatically loads this, making the command `drake network_config show` immediately available.
312
+
313
+ ### Failure Isolation
314
+ If a plugin raises an exception during import or initialization:
315
+ * The exception is caught and printed as a warning (`⚠ WARNING: Plugin load failed`).
316
+ * The core CLI continues to boot successfully, preserving primary operations.
317
+
318
+ ---
319
+
320
+ ## Security Features
321
+
322
+ ### Secrets Masking Shield
323
+ To ensure security, the CLI scans outputs for sensitive keys (e.g. `password`, `token`, `key`, `secret`, `authorization`, `ssn`) and masks them recursively:
324
+ * **Console Output**: Masked with `********` inside tables and panels.
325
+ * **JSON Mode**: Formatted structure replaces sensitive strings with `********`, preventing data leaks in automation logs.
326
+
327
+ ### Access Trails
328
+ Operations that alter states (e.g. `governance approve`, `governance reject`) write audit records to the local governance ledger, documenting administrative actor and time.
329
+
330
+ ---
331
+
332
+ ## Troubleshooting
333
+
334
+ ### Legacy Windows Output Crash (`UnicodeEncodeError`)
335
+ * *Symptom*: Commands crash printing `UnicodeEncodeError: 'charmap' codec can't encode character...`
336
+ * *Cause*: Legacy Windows terminal character set (e.g. CP-1252) cannot print unicode symbols (`⚠`, `✓`).
337
+ * *Resolution*: Force the environment to use UTF-8 encoding:
338
+ ```powershell
339
+ $env:PYTHONIOENCODING="utf-8"
340
+ ```
341
+
342
+ ### Packaging Script Location Error (`ModuleNotFoundError`)
343
+ * *Symptom*: Running `drake` raises `ModuleNotFoundError: No module named 'src'`.
344
+ * *Cause*: The bare `drake` command resolves to a system-level Python install that does not have access to the project source tree. This happens when the virtual environment is not activated.
345
+ * *Resolution (preferred)*: Activate the `uv` virtual environment before running any commands:
346
+ ```powershell
347
+ .venv\Scripts\Activate.ps1
348
+ drake --help
349
+ ```
350
+ * *Resolution (alternative)*: Use `uv run` to automatically route through the correct venv:
351
+ ```bash
352
+ uv run drake --help
353
+ uv run drake health
354
+ ```
355
+
356
+ ### SQLite Database Locks
357
+ * *Symptom*: Actions time out or fail with database locks.
358
+ * *Cause*: Concurrent operations on SQLite files during long-running tasks.
359
+ * *Resolution*: Run `drake diagnostics db` to check connection status. Ensure the microservice FastAPI server is running with WAL journal modes.
360
+
361
+ ---
362
+
363
+ ## Operator Workflows
364
+
365
+ ### Workflow 1: Platform Monitoring
366
+ Verify global status and watch for changes during maintenance windows:
367
+ ```bash
368
+ $env:PYTHONIOENCODING="utf-8"
369
+ drake health
370
+ drake overview --watch --interval 10
371
+ ```
372
+
373
+ ### Workflow 2: Safe Pre-Flight Validation & Approval
374
+ Review a workflow generated by clustering, validate it against target hardware, and approve it:
375
+ ```bash
376
+ # 1. List pending LLM workflows
377
+ drake governance pending
378
+
379
+ # 2. Inspect step details
380
+ drake governance review test_wf_1
381
+
382
+ # 3. Perform pre-flight compatibility evaluation cockpit
383
+ drake compatibility dashboard test_wf_1 --target-ip 192.168.0.120
384
+
385
+ # 4. Approve workflow
386
+ drake governance approve test_wf_1
387
+ ```
388
+
389
+ ### Workflow 3: IaC Automation Export
390
+ Validate a workflow and export it to an enriched Ansible playbook for target datacenter node setups:
391
+ ```bash
392
+ # 1. Verify compatibility
393
+ drake compatibility validate test_wf_1 --target-ip 192.168.0.120
394
+
395
+ # 2. Preview playbooks syntax
396
+ drake ansible preview test_wf_1
397
+
398
+ # 3. Export playbook to target directory
399
+ drake ansible export test_wf_1 --output playbooks/idrac_setup.yml
400
+ ```
@@ -0,0 +1,71 @@
1
+ [project]
2
+ name = "drake-mcp"
3
+ version = "0.1.0"
4
+ description = "Dell Enterprise MCP Workflow Proxy"
5
+ requires-python = ">=3.10"
6
+ dependencies = [
7
+ "fastmcp>=3.4.2",
8
+ "httpx>=0.28.1",
9
+ "instructor>=1.15.3",
10
+ "ollama>=0.6.2",
11
+ "openapi-core>=0.23.1",
12
+ "pydantic>=2.13.4",
13
+ "fastapi>=0.110.0",
14
+ "uvicorn>=0.30.0",
15
+ "networkx>=3.0",
16
+ "sentence-transformers>=3.0.0",
17
+ "scikit-learn>=1.5.0",
18
+ "leidenalg>=0.10.2",
19
+ "igraph>=0.11.0",
20
+ "tenacity>=9.1.4",
21
+ "sqlalchemy>=2.0.51",
22
+ "aiosqlite>=0.22.1",
23
+ "PyYAML>=6.0.1",
24
+ "mcp>=0.1.0",
25
+ "python-dotenv>=1.1.0",
26
+ "PyJWT>=2.10.0",
27
+ "click>=8.2.1",
28
+ "rich>=14.0.0",
29
+ "numpy>=2.0.0",
30
+ "typer>=0.16.0",
31
+ "openai>=1.84.0",
32
+ ]
33
+
34
+ [project.scripts]
35
+ drake = "drake.cli.main:main"
36
+
37
+ [dependency-groups]
38
+ dev = [
39
+ "black>=26.5.1",
40
+ "flake8>=7.3.0",
41
+ "mypy>=2.1.0",
42
+ "pytest>=9.1.0",
43
+ "pytest-asyncio>=0.23.5",
44
+ "pytest-xdist>=3.8.0",
45
+ ]
46
+
47
+ [tool.black]
48
+ line-length = 88
49
+ target-version = ["py311"]
50
+ include = '\.pyi?$'
51
+
52
+ [tool.mypy]
53
+ python_version = "3.11"
54
+ strict = true
55
+ disallow_untyped_defs = true
56
+ ignore_missing_imports = true
57
+
58
+ [tool.pytest.ini_options]
59
+ testpaths = ["tests"]
60
+ norecursedirs = ["generated"]
61
+ asyncio_mode = "auto"
62
+ addopts = "-n 2 --ignore=tests/generated"
63
+
64
+ [build-system]
65
+ requires = ["setuptools>=61.0.0", "wheel"]
66
+ build-backend = "setuptools.build_meta"
67
+
68
+ [tool.setuptools.packages.find]
69
+ where = ["src"]
70
+ include = ["drake*"]
71
+
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
File without changes
@@ -0,0 +1,160 @@
1
+ import json
2
+ import logging
3
+ import networkx as nx
4
+ from typing import List, Dict, Any
5
+
6
+ logger = logging.getLogger(__name__)
7
+
8
+ def extract_schema_fields_typed(schema_str: Any) -> Dict[str, str]:
9
+ """Extracts property names and types from a JSON schema string recursively."""
10
+ fields = {}
11
+ if not schema_str:
12
+ return fields
13
+ try:
14
+ schema = json.loads(schema_str) if isinstance(schema_str, str) else schema_str
15
+ if not isinstance(schema, dict):
16
+ return fields
17
+ def recurse(obj):
18
+ if isinstance(obj, dict):
19
+ if "properties" in obj and isinstance(obj["properties"], dict):
20
+ for k, v in obj["properties"].items():
21
+ t = v.get("type", "string") if isinstance(v, dict) else "unknown"
22
+ fields[k] = t
23
+ recurse(v)
24
+ for k, v in obj.items():
25
+ if k != "properties":
26
+ recurse(v)
27
+ elif isinstance(obj, list):
28
+ for item in obj:
29
+ recurse(item)
30
+ recurse(schema)
31
+ except Exception as e:
32
+ logger.warning(f"Failed to parse schema for dependency matching: {e}")
33
+ return fields
34
+
35
+ def extract_required_params_typed(params_str: Any) -> Dict[str, str]:
36
+ fields = {}
37
+ if not params_str:
38
+ return fields
39
+ try:
40
+ params = json.loads(params_str) if isinstance(params_str, str) else params_str
41
+ for p in params:
42
+ if isinstance(p, dict) and "name" in p:
43
+ t = p.get("schema", {}).get("type", "string")
44
+ fields[p["name"]] = t
45
+ except Exception:
46
+ pass
47
+ return fields
48
+
49
+ def build_execution_dag(endpoints: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
50
+ """
51
+ Takes a list of endpoints within a community.
52
+ Builds a Directed Acyclic Graph (DAG) based on data dependencies.
53
+ Resolves Cycles automatically.
54
+ Returns the endpoints ordered by topological sort with variable_bindings injected.
55
+ """
56
+ if not endpoints:
57
+ return []
58
+ if len(endpoints) == 1:
59
+ endpoints[0]["variable_bindings"] = json.dumps({})
60
+ return endpoints
61
+
62
+ G = nx.DiGraph()
63
+ bindings = {ep["operation_id"]: {} for ep in endpoints}
64
+
65
+ for ep in endpoints:
66
+ G.add_node(ep["operation_id"], data=ep)
67
+
68
+ common_fields = {"id", "name", "description", "status", "message", "error", "type"}
69
+
70
+ for ep_a in endpoints:
71
+ a_id = ep_a["operation_id"]
72
+ a_method = ep_a["method"].upper()
73
+ a_path = ep_a["url"]
74
+ a_outputs = extract_schema_fields_typed(ep_a.get("response_schema"))
75
+
76
+ for ep_b in endpoints:
77
+ b_id = ep_b["operation_id"]
78
+ if a_id == b_id:
79
+ continue
80
+ b_method = ep_b["method"].upper()
81
+ b_path = ep_b["url"]
82
+ b_inputs = extract_schema_fields_typed(ep_b.get("request_schema"))
83
+ b_inputs.update(extract_required_params_typed(ep_b.get("required_params")))
84
+
85
+ edge_weight = 0
86
+ mapped_fields = []
87
+
88
+ # Rule 1: Type-Aware Schema Intersection
89
+ for a_key, a_type in a_outputs.items():
90
+ if a_key.lower() in common_fields:
91
+ continue
92
+ for b_key, b_type in b_inputs.items():
93
+ if a_key.lower() == b_key.lower() and a_type == b_type:
94
+ edge_weight += 5
95
+ mapped_fields.append((b_key, a_key))
96
+
97
+ # Rule 2: Path Hierarchy (RESTful dependency)
98
+ if a_path in b_path and len(a_path) < len(b_path):
99
+ edge_weight += 10
100
+
101
+ # Rule 3: CRUD Semantics on the exact same path
102
+ if a_path == b_path:
103
+ crud_order = {"POST": 1, "GET": 2, "PUT": 3, "PATCH": 4, "DELETE": 5}
104
+ a_order = crud_order.get(a_method, 99)
105
+ b_order = crud_order.get(b_method, 99)
106
+ if a_order < b_order:
107
+ edge_weight += 3
108
+
109
+ if edge_weight > 0:
110
+ G.add_edge(a_id, b_id, weight=edge_weight)
111
+ for b_key, a_key in mapped_fields:
112
+ if b_key not in bindings[b_id]:
113
+ bindings[b_id][b_key] = f"{{{{{a_id}.{a_key}}}}}"
114
+
115
+ # Cycle Management Engine
116
+ try:
117
+ sorted_ids = list(nx.lexicographical_topological_sort(G))
118
+ except nx.NetworkXUnfeasible:
119
+ logger.warning("Cycle detected in DAG. Initializing Cycle Management Engine.")
120
+ while True:
121
+ try:
122
+ cycles = list(nx.simple_cycles(G))
123
+ if not cycles:
124
+ break
125
+ for cycle in cycles:
126
+ min_weight = float('inf')
127
+ weakest_edge = None
128
+ for i in range(len(cycle)):
129
+ u = cycle[i]
130
+ v = cycle[(i + 1) % len(cycle)]
131
+ if G.has_edge(u, v):
132
+ w = G[u][v]["weight"]
133
+ if w < min_weight:
134
+ min_weight = w
135
+ weakest_edge = (u, v)
136
+ if weakest_edge:
137
+ G.remove_edge(*weakest_edge)
138
+ logger.info(f"Cycle Management: Removed weakest edge {weakest_edge} (weight {min_weight})")
139
+ # Also remove the binding that caused this edge
140
+ target_id = weakest_edge[1]
141
+ bindings[target_id] = {k: v for k, v in bindings[target_id].items() if not v.startswith(f"{{{{{weakest_edge[0]}.")}
142
+ sorted_ids = list(nx.lexicographical_topological_sort(G))
143
+ break
144
+ except nx.NetworkXUnfeasible:
145
+ continue
146
+
147
+ ep_map = {ep["operation_id"]: ep for ep in endpoints}
148
+ sorted_endpoints = []
149
+
150
+ # Handle disconnected nodes gracefully
151
+ all_nodes = set(ep_map.keys())
152
+ sorted_set = set(sorted_ids)
153
+ missing = all_nodes - sorted_set
154
+
155
+ for op_id in sorted_ids + list(missing):
156
+ ep = ep_map[op_id]
157
+ ep["variable_bindings"] = json.dumps(bindings.get(op_id, {}))
158
+ sorted_endpoints.append(ep)
159
+
160
+ return sorted_endpoints