QuickLab-MCP 0.1.0__py3-none-any.whl

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 (92) hide show
  1. ml_mcp/__init__.py +3 -0
  2. ml_mcp/application/__init__.py +1 -0
  3. ml_mcp/application/analysis/__init__.py +15 -0
  4. ml_mcp/application/analysis/diagnostics.py +122 -0
  5. ml_mcp/application/analysis/service.py +155 -0
  6. ml_mcp/application/artifacts/__init__.py +5 -0
  7. ml_mcp/application/artifacts/service.py +149 -0
  8. ml_mcp/application/datasets/__init__.py +6 -0
  9. ml_mcp/application/datasets/service.py +178 -0
  10. ml_mcp/application/datasets/validator.py +156 -0
  11. ml_mcp/application/experiments/__init__.py +5 -0
  12. ml_mcp/application/experiments/service.py +254 -0
  13. ml_mcp/application/models/__init__.py +6 -0
  14. ml_mcp/application/models/catalog_seed.py +131 -0
  15. ml_mcp/application/models/service.py +177 -0
  16. ml_mcp/application/projects/__init__.py +5 -0
  17. ml_mcp/application/projects/service.py +93 -0
  18. ml_mcp/config/__init__.py +5 -0
  19. ml_mcp/config/settings.py +176 -0
  20. ml_mcp/domain/__init__.py +1 -0
  21. ml_mcp/domain/errors/__init__.py +39 -0
  22. ml_mcp/domain/errors/base.py +155 -0
  23. ml_mcp/domain/errors/codes.py +23 -0
  24. ml_mcp/domain/policies/__init__.py +16 -0
  25. ml_mcp/domain/policies/rbac.py +126 -0
  26. ml_mcp/domain/policies/tenant_isolation.py +34 -0
  27. ml_mcp/domain/policies/tool_policy.py +185 -0
  28. ml_mcp/domain/value_objects/__init__.py +41 -0
  29. ml_mcp/domain/value_objects/dataset.py +60 -0
  30. ml_mcp/domain/value_objects/experiment.py +131 -0
  31. ml_mcp/domain/value_objects/model.py +48 -0
  32. ml_mcp/infrastructure/__init__.py +1 -0
  33. ml_mcp/infrastructure/object_storage/__init__.py +5 -0
  34. ml_mcp/infrastructure/object_storage/s3.py +272 -0
  35. ml_mcp/infrastructure/postgres/__init__.py +14 -0
  36. ml_mcp/infrastructure/postgres/base.py +40 -0
  37. ml_mcp/infrastructure/postgres/models.py +356 -0
  38. ml_mcp/infrastructure/postgres/repositories/__init__.py +21 -0
  39. ml_mcp/infrastructure/postgres/repositories/artifacts.py +34 -0
  40. ml_mcp/infrastructure/postgres/repositories/audit.py +34 -0
  41. ml_mcp/infrastructure/postgres/repositories/datasets.py +85 -0
  42. ml_mcp/infrastructure/postgres/repositories/experiments.py +134 -0
  43. ml_mcp/infrastructure/postgres/repositories/metrics.py +61 -0
  44. ml_mcp/infrastructure/postgres/repositories/models.py +61 -0
  45. ml_mcp/infrastructure/postgres/repositories/outbox.py +47 -0
  46. ml_mcp/infrastructure/postgres/repositories/projects.py +83 -0
  47. ml_mcp/infrastructure/postgres/session.py +117 -0
  48. ml_mcp/infrastructure/queue/__init__.py +6 -0
  49. ml_mcp/infrastructure/queue/outbox_processor.py +67 -0
  50. ml_mcp/infrastructure/queue/task_queue.py +98 -0
  51. ml_mcp/infrastructure/redis/__init__.py +11 -0
  52. ml_mcp/infrastructure/redis/client.py +64 -0
  53. ml_mcp/infrastructure/redis/rate_limiter.py +129 -0
  54. ml_mcp/infrastructure/telemetry/__init__.py +23 -0
  55. ml_mcp/infrastructure/telemetry/logging.py +155 -0
  56. ml_mcp/infrastructure/telemetry/otel.py +141 -0
  57. ml_mcp/mcp/__init__.py +1 -0
  58. ml_mcp/mcp/prompts.py +38 -0
  59. ml_mcp/mcp/resources.py +35 -0
  60. ml_mcp/mcp/schemas/__init__.py +1 -0
  61. ml_mcp/mcp/schemas/tools.py +124 -0
  62. ml_mcp/mcp/tools/__init__.py +63 -0
  63. ml_mcp/mcp/tools/analysis.py +37 -0
  64. ml_mcp/mcp/tools/datasets.py +82 -0
  65. ml_mcp/mcp/tools/discovery.py +82 -0
  66. ml_mcp/mcp/tools/experiments.py +96 -0
  67. ml_mcp/mcp/tools/projects.py +39 -0
  68. ml_mcp/mcp/tools/results.py +59 -0
  69. ml_mcp/server/__init__.py +1 -0
  70. ml_mcp/server/app.py +488 -0
  71. ml_mcp/server/auth.py +146 -0
  72. ml_mcp/server/context.py +59 -0
  73. ml_mcp/server/http.py +183 -0
  74. ml_mcp/server/middleware.py +121 -0
  75. ml_mcp/server/stdio.py +42 -0
  76. ml_mcp/workers/__init__.py +1 -0
  77. ml_mcp/workers/daemon.py +130 -0
  78. ml_mcp/workers/metrics.py +110 -0
  79. ml_mcp/workers/preprocessing.py +170 -0
  80. ml_mcp/workers/runner.py +250 -0
  81. ml_mcp/workers/sandbox.py +35 -0
  82. ml_mcp/workers/trainers/__init__.py +52 -0
  83. ml_mcp/workers/trainers/base.py +52 -0
  84. ml_mcp/workers/trainers/catboost_model.py +85 -0
  85. ml_mcp/workers/trainers/lightgbm_model.py +81 -0
  86. ml_mcp/workers/trainers/sklearn_models.py +266 -0
  87. ml_mcp/workers/trainers/xgboost_model.py +82 -0
  88. quicklab_mcp-0.1.0.dist-info/METADATA +540 -0
  89. quicklab_mcp-0.1.0.dist-info/RECORD +92 -0
  90. quicklab_mcp-0.1.0.dist-info/WHEEL +5 -0
  91. quicklab_mcp-0.1.0.dist-info/entry_points.txt +4 -0
  92. quicklab_mcp-0.1.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,540 @@
