VMware Debug
Disclaimer: Community-maintained open-source project, not affiliated with, endorsed by, or sponsored by VMware, Inc. or Broadcom Inc. "VMware" and "vSphere" are trademarks of Broadcom. Source is publicly auditable under the MIT license.
The diagnostic brain of the VMware skill family. You bring the symptom; this skill runs the investigation and points at the root cause. It reads and reasons — it never writes. Companion skills do the data collection and the fixing.
What This Skill Does
| Category | What | Read or Write |
|---|---|---|
| Incident correlation | Merge events from many sources into one timeline, detect spikes | Read |
| Root-cause ranking | Score symptom clusters, surface the most likely cause first | Read |
| Next-check ideas | Suggest exactly what to look at next (which skill/tool) when you're stuck | Read |
| Remediation routing | Hand the fix to vmware-aiops (single) or vmware-pilot (gated, multi-step) | Read (routes only) |
Zero write tools. Zero network access of its own. It correlates data the agent has already gathered with the other skills' read tools.
Quick Install
uv tool install vmware-debug
vmware-debug categories # see what it can diagnose
When to Use This Skill
Use it when there is a problem to solve: an error message, a stack of logs, an alarm storm, "my VM won't power on", "storage feels slow", "the host disconnected".
- Need raw inventory/health with no incident? → vmware-monitor
- Need to actually run a fix? → vmware-aiops (single op) or vmware-pilot (gated workflow)
- Need metrics/anomalies? → vmware-aria; centralized logs? → vmware-log-insight
Do NOT use when there is nothing wrong (routine listing → monitor), or when the user wants the fix executed (→ aiops/pilot). This skill stops at the diagnosis and a recommended plan.
Related Skills — Skill Routing
| Symptom touches | Pull signals from | Then |
|---|---|---|
| Storage / datastore / vSAN | vmware-storage, vmware-log-insight | rank → route fix to aiops/pilot |
| Network / firewall / vMotion | vmware-nsx, vmware-nsx-security | run traceflow, check DFW |
| CPU / memory contention | vmware-aria (metrics/anomalies) | rightsizing via pilot |
| HA / DRS / cluster | vmware-monitor, vmware-aiops | cluster remediation via pilot |
| Power / clone / snapshot | vmware-aiops, vmware-monitor | task status, then fix via aiops |
| Auth / cert / login | check creds & cert; (security) | fix config/.env |
Common Workflows
1. "Here's a pile of logs / alarms — what broke?"
- Collect events with the data-source skills (e.g.
vmware-monitor event_list --vm web01 --since 1h,vmware-log-insight log_search ...,vmware-aria alert_query ...). - Pass them all to
incident_timeline(envelope below). Read the top hypothesis +next_checks. - Follow
next_checksto pull more targeted data; re-runincident_timelineto confirm. - Failure branch — no events come back: the affected target may be unreachable. Run the source skill's
doctor/health first; a 503/timeout is a signal (platform not ready), not a dead end. - Produce a diagnosis + recommended fix. Route execution to aiops/pilot. Do not fix here.
2. "I don't even know what to check"
- Run
list_symptom_categories(orvmware-debug categories) to see the catalogue. - Describe the symptom; map it to a category; the
suggested_checktells you which skill/tool to run first. - Collect →
incident_timeline→ narrow. Loop until one hypothesis dominates.
3. Hand off the fix (advisor → executor, like vmware-harden)
- Debug emits a structured diagnosis + a proposed remediation (steps).
- Single, low-risk fix → call the matching vmware-aiops tool (it has its own double-confirm).
- Multi-step / needs approval / cross-skill → submit the plan to vmware-pilot, which owns the state machine, approval gate, rollback, and audit.
- Failure branch — fix is ambiguous or risky: stop and present the hypotheses to the user; never guess-execute.
Usage Mode
- MCP (in an agent): the agent calls the other skills' read tools, then
incident_timelineto correlate. This is the primary mode — that's where the cross-skill "联动" happens. - CLI (humans):
vmware-debug triage --events events.jsoncorrelates a JSON array you collected yourself.
MCP Tools (14 — 7 read, 7 write)
Correlation — stateless, for a single look:
| Tool | What |
|---|---|
incident_timeline |
[READ] Correlate pre-fetched events → timeline + spikes + ranked hypotheses + next-check ideas |
list_symptom_categories |
[READ] List recognised symptom categories + what to check for each |
Investigation ledger — for an incident you will reason about over time:
| Tool | What |
|---|---|
case_open |
[WRITE] Define the event; returns a case id and the grade this environment can reach |
case_readiness |
[READ] What grade this environment can reach, per symptom category, before you start |
case_knowledge |
[READ] Which knowledge formats are accepted, what is mounted, and which entries apply to a case |
case_plan |
[READ] What to fetch next — skill, tool and purpose per step; recomputed from the case's current state |
case_list |
[READ] Cases, newest first |
case_get |
[READ] One case: scope, ledger sizes, grade history |
case_hypotheses |
[WRITE] Register a candidate explanation, or read the ledger of what supports and refutes each |
case_submit_evidence |
[WRITE] Record one retrieved fact, with its source, query and time basis |
case_record_gap |
[WRITE] Record what could not be retrieved, and how to close it |
case_timeline |
[WRITE] Correlate everything the case has collected into one timeline |
case_grade |
[WRITE] Recompute the conclusion grade from the ledger and record it |
case_close |
[WRITE] Record the final grade, archive, and name what was left open |
The four writes go to $OPS_HOME (default ~/.vmware/cases/) and nowhere else.
List envelope (output of list_symptom_categories): {items, returned, limit, total, truncated, hint} — read the rows from items. truncated is always false here, which is the point: it states that the catalogue is complete instead of leaving you to infer it.
Event envelope (input to incident_timeline): {ts, source, severity, entity, text, fields}.
See references/event-envelope.md. The agent normalises each source's events into this
shape; debug stays source-agnostic and has no dependency on the other packages.
Keep each event's event_type in fields — the classifier matches it as well as
the message, and on a modern EventEx it is the only thing that says what the
event was.
The Investigation Ledger
Correlating events answers "what happened together". A case answers "what do we believe, on what evidence, and what is still missing" — and keeps answering it across sessions and across people.
The case folder is the deliverable, not an implementation detail. Everything in it but the index is plain text, so a customer can take the folder away and audit how a conclusion was reached with none of this installed:
~/.vmware/cases/<case-id>/
├── scope.json what is being investigated, and how that was decided
├── evidence/ one file per fact: source skill, exact query, time basis
├── gaps.json what could NOT be obtained, what it blocks, how to close it
├── conclusion.md the grade, appended — including every time it went down
└── timeline.md · hypotheses.md · plan.jsonl · case.json
Hypotheses get ids (H1, H2, …), and those ids are what case_record_gap(blocks=…)
and case_submit_evidence(falsifies=…) refer to. An id that was never
registered is refused, not ignored — a dangling reference blocks nothing and
falsifies nothing, which quietly reports a stronger case than you have.
You cannot state a conclusion level. case_grade has no parameter for one;
the grade is recomputed from the ledger on every call. To change it, change the
ledger — submit the missing evidence, or record the gap that is blocking it.
- Candidate — a hypothesis exists
- Probable — ≥2 independent sources agree (two calls to one skill are one source) and nothing outstanding could overturn it
- Confirmed — that, plus a decisive item: a direct hardware diagnostic, a version-checked knowledge-base entry, or a vendor SR; and no gap left open
- Excluded — an observation that actually rules it out. "We looked and found nothing" is a gap, not an exclusion
case_plan is not a checklist: submit evidence and the next plan is shorter,
lose a source and it routes around it. Its unavailable half is the important
one — a source this install cannot reach is listed there with how to supply it,
so the gap is visible now rather than when the conclusion refuses to firm up.
case_readiness answers this per symptom category rather than as one number —
"storage reaches Probable, hardware reaches Candidate" can be acted on;
"readiness 78%" cannot. Two classes served by the same skill count as one
source, so it agrees with what case_grade will actually award.
Mounting a knowledge library
case_knowledge answers "what can I add" without anyone reading this file.
Entries go under $OPS_HOME/knowledge/{kb,runbook,sr,cases}/:
| Format | How metadata travels |
|---|---|
.md .markdown |
YAML front-matter between --- fences, body below — preferred |
.yaml .yml |
the whole file is one entry |
.json |
one entry per file |
.jsonl |
one JSON object per line — what ticketing systems export |
.csv .tsv |
one entry per row; use dotted columns (driver.version) for nested constraints |
.txt .log |
a sibling <name>.yaml carries the metadata |
PDF, DOCX, PPTX and HTML must be converted to Markdown first — case_knowledge
names them rather than ignoring them.
Every entry needs an applies_to block to be decisive:
---
id: KB-2026-0417
applies_to:
product: vsphere
build: ">=8.0.3, <9.0"
driver: {name: nvme_pcie, version: ">=1.2.4"}
firmware: {vendor: dell, version: ">=52.26"}
---
product, build, driver and firmware are the constraints the checker
evaluates. Any other key leaves the entry non-decisive — including a typo —
because an unverified constraint is not a satisfied one, and case_knowledge
names the key it could not check.
Knowledge evidence must say which entry it is
(case_submit_evidence(source_skill="knowledge-kb", knowledge_entry_id="KB-…"))
— "some applicable entry is mounted somewhere" is a different claim from "this
one applies", and only the second can carry a conclusion.
Matching is by version applicability, never by similarity — an entry written
for the wrong build reads exactly like the right one, and similarity is the only
thing that would let it through. An entry with no applies_to can support a
hypothesis but can never make a case Confirmed. A constraint the case scope
cannot answer is not a match either: silence is not a pass.
On a stock install the ceiling is Probable. Confirmed needs a decisive source, and there is neither a hardware-diagnostic channel (no Redfish/BMC, no SMART/NVMe) nor a knowledge library mounted —
~/.vmware/knowledge/ships empty. Every tool that can reach the ceiling says so in its output rather than letting you wonder why a well-supported case never goes higher. Mount a knowledge library and the ceiling rises on its own.
Recording a gap is meant to be free: a missing confirmation caps the grade, it does not demote it. Only a gap that could overturn the hypothesis holds a case at Candidate.
No Network, By Design
vmware-debug connects to nothing and holds no credentials. The calling agent
fetches with the other skills' read tools and submits the results here. Its only
writes are to the local case ledger. Running with local or small models? See
references/agent-guardrails.md.
CLI Quick Reference
vmware-debug categories # what can it diagnose
vmware-debug triage --events events.json # correlate a collected event set
cat events.json | vmware-debug triage # or via stdin
vmware-debug mcp # start stdio MCP server (proxy-safe)
Troubleshooting
incident_timelineraises "event[N] could not be normalised" — event N is missing a timestamp or has an unparseable one. Every event needsts(ISO-8601, epoch seconds, or millis).- Most events come back "uncategorized" — read
classificationin the result: it says how many, what share, and quotes the texts that matched nothing. Do not widen the window; a wider window adds baseline, not signal. The spikes still tell you when, which is answerable without a category. If the samples name a subsystem the taxonomy does not know, add a signature (seereferences/routing.md). - No spikes detected on an obvious burst — check
binningfor the resolution you were given. The width is chosen from event density so that bins average ≥4 events; a burst shorter than one bin can still be flattened by it. Passbin_secondsto narrow. Below three bins there is no baseline at all and nothing is reported. case_timelinesays zero events after you submitted results — checkpayload_eventsin eachcase_submit_evidencereply. Events are read from a bare list, or fromitems/events/rows; a summary of a tool's result carries none.notenames which items carried nothing and what keys they held instead.case_readinesssays a skill you have is not installed — both spellings are accepted (monitorandvmware-monitor). A name it did not recognise comes back inunrecognised_skillsrather than being read as missing.- It won't execute the fix — by design. Route to vmware-aiops or vmware-pilot.
Audit & Safety
Read-only by construction: no write tools, no network, nothing executed. Remediation
is always routed to aiops/pilot, where the double-confirm / approval / audit gates live
(audit DB ~/.vmware/audit.db). Policy rules scope by environment; debug has no config
and no connection to declare one about, so it reports a constant local — nothing here
touches a remote VMware estate. See references/setup-guide.md.
License
MIT.