minio-aiops 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 (80) hide show
  1. minio_aiops-0.1.0/.github/workflows/mcp-publish.yml +55 -0
  2. minio_aiops-0.1.0/.github/workflows/publish.yml +26 -0
  3. minio_aiops-0.1.0/.gitignore +8 -0
  4. minio_aiops-0.1.0/CHANGELOG.md +54 -0
  5. minio_aiops-0.1.0/LICENSE +21 -0
  6. minio_aiops-0.1.0/PKG-INFO +193 -0
  7. minio_aiops-0.1.0/README.md +176 -0
  8. minio_aiops-0.1.0/RELEASE_NOTES.md +39 -0
  9. minio_aiops-0.1.0/SECURITY.md +82 -0
  10. minio_aiops-0.1.0/mcp_server/__init__.py +1 -0
  11. minio_aiops-0.1.0/mcp_server/_shared.py +105 -0
  12. minio_aiops-0.1.0/mcp_server/server.py +36 -0
  13. minio_aiops-0.1.0/mcp_server/tools/__init__.py +1 -0
  14. minio_aiops-0.1.0/mcp_server/tools/bucket_writes.py +304 -0
  15. minio_aiops-0.1.0/mcp_server/tools/buckets.py +129 -0
  16. minio_aiops-0.1.0/mcp_server/tools/capacity.py +36 -0
  17. minio_aiops-0.1.0/mcp_server/tools/exposure.py +43 -0
  18. minio_aiops-0.1.0/mcp_server/tools/healing.py +47 -0
  19. minio_aiops-0.1.0/mcp_server/tools/health.py +74 -0
  20. minio_aiops-0.1.0/mcp_server/tools/undo.py +121 -0
  21. minio_aiops-0.1.0/minio_aiops/__init__.py +14 -0
  22. minio_aiops-0.1.0/minio_aiops/cli/__init__.py +9 -0
  23. minio_aiops-0.1.0/minio_aiops/cli/_common.py +84 -0
  24. minio_aiops-0.1.0/minio_aiops/cli/_root.py +63 -0
  25. minio_aiops-0.1.0/minio_aiops/cli/bucket.py +230 -0
  26. minio_aiops-0.1.0/minio_aiops/cli/capacity.py +39 -0
  27. minio_aiops-0.1.0/minio_aiops/cli/doctor.py +21 -0
  28. minio_aiops-0.1.0/minio_aiops/cli/heal.py +45 -0
  29. minio_aiops-0.1.0/minio_aiops/cli/health.py +35 -0
  30. minio_aiops-0.1.0/minio_aiops/cli/init.py +152 -0
  31. minio_aiops-0.1.0/minio_aiops/cli/overview.py +16 -0
  32. minio_aiops-0.1.0/minio_aiops/cli/secret.py +103 -0
  33. minio_aiops-0.1.0/minio_aiops/cli/undo.py +62 -0
  34. minio_aiops-0.1.0/minio_aiops/config.py +155 -0
  35. minio_aiops-0.1.0/minio_aiops/connection.py +644 -0
  36. minio_aiops-0.1.0/minio_aiops/doctor.py +123 -0
  37. minio_aiops-0.1.0/minio_aiops/governance/__init__.py +40 -0
  38. minio_aiops-0.1.0/minio_aiops/governance/audit.py +377 -0
  39. minio_aiops-0.1.0/minio_aiops/governance/budget.py +225 -0
  40. minio_aiops-0.1.0/minio_aiops/governance/decorators.py +482 -0
  41. minio_aiops-0.1.0/minio_aiops/governance/paths.py +23 -0
  42. minio_aiops-0.1.0/minio_aiops/governance/patterns.py +378 -0
  43. minio_aiops-0.1.0/minio_aiops/governance/policy.py +432 -0
  44. minio_aiops-0.1.0/minio_aiops/governance/sanitize.py +45 -0
  45. minio_aiops-0.1.0/minio_aiops/governance/undo.py +218 -0
  46. minio_aiops-0.1.0/minio_aiops/ops/__init__.py +1 -0
  47. minio_aiops-0.1.0/minio_aiops/ops/_util.py +61 -0
  48. minio_aiops-0.1.0/minio_aiops/ops/bucket_writes.py +215 -0
  49. minio_aiops-0.1.0/minio_aiops/ops/buckets.py +123 -0
  50. minio_aiops-0.1.0/minio_aiops/ops/capacity.py +195 -0
  51. minio_aiops-0.1.0/minio_aiops/ops/exposure.py +176 -0
  52. minio_aiops-0.1.0/minio_aiops/ops/healing.py +238 -0
  53. minio_aiops-0.1.0/minio_aiops/ops/health.py +86 -0
  54. minio_aiops-0.1.0/minio_aiops/ops/ilm.py +192 -0
  55. minio_aiops-0.1.0/minio_aiops/ops/overview.py +42 -0
  56. minio_aiops-0.1.0/minio_aiops/prom.py +78 -0
  57. minio_aiops-0.1.0/minio_aiops/secretstore.py +304 -0
  58. minio_aiops-0.1.0/pyproject.toml +61 -0
  59. minio_aiops-0.1.0/server.json +21 -0
  60. minio_aiops-0.1.0/skills/minio-aiops/SKILL.md +113 -0
  61. minio_aiops-0.1.0/skills/minio-aiops/references/capabilities.md +63 -0
  62. minio_aiops-0.1.0/skills/minio-aiops/references/cli-reference.md +62 -0
  63. minio_aiops-0.1.0/skills/minio-aiops/references/setup-guide.md +111 -0
  64. minio_aiops-0.1.0/smithery.yaml +9 -0
  65. minio_aiops-0.1.0/tests/conftest.py +48 -0
  66. minio_aiops-0.1.0/tests/test_bucket_writes.py +278 -0
  67. minio_aiops-0.1.0/tests/test_buckets.py +88 -0
  68. minio_aiops-0.1.0/tests/test_capacity.py +90 -0
  69. minio_aiops-0.1.0/tests/test_cli_writes.py +103 -0
  70. minio_aiops-0.1.0/tests/test_doctor.py +207 -0
  71. minio_aiops-0.1.0/tests/test_exposure.py +91 -0
  72. minio_aiops-0.1.0/tests/test_governance_persistence.py +177 -0
  73. minio_aiops-0.1.0/tests/test_healing.py +104 -0
  74. minio_aiops-0.1.0/tests/test_ilm.py +96 -0
  75. minio_aiops-0.1.0/tests/test_init.py +150 -0
  76. minio_aiops-0.1.0/tests/test_prom.py +59 -0
  77. minio_aiops-0.1.0/tests/test_secretstore.py +99 -0
  78. minio_aiops-0.1.0/tests/test_smoke.py +334 -0
  79. minio_aiops-0.1.0/tests/test_undo_executor.py +138 -0
  80. minio_aiops-0.1.0/uv.lock +1221 -0
