{
  "markdown": "<!-- mcp-name: io.github.AIops-tools/minio-aiops -->\n\n# MinIO AIops\n\n> **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.\n\nGoverned AI-ops for **MinIO** object storage — for the homelab and small/medium\nself-hosted deployments where MinIO actually lives. Talks to the **S3 API**\n(official `minio` SDK, SigV4), the **admin API** (bucket quota, server info),\nthe unauthenticated **health endpoints** (`/minio/health/live|ready|cluster`),\nand the **cluster metrics endpoint** (`/minio/v2/metrics/cluster`, bearer-token\nor public auth) — with a **built-in governance harness**: a unified audit log,\na token/runaway budget guard, undo-token recording, and a descriptive risk\ntier on every audit row. Self-contained: no external skill-family dependency.\n\n## What it does\n\nFour flagship analyses, plus the guarded reads and writes around them:\n\n- **`capacity_rca`** — capacity vs used, offline drives/nodes, per-drive\n  hotspots and imbalance → each finding as **cause + suggested action**\n  (nearfull/full thresholds are named constants, not magic).\n- **`bucket_exposure_audit`** — every bucket scored and **ranked** for\n  anonymous/public policy statements (read and, far worse, write), missing\n  default encryption, versioning off, no lifecycle.\n- **`lifecycle_gap_analysis`** — the storage ILM should be reclaiming but\n  isn't: versioned buckets with **no noncurrent expiry** (old bytes accrue\n  forever), **incomplete multipart uploads** with no abort rule (invisible\n  space), large buckets with no lifecycle — with a clearly-labelled\n  **reclaimable estimate**.\n- **`healing_health`** — heal backlog and per-erasure-set **write-quorum\n  risk**: how many more drive failures each set can tolerate, which sets are\n  healing, where heal errors are piling up.\n- **Governed writes.** Bucket policy / versioning / lifecycle / quota changes\n  capture the **real prior state** and record an **undo descriptor**;\n  `bucket_delete` is **refused unless the bucket is verifiably empty**\n  (including versions and delete markers) and `remove_incomplete_uploads`\n  only touches uploads older than a safety window.\n\n## What works\n\n- **CLI** (`minio-aiops ...`): `init`, `overview`, `doctor`, `health\n  check/status`, `capacity rca/usage`, `heal status/drives/nodes`, `bucket\n  ls/info/objects/audit/ilm-gap/uploads` plus guarded writes (`bucket\n  versioning-set/policy-set/lifecycle-set/quota-set/purge-uploads/delete`),\n  `secret set/list/rm/migrate/rotate-password`, `mcp`. Destructive commands\n  take `--dry-run` and double-confirm.\n- **MCP server** (`minio-aiops mcp` or `minio-aiops-mcp`): the full **48\n  tools** (29 read, 19 write), every one wrapped with the bundled\n  `@governed_tool` harness. The CLI is a convenience subset; the MCP surface\n  is the whole tool. CLI writes delegate to the same governed functions, so\n  they are audited identically.\n- **Encrypted credentials**: the secret key lives in an encrypted store\n  `~/.minio-aiops/secrets.enc` (Fernet + scrypt) — **never plaintext on\n  disk**. Unlock with a master password from `MINIO_AIOPS_MASTER_PASSWORD`\n  (MCP/CI) or an interactive prompt (CLI).\n- **Metrics auth, both modes**: servers running\n  `MINIO_PROMETHEUS_AUTH_TYPE=public` are scraped directly; for the default\n  (`jwt`) mode the bearer token is **derived from the stored credentials** —\n  no extra secret to manage.\n- **Reversibility**: reversible writes capture prior state and record an\n  inverse undo descriptor (prior policy JSON, prior lifecycle XML, prior\n  versioning state, prior quota).\n\n## Capability matrix (48 MCP tools)\n\n| Group | Tools | Count | R/W |\n|-------|-------|:-----:|:---:|\n| **Health** | `health_live`, `health_ready`, `health_cluster`, `cluster_status`, `fleet_overview` | 5 | read |\n| **Capacity** | `capacity_rca` (flagship), `usage_by_bucket` | 2 | read |\n| **Healing** | `healing_health` (flagship), `drive_status`, `node_status` | 3 | read |\n| **Exposure / ILM** | `bucket_exposure_audit` (flagship), `lifecycle_gap_analysis` (flagship) | 2 | read |\n| **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 |\n| **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 |\n| | `bucket_delete` (**high**, dry-run, empty-only, irreversible), `remove_incomplete_uploads` (med, dry-run, priorState only) | 2 | write |\n| **Object lock (WORM)** | `bucket_lock_config`, `object_lock_status`, `diagnose_retention_gaps` (flagship) | 3 | read |\n| | `bucket_create` (med, undo — the only way to enable object lock), `set_default_retention` (**high**, undo), `clear_default_retention` (med, undo), `set_legal_hold` (med, undo) | 4 | write |\n| | `set_object_retention` (**critical**, dry-run, extend-only, **no undo exists**) | 1 | write |\n| **IAM** | `iam_users`, `iam_groups`, `iam_policies`, `diagnose_iam_exposure` (flagship) | 4 | read |\n| | `create_user` (med, undo, secret redacted + never returned), `set_user_status` (med, undo), `attach_user_policy` (med, undo), `detach_user_policy` (med, undo) — **all refused for this tool's own credential** | 4 | write |\n| | `remove_user` (**high**, dry-run, **no undo: MinIO keeps no recoverable secret**) | 1 | write |\n| **Undo** | `undo_list`, `undo_apply` | 2 | read + replay |\n\nTotals: **48 tools — 29 read (incl. `undo_list`), 19 write (incl. `undo_apply`).**\n\n## What this tool does, and does not, decide\n\nIt delivers MinIO object-storage operations — reads and writes — accurately and\nefficiently, and records every one of them. It does **not** decide whether a\nwrite is allowed to happen. That is the agent's judgement, or the permission of\nthe access key you connect it with: give the key a read-only IAM policy and the\nwrites fail at the server — the place that actually owns the permission.\n\nSo there is no read-only switch, no policy file, no approval gate to configure.\nThe one thing the tool guarantees is that nothing is silent: **every call, over\nMCP and over the CLI alike, lands an audit row** in `~/.minio-aiops/audit.db`,\nand reversible writes still capture their real prior state and record an inverse\nundo descriptor.\n\n> Each tool declares a `risk_level`, kept in agreement with its `[READ]`/`[WRITE]`\n> documentation tag by a test, and carried into the audit row as a descriptive\n> tier — so a reviewer can see at a glance that a row was a high-risk delete. It\n> is a label, not a gate.\n\nRunning a smaller / local model? See\n[agent-guardrails.md](skills/minio-aiops/references/agent-guardrails.md) — it lists\nthe guardrails this tool enforces for you (so you don't spend prompt budget\nrestating them) and gives a ready-made system prompt for what's left.\n\n## Quick start\n\n### As a Claude Code plugin\n\nOne install gives an agent both the skill and the MCP server:\n\n```\n/plugin marketplace add AIops-tools/marketplace\n/plugin install minio-aiops@aiops-tools\n```\n\nThe MCP server is fetched with [uv](https://docs.astral.sh/uv/) and pinned to the\npackage version this plugin declares, so an audit row can be traced back to the\ncode that wrote it. Credentials are still configured with `minio-aiops init` — see below.\n\n### As a CLI or standalone MCP server\n\n```bash\nuv tool install minio-aiops         # or: pipx install minio-aiops\nminio-aiops init                    # wizard: endpoint + access key; secret key stored encrypted\nminio-aiops doctor                  # live/ready + S3 auth + metrics reachability\nminio-aiops overview                # health + capacity headline + exposure headline\nminio-aiops capacity rca            # why is storage filling up, and what to do\nminio-aiops bucket audit            # ranked bucket-exposure findings\n```\n\nRun as an MCP server (stdio):\n\n```bash\nexport MINIO_AIOPS_MASTER_PASSWORD=...   # unlock secrets non-interactively\nminio-aiops-mcp\n```\n\n### MCP client config\n\n```json\n{\n  \"mcpServers\": {\n    \"minio-aiops\": {\n      \"command\": \"uvx\",\n      \"args\": [\"--from\", \"minio-aiops\", \"minio-aiops-mcp\"],\n      \"env\": { \"MINIO_AIOPS_MASTER_PASSWORD\": \"your-master-password\" }\n    }\n  }\n}\n```\n\n> **Env-block caveat**: MCP clients launch the server **without a TTY and\n> without your shell profile**, so the master password cannot be prompted for\n> and an `export` in `~/.zshrc` is not seen — it must be passed in the client's\n> `env` block (or the client process's environment) as above. Everything else\n> (targets, TLS, region, metrics mode) comes from `~/.minio-aiops/config.yaml`\n> written by `minio-aiops init`.\n\n## Configuration\n\n`~/.minio-aiops/config.yaml` (non-secret connection details only):\n\n```yaml\ntargets:\n  - name: lab1\n    host: 192.0.2.10\n    port: 9000\n    access_key: minio-ops        # identifies the account; NOT the secret\n    secure: true                 # https (false for plain-http labs)\n    verify_ssl: true             # false for self-signed lab certs\n    region: \"\"                   # optional\n    metrics_public: false        # true when MINIO_PROMETHEUS_AUTH_TYPE=public\n```\n\nThe secret key is stored with `minio-aiops secret set lab1` (encrypted; a\nlegacy `MINIO_LAB1_SECRET_KEY` env var is honoured as a fallback with a\nmigration warning).\n\n## Governance\n\nEvery MCP tool passes through the bundled `@governed_tool` harness:\n\n- **Audit** — every call (params, result, status, duration, risk tier, and any\n  `MINIO_AUDIT_APPROVED_BY` / `MINIO_AUDIT_RATIONALE` annotations) is logged to\n  `~/.minio-aiops/audit.db` (relocatable via `MINIO_AIOPS_HOME`).\n- **Budget / runaway guard** — token and call budgets trip a circuit breaker.\n  A safety backstop, not authorization.\n- **Risk-tier labelling** — each tool's declared `risk_level` is recorded on the\n  audit row as a descriptive tier (`bucket_delete` is high). It is a label for\n  the reviewer, not a gate: there is no read-only switch, policy file, or\n  approval gate, and `MINIO_AUDIT_APPROVED_BY` / `MINIO_AUDIT_RATIONALE` are\n  optional annotations recorded when set, never required.\n- **Undo recording** — reversible writes record an inverse descriptor built\n  from the captured prior state.\n\n## Supported scope & limitations\n\n- **Deployments**: any reasonably current MinIO server (single-node or\n  distributed/erasure-coded) reachable over its S3 port. Admin features\n  (quota, `server_info`) need admin-capable keys. Generic S3 services are not\n  a target: the health/metrics/admin surfaces used here are MinIO-specific.\n- **Metrics**: the capacity/healing RCAs read the **v2 cluster metrics**\n  endpoint; both `public` and bearer-token (default) auth modes are supported.\n- **Incomplete-upload listing** uses the SDK's core ListMultipartUploads call\n  (the public alias was removed from the SDK); it is exercised in tests and\n  documented in `connection.py`.\n- **Verification status.** **Live-verified against a real single-node MinIO\n  server (2026-07-19)**: connectivity, the reads, the exposure audit (it correctly\n  scored an anonymously-writable bucket `high` and named `PUBLIC_WRITE_POLICY`), and\n  the governance loop (real `set_versioning` → undo restoring it to `Suspended`, the\n  correct S3 inverse). **Distributed / multi-node MinIO is still unverified** —\n  healing was never exercised against a real degraded drive or erasure set — as are\n  lifecycle/quota writes and TLS endpoints. See\n  [docs/VERIFICATION.md](docs/VERIFICATION.md); `minio-aiops doctor` is the fastest\n  live check.\n\n## Missing a capability?\n\nSite replication status, IAM **policy authoring** (creating and editing policy\ndocuments — attachment is supported), group membership writes, tiering to remote\nstorage — not here yet. **Open an issue or send a PR** — feedback and\ncontributions are welcome.\n",
  "bytes": 11977,
  "sha": "cc654e20eedc2289a96dd61431faaf7706e032ecd234f751c766f9f1c5aba0e8",
  "repo_slug": "aiops-tools/minio-aiops",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_aiops_tools_minio_aiops_f5ca079a/readme"
}