{
  "markdown": "<!-- mcp-name: io.github.AIops-tools/nutanix-aiops -->\n\n# Nutanix AIops\n\n> **Disclaimer**: Community-maintained open-source project. **Not affiliated with, endorsed by, or sponsored by Nutanix.** Product and trademark names belong to their owners. MIT licensed.\n\nGoverned AI-ops for **Nutanix Prism Central** (v4 REST API) — clusters, hosts,\nVMs (AHV + ESXi), storage, network, catalog, data protection / DR, alerts, LCM\nupgrades, and capacity — with a **built-in governance harness**: unified audit\nlog, token/runaway budget guard, undo-token recording, and descriptive\nrisk-tier labels. Connects to Prism Central on HTTPS `:9440` with\nHTTP Basic auth (username + encrypted password). Self-contained: no dependencies\nbeyond `httpx` and the MCP SDK.\n\n## Why this over a read-only Nutanix MCP\n\n- **Automatic ETag / If-Match** on every mutation. The v4 API rejects an update\n  or delete without the entity's current ETag — the classic footgun. This tool\n  fetches and sends `If-Match` for you.\n- **Automatic pagination** — list tools walk every v4 page for you, and return a\n  `{\"<items>\": [...], \"returned\", \"limit\", \"truncated\"}` envelope so a capped\n  read announces itself instead of looking like the whole estate.\n- **Absent is not empty** — a field Prism Central did not return comes back as\n  `null`, never as `\"\"`. v4 omits a lot of fields; the two facts stay distinct.\n- **Mixed-hypervisor VM listing** — `vm_list` returns both **AHV** and **ESXi**\n  guests under the same Prism Central (built for hypervisor-migration estates).\n- **Governance harness** — audit / token+call budget / descriptive risk-tier\n  labels / undo-token / prompt-injection sanitize, with **dry-run +\n  double-confirm** on destructive writes.\n\n## What this tool does, and does not, decide\n\nIt delivers Nutanix Prism Central operations — reads and writes — accurately and\nefficiently, and records every one of them. It does **not** decide whether a write is\nallowed to happen. That is the agent's judgement, or the permission of the account\nyou connect it with: connect with a Prism Central account holding only a\nread-only (Viewer) role, and the writes fail at the server — the place that\nactually owns the permission.\n\nSo there is no read-only switch, no policy file, no approval gate to configure. The\none thing the tool guarantees is that nothing is silent: **every call, over MCP and\nover the CLI alike, lands an audit row** in `~/.nutanix-aiops/audit.db`, and\ndestructive writes still capture their before-state and record an inverse where one\nexists.\n\n> Each tool declares a `risk_level`, carried into the audit row as a descriptive\n> tier (none/confirm/review) — so a reviewer can see at a glance that a row was a\n> high-risk delete. It is a label, not a gate.\n\nRunning a smaller / local model? See\n[agent-guardrails.md](skills/nutanix-aiops/references/agent-guardrails.md) — it lists\nthe guardrails this tool now 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## Capability matrix (51 MCP tools)\n\n| Group | Tools | Count | R/W |\n|-------|-------|:-----:|:---:|\n| **Clusters** | `cluster_list`, `cluster_health`, `host_list`, `cluster_utilization` | 4 | 4 read |\n| **VMs** | `vm_list`, `vm_get`, `vm_power_on`, `vm_guest_shutdown`, `vm_power_off`, `vm_reboot`, `vm_create`, `vm_update`, `vm_clone`, `vm_delete`, `vm_migrate` | 11 | 2 read · 9 write |\n| **Storage** | `storage_container_list` / `_create` / `_update` / `_delete` | 4 | 1 read · 3 write |\n| **Network** | `subnet_list`, `subnet_get`, `subnet_create`, `subnet_delete` | 4 | 2 read · 2 write |\n| **Catalog** | `image_list`, `image_delete`, `category_list`, `category_create`, `category_assign` | 5 | 2 read · 3 write |\n| **Data protection / DR** | `snapshot_list` / `_create` / `_delete` / `_restore`, `recovery_point_list`, `protection_domain_list`, `vm_protect`, `pd_failover` | 8 | 3 read · 5 write |\n| **Alerts** | `alert_list`, `event_list`, `audit_list`, `analyze_alert` (RCA), `alert_acknowledge`, `alert_resolve` | 6 | 4 read · 2 write |\n| **LCM (upgrades)** | `lcm_inventory`, `lcm_precheck`, `lcm_update` | 3 | 1 read · 2 write |\n| **Capacity** | `task_list`, `capacity_runway` | 2 | 2 read |\n| **Diagnostics / RCA** | `cluster_health_rca`, `alert_triage_rca` | 2 | 2 read |\n| **Undo** | `undo_list`, `undo_apply` | 2 | 1 read · 1 write |\n| **Total** | | **51** | 24 read · 27 write |\n\n**Diagnostics / RCA** are the flagship reads. `cluster_health_rca` ranks the whole\nestate — degraded fault-tolerance state, storage pools and containers over 80%\n(warning) / 90% (critical), nodes not healthy or missing from inventory —\nworst-first, each finding citing the measured percentage or raw Prism state that\ntripped it. `alert_triage_rca` groups active alerts by severity with a count per\nlevel, flags unacknowledged criticals, and surfaces the oldest unresolved alert\nwith its age. Both are read-only (`risk_level=\"low\"`) and deterministic — no\nclock, no randomness, same input → same answer. `analyze_alert` complements them\nat the single-alert level: it correlates an alert with its related\nevents into a probable-cause + suggested-actions summary. High-risk writes\n(`vm_delete`, `vm_migrate`, `storage_container_delete`, `subnet_delete`,\n`snapshot_delete`, `snapshot_restore`, `pd_failover`, `image_delete`,\n`lcm_update`) support `dry_run` and, at the CLI, double confirmation.\n\n## Install\n\n```bash\nuv tool install nutanix-aiops          # or: pipx install nutanix-aiops\n```\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 nutanix-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 `nutanix-aiops init` — see below.\n\n### As a CLI or standalone MCP server\n\n```bash\nnutanix-aiops init                     # wizard: PC host / port 9440 / username / verify_ssl + encrypted password\nnutanix-aiops doctor                   # config, secrets, connectivity + REST-RBAC preflight\nnutanix-aiops overview                 # one-shot estate summary\nnutanix-aiops diagnose cluster-health  # worst-first RCA: resiliency, storage, nodes\nnutanix-aiops vm list                  # AHV + ESXi VMs\n```\n\nRun as an MCP server (stdio):\n\n```bash\nexport NUTANIX_AIOPS_MASTER_PASSWORD=...   # unlock the encrypted secret store non-interactively\nnutanix-aiops mcp\n```\n\n## CLI\n\n`nutanix-aiops` (Typer): `init`, `overview`, `doctor`, `mcp`; `cluster\nlist/health/hosts/util`; `vm list/get/power/delete/migrate` (`delete` & `migrate`\ntake `--dry-run` + double confirm); `diagnose cluster-health`, `diagnose\nalert-triage`; `secret set/list/rm/migrate/rotate-password`.\nThe CLI is a convenience subset — the full 51-tool surface is via the MCP server.\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  operator-supplied approver/rationale) is logged to `~/.nutanix-aiops/audit.db`\n  (relocatable via `NUTANIX_AIOPS_HOME`). The CLI writes the same row the MCP\n  path does — there is no unaudited entry point.\n- **Runaway guard** — a safety backstop, not an authorization gate: the same\n  call hammered in a tight loop trips a circuit breaker. Disable with\n  `NUTANIX_RUNAWAY_MAX=0`; optional hard ceilings via `NUTANIX_MAX_TOOL_CALLS` /\n  `NUTANIX_MAX_TOOL_SECONDS`.\n- **Undo recording** — reversible writes record an inverse descriptor built\n  from the fetched before-state (`vm_update` → prior CPU/memory, `vm_migrate`\n  → prior host).\n- **Risk tier** — a descriptive label on the audit row derived from\n  `risk_level`; it gates nothing.\n\n## Credentials\n\nThe Prism Central password is stored **encrypted** in\n`~/.nutanix-aiops/secrets.enc` (Fernet + scrypt) — never plaintext on disk.\nUnlock with a master password from `NUTANIX_AIOPS_MASTER_PASSWORD` (MCP/CI) or an\ninteractive prompt (CLI). The non-secret connection details (host, port,\nusername, verify_ssl) live in `~/.nutanix-aiops/config.yaml`. A legacy plaintext\nenv var `NUTANIX_<TARGET>_PASSWORD` is honoured as a fallback.\n\n> **Gotcha:** the Prism Central account needs **REST API** rights, not just Web\n> UI access. `doctor`'s REST-RBAC preflight catches this early.\n\n## Supported scope & limitations\n\n- **Validation status.** All behaviour is currently validated against mocked v4\n  REST responses; it has not yet been run against a live Prism Central. The\n  fastest live check is `nutanix-aiops doctor`. See\n  [`docs/VERIFICATION.md`](docs/VERIFICATION.md) for the full live-verification\n  checklist.\n- **Self-testable free** on **Nutanix Community Edition (CE)**: a single-node CE\n  cluster + an X-Small Prism Central VM.\n- **Least-verified paths:** LCM update (`lcm_update`), protection-domain failover\n  (`pd_failover`), and **ESXi-VM listing** in particular need live validation.\n- **Out of scope this release:** IAM / users / roles, Files / Objects / Volumes\n  services, reports, X-Play playbooks, and anything outside Prism Central v4.\n\n## Missing a capability?\n\nMissing a tool, an API dialect, or a workflow? **Open an issue or PR** —\nfeedback and contributions are welcome.\n</content>\n",
  "bytes": 9394,
  "sha": "93ab71f76fb3690f38bca5bc5c13c95e4e9464bb62d10b6a3972de337c817405",
  "repo_slug": "aiops-tools/nutanix-aiops",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_aiops_tools_nutanix_aiops_7998915f/readme"
}