1
+ Metadata-Version: 2.4
2
+ Name: QuickLab-MCP
3
+ Version: 0.1.0
4
+ Summary: QuickLab MCP Server - Production Tabular ML Experimentation Control Plane for AI Agents
5
+ Author: QuickLab Team
6
+ License-Expression: Apache-2.0
7
+ Project-URL: Homepage, https://github.com/Aldrin-Joan/QuickLab-MCP
8
+ Project-URL: Repository, https://github.com/Aldrin-Joan/QuickLab-MCP.git
9
+ Project-URL: Issues, https://github.com/Aldrin-Joan/QuickLab-MCP/issues
10
+ Project-URL: Documentation, https://github.com/Aldrin-Joan/QuickLab-MCP#readme
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
16
+ Requires-Python: >=3.13
17
+ Description-Content-Type: text/markdown
18
+ Requires-Dist: fastmcp==4.0.5
19
+ Requires-Dist: pydantic<3.0.0,>=2.7.0
20
+ Requires-Dist: pydantic-settings<3.0.0,>=2.2.0
21
+ Requires-Dist: sqlalchemy[asyncio]<3.0.0,>=2.0.30
22
+ Requires-Dist: asyncpg>=0.29.0
23
+ Requires-Dist: redis>=5.0.4
24
+ Requires-Dist: boto3>=1.34.0
25
+ Requires-Dist: aioboto3>=13.0.0
26
+ Requires-Dist: botocore>=1.34.0
27
+ Requires-Dist: pyarrow>=16.0.0
28
+ Requires-Dist: pandas>=2.2.0
29
+ Requires-Dist: numpy>=1.26.0
30
+ Requires-Dist: scikit-learn>=1.5.0
31
+ Requires-Dist: xgboost>=2.0.3
32
+ Requires-Dist: lightgbm>=4.3.0
33
+ Requires-Dist: catboost>=1.2.5
34
+ Requires-Dist: joblib>=1.4.0
35
+ Requires-Dist: httpx>=0.27.0
36
+ Requires-Dist: pyjwt[crypto]>=2.8.0
37
+ Requires-Dist: cryptography>=42.0.0
38
+ Requires-Dist: alembic>=1.13.0
39
+ Requires-Dist: opentelemetry-api>=1.24.0
40
+ Requires-Dist: opentelemetry-sdk>=1.24.0
41
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.24.0
42
+ Requires-Dist: uvicorn>=0.30.0
43
+ Provides-Extra: dev
44
+ Requires-Dist: pytest>=8.2.0; extra == "dev"
45
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
46
+ Requires-Dist: pytest-cov>=5.0.0; extra == "dev"
47
+ Requires-Dist: aiosqlite>=0.20.0; extra == "dev"
48
+ Requires-Dist: ruff>=0.4.0; extra == "dev"
49
+ Requires-Dist: mypy>=1.10.0; extra == "dev"
50
+ Requires-Dist: types-redis>=4.6.0; extra == "dev"
51
+ Requires-Dist: types-boto3>=1.34.0; extra == "dev"
52
+ Requires-Dist: types-PyYAML>=6.0.0; extra == "dev"
53
+
54
+ # QuickLab MCP
55
+
56
+ [![Python Version](https://img.shields.io/badge/python-3.13%2B-blue.svg)](https://www.python.org/downloads/)
57
+ [![PyPI](https://img.shields.io/badge/pypi-QuickLab--MCP-blue.svg)](https://pypi.org/project/QuickLab-MCP/)
58
+ [![MCP Protocol](https://img.shields.io/badge/MCP%20Protocol-2026--07--28-orange.svg)](https://modelcontextprotocol.io/)
59
+ [![FastMCP](https://img.shields.io/badge/FastMCP-4.0.5%20GA-green.svg)](https://github.com/jlowin/fastmcp)
60
+ [![Tests](https://img.shields.io/badge/tests-104%20passed%20%7C%20100%25-brightgreen.svg)]()
61
+ [![Code Style](https://img.shields.io/badge/code%20style-ruff-black.svg)](https://github.com/astral-sh/ruff)
62
+ [![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)
63
+ [![Security](https://img.shields.io/badge/security-OAuth%202.1%20%2F%20OIDC-purple.svg)]()
64
+
65
+ **QuickLab MCP** (formerly ModelLab) is an enterprise-grade Machine Learning Experimentation Control Plane exposed via the **Model Context Protocol (MCP)**. Engineered with FastMCP 4 and conforming to the standard MCP baseline (`2026-07-28`), QuickLab enables autonomous AI agents and human data scientists to discover approved architectures, validate tabular datasets, submit reproducible training experiments, inspect predictions/metrics, and perform deep diagnostic analysis—**with zero arbitrary code execution**.
66
+
67
+ ---
68
+
69
+ ## Key Highlights
70
+
71
+ - **Zero Placeholders, Real Tabular ML**: Fully implemented, sandboxed training algorithms for all 7 approved tabular architectures: **Logistic Regression**, **Random Forest**, **XGBoost**, **LightGBM**, **CatBoost**, **Linear SVM**, and **Multi-Layer Perceptron (MLP)**.
72
+ - **23 MCP Tools, 3 Resources, 2 Prompts**: Comprehensive tool catalog across Projects, Discovery, Ingestion, Experimentation, Artifacts, and Diagnostics.
73
+ - **Strict Leak-Free Preprocessing**: Preprocessing transforms (median/mode imputation, standard scaling, one-hot encoding) are fitted strictly on training folds and serialized alongside models.
74
+ - **Dual Production Transports**:
75
+ - **STDIO Transport**: Pure JSON-RPC on standard output (`sys.stdout`) with all structured logging isolated strictly to `sys.stderr`.
76
+ - **Streamable HTTP Transport**: Modern HTTP transport mounted at `/mcp` with Bearer auth middleware and operational probes (`/health/live`, `/health/ready`).
77
+ - **OAuth 2.1 & Multi-Tenant Security**: Tenant boundary enforcement, RBAC matrix (`Viewer`, `Researcher`, `Operator`, `Admin`), token scope attenuation, and anti-enumeration protections (HTTP 404 instead of 403 on cross-tenant probes).
78
+ - **Transactional Outbox Architecture**: Guarantees zero lost experiment submissions using PostgreSQL transactional Outbox events dispatched to Redis queues.
79
+ - **S3 / MinIO Object Storage**: Immutable tenant-isolated artifact storage with SHA-256 integrity verification, presigned download URLs, and offline memory fallback.
80
+ - **Full Test Coverage**: **104 tests passing (100% green)** across unit, integration, security matrix, MCP contract, and full end-to-end experiment lifecycle.
81
+
82
+ ---
83
+
84
+ ## Architectural Topology
85
+
86
+ ```mermaid
87
+ flowchart TD
88
+ subgraph Clients["AI Agents & IDE Interfaces"]
89
+ Claude["Claude Desktop / VS Code / Cursor"]
90
+ Autonomous["Autonomous Agent Mesh"]
91
+ end
92
+
93
+ subgraph ControlPlane["ModelLab Control Plane (FastMCP 4)"]
94
+ HTTPGateway["Streamable HTTP Gateway (/mcp)"]
95
+ STDIOGateway["STDIO Transport (Local IPC)"]
96
+ AuthMiddleware["OAuth 2.1 / OIDC Bearer Validator"]
97
+ RateLimiter["Sliding-Window Rate Limiter"]
98
+ ToolRouter["21 MCP Tools & Resource Engine"]
99
+ end
100
+
101
+ subgraph Persistence["Persistence & Message Broker"]
102
+ Postgres[(PostgreSQL 16\nSchema & Outbox Events)]
103
+ Redis[(Redis 7\nQueue & Rate Limit Window)]
104
+ MinIO[(MinIO / S3\nDatasets & Model Artifacts)]
105
+ end
106
+
107
+ subgraph WorkerLayer["Sandboxed Worker Execution"]
108
+ WorkerEngine["Tabular ML Execution Runner"]
109
+ Preproc["Leak-Free Preprocessing Pipeline"]
110
+ Trainers["7 Approved Tabular Trainers\n(RF, XGB, LGBM, CatB, LR, SVM, MLP)"]
111
+ end
112
+
113
+ subgraph Telemetry["Observability & Diagnostics"]
114
+ OTEL["OpenTelemetry Collector"]
115
+ JSONStderr["Structured JSON Logs (stderr)"]
116
+ end
117
+
118
+ Claude -->|STDIO| STDIOGateway
119
+ Autonomous -->|HTTP Bearer| HTTPGateway
120
+ HTTPGateway --> AuthMiddleware
121
+ AuthMiddleware --> RateLimiter
122
+ RateLimiter --> ToolRouter
123
+ STDIOGateway --> ToolRouter
124
+
125
+ ToolRouter --> Postgres
126
+ ToolRouter --> Redis
127
+ ToolRouter --> MinIO
128
+
129
+ Postgres -->|Transactional Outbox| Redis
130
+ Redis --> WorkerEngine
131
+ WorkerEngine --> Preproc
132
+ Preproc --> Trainers
133
+ Trainers --> MinIO
134
+ Trainers --> Postgres
135
+
136
+ ControlPlane --> JSONStderr
137
+ ControlPlane --> OTEL
138
+ WorkerEngine --> OTEL
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Complete MCP Tool Catalog
144
+
145
+ ModelLab exposes 23 granular tools across 6 functional categories:
146
+
147
+ ### 1. Project Management Tools
148
+
149
+ | Tool Name | Parameters | Required Scope | Description |
150
+ | :--- | :--- | :--- | :--- |
151
+ | `create_project` | `name`, `description` *(opt)* | `ml:projects:write` | Create a new project workspace under the caller's tenant boundary. |
152
+ | `list_projects` | `limit` *(opt)*, `offset` *(opt)* | `ml:projects:read` | List active projects accessible within the caller's tenant boundary. |
153
+
154
+ ### 2. Discovery Tools
155
+
156
+ | Tool Name | Parameters | Required Scope | Description |
157
+ | :--- | :--- | :--- | :--- |
158
+ | `list_models` | *none* | `ml:models:read` | List all approved tabular ML models in the catalog. |
159
+ | `get_model` | `model_id` | `ml:models:read` | Inspect hyperparameter schemas, bounds, and container digests for a model. |
160
+ | `list_model_versions` | `model_id` | `ml:models:read` | List registered immutable versions for a specific model family. |
161
+ | `list_datasets` | `project_id` *(opt)* | `ml:datasets:read` | List datasets available within the caller's tenant/project boundary. |
162
+ | `get_dataset` | `dataset_id` | `ml:datasets:read` | Retrieve metadata, format, and version history for a specific dataset. |
163
+ | `list_dataset_versions` | `dataset_id` | `ml:datasets:read` | List immutable versions, row counts, and SHA-256 hashes for a dataset. |
164
+
165
+ ### 3. Dataset Management & Validation Tools
166
+
167
+ | Tool Name | Parameters | Required Scope | Description |
168
+ | :--- | :--- | :--- | :--- |
169
+ | `register_dataset` | `project_id`, `name`, `description`, `format`, `data_base64`, `version` | `ml:datasets:write` | Ingest and validate a tabular dataset (CSV/Parquet/JSONL), store as Parquet, and record content hash. |
170
+ | `validate_dataset` | `format`, `data_base64` | `ml:datasets:read` | Validate raw dataset bytes against schema rules and row limits without persisting. |
171
+ | `inspect_dataset` | `dataset_id`, `version`, `sample_rows` | `ml:datasets:read` | Inspect schema column types, missingness, and head preview rows. |
172
+
173
+ ### 4. Experimentation Tools
174
+
175
+ | Tool Name | Parameters | Required Scope | Description |
176
+ | :--- | :--- | :--- | :--- |
177
+ | `create_experiment` | `project_id`, `dataset_version_id`, `model_version_id`, `task_type`, `target_column`, `feature_columns`, `primary_metric`, `additional_metrics`, `hyperparameters`, `random_seed`, `idempotency_key` | `ml:experiments:create` | Formulate, validate (target/feature columns, model bounds), and queue an ML experiment with transactional Outbox event. |
178
+ | `get_experiment` | `experiment_id` | `ml:experiments:read` | Retrieve current lifecycle state (`QUEUED`, `RUNNING`, `SUCCEEDED`, `FAILED`, `CANCELLED`), run counts, timestamps, and error details (`error_message`, `error_type`) if failed. |
179
+ | `cancel_experiment` | `experiment_id` | `ml:experiments:cancel` | Gracefully cancel an active or queued experiment run. |
180
+ | `list_experiments` | `project_id`, `status`, `limit`, `offset` | `ml:experiments:read` | Paginated listing of experiments within a project with optional status filter. |
181
+
182
+ ### 5. Results & Artifacts Tools
183
+
184
+ | Tool Name | Parameters | Required Scope | Description |
185
+ | :--- | :--- | :--- | :--- |
186
+ | `get_experiment_metrics` | `experiment_id` | `ml:experiments:read` | Retrieve computed metrics across `train` and `validation` splits. |
187
+ | `get_experiment_predictions` | `experiment_id`, `limit` | `ml:artifacts:read` | Retrieve sample prediction records (`y_true`, `y_pred`, `y_proba_*`) and presigned download URL. |
188
+ | `list_experiment_artifacts` | `experiment_id` | `ml:artifacts:read` | List all persisted artifacts (`model.joblib`, `preprocessor.joblib`, `predictions.parquet`, `metrics.json`). |
189
+ | `read_experiment_artifact` | `artifact_id` | `ml:artifacts:read` | Retrieve artifact metadata and secure presigned S3 download URL. |
190
+ | `compare_experiments` | `experiment_ids` | `ml:experiments:read` | Side-by-side comparison of validation metrics and hyperparameters across runs. |
191
+
192
+ ### 6. Structured Diagnostic Analysis Tools
193
+
194
+ | Tool Name | Parameters | Required Scope | Description |
195
+ | :--- | :--- | :--- | :--- |
196
+ | `analyze_experiment` | `experiment_id` | `ml:analysis:create` | Automated diagnostic report evaluating generalization gap, overfitting severity, and data leakage risks. |
197
+ | `analyze_model_errors` | `experiment_id` | `ml:analysis:create` | Deep error slice analysis including residual skew, false positives vs false negatives, and anomaly counts. |
198
+ | `check_experiment_validity` | `experiment_id` | `ml:analysis:create` | Automated verification of experiment validity, dataset lineage, and metric reproducibility. |
199
+
200
+ ---
201
+
202
+ ## MCP Resources & Prompts
203
+
204
+ ### Resources
205
+ - `modellab://models`: Static resource cataloging all approved model architectures.
206
+ - `modellab://models/{model_id}`: Parameterized template for full model hyperparameter schemas.
207
+ - `modellab://experiments/{experiment_id}/metrics`: Parameterized template for experiment metrics.
208
+
209
+ ### Prompts
210
+ - `experiment_design`: Guided architectural workflow prompting agents to formulate sound hypotheses, choose candidate models, and select non-leaking split strategies.
211
+ - `error_diagnosis`: Structured diagnostic workflow assisting agents in diagnosing training regressions, severe class imbalances, or generalization gaps.
212
+
213
+ ---
214
+
215
+ ## Approved Model Families & Hyperparameter Bounds
216
+
217
+ | Model Family | `model_id` | Supported Task Types | Key Hyperparameters (Strictly Validated) |
218
+ | :--- | :--- | :--- | :--- |
219
+ | **Random Forest** | `random_forest` | Binary / Multiclass Classification, Regression | `n_estimators` [10–1000], `max_depth` [1–50], `min_samples_split` [2–20] |
220
+ | **XGBoost** | `xgboost` | Binary / Multiclass Classification, Regression | `n_estimators` [10–2000], `max_depth` [1–16], `learning_rate` [0.001–1.0], `subsample` [0.1–1.0] |
221
+ | **LightGBM** | `lightgbm` | Binary / Multiclass Classification, Regression | `n_estimators` [10–2000], `num_leaves` [7–256], `learning_rate` [0.001–1.0] |
222
+ | **CatBoost** | `catboost` | Binary / Multiclass Classification, Regression | `iterations` [10–2000], `depth` [1–12], `learning_rate` [0.001–1.0] |
223
+ | **Logistic Regression** | `logistic_regression` | Binary / Multiclass Classification | `C` [0.001–1000.0], `penalty` (`l1`, `l2`, `elasticnet`, `none`), `solver` |
224
+ | **Linear SVM** | `linear_svm` | Binary / Multiclass Classification, Regression | `C` [0.001–100.0], `loss` (`hinge`, `squared_hinge`), `max_iter` [100–10000] |
225
+ | **Multi-Layer Perceptron** | `mlp` | Binary / Multiclass Classification, Regression | `hidden_layer_sizes`, `activation` (`relu`, `tanh`), `alpha` [1e-6–1.0], `learning_rate_init` |
226
+
227
+ ---
228
+
229
+ ## Quickstart
230
+
231
+ ### Prerequisites
232
+ - Python 3.13+ (or Conda environment `ML_LLM`)
233
+ - Docker & Docker Compose (optional, for local services)
234
+
235
+ ### 1. Installation
236
+
237
+ #### Instant Execution via `uvx` (Recommended)
238
+ No cloning required — run QuickLab directly with Astral `uv`:
239
+ ```bash
240
+ uvx quicklab-mcp
241
+ ```
242
+
243
+ #### Local Development Installation
244
+ ```bash
245
+ # Clone the repository
246
+ git clone https://github.com/Aldrin-Joan/QuickLab-MCP.git
247
+ cd QuickLab-MCP
248
+
249
+ # Install dependencies using uv
250
+ uv sync
251
+ ```
252
+
253
+ ### 2. Run the Full Test Suite
254
+
255
+ Verify all 75 automated tests across unit, integration, contract, security, and e2e suites:
256
+
257
+ ```bash
258
+ pytest tests/ -v
259
+ ```
260
+
261
+ Output:
262
+ ```text
263
+ ================= 75 passed, 7 warnings in 187.73s (0:03:07) ==================
264
+ ```
265
+
266
+ ### 3. Launch Local Infrastructure (Optional)
267
+
268
+ Spin up PostgreSQL 16, Redis 7, MinIO S3, and OpenTelemetry Collector:
269
+
270
+ ```bash
271
+ docker compose up -d
272
+ ```
273
+
274
+ Apply database migrations:
275
+
276
+ ```bash
277
+ alembic upgrade head
278
+ ```
279
+
280
+ ### 4. Running ModelLab
281
+
282
+ #### Option A: Streamable HTTP Mode (Production & Remote Agents)
283
+
284
+ ```bash
285
+ python -m ml_mcp.server.http
286
+ ```
287
+
288
+ Access operational endpoints:
289
+ - Liveness Probe: `http://127.0.0.1:8000/health/live`
290
+ - Readiness Probe: `http://127.0.0.1:8000/health/ready`
291
+ - MCP Endpoint: `http://127.0.0.1:8000/mcp`
292
+
293
+ #### Option B: STDIO Transport Mode (IDE & Desktop Agents)
294
+
295
+ ```bash
296
+ python -m ml_mcp.server.stdio
297
+ ```
298
+
299
+ ---
300
+
301
+ ## MCP Client Configuration
302
+
303
+ ModelLab supports both **STDIO** (local subprocess IPC) and **Streamable HTTP** (networked SSE + POST) transports across both **Docker** and **UV / local Python**.
304
+
305
+ Select your preferred runtime configuration below:
306
+
307
+ ### 1. Docker + STDIO
308
+ Runs ModelLab inside an isolated Docker container with standard I/O (`sys.stdin` / `sys.stdout`) piped directly to the MCP client.
309
+
310
+ ```json
311
+ {
312
+ "mcpServers": {
313
+ "modellab": {
314
+ "command": "docker",
315
+ "args": [
316
+ "run",
317
+ "-i",
318
+ "--rm",
319
+ "--entrypoint", "python",
320
+ "--network", "host",
321
+ "-e", "APP_ENV=production",
322
+ "-e", "DATABASE_URL=postgresql+asyncpg://postgres:postgres@localhost:5433/modellab",
323
+ "-e", "REDIS_URL=redis://localhost:6379/0",
324
+ "-e", "OBJECT_STORE_ENDPOINT_URL=http://localhost:9000",
325
+ "-e", "OBJECT_STORE_ACCESS_KEY_ID=minioadmin",
326
+ "-e", "OBJECT_STORE_SECRET_ACCESS_KEY=minioadmin",
327
+ "-e", "OBJECT_STORE_BUCKET_NAME=modellab-artifacts",
328
+ "modellab-api",
329
+ "-m", "ml_mcp.server.stdio"
330
+ ]
331
+ }
332
+ }
333
+ }
334
+ ```
335
+
336
+ > **Note for Docker Desktop (macOS / Windows)**: If `--network host` is unavailable in your Docker Desktop environment, connect via the shared Docker network:
337
+ > ```json
338
+ > "args": [
339
+ > "run", "-i", "--rm",
340
+ > "--entrypoint", "python",
341
+ > "--network", "modellab_default",
342
+ > "-e", "DATABASE_URL=postgresql+asyncpg://postgres:postgres@postgres:5432/modellab",
343
+ > "-e", "REDIS_URL=redis://redis:6379/0",
344
+ > "-e", "OBJECT_STORE_ENDPOINT_URL=http://minio:9000",
345
+ > "-e", "OBJECT_STORE_ACCESS_KEY_ID=minioadmin",
346
+ > "-e", "OBJECT_STORE_SECRET_ACCESS_KEY=minioadmin",
347
+ > "-e", "OBJECT_STORE_BUCKET_NAME=modellab-artifacts",
348
+ > "modellab-api",
349
+ > "-m", "ml_mcp.server.stdio"
350
+ > ]
351
+ > ```
352
+
353
+ ---
354
+
355
+ ### 2. Docker + HTTP
356
+ Connects to the ModelLab API service running inside Docker Compose (`docker compose -f docker-compose.http.yml up -d`).
357
+
358
+ ```json
359
+ {
360
+ "mcpServers": {
361
+ "modellab": {
362
+ "url": "http://localhost:8000/mcp",
363
+ "headers": {
364
+ "Authorization": "Bearer <YOUR_JWT_BEARER_TOKEN>"
365
+ }
366
+ }
367
+ }
368
+ }
369
+ ```
370
+
371
+ ---
372
+
373
+ ### 3. UVX + STDIO (Recommended Turnkey Setup)
374
+ Runs QuickLab globally via `uvx` directly from PyPI:
375
+
376
+ ```json
377
+ {
378
+ "mcpServers": {
379
+ "quicklab": {
380
+ "command": "uvx",
381
+ "args": ["quicklab-mcp"],
382
+ "env": {
383
+ "APP_ENV": "production",
384
+ "DATABASE_URL": "postgresql+asyncpg://postgres:postgres@localhost:5433/modellab",
385
+ "REDIS_URL": "redis://localhost:6379/0",
386
+ "OBJECT_STORE_ENDPOINT_URL": "http://localhost:9000",
387
+ "OBJECT_STORE_ACCESS_KEY_ID": "minioadmin",
388
+ "OBJECT_STORE_SECRET_ACCESS_KEY": "minioadmin",
389
+ "OBJECT_STORE_BUCKET_NAME": "modellab-artifacts"
390
+ }
391
+ }
392
+ }
393
+ }
394
+ ```
395
+
396
+ Or for local source development with `uv`:
397
+ ```json
398
+ {
399
+ "mcpServers": {
400
+ "quicklab": {
401
+ "command": "uv",
402
+ "args": [
403
+ "run",
404
+ "--directory", "/absolute/path/to/QuickLab-MCP",
405
+ "python", "-m", "ml_mcp.server.stdio"
406
+ ],
407
+ "env": {
408
+ "APP_ENV": "production",
409
+ "DATABASE_URL": "postgresql+asyncpg://postgres:postgres@localhost:5433/modellab",
410
+ "REDIS_URL": "redis://localhost:6379/0",
411
+ "OBJECT_STORE_ENDPOINT_URL": "http://localhost:9000",
412
+ "OBJECT_STORE_ACCESS_KEY_ID": "minioadmin",
413
+ "OBJECT_STORE_SECRET_ACCESS_KEY": "minioadmin",
414
+ "OBJECT_STORE_BUCKET_NAME": "modellab-artifacts"
415
+ }
416
+ }
417
+ }
418
+ }
419
+ ```
420
+
421
+ ---
422
+
423
+ ### 4. UV + HTTP
424
+ Starts the ModelLab HTTP service locally with `uv` and connects client agents via Streamable HTTP.
425
+
426
+ **1. Launch the server:**
427
+ ```bash
428
+ uv run python -m ml_mcp.server.http
429
+ ```
430
+
431
+ **2. Client Configuration (`mcp.json` / `claude_desktop_config.json`):**
432
+ ```json
433
+ {
434
+ "mcpServers": {
435
+ "modellab": {
436
+ "url": "http://localhost:8000/mcp",
437
+ "headers": {
438
+ "Authorization": "Bearer <YOUR_JWT_BEARER_TOKEN>"
439
+ }
440
+ }
441
+ }
442
+ }
443
+ ```
444
+
445
+ ---
446
+
447
+ ### Generating an OAuth 2.1 Bearer Token (for HTTP Modes)
448
+
449
+ Generate a cryptographically signed JWT token for authentication in HTTP mode:
450
+
451
+ ```bash
452
+ uv run python -c "
453
+ from ml_mcp.server.auth import TokenValidator
454
+ from ml_mcp.domain.policies import Role, Scope
455
+
456
+ validator = TokenValidator()
457
+ token = validator.create_access_token(
458
+ principal_id='agent-user',
459
+ tenant_id='default-tenant',
460
+ role=Role.ADMIN,
461
+ scopes=[s.value for s in Scope],
462
+ )
463
+ print('Bearer Token:\n' + token)
464
+ "
465
+ ```
466
+
467
+ ---
468
+
469
+ ## Security & Access Control (RBAC)
470
+
471
+ ModelLab implements a zero-trust security architecture adhering to OAuth 2.1:
472
+
473
+ | Scope | Viewer | Researcher | Operator | Admin |
474
+ | :--- | :---: | :---: | :---: | :---: |
475
+ | `ml:models:read` | ✅ | ✅ | ✅ | ✅ |
476
+ | `ml:datasets:read` | ✅ | ✅ | ✅ | ✅ |
477
+ | `ml:datasets:write` | ❌ | ✅ | ✅ | ✅ |
478
+ | `ml:experiments:read` | ✅ | ✅ | ✅ | ✅ |
479
+ | `ml:experiments:create` | ❌ | ✅ | ✅ | ✅ |
480
+ | `ml:experiments:cancel` | ❌ | ✅ | ✅ | ✅ |
481
+ | `ml:analysis:create` | ❌ | ✅ | ✅ | ✅ |
482
+ | `ml:artifacts:read` | ✅ | ✅ | ✅ | ✅ |
483
+ | `ml:worker:operate` | ❌ | ❌ | ✅ | ✅ |
484
+ | `ml:experiment:override` | ❌ | ❌ | ❌ | ✅ |
485
+
486
+ - **Scope Attenuation**: Access tokens carrying specific scopes attenuate privileges below role defaults.
487
+ - **Anti-Enumeration Defense**: Requests attempting cross-tenant resource access consistently return HTTP 404 (`ResourceNotFoundError`) rather than 403, preventing attackers from probing valid resource IDs.
488
+ - **Sensitive Key Redaction**: Telemetry and logs automatically scrub sensitive credentials (`password`, `secret`, `token`, `key`, `authorization`).
489
+
490
+ ---
491
+
492
+ ## Production Containerization
493
+
494
+ Multi-stage [Dockerfile](Dockerfile) provides hardened images running as unprivileged users:
495
+
496
+ ```bash
497
+ # Build API Server container
498
+ docker build --target ml-mcp-api -t modellab/ml-mcp-api:latest .
499
+
500
+ # Build Sandboxed Worker container
501
+ docker build --target ml-worker-tabular-cpu -t modellab/ml-worker-tabular-cpu:latest .
502
+ ```
503
+
504
+ Both container images run with read-only root filesystems and non-root users (`uid 10001` / `uid 10002`).
505
+
506
+ ---
507
+
508
+ ## Project Repository Structure
509
+
510
+ ```text
511
+ ModelLab/
512
+ ├── .github/workflows/ci.yml # Automated CI/CD pipeline (lint, test, build)
513
+ ├── alembic/versions/ # Database migration scripts
514
+ ├── deploy/docker/ # OTEL Collector and container deployment configs
515
+ ├── Docs/ # Architecture, Tech-Stack & Operational Guide
516
+ ├── src/ml_mcp/ # Core ModelLab application source
517
+ │ ├── application/ # Application services (models, datasets, analysis)
518
+ │ ├── config/ # Pydantic Settings & environment parsing
519
+ │ ├── domain/ # Domain models, policies, RBAC & error hierarchy
520
+ │ ├── infrastructure/ # Postgres ORM, Redis queue, S3 storage, OTEL
521
+ │ ├── mcp/ # FastMCP 4 tools, schemas, resources & prompts
522
+ │ ├── server/ # Server factory, auth validator, HTTP & STDIO
523
+ │ └── workers/ # Preprocessing, ML trainers & execution runner
524
+ ├── tests/ # 75 Automated Test Cases
525
+ │ ├── contract/ # FastMCP tool contract compliance tests
526
+ │ ├── e2e/ # Full ML experiment lifecycle end-to-end tests
527
+ │ ├── integration/ # Database, Outbox, Redis & Worker integration
528
+ │ ├── security/ # Multi-tenant isolation & RBAC security matrix
529
+ │ └── unit/ # Fast unit tests across all domain layers
530
+ ├── docker-compose.yml # Local PostgreSQL, Redis, MinIO & OTEL stack
531
+ ├── Dockerfile # Multi-stage production container build
532
+ ├── pyproject.toml # Package definition and locked dependencies
533
+ └── README.md # Project documentation
534
+ ```
535
+
536
+ ---
537
+
538
+ ## License
539
+
540
+ ModelLab is licensed under the Apache License, Version 2.0. See [LICENSE](LICENSE) for details.
@@ -0,0 +1,92 @@
1
+ ml_mcp/__init__.py,sha256=5NKCu2Ln5IJ4GP5to3YpPcDUVGLDpVgU4xDUbCstj_M,63
2
+ ml_mcp/application/__init__.py,sha256=G-ZEVx1uiabj6vGQGdMvxqPmkudfqGbb9olEWN5YcNM,33
3
+ ml_mcp/application/analysis/__init__.py,sha256=aFHqMi3rFE-O5GZUCKSzdJuVUpq8u91IILgdhyEe1UA,352
4
+ ml_mcp/application/analysis/diagnostics.py,sha256=8mG6nWlhtV5zx-T95Dq736EuB9hC-yO_VGN1iTH3IeQ,4745
5
+ ml_mcp/application/analysis/service.py,sha256=XlEWSuZdbRZfbda1QqqKtArhQkcd9hJbMXK4Na9xzF8,6691
6
+ ml_mcp/application/artifacts/__init__.py,sha256=85Ge7LiOVi3X6e1DineTas-djVLpEuLaCMENqS5HsEM,133
7
+ ml_mcp/application/artifacts/service.py,sha256=VArkaMzdQc4LTew7nzlMoAWUr8qzQfyPIghTYC5hIpM,5438
8
+ ml_mcp/application/datasets/__init__.py,sha256=FOig5S_BxChC1j5alYm2JtHVSdsS_SiogipPxW0lTOU,229
9
+ ml_mcp/application/datasets/service.py,sha256=7lV1Ulu2YmTVCouWQ3AuCeL6aWmaal__ArQ0gJWM5vs,6413
10
+ ml_mcp/application/datasets/validator.py,sha256=Lzmpg8LMZk8GRtbKlZNoTPUZmmXNyuNOhLcO3c08J0g,6744
11
+ ml_mcp/application/experiments/__init__.py,sha256=OCTOflG16HnaCE7WP2dZOWPGUPg7fJNDccc09Q_Tx8A,141
12
+ ml_mcp/application/experiments/service.py,sha256=1wDTk0vrgAUx405SK9NQ8IXKEnFH5LGzSwODLOgCAK0,9779
13
+ ml_mcp/application/models/__init__.py,sha256=lOf3lQgHkF430D6I4M3qddvnUoc1BFXLdV20JK5kSL0,203
14
+ ml_mcp/application/models/catalog_seed.py,sha256=fbMi5dXwCxyQS5mY8Is0Pc9rVuY-MTG4YnuLkIbtAGY,7556
15
+ ml_mcp/application/models/service.py,sha256=ql3LGQK2TIw_2AokE8IcF1JqmB_XQRRGQWCYgZL3cDg,7705
16
+ ml_mcp/application/projects/__init__.py,sha256=DiYSga6TqMv1XJxjmCATNQ49mJF__TYAMeu-lb9iJGY,130
17
+ ml_mcp/application/projects/service.py,sha256=V2HprpqG_q_sZdU7swF54qIyxVG563lCfK6njdJcDGQ,3333
18
+ ml_mcp/config/__init__.py,sha256=Y2vwEx9LaWwnxVgDdWi4droTS_i9kYhsVOLmlwcCAdU,145
19
+ ml_mcp/config/settings.py,sha256=hHQRz1m0guOLq7ZFNmDDYjHUPzpoF5hIK5myOgO6geI,5700
20
+ ml_mcp/domain/__init__.py,sha256=bS6yxbqgrdZchhheO-d3crM232Bh68v2CIGsJVLsojM,48
21
+ ml_mcp/domain/errors/__init__.py,sha256=pTs3gJriPqaAFI7MvVyRGJ23_PpzLnDREtpDbwfpZhI,1055
22
+ ml_mcp/domain/errors/base.py,sha256=CshLpNOU7aMMbtGeK942nN4L2NfXVyX8hX65fJHxc2A,5491
23
+ ml_mcp/domain/errors/codes.py,sha256=mbxQagM4qBt4G1iA__2s8Ty5-SZrIP2zGSoGIQYIcnM,943
24
+ ml_mcp/domain/policies/__init__.py,sha256=9k1QWtiX_-YW441mlh3Qs3G3cb-K_ECkDHL3dabyMGc,439
25
+ ml_mcp/domain/policies/rbac.py,sha256=Ek0HQMqjDrpD9oGxU58bpcWpmyD-muFtdVxV4EqXg2E,4198
26
+ ml_mcp/domain/policies/tenant_isolation.py,sha256=PSD3zRAxPO7Z0ywErQQ_LAEVEv1nzLQjON7cTNq-9KU,1493
27
+ ml_mcp/domain/policies/tool_policy.py,sha256=xw0ZWCBgzfNS3zcLnXeI3Ihyurb-J6RqQ4zRLJyIcJk,5806
28
+ ml_mcp/domain/value_objects/__init__.py,sha256=6kWLexj_bLrhymNfHGfl2VGe3fd7rRI8VyDWQ2-ruQA,837
29
+ ml_mcp/domain/value_objects/dataset.py,sha256=0Vzgnl7J_McpaJwUHM9yt1HvaPDTj1Rm6vBB9t4SQSU,1795
30
+ ml_mcp/domain/value_objects/experiment.py,sha256=6VDefA_jADAWFjiBckFyZSV25o33INx3jgtkkzSFjkQ,4276
31
+ ml_mcp/domain/value_objects/model.py,sha256=dozqWALnxZq3iB9JeOWX0b-hoOouFh7vnEZiSu_Ms9o,1447
32
+ ml_mcp/infrastructure/__init__.py,sha256=D_StCHKRqyvxeKpP-_lrddfbBbJe75K86cT5biZvmcw,36
33
+ ml_mcp/infrastructure/object_storage/__init__.py,sha256=u4lX7ltzW6xqD7-VEL8hSE8mhYp7FTm32fPVYM0qXbc,176
34
+ ml_mcp/infrastructure/object_storage/s3.py,sha256=ZAS1DVqOrs-zdGBrUOUDBVQ7SQ1tb3L7LuJT0JUpZ3s,11518
35
+ ml_mcp/infrastructure/postgres/__init__.py,sha256=Eh9Vp9-pjlBI33g_vXD29fOcXr_IvkPL-J73C7f9opg,395
36
+ ml_mcp/infrastructure/postgres/base.py,sha256=UaBIzrNt4PCbMpllhVl_kU42lehH0OaKPS9Sc3Mcmaw,1060
37
+ ml_mcp/infrastructure/postgres/models.py,sha256=Y2thMyPpIapWerEXh83rJj6GWjN5EGis75KC6rsTGcE,16206
38
+ ml_mcp/infrastructure/postgres/session.py,sha256=8rrT23q0dfEN659IxJJLhe0wc5BP6zMmhWACKQX4KCc,3908
39
+ ml_mcp/infrastructure/postgres/repositories/__init__.py,sha256=cqMMMLyDG7XuvWt0OG3gxgjUsMXXdEwbxiGePxWrQ7g,911
40
+ ml_mcp/infrastructure/postgres/repositories/artifacts.py,sha256=P8CpQl-T2EEgiXJ5A5hdF4SNFkVoWcOQ9O5kLBjPJgY,1273
41
+ ml_mcp/infrastructure/postgres/repositories/audit.py,sha256=R2FFOOC4wN6j1tejDxvTu3NutA_ClAERs9_3z9LoGW8,981
42
+ ml_mcp/infrastructure/postgres/repositories/datasets.py,sha256=0znA8JSyb3ycxc44jaehixvlv85aZZY5MrBshb2pif0,3236
43
+ ml_mcp/infrastructure/postgres/repositories/experiments.py,sha256=TWn8lZ4wzll7Vf4hfa2VY5dVWchK0qneT1bd1h4sZMA,4792
44
+ ml_mcp/infrastructure/postgres/repositories/metrics.py,sha256=xeEPeevxyUzGDD6S3ZxTkQnpPiR6T5fhhjv6schuUdQ,2139
45
+ ml_mcp/infrastructure/postgres/repositories/models.py,sha256=xRzlRqrbdZ9Zcj8Wq7EZLepldu0caccYJ00xdiQl6tw,2306
46
+ ml_mcp/infrastructure/postgres/repositories/outbox.py,sha256=emKjSHiPqQ46ohWd48D5qD7NiU9pD_FSSo75LbxttdU,1733
47
+ ml_mcp/infrastructure/postgres/repositories/projects.py,sha256=8L1D1x4ze2rNYthI-l2Rvtr5d2auU8PqUbTia54VeL0,3066
48
+ ml_mcp/infrastructure/queue/__init__.py,sha256=n2LacJamnQuge-1uQOb422x6OraFWOjVGKjTkYgyavI,253
49
+ ml_mcp/infrastructure/queue/outbox_processor.py,sha256=KlorHH9gAsg88Y0EtPZQleU4tvZWUICifV2MlKm3KNg,2342
50
+ ml_mcp/infrastructure/queue/task_queue.py,sha256=PGDXZhBWSnrotSokA_0e1u5p3VEzMYLmRChLHoWQkUQ,3249
51
+ ml_mcp/infrastructure/redis/__init__.py,sha256=I6krHFx5_D1ToYV7lBsF4gQE2OObHIrZuaG3f2lil30,343
52
+ ml_mcp/infrastructure/redis/client.py,sha256=q8eKG1BMggwhgSQyDHlWAYCtle7ECR3Dh_RecPP8Lc4,1926
53
+ ml_mcp/infrastructure/redis/rate_limiter.py,sha256=ahLPYceisKhRqDnxlGzXQiW8gZ9ZV685YhWLcpdVXf0,4280
54
+ ml_mcp/infrastructure/telemetry/__init__.py,sha256=eGtXhRaYpBCUdxnaGhjqf6jYqVfayq-VTLUYtGyYGwo,465
55
+ ml_mcp/infrastructure/telemetry/logging.py,sha256=pf32yniOGeuVe8Xu9sTeZJn5ZCTUSRbZEm7sLQ5K6fc,4718
56
+ ml_mcp/infrastructure/telemetry/otel.py,sha256=K3ChWsaaS4KOheuwJZudXLCiWVoBtHlEGIOMcKtEv1I,5565
57
+ ml_mcp/mcp/__init__.py,sha256=6VQq-epTZC9ttcgn8xp4WsV7Id7tzByWs8phCNrVEOI,38
58
+ ml_mcp/mcp/prompts.py,sha256=dWoEC3GzJmtAmF30C_667pfv20BJqB9CIdNEcfvDVY4,1723
59
+ ml_mcp/mcp/resources.py,sha256=1eJLWjPrPzYw3nFnQkOD6Ww6eRLGIFzVaUWGIlM1xzg,1389
60
+ ml_mcp/mcp/schemas/__init__.py,sha256=wCjDRgWW8J9lIyY2rdoI1n-Uwn1N8QgeX5u6Z--fJ2c,37
61
+ ml_mcp/mcp/schemas/tools.py,sha256=0fFMD32t2dsIFIFa5rjS9Drj4shOV2A3ayOWGYVUyoo,4378
62
+ ml_mcp/mcp/tools/__init__.py,sha256=chI70okepM0zhsxl49zdgW9k-J8Y6Oewyz3eTbLjAEU,1741
63
+ ml_mcp/mcp/tools/analysis.py,sha256=7Zk61-sJEgkAsB319yfOAg4blj9yiq7phKQ0iFSDN-g,1282
64
+ ml_mcp/mcp/tools/datasets.py,sha256=ZgoArz9GK-BuLbAPuel8rb1ZQlroYla9QvG4H7BvOHg,2724
65
+ ml_mcp/mcp/tools/discovery.py,sha256=EBcMDSHFl2OwZfkBiNBDXIHDztmpDBuUnn3XCwavwos,3199
66
+ ml_mcp/mcp/tools/experiments.py,sha256=gGfUtxEtlTiEV6cTa6ltqhu3grjiEMqL5_5m_kGGd8I,3657
67
+ ml_mcp/mcp/tools/projects.py,sha256=a4WM3cwAE-53yEHjU5pHXMScGZ-RK0pe1jst6BKP66Y,1173
68
+ ml_mcp/mcp/tools/results.py,sha256=1HikgbP5kBqjy7E33d_oQT0hNJx6o_uIjnXlUUJp_us,2038
69
+ ml_mcp/server/__init__.py,sha256=IKeTjAkSQmw1FHUytnB2C6Jkn92z4dGeiDbnuDjbiug,33
70
+ ml_mcp/server/app.py,sha256=4J7SsW1saJGqa5qew7e0MWWhmZ3ouAU-ueIGS218lcA,18825
71
+ ml_mcp/server/auth.py,sha256=PlR4eQXbJBDX9waC0xIg-HdbeH9RSTCvskfL5TEZ39o,5293
72
+ ml_mcp/server/context.py,sha256=VhNiDkYJulORb3TmKl5v231RNiK_s4hMadKJlcNsMYc,2015
73
+ ml_mcp/server/http.py,sha256=TiIMQQIXlgC-wD4X4IG1CCrveVtTRGUjyGfMmk7nErs,5977
74
+ ml_mcp/server/middleware.py,sha256=2qOkGjAV4hpqVMwe6eyviKAFAbENxraSMupyaVVhgkc,4251
75
+ ml_mcp/server/stdio.py,sha256=4dL5OD2zi9ftZ5quOe8q0RPpmGN1exu9_577y1NK3QA,1246
76
+ ml_mcp/workers/__init__.py,sha256=TxJ2Un6ky24-Nslw68gM87mpcFvL7T0lV2dGpvGS-w0,34
77
+ ml_mcp/workers/daemon.py,sha256=jVAOC7ac9svDp2yL-ie2oZCz1fbDjCzuEZIAILyq7pQ,5022
78
+ ml_mcp/workers/metrics.py,sha256=HTCZ2PtWHtq4COZUNZZLffzJWU2Zuq7FhetxQcebGIM,3858
79
+ ml_mcp/workers/preprocessing.py,sha256=VmqDUg-9_JneR6VnSp9PFXkIyJ6jRsJdDKNlhirhV28,6430
80
+ ml_mcp/workers/runner.py,sha256=cs8rqs086-mjVnebO41y4USIGScp3mIyOxhRBBxceKA,9156
81
+ ml_mcp/workers/sandbox.py,sha256=FzucmltcgB9Ns0N9q8WE3_hFFLgnWHUErEA8amwkNdg,1176
82
+ ml_mcp/workers/trainers/__init__.py,sha256=db6zP8APwfYh0ePFeBxPYyXnw_giB673oSuHVG0hv1Q,1828
83
+ ml_mcp/workers/trainers/base.py,sha256=td30S54OPhdgFn0yGvzfXdJk9wUZrKue-HVt0si1bgc,1407
84
+ ml_mcp/workers/trainers/catboost_model.py,sha256=q57rS5ciZxwVkD8szpcGSYVV88Hsi8mh8-JZIdQ1pGI,3006
85
+ ml_mcp/workers/trainers/lightgbm_model.py,sha256=HM6OQM1e5tRwWtaR7H8XKmI-qvOkqmrCD-Wn2ZwwBzE,2854
86
+ ml_mcp/workers/trainers/sklearn_models.py,sha256=4lKAd0KVMHethg0j8AxJFie-pHTO1KUQ0HRWaq7Rl6c,9399
87
+ ml_mcp/workers/trainers/xgboost_model.py,sha256=dTmonoqo4wiUwwroYbnZMmFsa8pORfwboRyRTuCnoBs,2940
88
+ quicklab_mcp-0.1.0.dist-info/METADATA,sha256=0ke7J8ZSGngQ0yh35O8GKutBBqUCjaf_2CA9aGwwX0A,23667
89
+ quicklab_mcp-0.1.0.dist-info/WHEEL,sha256=a-udL2m4V_6Yn8b-uKzWb12RjRxwwMo6ohYFM24tpaY,91
90
+ quicklab_mcp-0.1.0.dist-info/entry_points.txt,sha256=7f1Tqr8i6tUIR36fCr0t9cUb41OlRcmlt_xUrwRAA9M,145
91
+ quicklab_mcp-0.1.0.dist-info/top_level.txt,sha256=tSWoPBcibglwAU_c0ODk8ewNwk13EuPSIgzayLv_pPc,7
92
+ quicklab_mcp-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,4 @@
1
+ [console_scripts]
2
+ modellab = ml_mcp.server.stdio:run_stdio
3
+ quicklab = ml_mcp.server.stdio:run_stdio
4
+ quicklab-mcp = ml_mcp.server.stdio:run_stdio
@@ -0,0 +1 @@
1
+ ml_mcp