@@ -0,0 +1,55 @@
1
+ name: mcp-publish
2
+
3
+ on:
4
+ workflow_dispatch:
5
+ release:
6
+ types: [published]
7
+
8
+ permissions:
9
+ id-token: write
10
+ contents: read
11
+
12
+ jobs:
13
+ publish-mcp:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+ - name: Wait for PyPI
18
+ # The release event also triggers the PyPI publish workflow; the MCP
19
+ # registry validates that the package version exists on PyPI, so poll
20
+ # until it has propagated (every 15s, up to 10 minutes).
21
+ run: |
22
+ python3 - <<'EOF'
23
+ import json
24
+ import sys
25
+ import time
26
+ import urllib.error
27
+ import urllib.request
28
+
29
+ with open("server.json", encoding="utf-8") as f:
30
+ package = json.load(f)["packages"][0]
31
+ name, version = package["identifier"], package["version"]
32
+ url = f"https://pypi.org/pypi/{name}/{version}/json"
33
+ deadline = time.monotonic() + 600
34
+ while True:
35
+ try:
36
+ with urllib.request.urlopen(url, timeout=10):
37
+ print(f"{name}=={version} is available on PyPI.")
38
+ sys.exit(0)
39
+ except (urllib.error.URLError, OSError) as exc:
40
+ print(f"{name}=={version} not on PyPI yet ({exc}); "
41
+ "retrying in 15s...")
42
+ if time.monotonic() >= deadline:
43
+ sys.exit(f"Timed out after 10 minutes waiting for "
44
+ f"{name}=={version} to appear on PyPI. "
45
+ "Check the PyPI publish workflow, then re-run "
46
+ "this workflow via workflow_dispatch.")
47
+ time.sleep(15)
48
+ EOF
49
+ - name: Install mcp-publisher
50
+ run: |
51
+ curl -sL "https://github.com/modelcontextprotocol/registry/releases/latest/download/mcp-publisher_$(uname -s | tr '[:upper:]' '[:lower:]')_$(uname -m | sed 's/x86_64/amd64/;s/aarch64/arm64/').tar.gz" | tar xz mcp-publisher
52
+ - name: Login to MCP Registry (GitHub OIDC)
53
+ run: ./mcp-publisher login github-oidc
54
+ - name: Publish server.json
55
+ run: ./mcp-publisher publish
@@ -0,0 +1,26 @@
1
+ name: Publish to PyPI
2
+
3
+ # Trusted Publishing (OIDC) — publishes from GitHub's runners with no API token,
4
+ # sidestepping the local-IP / account new-project rate limit. Configure a matching
5
+ # "trusted publisher" for this package on PyPI (see the repo release notes).
6
+ on:
7
+ release:
8
+ types: [published]
9
+ workflow_dispatch:
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ publish:
16
+ runs-on: ubuntu-latest
17
+ permissions:
18
+ id-token: write # required for PyPI Trusted Publishing (OIDC)
19
+ steps:
20
+ - uses: actions/checkout@v4
21
+ - name: Set up uv
22
+ uses: astral-sh/setup-uv@v5
23
+ - name: Build sdist + wheel
24
+ run: uv build
25
+ - name: Publish to PyPI (Trusted Publishing)
26
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,8 @@
1
+ .venv/
2
+ dist/
3
+ __pycache__/
4
+ *.pyc
5
+ .pytest_cache/
6
+ .ruff_cache/
7
+ *.egg-info/
8
+ .coverage
@@ -0,0 +1,54 @@
1
+ # Changelog
2
+
3
+ All notable changes to **minio-aiops** are documented here.
4
+
5
+ ## v0.1.0 — 2026-07-17
6
+
7
+ Initial preview release: governed AI-ops for **MinIO** object storage over the
8
+ S3 API (official SDK), the admin API, the unauthenticated health endpoints,
9
+ and the cluster metrics endpoint — with a bundled governance harness.
10
+
11
+ ### Highlights
12
+
13
+ - **Four flagship analyses** (cause + suggested action, thresholds as named
14
+ constants):
15
+ - `capacity_rca` — usable capacity vs used, offline drives/nodes, per-drive
16
+ hotspots, fill imbalance.
17
+ - `bucket_exposure_audit` — ranked findings: anonymous/public policy
18
+ statements (read/write), missing default encryption, versioning off, no
19
+ lifecycle.
20
+ - `lifecycle_gap_analysis` — unbounded noncurrent versions, incomplete
21
+ multipart uploads with no abort rule, large buckets with no lifecycle —
22
+ with a labelled reclaimable estimate.
23
+ - `healing_health` — heal backlog/errors + per-erasure-set write-quorum
24
+ risk and remaining drive-failure tolerance.
25
+ - **29 MCP tools** (21 read, 8 write), every one wrapped with the bundled
26
+ `@governed_tool` harness (audit / budget / risk-tier / undo).
27
+ - **Guarded writes**: `set_bucket_policy`, `delete_bucket_policy`,
28
+ `set_versioning`, `set_lifecycle`, `delete_lifecycle`, `set_bucket_quota`
29
+ (all reversible — real prior state captured, undo recorded);
30
+ `bucket_delete` (high risk, refused unless verifiably empty, irreversible);
31
+ `remove_incomplete_uploads` (age-gated, priorState only). All writes take
32
+ `dry_run`.
33
+ - **CLI**: `init` wizard (encrypted secret store, TLS prompts with lab hints,
34
+ seeds a secure-by-default `rules.yaml`), `doctor` (live/ready + S3 auth +
35
+ metrics reachability), `overview`, read groups (`health`, `capacity`,
36
+ `heal`, `bucket`) and guarded write commands with `--dry-run` +
37
+ double-confirm, delegated to the governed MCP twins (CLI writes are
38
+ audited).
39
+ - **Metrics auth, both modes**: `MINIO_PROMETHEUS_AUTH_TYPE=public` scraped
40
+ directly; default `jwt` mode uses a bearer token derived from the stored
41
+ credentials.
42
+ - **Encrypted credentials**: secret key in `~/.minio-aiops/secrets.enc`
43
+ (Fernet + scrypt), master password via `MINIO_AIOPS_MASTER_PASSWORD`;
44
+ legacy `MINIO_<TARGET>_SECRET_KEY` env fallback with `secret migrate`.
45
+
46
+ ### Known limitations
47
+
48
+ - **Preview / mock-only** — validated against mocked SDK/HTTP responses, not
49
+ yet against a live server. Fastest live check: a single-node MinIO server
50
+ running `minio-aiops doctor`.
51
+ - Incomplete-upload listing uses the SDK's core ListMultipartUploads call
52
+ (the public alias was removed upstream).
53
+ - Out of scope for v0.1.0: site replication, object locking/legal hold, IAM
54
+ (users/policies) management, remote tiering.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 wei <zhouwei008@gmail.com>
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,193 @@
1
+ Metadata-Version: 2.4
2
+ Name: minio-aiops
3
+ Version: 0.1.0
4
+ Summary: Governed AI-ops for MinIO object storage: capacity & usage RCA, bucket exposure audit, lifecycle/ILM gap analysis, healing & erasure-set health, and guarded bucket writes with a built-in governance harness (audit, budget, undo, risk tiers)
5
+ Author-email: wei <zhouwei008@gmail.com>
6
+ License-Expression: MIT
7
+ License-File: LICENSE
8
+ Requires-Python: >=3.11
9
+ Requires-Dist: cryptography>=42.0
10
+ Requires-Dist: httpx<1.0,>=0.27
11
+ Requires-Dist: mcp[cli]<2.0,>=1.10
12
+ Requires-Dist: minio<8.0,>=7.2
13
+ Requires-Dist: pyyaml<7.0,>=6.0
14
+ Requires-Dist: rich<16.0,>=13.0
15
+ Requires-Dist: typer<1.0,>=0.12
16
+ Description-Content-Type: text/markdown
17
+
18
+ <!-- mcp-name: io.github.AIops-tools/minio-aiops -->
19
+
20
+ # MinIO AIops (preview)
21
+
22
+ > **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by MinIO, Inc. or any storage vendor.** Product and trademark names belong to their owners. MIT licensed.
23
+
24
+ Governed AI-ops for **MinIO** object storage — for the homelab and small/medium
25
+ self-hosted deployments where MinIO actually lives. Talks to the **S3 API**
26
+ (official `minio` SDK, SigV4), the **admin API** (bucket quota, server info),
27
+ the unauthenticated **health endpoints** (`/minio/health/live|ready|cluster`),
28
+ and the **cluster metrics endpoint** (`/minio/v2/metrics/cluster`, bearer-token
29
+ or public auth) — with a **built-in governance harness**: unified audit log,
30
+ policy engine, token/runaway budget guard, undo-token recording, and
31
+ graduated-autonomy risk tiers. Self-contained: no external skill-family
32
+ dependency. **Preview — mock-validated only, not yet verified against a live
33
+ server.**
34
+
35
+ ## What it does
36
+
37
+ Four flagship analyses, plus the guarded reads and writes around them:
38
+
39
+ - **`capacity_rca`** — capacity vs used, offline drives/nodes, per-drive
40
+ hotspots and imbalance → each finding as **cause + suggested action**
41
+ (nearfull/full thresholds are named constants, not magic).
42
+ - **`bucket_exposure_audit`** — every bucket scored and **ranked** for
43
+ anonymous/public policy statements (read and, far worse, write), missing
44
+ default encryption, versioning off, no lifecycle.
45
+ - **`lifecycle_gap_analysis`** — the storage ILM should be reclaiming but
46
+ isn't: versioned buckets with **no noncurrent expiry** (old bytes accrue
47
+ forever), **incomplete multipart uploads** with no abort rule (invisible
48
+ space), large buckets with no lifecycle — with a clearly-labelled
49
+ **reclaimable estimate**.
50
+ - **`healing_health`** — heal backlog and per-erasure-set **write-quorum
51
+ risk**: how many more drive failures each set can tolerate, which sets are
52
+ healing, where heal errors are piling up.
53
+ - **Governed writes.** Bucket policy / versioning / lifecycle / quota changes
54
+ capture the **real prior state** and record an **undo descriptor**;
55
+ `bucket_delete` is **refused unless the bucket is verifiably empty**
56
+ (including versions and delete markers) and `remove_incomplete_uploads`
57
+ only touches uploads older than a safety window.
58
+
59
+ ## What works
60
+
61
+ - **CLI** (`minio-aiops ...`): `init`, `overview`, `doctor`, `health
62
+ check/status`, `capacity rca/usage`, `heal status/drives/nodes`, `bucket
63
+ ls/info/audit/ilm-gap/uploads` plus guarded writes (`bucket
64
+ versioning-set/policy-set/lifecycle-set/quota-set/purge-uploads/delete`),
65
+ `secret set/list/rm/migrate/rotate-password`, `mcp`. Destructive commands
66
+ take `--dry-run` and double-confirm.
67
+ - **MCP server** (`minio-aiops mcp` or `minio-aiops-mcp`): the full **29
68
+ tools** (21 read, 8 write), every one wrapped with the bundled
69
+ `@governed_tool` harness. The CLI is a convenience subset; the MCP surface
70
+ is the whole tool. CLI writes delegate to the same governed functions, so
71
+ they are audited identically.
72
+ - **Encrypted credentials**: the secret key lives in an encrypted store
73
+ `~/.minio-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on
74
+ disk**. Unlock with a master password from `MINIO_AIOPS_MASTER_PASSWORD`
75
+ (MCP/CI) or an interactive prompt (CLI).
76
+ - **Metrics auth, both modes**: servers running
77
+ `MINIO_PROMETHEUS_AUTH_TYPE=public` are scraped directly; for the default
78
+ (`jwt`) mode the bearer token is **derived from the stored credentials** —
79
+ no extra secret to manage.
80
+ - **Reversibility**: reversible writes capture prior state and record an
81
+ inverse undo descriptor (prior policy JSON, prior lifecycle XML, prior
82
+ versioning state, prior quota).
83
+
84
+ ## Capability matrix (29 MCP tools)
85
+
86
+ | Group | Tools | Count | R/W |
87
+ |-------|-------|:-----:|:---:|
88
+ | **Health** | `health_live`, `health_ready`, `health_cluster`, `cluster_status`, `fleet_overview` | 5 | read |
89
+ | **Capacity** | `capacity_rca` (flagship), `usage_by_bucket` | 2 | read |
90
+ | **Healing** | `healing_health` (flagship), `drive_status`, `node_status` | 3 | read |
91
+ | **Exposure / ILM** | `bucket_exposure_audit` (flagship), `lifecycle_gap_analysis` (flagship) | 2 | read |
92
+ | **Buckets** | `bucket_ls`, `bucket_info`, `bucket_policy_get`, `bucket_lifecycle_get`, `bucket_versioning_get`, `bucket_quota_get`, `object_ls`, `incomplete_uploads_ls`, `server_info` | 9 | read |
93
+ | **Writes** | `set_bucket_policy` (med, undo), `delete_bucket_policy` (med, undo), `set_versioning` (med, undo), `set_lifecycle` (med, undo), `delete_lifecycle` (med, undo), `set_bucket_quota` (med, undo) | 6 | write |
94
+ | | `bucket_delete` (**high**, dry-run, empty-only, irreversible), `remove_incomplete_uploads` (med, dry-run, priorState only) | 2 | write |
95
+
96
+ Totals: **29 tools — 21 read, 8 write.**
97
+
98
+ ## Quick start
99
+
100
+ ```bash
101
+ uv tool install minio-aiops # or: pipx install minio-aiops
102
+ minio-aiops init # wizard: endpoint + access key; secret key stored encrypted
103
+ minio-aiops doctor # live/ready + S3 auth + metrics reachability
104
+ minio-aiops overview # health + capacity headline + exposure headline
105
+ minio-aiops capacity rca # why is storage filling up, and what to do
106
+ minio-aiops bucket audit # ranked bucket-exposure findings
107
+ ```
108
+
109
+ Run as an MCP server (stdio):
110
+
111
+ ```bash
112
+ export MINIO_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
113
+ minio-aiops-mcp
114
+ ```
115
+
116
+ ### MCP client config
117
+
118
+ ```json
119
+ {
120
+ "mcpServers": {
121
+ "minio-aiops": {
122
+ "command": "uvx",
123
+ "args": ["--from", "minio-aiops", "minio-aiops-mcp"],
124
+ "env": { "MINIO_AIOPS_MASTER_PASSWORD": "your-master-password" }
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ > **Env-block caveat**: MCP clients launch the server **without a TTY and
131
+ > without your shell profile**, so the master password cannot be prompted for
132
+ > and an `export` in `~/.zshrc` is not seen — it must be passed in the client's
133
+ > `env` block (or the client process's environment) as above. Everything else
134
+ > (targets, TLS, region, metrics mode) comes from `~/.minio-aiops/config.yaml`
135
+ > written by `minio-aiops init`.
136
+
137
+ ## Configuration
138
+
139
+ `~/.minio-aiops/config.yaml` (non-secret connection details only):
140
+
141
+ ```yaml
142
+ targets:
143
+ - name: lab1
144
+ host: 192.0.2.10
145
+ port: 9000
146
+ access_key: minio-ops # identifies the account; NOT the secret
147
+ secure: true # https (false for plain-http labs)
148
+ verify_ssl: true # false for self-signed lab certs
149
+ region: "" # optional
150
+ metrics_public: false # true when MINIO_PROMETHEUS_AUTH_TYPE=public
151
+ ```
152
+
153
+ The secret key is stored with `minio-aiops secret set lab1` (encrypted; a
154
+ legacy `MINIO_LAB1_SECRET_KEY` env var is honoured as a fallback with a
155
+ migration warning).
156
+
157
+ ## Governance
158
+
159
+ Every MCP tool passes through the bundled `@governed_tool` harness:
160
+
161
+ - **Audit** — every call (params, result, status, duration, risk tier,
162
+ approver, rationale) is logged to `~/.minio-aiops/audit.db` (relocatable
163
+ via `MINIO_AIOPS_HOME`).
164
+ - **Budget / runaway guard** — token and call budgets trip a circuit breaker.
165
+ - **Risk tiers, secure by default** — with no `rules.yaml`, high-risk ops
166
+ (`bucket_delete`) **require a named approver**
167
+ (`MINIO_AUDIT_APPROVED_BY` / `MINIO_AUDIT_RATIONALE`); `init` seeds an
168
+ explicit, editable starter policy.
169
+ - **Undo recording** — reversible writes record an inverse descriptor built
170
+ from the captured prior state.
171
+
172
+ ## Supported scope & limitations
173
+
174
+ - **Deployments**: any reasonably current MinIO server (single-node or
175
+ distributed/erasure-coded) reachable over its S3 port. Admin features
176
+ (quota, `server_info`) need admin-capable keys. Generic S3 services are not
177
+ a target: the health/metrics/admin surfaces used here are MinIO-specific.
178
+ - **Metrics**: the capacity/healing RCAs read the **v2 cluster metrics**
179
+ endpoint; both `public` and bearer-token (default) auth modes are supported.
180
+ - **Incomplete-upload listing** uses the SDK's core ListMultipartUploads call
181
+ (the public alias was removed from the SDK); it is exercised in tests and
182
+ documented in `connection.py`.
183
+ - **Preview / mock-only.** Behaviour is validated against mocked SDK/HTTP
184
+ responses. The cheapest **live** check is a single-node MinIO server (a
185
+ container or the bare binary with a data directory) running
186
+ `minio-aiops doctor`. Erasure-set/healing findings need a multi-drive
187
+ deployment to observe for real.
188
+
189
+ ## Missing a capability?
190
+
191
+ Site replication status, object locking / legal-hold governance, per-user /
192
+ policy (IAM) management, tiering to remote storage — not here yet. **Open an
193
+ issue or send a PR** — feedback and contributions are welcome.
@@ -0,0 +1,176 @@
1
+ <!-- mcp-name: io.github.AIops-tools/minio-aiops -->
2
+
3
+ # MinIO AIops (preview)
4
+
5
+ > **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by MinIO, Inc. or any storage vendor.** Product and trademark names belong to their owners. MIT licensed.
6
+
7
+ Governed AI-ops for **MinIO** object storage — for the homelab and small/medium
8
+ self-hosted deployments where MinIO actually lives. Talks to the **S3 API**
9
+ (official `minio` SDK, SigV4), the **admin API** (bucket quota, server info),
10
+ the unauthenticated **health endpoints** (`/minio/health/live|ready|cluster`),
11
+ and the **cluster metrics endpoint** (`/minio/v2/metrics/cluster`, bearer-token
12
+ or public auth) — with a **built-in governance harness**: unified audit log,
13
+ policy engine, token/runaway budget guard, undo-token recording, and
14
+ graduated-autonomy risk tiers. Self-contained: no external skill-family
15
+ dependency. **Preview — mock-validated only, not yet verified against a live
16
+ server.**
17
+
18
+ ## What it does
19
+
20
+ Four flagship analyses, plus the guarded reads and writes around them:
21
+
22
+ - **`capacity_rca`** — capacity vs used, offline drives/nodes, per-drive
23
+ hotspots and imbalance → each finding as **cause + suggested action**
24
+ (nearfull/full thresholds are named constants, not magic).
25
+ - **`bucket_exposure_audit`** — every bucket scored and **ranked** for
26
+ anonymous/public policy statements (read and, far worse, write), missing
27
+ default encryption, versioning off, no lifecycle.
28
+ - **`lifecycle_gap_analysis`** — the storage ILM should be reclaiming but
29
+ isn't: versioned buckets with **no noncurrent expiry** (old bytes accrue
30
+ forever), **incomplete multipart uploads** with no abort rule (invisible
31
+ space), large buckets with no lifecycle — with a clearly-labelled
32
+ **reclaimable estimate**.
33
+ - **`healing_health`** — heal backlog and per-erasure-set **write-quorum
34
+ risk**: how many more drive failures each set can tolerate, which sets are
35
+ healing, where heal errors are piling up.
36
+ - **Governed writes.** Bucket policy / versioning / lifecycle / quota changes
37
+ capture the **real prior state** and record an **undo descriptor**;
38
+ `bucket_delete` is **refused unless the bucket is verifiably empty**
39
+ (including versions and delete markers) and `remove_incomplete_uploads`
40
+ only touches uploads older than a safety window.
41
+
42
+ ## What works
43
+
44
+ - **CLI** (`minio-aiops ...`): `init`, `overview`, `doctor`, `health
45
+ check/status`, `capacity rca/usage`, `heal status/drives/nodes`, `bucket
46
+ ls/info/audit/ilm-gap/uploads` plus guarded writes (`bucket
47
+ versioning-set/policy-set/lifecycle-set/quota-set/purge-uploads/delete`),
48
+ `secret set/list/rm/migrate/rotate-password`, `mcp`. Destructive commands
49
+ take `--dry-run` and double-confirm.
50
+ - **MCP server** (`minio-aiops mcp` or `minio-aiops-mcp`): the full **29
51
+ tools** (21 read, 8 write), every one wrapped with the bundled
52
+ `@governed_tool` harness. The CLI is a convenience subset; the MCP surface
53
+ is the whole tool. CLI writes delegate to the same governed functions, so
54
+ they are audited identically.
55
+ - **Encrypted credentials**: the secret key lives in an encrypted store
56
+ `~/.minio-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on
57
+ disk**. Unlock with a master password from `MINIO_AIOPS_MASTER_PASSWORD`
58
+ (MCP/CI) or an interactive prompt (CLI).
59
+ - **Metrics auth, both modes**: servers running
60
+ `MINIO_PROMETHEUS_AUTH_TYPE=public` are scraped directly; for the default
61
+ (`jwt`) mode the bearer token is **derived from the stored credentials** —
62
+ no extra secret to manage.
63
+ - **Reversibility**: reversible writes capture prior state and record an
64
+ inverse undo descriptor (prior policy JSON, prior lifecycle XML, prior
65
+ versioning state, prior quota).
66
+
67
+ ## Capability matrix (29 MCP tools)
68
+
69
+ | Group | Tools | Count | R/W |
70
+ |-------|-------|:-----:|:---:|
71
+ | **Health** | `health_live`, `health_ready`, `health_cluster`, `cluster_status`, `fleet_overview` | 5 | read |
72
+ | **Capacity** | `capacity_rca` (flagship), `usage_by_bucket` | 2 | read |
73
+ | **Healing** | `healing_health` (flagship), `drive_status`, `node_status` | 3 | read |
74
+ | **Exposure / ILM** | `bucket_exposure_audit` (flagship), `lifecycle_gap_analysis` (flagship) | 2 | read |
75
+ | **Buckets** | `bucket_ls`, `bucket_info`, `bucket_policy_get`, `bucket_lifecycle_get`, `bucket_versioning_get`, `bucket_quota_get`, `object_ls`, `incomplete_uploads_ls`, `server_info` | 9 | read |
76
+ | **Writes** | `set_bucket_policy` (med, undo), `delete_bucket_policy` (med, undo), `set_versioning` (med, undo), `set_lifecycle` (med, undo), `delete_lifecycle` (med, undo), `set_bucket_quota` (med, undo) | 6 | write |
77
+ | | `bucket_delete` (**high**, dry-run, empty-only, irreversible), `remove_incomplete_uploads` (med, dry-run, priorState only) | 2 | write |
78
+
79
+ Totals: **29 tools — 21 read, 8 write.**
80
+
81
+ ## Quick start
82
+
83
+ ```bash
84
+ uv tool install minio-aiops # or: pipx install minio-aiops
85
+ minio-aiops init # wizard: endpoint + access key; secret key stored encrypted
86
+ minio-aiops doctor # live/ready + S3 auth + metrics reachability
87
+ minio-aiops overview # health + capacity headline + exposure headline
88
+ minio-aiops capacity rca # why is storage filling up, and what to do
89
+ minio-aiops bucket audit # ranked bucket-exposure findings
90
+ ```
91
+
92
+ Run as an MCP server (stdio):
93
+
94
+ ```bash
95
+ export MINIO_AIOPS_MASTER_PASSWORD=... # unlock secrets non-interactively
96
+ minio-aiops-mcp
97
+ ```
98
+
99
+ ### MCP client config
100
+
101
+ ```json
102
+ {
103
+ "mcpServers": {
104
+ "minio-aiops": {
105
+ "command": "uvx",
106
+ "args": ["--from", "minio-aiops", "minio-aiops-mcp"],
107
+ "env": { "MINIO_AIOPS_MASTER_PASSWORD": "your-master-password" }
108
+ }
109
+ }
110
+ }
111
+ ```
112
+
113
+ > **Env-block caveat**: MCP clients launch the server **without a TTY and
114
+ > without your shell profile**, so the master password cannot be prompted for
115
+ > and an `export` in `~/.zshrc` is not seen — it must be passed in the client's
116
+ > `env` block (or the client process's environment) as above. Everything else
117
+ > (targets, TLS, region, metrics mode) comes from `~/.minio-aiops/config.yaml`
118
+ > written by `minio-aiops init`.
119
+
120
+ ## Configuration
121
+
122
+ `~/.minio-aiops/config.yaml` (non-secret connection details only):
123
+
124
+ ```yaml
125
+ targets:
126
+ - name: lab1
127
+ host: 192.0.2.10
128
+ port: 9000
129
+ access_key: minio-ops # identifies the account; NOT the secret
130
+ secure: true # https (false for plain-http labs)
131
+ verify_ssl: true # false for self-signed lab certs
132
+ region: "" # optional
133
+ metrics_public: false # true when MINIO_PROMETHEUS_AUTH_TYPE=public
134
+ ```
135
+
136
+ The secret key is stored with `minio-aiops secret set lab1` (encrypted; a
137
+ legacy `MINIO_LAB1_SECRET_KEY` env var is honoured as a fallback with a
138
+ migration warning).
139
+
140
+ ## Governance
141
+
142
+ Every MCP tool passes through the bundled `@governed_tool` harness:
143
+
144
+ - **Audit** — every call (params, result, status, duration, risk tier,
145
+ approver, rationale) is logged to `~/.minio-aiops/audit.db` (relocatable
146
+ via `MINIO_AIOPS_HOME`).
147
+ - **Budget / runaway guard** — token and call budgets trip a circuit breaker.
148
+ - **Risk tiers, secure by default** — with no `rules.yaml`, high-risk ops
149
+ (`bucket_delete`) **require a named approver**
150
+ (`MINIO_AUDIT_APPROVED_BY` / `MINIO_AUDIT_RATIONALE`); `init` seeds an
151
+ explicit, editable starter policy.
152
+ - **Undo recording** — reversible writes record an inverse descriptor built
153
+ from the captured prior state.
154
+
155
+ ## Supported scope & limitations
156
+
157
+ - **Deployments**: any reasonably current MinIO server (single-node or
158
+ distributed/erasure-coded) reachable over its S3 port. Admin features
159
+ (quota, `server_info`) need admin-capable keys. Generic S3 services are not
160
+ a target: the health/metrics/admin surfaces used here are MinIO-specific.
161
+ - **Metrics**: the capacity/healing RCAs read the **v2 cluster metrics**
162
+ endpoint; both `public` and bearer-token (default) auth modes are supported.
163
+ - **Incomplete-upload listing** uses the SDK's core ListMultipartUploads call
164
+ (the public alias was removed from the SDK); it is exercised in tests and
165
+ documented in `connection.py`.
166
+ - **Preview / mock-only.** Behaviour is validated against mocked SDK/HTTP
167
+ responses. The cheapest **live** check is a single-node MinIO server (a
168
+ container or the bare binary with a data directory) running
169
+ `minio-aiops doctor`. Erasure-set/healing findings need a multi-drive
170
+ deployment to observe for real.
171
+
172
+ ## Missing a capability?
173
+
174
+ Site replication status, object locking / legal-hold governance, per-user /
175
+ policy (IAM) management, tiering to remote storage — not here yet. **Open an
176
+ issue or send a PR** — feedback and contributions are welcome.
@@ -0,0 +1,39 @@
1
+ # MinIO AIops v0.1.0 — preview
2
+
3
+ Governed AI-ops for **MinIO** object storage for AI agents (MCP) and humans
4
+ (CLI), with a bundled governance harness: audit, policy, token/runaway budget,
5
+ undo recording, graduated risk tiers.
6
+
7
+ > **Preview**: behaviour is validated against mocked SDK/HTTP responses; it
8
+ > has not been run against a live MinIO server. The fastest live check is a
9
+ > single-node server running `minio-aiops doctor`.
10
+
11
+ ## Surface
12
+
13
+ - **29 MCP tools** (21 read, 8 write) over four access paths: S3 API (official
14
+ SDK), admin API (quota, server info), unauthenticated health endpoints, and
15
+ the cluster metrics endpoint (public or bearer-token auth — the token is
16
+ derived from the stored credentials).
17
+ - **Flagship analyses**: `capacity_rca`, `bucket_exposure_audit`,
18
+ `lifecycle_gap_analysis`, `healing_health` — every finding is
19
+ cause + suggested action, thresholds are named constants.
20
+ - **Guarded writes**: policy / versioning / lifecycle / quota (reversible,
21
+ prior state captured, undo recorded), `bucket_delete` (high risk, empty-only,
22
+ irreversible), `remove_incomplete_uploads` (age-gated purge, priorState
23
+ only). All writes take `dry_run`; destructive CLI commands double-confirm.
24
+
25
+ ## Governance
26
+
27
+ - Unified audit log `~/.minio-aiops/audit.db` (relocatable via
28
+ `MINIO_AIOPS_HOME`); CLI writes route through the same governed functions.
29
+ - Secure by default: with no `rules.yaml`, high-risk writes require a named
30
+ approver (`MINIO_AUDIT_APPROVED_BY`); `init` seeds an explicit starter
31
+ policy.
32
+ - Encrypted secret store (`secrets.enc`, Fernet + scrypt) — no plaintext
33
+ secrets on disk.
34
+
35
+ ## Quality gates (this release)
36
+
37
+ - 114 tests green (pytest), `ruff check` clean, bandit 0 Medium+ findings.
38
+ - Every MCP tool carries the `_is_governed_tool` marker.
39
+ - Undo descriptors are replay-tested against the target tool signatures.
@@ -0,0 +1,82 @@
1
+ # Security Policy
2
+
3
+ ## Disclaimer
4
+
5
+ Community-maintained open-source project. **Not affiliated with, endorsed by, or
6
+ sponsored by MinIO, Inc. or any storage vendor.** Product and trademark names
7
+ belong to their owners. Source is publicly auditable under the MIT license.
8
+
9
+ ## Reporting Vulnerabilities
10
+
11
+ Report privately via a GitHub Security Advisory on
12
+ [github.com/AIops-tools/MinIO-AIops](https://github.com/AIops-tools/MinIO-AIops/security/advisories)
13
+ or email zhouwei008@gmail.com. Please do not open public issues for security
14
+ reports.
15
+
16
+ ## Security Design
17
+
18
+ ### Credential Management
19
+ - Per-target **secret keys** live **encrypted** in
20
+ `~/.minio-aiops/secrets.enc` (Fernet/AES-128 + scrypt-derived key; chmod
21
+ 600), never in `config.yaml` and never in source. The master password is
22
+ never stored — only a per-store random salt and the ciphertext are on disk.
23
+ - A legacy plaintext env var `MINIO_<TARGET_NAME_UPPER>_SECRET_KEY` is still
24
+ honoured as a fallback with a deprecation warning (migrate with
25
+ `minio-aiops secret migrate`).
26
+ - S3/admin requests are **SigV4-signed** by the official SDK; the secret key
27
+ is held only in memory, never logged or echoed. The metrics bearer token is
28
+ derived from the credentials at request time (short TTL) and never stored.
29
+ The config file holds only host, port, access key, TLS/region/metrics
30
+ settings.
31
+
32
+ ### Governed Operations
33
+ Every MCP tool runs through the bundled `@governed_tool` harness
34
+ (`minio_aiops.governance`):
35
+ - **Audit** — every call logged to a local SQLite DB under `~/.minio-aiops/`
36
+ (relocatable via `MINIO_AIOPS_HOME`), agent-attributed, secret-redacted.
37
+ - **Token/runaway budget** — hard ceilings (`MINIO_MAX_TOOL_CALLS` /
38
+ `MINIO_MAX_TOOL_SECONDS`) plus an on-by-default guard that trips a tight
39
+ poll/retry loop, preventing unbounded API consumption.
40
+ - **Graduated risk tiers, secure by default** — with no
41
+ `~/.minio-aiops/rules.yaml`, high-risk writes require a recorded approver;
42
+ the `init` wizard seeds an explicit, editable starter policy.
43
+ - **Undo-token recording** — reversible writes capture the BEFORE state and
44
+ record an inverse descriptor (prior policy JSON, prior lifecycle XML, prior
45
+ versioning state, prior quota) so the change can be rolled back.
46
+
47
+ ### State-Changing Operations
48
+ `bucket_delete` is `risk_level=high`, accepts a `dry_run` preview, requires a
49
+ recorded approver (`MINIO_AUDIT_APPROVED_BY` + `MINIO_AUDIT_RATIONALE`) under
50
+ the default policy, and is **refused unless the bucket is verifiably empty**
51
+ (including noncurrent versions and delete markers) — this tool never
52
+ mass-deletes objects to force a bucket empty. `remove_incomplete_uploads`
53
+ only aborts uploads older than a safety window (default 7 days) and records
54
+ priorState (count + sample). The CLI double-confirms both and supports
55
+ `--dry-run` everywhere. All agent-supplied bucket names are validated against
56
+ strict S3 naming rules before any request is built (the injection gate).
57
+
58
+ ### SSL/TLS Verification
59
+ `secure` (https) and `verify_ssl` default to true; disable verification only
60
+ for self-signed lab certificates.
61
+
62
+ ### Output Hygiene
63
+ All server-returned text (bucket/object names, policy contents, error bodies,
64
+ metric labels) is passed through a `sanitize()` truncate + control-character
65
+ strip before reaching the agent.
66
+
67
+ ### Network Scope
68
+ No webhooks, no telemetry, no outbound calls beyond the configured MinIO
69
+ endpoint (S3/admin/health/metrics paths on the same origin). No post-install
70
+ scripts or background services.
71
+
72
+ ## Static Analysis
73
+
74
+ ```bash
75
+ uvx bandit -r minio_aiops/ mcp_server/
76
+ uv run ruff check .
77
+ ```
78
+
79
+ ## Supported Versions
80
+
81
+ The latest released version receives security fixes. This is a preview (0.x);
82
+ pin a version in production.
@@ -0,0 +1 @@
1
+ """MCP server package for minio-aiops."""