io.github.zw008/vmware-debug
This server provides offline VMware incident diagnosis: it correlates already-fetched events into timelines and hypotheses, and tracks an investigation case ledger with evidence, gaps, grades, and knowledge checks.
Correlate pre-fetched VMware events into one incident view with spikes, ranked root-cause hypotheses, and suggested next checks (
incident_timeline).List recognized symptom categories and what to check next (
list_symptom_categories).Open, list, and inspect investigation cases; plan next data fetches; record evidence, gaps, and hypotheses; build case timelines; grade and close cases.
Check what conclusion strength the environment can reach and which mounted knowledge entries apply to a case (
case_readiness,case_knowledge).Operate offline and credential-free: it never connects to vSphere, never executes fixes, and only writes to the local
$OPS_HOMEcase ledger.Route remediation to
vmware-aiopsorvmware-pilot; optionally serve MCP over HTTPS with bearer tokens and limited tool exposure.
Provides diagnostic tools for VMware environments, correlating events and ranking hypotheses from logs and symptoms.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@io.github.zw008/vmware-debugShow timeline for recent ESXi host failures"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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 (an error,
a log dump, a slow VM); this skill runs a systematic investigation, correlates
events from the other skills into one timeline, ranks root-cause hypotheses, and
tells you what to check next. It never touches vSphere — it connects to
nothing and never executes fixes; its only writes are to a local case ledger
under $OPS_HOME. Remediation is routed to vmware-aiops (single op) or
vmware-pilot (multi-step, gated), mirroring the vmware-harden → vmware-pilot
advisor/executor split.
See skills/vmware-debug/SKILL.md for the full
methodology, the event-envelope contract, and symptom routing.
Upgrading to 2.0
2.0 renames 13 of its 14 MCP tools so every name starts with a verb (e.g. case_close → close_case, case_get → get_case, case_grade → grade_case). The full old → new table is in
RELEASE_NOTES.md. Nothing else changes: same tools, parameters,
safety gates and CLI commands. If an agent prompt, script or ~/.vmware/rules.yaml names a tool, update it — though deny
rules written with the old names keep working with vmware-policy ≥ 1.18.1 (vmware-audit policy lists any rule the
renames widened), and vmware-pilot ≥ 1.13 translates old names in saved workflows.
If an install older than 2.0 shares that rules.yaml, give it vmware-policy ≥ 1.18.2 too: it matches each rule
against both the old and the new name, so one file serves both.
Related MCP server: LogLens
Companion Skills
Need | Skill |
Incident correlation / root cause | vmware-debug (this project) |
Centralized log search | vmware-log-insight (feed its |
vCenter events and alarms | vmware-monitor |
Metrics / anomalies | vmware-aria |
Executing a fix | vmware-aiops (single op) / vmware-pilot (multi-step, gated) |
Install
uv tool install vmware-debug
vmware-debug categories # see which symptom categories it can diagnoseMCP tools (14 — 7 read, 7 write)
The seven writes go to the local case ledger only; none reaches a VMware system.
Correlation — stateless, for a single look:
Tool | What |
| [READ] Correlate pre-fetched events → timeline + spikes + ranked hypotheses + next-check ideas |
| [READ] List recognised symptom categories + what to check for each |
Investigation ledger — for an incident you will reason about over time:
Tool | What |
| [WRITE] Define the event; returns a case id and the grade this environment can reach |
| [READ] What grade this environment can reach, per symptom category, before you start |
| [READ] Which knowledge formats are accepted, what is mounted, and which entries apply to a case |
| [READ] What to fetch next — skill, tool and purpose per step; recomputed from the case's current state |
| [READ] Cases, newest first |
| [READ] One case: scope, ledger sizes, grade history |
| [WRITE] Register a candidate explanation, or read the ledger of what supports and refutes each |
| [WRITE] Record one retrieved fact, with its source, query and time basis |
| [WRITE] Record what could not be retrieved, and how to close it |
| [WRITE] Correlate everything the case has collected into one timeline |
| [WRITE] Recompute the conclusion grade from the ledger and record it |
| [WRITE] Record the final grade, archive, and name what was left open |
Event envelope: {ts, source, severity, entity, text, fields}. The agent normalizes events from each source
into this shape before handing them to debug, so debug has zero runtime dependency on the other packages.
Keep each event's event_type in fields — the classifier matches it as well as the text, and most modern
vSphere events are EventEx: the text is a generic boilerplate sentence, and only eventTypeId says what the
event actually is.
Security
Offline and credential-free by construction: it connects to no vCenter/NSX/Aria, has no destructive surface on
VMware, and holds no secret to leak. The only writes are the local case ledger: evidence, gaps, hypotheses and
grade history are append-only; timeline.md is regenerated from the evidence, and case.json holds the current
grade and status. The same holds with several writers: every write to a case first takes that case's lock file
(.ledger.lock, exclusive create), so two processes writing the same case in a shared $OPS_HOME are serialized
instead of dropping each other's entries; every file is written under a temporary name and then moved into place,
so a reader never sees a half-written file (on a file system without hard links, a new evidence file is instead
created in place: still never overwritten, but it can be read half-written). A lock left behind by a crashed
process is reported together with its holder and never deleted automatically; delete it by hand once you have
confirmed no process is writing that case. Released versions 1.11.3 and earlier do not take this lock, so every
machine sharing a case directory must upgrade. See SECURITY.md.
Offline / Air-Gapped Install (from source)
This project uses the modern PEP 517 build system (hatchling), so there is no
setup.py by design — that is expected, not a missing file. If you cloned the
source and hit ERROR: File "setup.py" or "setup.cfg" not found ... editable mode currently requires a setuptools-based build, your pip is older than 21.3 and
cannot do an editable (-e) install with a non-setuptools backend. Editable
mode is a developer convenience, not needed to run the tool — do one of:
# From the source tree — a normal (non-editable) install builds a wheel:
pip install . # NOT pip install -e .
# ...or upgrade pip first, and editable works too:
pip install --upgrade pip && pip install -e .For a truly air-gapped host, build the wheels on a connected machine and copy them over — the target then needs no network:
# On a connected machine, collect this package + its dependencies as wheels:
pip wheel . -w dist # → dist/*.whl (or: uv build, for just this package)
# Copy dist/ to the air-gapped host, then install offline:
pip install --no-index --find-links dist vmware-debugRemote access (HTTPS) and limiting tools
By default vmware-debug mcp speaks stdio to one local client and offers every tool. Two options change that
(vmware-policy ≥ 1.21.0).
Serve over HTTPS so clients on other machines can connect. Every caller needs a bearer token:
vmware-audit token create alice # prints the token once; give it to alice
vmware-audit token list # names only
vmware-audit token revoke alice # refused from its next request, no restart
vmware-debug mcp --transport https --host 0.0.0.0 --port 8443 \
--cert /etc/vmware-mcp/server.pem --key /etc/vmware-mcp/server-key.pem \
--public-name mcp.example.comConnect a client (Claude Code shown; any MCP client that supports streamable HTTP and custom headers works):
claude mcp add --transport http vmware-debug https://mcp.example.com:8443/mcp \
--header "Authorization: Bearer $VMWARE_MCP_TOKEN"{
"mcpServers": {
"vmware-debug": {
"type": "http",
"url": "https://mcp.example.com:8443/mcp",
"headers": { "Authorization": "Bearer ${VMWARE_MCP_TOKEN}" }
}
}
}The server will not start without a token, refuses Host/Origin values outside
--public-name, and checks before it binds that unauthenticated requests get 401. Use a certificate your clients trust for those names.Behind a TLS-terminating reverse proxy on the same machine use
--transport http --host 127.0.0.1 --public-name mcp.example.comand pass theAuthorizationheader through.Behind a load balancer or gateway on another machine, keep
--transport https(a self-signed certificate is fine), list in--public-namethe host name the balancer sends asHost, and have it forwardAuthorization. Its health probe can useGET /healthz, which needs no token and returns only{"status": "ok"}(vmware-policy ≥ 1.23.0).Send
traceparentorX-Request-IDwith each request to have it stored on the audit row;vmware-audit log --correlation-id IDthen finds the calls behind one platform request.The audit log records each caller as
token:<name>. Calls naming different targets run in parallel; calls that name no target run one at a time, so name the target when several people share a server.Everyone who can reach the endpoint acts with this server's account. Tokens identify callers; they grant nothing on the platform. Run one endpoint per privilege level.
Several people or roles on one endpoint: run
vmware-audit roles enableonce, then give each token a role (vmware-audit token create NAME --role reader, or a role inroles.yamlnaming tools and targets; vmware-policy ≥ 1.24.0). A role limits what the token may call on this endpoint; it cannot grant more than the account has. See vmware-policy's README, "Roles for network callers".
Offer only read tools, plus the writes you choose:
vmware-debug mcp --expose read --allow-write close_case
# or: VMWARE_DEBUG_MCP_EXPOSE=read VMWARE_DEBUG_MCP_ALLOW_WRITE=close_case vmware-debug mcpTools not offered do not appear in the client's tool list. A bad value or an unknown write tool stops the server (exit 2). This limits what clients are offered; it is not authorization, so the account itself should be least-privilege.
Details: skills/vmware-debug/references/setup-guide.md ("Serving MCP over HTTPS", "Limiting which tools are offered").
License
MIT.
Available Tools
14 toolsbuild_incident_timelineARead-onlyIdempotent
[READ] Correlate already-fetched VMware events into one incident view.
WHEN: use this after you've pulled events for an incident from the data-source skills (vmware-monitor get_events/get_alarms, vmware-aria list_alerts/list_anomalies, vmware-log-insight search_logs/aggregate_logs, vmware-nsx) — feed them here to find what correlates and where to look next. Not sure which events to pull? Run list_symptom_categories first. This tool does NOT fetch anything itself.
RETURNS: {event_count, window, binning, classification, spikes
(strongest anomalous bins), spikes_total, hypotheses (ranked
root-cause candidates, each with a suggested_check), next_checks (which
skill/tool to run next)}. Read binning for the resolution you were
given, and classification for how much of the stream matched nothing —
the ranking describes only the part that did.
GOTCHAS: read-only, stateless, no network — nothing is executed. Remediation routes to vmware-aiops (single fix) or vmware-pilot (multi-step). A malformed event returns {error, hint} naming the offending index.
| Name | Required | Description | Default |
|---|---|---|---|
| top_n | No | How many ranked hypotheses come back (default 5). Spikes are capped separately at 20, true count in 'spikes_total'. | |
| events | Yes | Event envelopes, each {ts, source, severity, entity, text, fields}. ts may be ISO-8601, epoch seconds or epoch millis and is required; severity is normalised onto critical/error/warning/ info/unknown, so vendor spellings (fatal, red, warn, yellow, notice, green) are accepted. An entry that cannot be normalised is refused with its index, not skipped. Keep each event's event_type in fields — vmware-monitor's get_events returns it, and the symptom classifier matches it alongside the message. On a modern EventEx the message is generic boilerplate and the eventTypeId is the only thing that says what happened, so dropping it turns a readable event into an uncategorized one. | |
| bin_seconds | No | Time-bin width in seconds. Omit and it is chosen from event density off the ladder 1/10/60/300/900/3600/21600/86400, taking the finest width still averaging 4 events per bin. | |
| z_threshold | No | Standard deviations above the mean bin count that mark a spike (default 2.0). Under 3 bins, or a flat series, yields none at any threshold — empty spikes is not "calm". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, but the description adds context beyond them: stateless, no network, nothing executed, remediation routed to vmware-aiops or vmware-pilot, and explicit failure behavior ({error, hint} naming the offending index rather than skipping). That is substantive behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Labeled WHEN/RETURNS/GOTCHAS sections front-load the routing decision before the return shape, and each line carries information. The RETURNS block is long, but with no output schema it is doing necessary work rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No output schema exists, so the description carries the full return contract (event_count, binning, classification, spikes/spikes_total, hypotheses with suggested_check, next_checks) plus error shape and follow-on routing. Nothing an agent needs to call or interpret this tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already documents ts formats, severity normalization, binning ladder and z_threshold caveats, so the baseline is 3. The description mostly reiterates this; its only added guidance (keep event_type in fields) duplicates the schema text rather than extending it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Correlate already-fetched VMware events into one incident view') and draws a hard boundary that separates it from the data-source siblings: 'This tool does NOT fetch anything itself.' An agent can distinguish this from get_events/list_alerts without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN block names the upstream skills whose output feeds this tool, gives an explicit prerequisite (list_symptom_categories first when unsure what to pull), and states the exclusion ('does NOT fetch'). Use-vs-alternative routing is fully specified.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
close_caseA
[WRITE] Record the final grade and archive the case — step 08.
WHEN: when the investigation is finished, or is being handed over. Closing turns a working folder into a record other people rely on, so it computes and records the grade rather than accepting one.
RETURNS: {case_id, state, grade, open_gaps, path, note}. open_gaps
names anything still blocking a hypothesis at the moment of closing —
stated here rather than left in the file for someone to find.
GOTCHAS: a closed case is not closed again and its record is never rewritten. To reopen the question, open a new case that cites this one, so the original conclusion and whatever changed it both stay readable.
| Name | Required | Description | Default |
|---|---|---|---|
| case_id | Yes | The case to close (from open_case/list_cases). There is no grade parameter — closing recomputes the grade from the ledger. An already-closed case is refused rather than closed again. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give the bare safety profile (write, not read-only, not idempotent, not destructive). The description adds real context: an already-closed case is refused, the record is never rewritten, and open_gaps is surfaced at closing time. The 'not closed again / never rewritten' behavior is consistent with idempotentHint=false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a [WRITE] marker and one-line purpose, then cleanly sectioned into WHEN / RETURNS / GOTCHAS. Every sentence carries information an agent needs and none is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description helpfully enumerates the return shape ({case_id, state, grade, open_gaps, path, note}), plus trigger conditions and irreversible-behavior caveats. Nothing needed to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single case_id parameter is already well documented in the schema, including the note that there is no grade parameter. The description restates the grade-computation behavior but adds no syntax or format detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb (archive/record grade), the resource (the case), and its position in the workflow (step 08). It clearly separates this from siblings like open_case and grade_case by stating that closing computes the grade rather than accepting one.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN line names the trigger (investigation finished or being handed over), and the GOTCHAS section explicitly routes the reopen scenario to opening a new case that cites this one. It also explains why closing is one-way, so the agent won't reach for a reopen tool that doesn't exist.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_caseARead-onlyIdempotent
[READ] One case: its scope, its ledger sizes, and its grade history.
WHEN: to pick up an investigation, or to see why a case sits at the
grade it does. Returns counts and identifiers rather than the whole
ledger — read the case folder itself (the path from open_case) for
full evidence bodies.
RETURNS: {case_id, path, state, grade, opened_at, scope, evidence_count,
sources, gap_count, blocking_gaps, grade_history}. sources is the
distinct skills evidence came from, which is what corroboration is
counted in.
| Name | Required | Description | Default |
|---|---|---|---|
| case_id | Yes | The case id returned by open_case, or listed by list_cases. An unknown id is an error, never an empty case. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the bar is lower. The description adds real behavioral value: it returns counts and identifiers rather than whole evidence bodies, and flags that an unknown id is an error rather than an empty case.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core statement, then clearly sectioned into WHEN and RETURNS. Every sentence carries information, and the return-field enumeration compensates for the absent output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes on the burden of documenting the return shape and does so explicitly, including the subtle meaning of 'sources'. Nothing an agent needs to call this correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With a single parameter at 100% schema coverage, the schema fully documents case_id (including its error behavior). The description adds no syntax or format detail beyond that, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific operation ('One case') plus what it exposes (scope, ledger sizes, grade history), and the '[READ]' tag and singular scope distinguish it from siblings like list_cases and open_case. An agent can tell what this returns without consulting the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN section gives concrete triggers ('pick up an investigation', 'see why a case sits at the grade it does') and steers away from using it for full evidence, pointing to the case folder via open_case's path. It does not explicitly compare against get_case_readiness or get_case_knowledge, so it stops short of full alternative routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_case_knowledgeARead-onlyIdempotent
[READ] What the knowledge layer accepts, and what is mounted.
WHEN: when someone asks what can be added to make conclusions stronger, or when a case will not reach Confirmed and you need to say why in terms they can act on. This is the answer to "which knowledge formats do you take" — the first question anyone mounting a library asks.
RETURNS: {root, sections, entries, with_applies_to, by_source, unreadable, unsupported, formats, needs_conversion, note} — plus {applicable, decisive_here} when a case_id is given.
formats lists every extension read and how each carries its metadata:
Markdown front-matter, YAML/JSON whole-file, JSONL per line, CSV/TSV per
row, and plain text with a sibling .yaml. needs_conversion names the
ones that must become Markdown first (PDF, DOCX, PPTX, HTML).
GOTCHAS: an entry is decisive ONLY if its applies_to block was checked
against the case scope and passed — matching is by version
applicability, never by similarity, because an entry written for the
wrong build reads exactly like the right one. 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.
| Name | Required | Description | Default |
|---|---|---|---|
| case_id | No | Omit to describe the knowledge layer itself — what formats are read and what is mounted. Pass a case id and every mounted entry is additionally version-checked against THAT case's product_versions, adding `applicable` and `decisive_here` with the reason each entry did or did not qualify. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive, so the safety profile is covered. The description goes further with real behavioral disclosure: version-checking only happens when case_id is passed, and the GOTCHAS explain that decisive matching is by version applicability, not similarity, and that silence is not a pass. That is meaningful context beyond structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the one-line purpose then uses WHEN/RETURNS/GOTCHAS headings, which scan well. It is on the verbose side (long GOTCHAS prose), but each section carries distinct information rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description takes on return-value explanation and does so thoroughly: it enumerates the return keys, describes what `formats` and `needs_conversion` contain, and pre-empts the most likely misreading (showing how entries qualify as decisive). An agent has everything needed to call and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the case_id description already explains omission vs. passing a case id and the resulting `applicable`/`decisive_here` fields. The prose only restates that behavior, adding no syntax or format detail the schema lacks; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb+resource: 'What the knowledge layer accepts, and what is mounted.' An agent can distinguish this from siblings like get_case_readiness or get_case, though the terms 'knowledge layer' and 'mounted' are domain jargon that isn't defined inline.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN block gives explicit triggering conditions ('when someone asks what can be added to make conclusions stronger', 'when a case will not reach Confirmed'). It does not name competing siblings (e.g. get_case_readiness) or state when NOT to use it, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_case_readinessARead-onlyIdempotent
[READ] What strength of conclusion can this environment reach?
WHEN: before starting an investigation, or when a case will not go higher and you want to know whether that is fixable. Answering this first is worth far more than discovering it halfway through.
RETURNS: {classes, categories, unrecognised_skills, note}. A name that
matched no skill in the catalogue comes back in unrecognised_skills
rather than being absorbed into "not installed" — otherwise a typo reads
as advice to install something you already have. Per evidence class:
whether it is
available, through which tools, and if not, how_to_supply. Per
symptom category (storage, network, compute, ha_drs, configuration,
accelerator, kubernetes, hardware, host_lifecycle, power_lifecycle,
auth, platform, licensing, data_collection): a ceiling and the
independent_sources behind it. There is deliberately no single score —
"readiness 78%" cannot be acted on, "storage reaches Probable, hardware
reaches Candidate" can.
GOTCHAS: two classes served by the SAME skill count as one source, so two available classes do not always mean Probable. The hardware class is unavailable no matter what is installed — nothing in this family reaches below ESXi — and the knowledge class becomes available only when entries are mounted under $OPS_HOME/knowledge/.
| Name | Required | Description | Default |
|---|---|---|---|
| available_skills | No | The skills actually installed and configured, in either of the family's spellings — "monitor" and "vmware-monitor" name the same thing. Omit to assume all of them, which reports the ceiling imposed by the family itself rather than by this install. A name matching no catalogued skill comes back in `unrecognised_skills` rather than being read as "not installed". |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, idempotent, not destructive, closed-world), and the description adds genuinely non-obvious behavior: two classes served by the same skill count as one source, the hardware class is never reachable in this family, and the knowledge class only activates with entries under $OPS_HOME/knowledge/. These are real traps an agent could not derive from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a [READ] tag and WHEN/RETURNS/GOTCHAS sections, which makes scanning easy. There is mild redundancy: unrecognised_skills behavior is explained in both the RETURNS block and the parameter schema, and the category enumeration is lengthy, but the structure earns its length for a no-output-schema tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must carry the return contract, and it does: field names, the rationale for unstructured ceilings over a single score, and an explicit statement that no aggregate score exists. Combined with the gotchas, an agent has everything needed to call and interpret this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the single optional parameter's aliasing rule ('monitor' vs 'vmware-monitor') and omit-behavior are already documented in the schema. The description restates the unrecognised_skills consequence rather than adding new semantics. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific, if rhetorically framed, purpose: determining what strength of conclusion the environment can reach. The RETURNS block makes the resource concrete (evidence classes, symptom categories, ceilings). It stops short of naming siblings like grade_case or plan_case, so an agent must infer the boundary between 'readiness' and 'grading' from context.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit WHEN clause gives two triggering conditions: before starting an investigation, and when a case stalls and you want to know if the ceiling is fixable. It even argues the sequencing ('worth far more than discovering it halfway through'). No explicit when-not or named alternative tool, which keeps it from a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
grade_caseA
[WRITE] Compute and record the conclusion grade — steps 07/08.
WHEN: when you think the investigation has reached a conclusion, or to record where it stands before handing it over.
There is deliberately NO parameter for the grade. You cannot state a conclusion level; it is recomputed from the ledger on every call. If you disagree with the result, change the ledger — submit the evidence that is missing, or record the gap that is blocking it.
The levels: Candidate (a hypothesis exists); Probable (at least two INDEPENDENT sources agree — two calls to the same 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 the hypothesis out — "we looked and found nothing" is a gap, not an exclusion). Exclusion is per hypothesis, counting only sources that falsify THAT hypothesis; the case is Excluded only when every registered one is. A hypothesis contradicted but not yet ruled out holds the case at Candidate. Otherwise the grade counts only evidence that falsifies nothing.
RETURNS: {grade, previous, direction, reasons, ceiling, ceiling_reasons,
rules_source, rules_origin, hypotheses}. hypotheses lists every
registered hypothesis as {id, status: open|excluded}. direction is
initial/up/down/unchanged — grades may go DOWN, and the history records
it when they do.
GOTCHAS: on a stock install ceiling is "probable", because Confirmed
needs a decisive source and there is neither a hardware-diagnostic
channel nor a knowledge library mounted yet. That is a real limit, not
a caution. Every grading is appended to conclusion.md and none is ever
rewritten.
| Name | Required | Description | Default |
|---|---|---|---|
| case_id | Yes | The case to grade (from open_case/list_cases). This is the only parameter — see above for why there is no grade parameter. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations mark this as a non-idempotent write (readOnlyHint=false, idempotentHint=false), and the description adds substantive context beyond them: the grade is recomputed from the ledger on every call, every grading is appended to conclusion.md and never rewritten, and the stock-install ceiling limits results to 'probable'. The 'no grade parameter' design constraint is exactly the kind of non-obvious behavior an agent must know before calling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and a WHEN block, then labeled RETURNS and GOTCHAS sections — an agent can skim to what it needs. It is long, and the level definitions are dense, but the length is load-bearing because there is no output schema to carry that semantics; a little of the level prose could still be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a complex, logic-heavy grading tool with no output schema, and the description compensates by enumerating the return keys, explaining direction/ceiling semantics, and defining each grade level with its evidence requirements. Nothing an agent needs to invoke it correctly or interpret its result is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for the single case_id parameter, so the baseline is 3. The description goes further by explaining why no grade parameter exists and why passing one is impossible, and by pointing to open_case/list_cases as the source of the id — meaning that adds value beyond the schema field text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource — '[WRITE] Compute and record the conclusion grade' — with the pipeline position (steps 07/08). It is immediately distinguishable from siblings like get_case_readiness (a read of readiness) and close_case (termination), so an agent knows this is the tool that writes the grade.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN block gives explicit conditions to call it ('when you think the investigation has reached a conclusion, or to record where it stands before handing it over'). It also routes the agent away from the wrong corrective action: if you disagree with the computed grade, submit evidence or record the gap rather than trying to assert a level.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_casesARead-onlyIdempotent
[READ] List investigation cases, newest first.
WHEN: to find the id of a case you or someone else opened earlier. Returns the family list envelope {items, returned, limit, total, truncated, hint}; each item is {case_id, summary, state, grade, opened_at}. A case whose folder is damaged appears with state="unreadable" rather than vanishing from the list.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum cases in the page, newest first (default 50). There is no offset — 'total' reports every case, so when truncated is true the only way to reach older ones is a larger limit. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, so safety is covered. The description adds genuinely useful behavioral context beyond annotations: the return envelope shape {items, returned, limit, total, truncated, hint}, and the notable edge case that damaged cases appear with state='unreadable' rather than disappearing.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the [READ] tag and purpose, then WHEN, then return shape. Slightly dense in the middle paragraph but every sentence carries information; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers purpose, when-to-use, return envelope, and an important edge case, which is strong for a listing tool with no output schema and rich annotations. Could be 5 with explicit sibling routing, but it's complete enough to call correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the single 'limit' parameter is already fully documented in the schema (default 50, no offset, truncated behavior). The description adds nothing parameter-specific beyond what the schema says. Baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a clear verb+resource ('List investigation cases') with ordering ('newest first'). It is distinguishable from get_case/open_case by being a listing operation, but it doesn't explicitly name how it differs from siblings beyond the WHEN line.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN line explicitly frames the use case: 'to find the id of a case you or someone else opened earlier.' This tells the agent the discovery intent that routes here rather than to get_case (which needs an id). No explicit exclusions, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_symptom_categoriesARead-onlyIdempotent
[READ] List the symptom categories vmware-debug recognises, each with example keywords and a suggested next check (which skill/tool to run). Takes no parameters. Use this when you don't yet know what to look at — it turns "something's wrong" into concrete investigation steps. Then gather the events those checks name and pass them to build_incident_timeline. Returns the family list envelope {items, returned, limit, total, truncated, hint}; each item is {category, example_keywords, suggested_check}. The routing table is a fixed constant, so truncated is always false and total exact — this is every category, not a page. Read-only; no network access.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnlyHint, idempotentHint, destructiveHint=false). The description adds non-obvious behavioral facts: it takes no parameters, the table is a fixed constant so truncated is always false and total is exact, and there is no network access. It stops short of anything beyond that, but this is solid added context over the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the [READ] marker and the core purpose, then the when-to-use and the return-envelope details. Every clause earns its place, though the return-envelope enumeration is slightly dense and could be trimmed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema and no parameters, the description carries the full burden and does so: it spells out the envelope shape {items, returned, limit, total, truncated, hint} and each item's fields, plus the completeness guarantee. An agent has everything needed to call and consume it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4. The description explicitly confirms "Takes no parameters," which is consistent with the empty schema and removes any doubt about required inputs.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource -- lists the symptom categories the tool recognizes -- and enumerates what each item contains (example keywords, suggested next check). It is clearly distinguishable from the case-management siblings and the timeline builder it routes to.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly names the trigger condition ("Use this when you don't yet know what to look at") and the follow-on workflow (gather the named events, then pass them to build_incident_timeline). The routing to a specific sibling tool leaves nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_caseA
[WRITE] Open an investigation case — step 01, define the event.
WHEN: at the start of an incident you expect to reason about rather than glance at. For a one-off lookup use build_incident_timeline alone.
RETURNS: {case_id, path, state, grade, ceiling, ceiling_reasons, next}.
Read ceiling now — it is the best grade this install can reach at all.
GOTCHAS: writes only under $OPS_HOME, never to a VMware system, and never over an existing case.
| Name | Required | Description | Default |
|---|---|---|---|
| objects | No | Entities in scope, names or MoIDs ("vm-web01", "host-12"). Omit for a case not yet pinned to specific objects. | |
| summary | Yes | What is wrong, one line. plan_case reads it to infer the symptom category, so name the symptom in the estate's own words ("datastore latency on cluster-a"), not a diagnosis. | |
| window_end | No | Believed end, ISO-8601. Omit while still in progress. | |
| window_start | No | When the incident is believed to have started, ISO-8601. Omit if unknown — evidence gets fetched against it, so an invented window is worse than none. | |
| determined_by | Yes | HOW the scope was decided — "user report", "vCenter alarm 42". Required: a scope from a phone call and one from an alarm id support different conclusions, and nobody remembers which it was later. | |
| product_versions | No | Versions keyed by product — {"esxi": "8.0.3"} — plus "driver.<name>" / "firmware.<name>" entries. Knowledge-base entries are version-checked against this: one constraining a product absent here can support a hypothesis but never make the case Confirmed, since an unanswerable constraint is not a pass. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false and idempotentHint=false; the description goes further with GOTCHAS that the annotations cannot express: writes are confined to $OPS_HOME, never touch a VMware system, and never overwrite an existing case. It also tells the agent to read `ceiling` immediately and explains what that field means, which is real behavioral guidance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a [WRITE] tag and purpose, then cleanly segmented into WHEN / RETURNS / GOTCHAS blocks. Every sentence carries load; no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter write tool with no output schema, the description compensates by enumerating the return keys and flagging the one the agent must read. Combined with write-scope caveats and the routing to build_incident_timeline, nothing an agent needs to invoke it correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so every parameter (summary, window_start/end, determined_by, objects, product_versions) is already explained with rationale in the schema itself. The description adds no additional parameter-level meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb+resource ('Open an investigation case') and positions it as 'step 01, define the event' in a named workflow. It explicitly contrasts with the sibling build_incident_timeline for one-off lookups, so an agent can distinguish it without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN block states the trigger ('at the start of an incident you expect to reason about rather than glance at') and names the alternative tool plus the condition that selects it ('For a one-off lookup use build_incident_timeline alone'). No inference required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
plan_caseARead-onlyIdempotent
[READ] What to fetch next for this case — step 02, recomputed each call.
WHEN: right after open_case, and again after each round of evidence. It is not a checklist: submit something and the next plan is shorter, lose a source and it routes around it.
RETURNS: {category, category_signals, steps, already_covered, held_back, unavailable, ceiling, note}. Steps are interleaved across evidence classes, so you get breadth before depth — corroboration is counted in distinct sources, which is what actually moves the grade. Each step is {evidence_class, skill, tool, purpose, objects, window, degraded} — call that skill's tool, then submit the result with submit_case_evidence.
GOTCHAS: unavailable is the important half. A source this install
cannot reach is listed there with how_to_supply rather than left out, so
the gap is visible now instead of when the conclusion refuses to firm
up. An empty steps is never silent — note says whether everything
reachable is already in, or whether nothing here can be reached.
category_signals names the words that chose the category, and any
category that also matched — check it first, since the rest runs off
that one word.
| Name | Required | Description | Default |
|---|---|---|---|
| case_id | Yes | The case to plan for (from open_case/list_cases). | |
| category | No | Force the symptom class instead of inferring it. Exactly one of: storage, network, compute, ha_drs, configuration, accelerator, kubernetes, hardware, host_lifecycle, power_lifecycle, auth, platform, licensing, data_collection. Omit to infer, then read `category_signals` for the word that decided it. | |
| max_steps | No | How many steps to return, at least 1. The default of 6 is two rounds across three evidence classes — enough to reach the two independent sources a Probable grade costs, without handing a model a fourteen-item menu it will work through. Raise it when `held_back` says there is more for this category; a storage case has fourteen reachable tools. Below 1 is refused rather than obeyed, because an empty plan already means "nothing left to fetch". | |
| available_skills | No | Narrow to the skills actually installed, in either spelling ("monitor" or "vmware-monitor"). Omit to assume all of them, which can produce steps this install cannot run. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only/idempotent/closed-world, and the description still adds substantial behavior: outputs are recomputed per call, `unavailable` sources carry how_to_supply rather than being dropped, empty `steps` is never silent (a `note` explains why), and `category_signals` should be inspected first. These are real operational traits not derivable from the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The WHEN/RETURNS/GOTCHAS structure front-loads the essentials and the return-shape block is dense but information-bearing. It runs long and leans on prose-heavy gotchas, but almost every sentence carries distinct guidance rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description must describe the return contract itself, and it does: the top-level keys, the per-step shape {evidence_class, skill, tool, purpose, objects, window, degraded}, and edge-case semantics. For a 4-parameter planning tool, an agent has everything needed to call and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so 3 is the floor; the description goes beyond it by explaining the rationale for max_steps' default (6 = two rounds across three classes, and two independent sources to reach Probable), the below-1 refusal behavior, and how category inference ties to category_signals. It clarifies the consequence of parameters rather than restating them.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: '[READ] What to fetch next for this case — step 02, recomputed each call.' The scope (next-fetch planning for a case) and its read-only nature are unambiguous, and it is clearly separable from siblings like submit_case_evidence, grade_case, and open_case.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN block gives explicit timing: 'right after open_case, and again after each round of evidence.' It also states the interactive contract with a named sibling ('call that skill's tool, then submit the result with submit_case_evidence') and clarifies it is not a checklist, so the agent knows both when and how to re-invoke it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_case_gapA
[WRITE] Record something the investigation could NOT obtain.
WHEN: any time a fetch failed, was refused, returned nothing, or the data simply does not exist in this environment. This is the tool that keeps a case honest: an unrecorded gap makes it look better supported than it is.
RETURNS: {case_id, gap_id, grade, reasons}.
GOTCHAS: recording a gap does not punish the case for the evidence it does have — a missing confirmation caps the grade, it does not demote it. Writing gaps down is meant to be free.
| Name | Required | Description | Default |
|---|---|---|---|
| why | Yes | Why it could not be had — refused, unreachable, collected by nothing in this family, absent from this environment. | |
| what | Yes | The observation that could not be obtained — the thing you wanted, not the error you got. | |
| blocks | No | Hypothesis ids (H1, H2, …) this gap holds up; they must already exist via record_case_hypothesis. Empty is fine. | |
| case_id | Yes | The case this gap belongs to (from open_case/list_cases). | |
| how_to_close | Yes | The next action that would close it, even outside this system ("open a vendor SR"). A gap with no stated next action reads like a to-do and gets skipped. | |
| could_falsify | No | Would OBTAINING this be able to prove the hypothesis WRONG? false (default) is the ordinary case — missing corroboration, capping the case below Confirmed. true means it could overturn the hypothesis, holding it at Candidate. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a write (readOnlyHint=false) that is non-idempotent and non-destructive; the description adds genuinely new behavior beyond them — recording a gap caps a grade rather than demoting it, and is intended to be 'free,' which tells the agent there is no penalty cost to logging gaps. It does not address duplicate/non-idempotent writes, which is the only notable omission.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Sectioned as WHEN / RETURNS / GOTCHAS with the write marker and core definition front-loaded. Every sentence carries information an agent needs, with no restatement of the schema or name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a six-parameter write tool with no output schema, the description supplies the return shape ({case_id, gap_id, grade, reasons}), the trigger conditions, and the consequence semantics. Nothing required to call it correctly — case_id provenance, gap semantics, grade impact — is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all six parameters, including the subtle could_falsify and how_to_close semantics, are already documented in the schema. The description's only parameter-adjacent content is the RETURNS shape, not the inputs, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb+resource ('Record something the investigation could NOT obtain') and immediately demarcates it from the evidence-writing siblings by defining a gap as an unobtainable observation. An agent can distinguish this from submit_case_evidence or record_case_hypothesis without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The WHEN section gives concrete triggers (fetch failed, refused, returned nothing, data does not exist in this environment) plus a rationale for why recording matters. It stops short of naming a sibling tool as the alternative for the opposite case (e.g., 'if you did obtain it, use submit_case_evidence'), so it is clear context without explicit routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_case_hypothesisA
[WRITE] Register a candidate explanation — step 06. Called without
statement it writes nothing and only reads the hypothesis ledger.
WHEN: as soon as you have a theory worth testing, and again to see where
each one stands. Pass statement to add one; omit it to just read.
Every hypothesis gets an id (H1, H2, …). Those ids are what record_case_gap(blocks=[...]) and submit_case_evidence(falsifies=[...]) refer to, and an id that was never registered is REFUSED rather than ignored — a dangling reference blocks nothing and falsifies nothing, which quietly reports a stronger case than you have.
RETURNS: {case_id, added, hypotheses, note}. Each entry carries its
status: refuted (ruled out by grade_case's rule), blocked (a gap is
in the way, with the gap id and how to close it), or open.
refuted_by lists every falsifying item; the first next step says when
more sources are needed. Status is computed from what points at the
hypothesis, never asserted.
GOTCHAS: refuted outranks blocked. Once an observation settles the question, a missing measurement no longer matters.
| Name | Required | Description | Default |
|---|---|---|---|
| case_id | Yes | The case whose hypothesis ledger this is (from open_case/list_cases). | |
| statement | No | The candidate explanation, in one line. Pass it to register a new hypothesis, which is assigned the next id (H1, H2, …); omit it to read the ledger without changing it. There is no parameter for a hypothesis's status — status is computed from the evidence and gaps that point at it. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only give the generic profile (not read-only, not idempotent, not destructive); the description adds the real behavioral contract: omitting `statement` is a pure read, ids are auto-assigned (H1, H2, …), unregistered ids are REFUSED rather than ignored, and status is computed rather than asserted. The GOTCHAS precedence rule ("refuted outranks blocked") is exactly the kind of non-obvious trait annotations cannot express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a bracketed [WRITE] tag and labeled WHEN / RETURNS / GOTCHAS blocks that make scanning easy. It is longer than most, and a few clauses ("which quietly reports a stronger case than you have") lean rhetorical, but each block carries distinct information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, so the description supplies the return shape ({case_id, added, hypotheses, note}), the status vocabulary (refuted/blocked/open), the `refuted_by` field, and the resulting next step. For a two-parameter ledger tool in an evidence-grading workflow, nothing needed to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description earns more by explaining the id-assignment scheme for `statement` and the deliberate absence of a status parameter ("status is computed from the evidence and gaps that point at it"). It adds semantics the schema cannot: that omitting statement must not be treated as an empty write.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
"[WRITE] Register a candidate explanation" gives a specific verb and resource, and the description immediately disambiguates the dual mode: with `statement` it adds a hypothesis, without it only reads the ledger. This distinguishes it from siblings like record_case_gap and submit_case_evidence, which are named as downstream consumers of the ids this tool mints.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
A dedicated WHEN clause states the trigger ("as soon as you have a theory worth testing") and the re-use case ("again to see where each one stands"). It also explicitly routes cross-tool usage by naming record_case_gap(blocks=[...]), submit_case_evidence(falsifies=[...]) and grade_case as the things that give a hypothesis its status.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
record_case_timelineA
[WRITE] Correlate everything this case has collected — steps 04/05.
WHEN: once evidence is in. Unlike build_incident_timeline, this takes no events: it reads the payloads already submitted, so the result is reproducible from the case folder alone months later, on a machine with access to nothing.
RETURNS: {event_count, window, binning, classification, spikes, spikes_total, hypotheses, evidence_without_events, evidence_without_events_detail, rejected, note} and writes timeline.md.
GOTCHAS: note distinguishes three states that all show zero events —
no evidence submitted at all, evidence that carried none, and a genuinely
quiet window — and names which items carried none, with what they held
instead. rejected names any row that could not be read, with the
evidence item it came from; dropping those silently would shrink the
picture the conclusion rests on. Submit a read tool's raw result as
payload for its events to reach here — a summary of the result carries
no rows, and submit_case_evidence says so at the time.
| Name | Required | Description | Default |
|---|---|---|---|
| top_n | No | How many ranked hypotheses come back (default 5). Spikes are capped separately at 20, true count in 'spikes_total'. | |
| case_id | Yes | The case whose submitted payloads are correlated (from open_case/list_cases). Unlike build_incident_timeline this takes no events — everything comes from the case folder. | |
| bin_seconds | No | Time-bin width in seconds. Omit and it is chosen from event density (ladder 1..86400, finest width still averaging 4 events per bin); `binning` reports which was used. | |
| z_threshold | No | Standard deviations above the mean bin count that mark a spike (default 2.0). Under 3 bins, or a flat series, yields none at any threshold. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare the write/non-destructive profile; the description goes well beyond by disclosing that timeline.md is written, that the result is reproducible from the case folder, that unreadable rows are surfaced via `rejected` rather than silently dropped, and that `note` disambiguates three zero-event states. This is exactly the behavioral context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a bracketed operation tag and organized under WHEN/RETURNS/GOTCHAS headers, so an agent can scan it quickly. The GOTCHAS paragraph is dense and slightly long, but each sentence carries a distinct operational fact.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description enumerates the return keys and explains the two most easily misread ones (`note`, `rejected`), plus the side effect of writing timeline.md. For a four-parameter write tool this covers everything needed to invoke and interpret it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so top_n, bin_seconds, and z_threshold are already fully documented in the schema, and the description does not restate them. It adds only indirect parameter context via the payload-submission prerequisite and the return-key list. Baseline 3 is appropriate when the schema does the heavy lifting.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (correlate) and resource (everything the case has collected), and explicitly contrasts itself with build_incident_timeline, noting it takes no events. An agent can distinguish it from its siblings without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ("WHEN: once evidence is in") and names the alternative (build_incident_timeline) along with the distinguishing condition (takes no events). The GOTCHAS section also tells the agent the prerequisite that a read tool's raw result must have been submitted as `payload`.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
submit_case_evidenceA
[WRITE] Record one retrieved fact — steps 02/03 of the evidence loop.
WHEN: after every read-tool call you intend to reason from.
RETURNS: {case_id, evidence_id, payload_events, payload_note, grade, reasons} — the resulting grade, so you need no second call to see whether this changed anything, and what the payload was read as, so a summary submitted in place of a result is visible here rather than as a zero from record_case_timeline later.
GOTCHAS: a fetch that failed or came back empty goes to record_case_gap, not here.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | The exact parameters the tool was called with, so it can be re-run. Omit only if there genuinely were none. | |
| case_id | Yes | The case this fact belongs to (from open_case/list_cases). Required. | |
| payload | No | The read tool's RAW result, not a summary. For its events to reach record_case_timeline it must be a list of event dicts, or carry them under 'items', 'events' or 'rows'. What was found comes back as payload_events/payload_note. | |
| summary | Yes | What this item shows, one line. | |
| falsifies | No | Hypothesis ids (H1, H2, …) this observation RULES OUT — the only route to Excluded; "we looked and found nothing" is a gap, not an exclusion. Ids must already exist via record_case_hypothesis; an unregistered id is refused and nothing is written. | |
| fetched_at | No | When the fetch happened, ISO-8601. Omit to stamp now — wrong for an item transcribed from earlier. | |
| window_end | No | End of the period the data covers, ISO-8601. | |
| source_tool | Yes | The tool within that skill, e.g. "get_events". Required, non-blank — "monitor said so" is not reproducible. | |
| time_source | No | Whose clock stamped it — "vcenter", "host" or "client". Recorded so a reader can judge whether two sources' timestamps compare; nothing in this release corrects for it. Null when unknown, never a guess. | |
| clock_skew_s | No | Known offset of that clock from UTC, in seconds. Recorded, likewise not applied. Null when unknown. | |
| source_skill | Yes | The skill that produced it, as the family spells it — "vmware-monitor", "vmware-aria", "vmware-log-insight". Required, non-blank. Two items from the SAME skill count as ONE source when corroboration is counted, so this string decides whether the case can reach Probable. Two reserved values name the knowledge layer instead: "knowledge-kb" and "knowledge-sr", the only sources that can be decisive. | |
| window_start | No | Start of the period the DATA COVERS, ISO-8601 — not when it was fetched. get_events(hours=24) run at 10:00 and at | |
| knowledge_entry_id | No | Which mounted knowledge entry this item IS. REQUIRED when source_skill is knowledge-kb or knowledge-sr — without it the entry's applies_to cannot be checked, so it counts as ordinary support and can never make the case Confirmed. get_case_knowledge lists what is mounted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnlyHint=false, idempotentHint=false), so the bar is lower, but the description still adds real value: it discloses the return shape ({case_id, evidence_id, payload_events, payload_note, grade, reasons}), why grade is returned (no second call needed), and the cross-tool consequence that a summary submitted in place of a raw payload becomes visible here rather than as a later zero. It does not itself warn about duplicate submissions, relying on the idempotency annotation for that.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the [WRITE] marker, then split into labeled WHEN / RETURNS / GOTCHAS sections. Every sentence carries operational content; nothing is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 13 parameters at 100% schema coverage and no output schema, the description carries the return-shape burden itself and does so. The routing rule to record_case_gap and the grade-return rationale close the loops an agent needs before calling.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds cross-parameter meaning beyond the per-field docs: it explains that the payload is read as raw events and that a summary used in its place is detectable via payload_note. The payload/summary/grade interplay is genuinely useful framing the schema does not state.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ("Record one retrieved fact") and frames it in the case workflow ("steps 02/03 of the evidence loop"). The GOTCHAS section explicitly names the sibling it is NOT (record_case_gap), so an agent can separate them without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit trigger ("after every read-tool call you intend to reason from") and an explicit exclusion with the alternative ("a fetch that failed or came back empty goes to record_case_gap, not here"). Both the when and the when-not are stated, not inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
26 tool updates
v2.3.0- Added
build_incident_timeline - Removed
case_close - Removed
case_get - Removed
case_grade - Removed
case_hypotheses - Removed
case_knowledge - Removed
case_list - Removed
case_open - Removed
case_plan - Removed
case_readiness - Removed
case_record_gap - Removed
case_submit_evidence - Removed
case_timeline - Added
close_case - Added
get_case - Added
get_case_knowledge - Added
get_case_readiness - Added
grade_case - Removed
incident_timeline - Added
list_cases - Added
open_case - Added
plan_case - Added
record_case_gap - Added
record_case_hypothesis - Added
record_case_timeline - Added
submit_case_evidence
14 tool updates
v1.13.0- Changed
case_close1 field changed- changed
Input schema / titlePrevious value: -"_case_close_implArguments"New value: +"case_closeArguments"
- Changed
case_get1 field changed- changed
Input schema / titlePrevious value: -"_case_get_implArguments"New value: +"case_getArguments"
- Changed
case_grade1 field changed- changed
Input schema / titlePrevious value: -"_case_grade_implArguments"New value: +"case_gradeArguments"
- Changed
case_hypotheses1 field changed- changed
Input schema / titlePrevious value: -"_case_hypotheses_implArguments"New value: +"case_hypothesesArguments"
- Changed
case_knowledge1 field changed- changed
Input schema / titlePrevious value: -"_case_knowledge_implArguments"New value: +"case_knowledgeArguments"
- Changed
case_list1 field changed- changed
Input schema / titlePrevious value: -"_case_list_implArguments"New value: +"case_listArguments"
- Changed
case_open1 field changed- changed
Input schema / titlePrevious value: -"_case_open_implArguments"New value: +"case_openArguments"
- Changed
case_plan3 fields changed- changed
Input schema / properties / category / descriptionPrevious value: -"Force the symptom class instead of inferring it. Exactly one of: storage, network, compute, ha_drs, configuration, accelerator, kubernetes, hardware, host_lifecycle, power_lifecycle, auth, platform. Omit to infer, then read `category_signals` for the word that decided it."New value: +"Force the symptom class instead of inferring it. Exactly one of: storage, network, compute, ha_drs, configuration, accelerator, kubernetes, hardware, host_lifecycle, power_lifecycle, auth, platform, licensing, data_collection. Omit to infer, then read `category_signals` for the word that decided it." - changed
Input schema / properties / max_steps / descriptionPrevious value: -"HAS NO EFFECT in this release — accepted but never forwarded to the planner, which always caps at 6. The result's note may still advise raising it; doing so changes nothing. Read `held_back` for how many steps were cut."New value: +"How many steps to return, at least 1. The default of 6 is two rounds across three evidence classes — enough to reach the two independent sources a Probable grade costs, without handing a model a fourteen-item menu it will work through. Raise it when `held_back` says there is more for this category; a storage case has fourteen reachable tools. Below 1 is refused rather than obeyed, because an empty plan already means \"nothing left to fetch\"." - changed
Input schema / titlePrevious value: -"_case_plan_implArguments"New value: +"case_planArguments"
- Changed
case_readiness1 field changed- changed
Input schema / titlePrevious value: -"_case_readiness_implArguments"New value: +"case_readinessArguments"
- Changed
case_record_gap1 field changed- changed
Input schema / titlePrevious value: -"_case_record_gap_implArguments"New value: +"case_record_gapArguments"
- Changed
case_submit_evidence1 field changed- changed
Input schema / titlePrevious value: -"_case_submit_evidence_implArguments"New value: +"case_submit_evidenceArguments"
- Changed
case_timeline1 field changed- changed
Input schema / titlePrevious value: -"_case_timeline_implArguments"New value: +"case_timelineArguments"
- Changed
incident_timeline2 fields changed- changed
Input schema / properties / events / descriptionPrevious value: -"Event envelopes, each {ts, source, severity, entity, text, fields}. ts may be ISO-8601, epoch seconds or epoch millis and is required; severity is normalised onto critical/error/warning/ info/unknown, so vendor spellings (fatal, red, warn, yellow, notice, green) are accepted. An entry that cannot be normalised is refused with its index, not skipped."New value: +"Event envelopes, each {ts, source, severity, entity, text, fields}. ts may be ISO-8601, epoch seconds or epoch millis and is required; severity is normalised onto critical/error/warning/ info/unknown, so vendor spellings (fatal, red, warn, yellow, notice, green) are accepted. An entry that cannot be normalised is refused with its index, not skipped. Keep each event's event_type in fields — vmware-monitor's get_events returns it, and the symptom classifier matches it alongside the message. On a modern EventEx the message is generic boilerplate and the eventTypeId is the only thing that says what happened, so dropping it turns a readable event into an uncategorized one." - changed
Input schema / titlePrevious value: -"_incident_timeline_implArguments"New value: +"incident_timelineArguments"
- Changed
list_symptom_categories1 field changed- changed
Input schema / titlePrevious value: -"_list_symptom_categories_implArguments"New value: +"list_symptom_categoriesArguments"
14 tool updates
v1.11.1- Added
case_close - Added
case_get - Added
case_grade - Added
case_hypotheses - Added
case_knowledge - Added
case_list - Added
case_open - Added
case_plan - Added
case_readiness - Added
case_record_gap - Added
case_submit_evidence - Added
case_timeline - Changed
incident_timeline5 fields changed- added
Input schema / additionalPropertiesAdded value: +false - added
Input schema / properties / bin_seconds / descriptionAdded value: +"Time-bin width in seconds. Omit and it is chosen from event density off the ladder 1/10/60/300/900/3600/21600/86400, taking the finest width still averaging 4 events per bin." - added
Input schema / properties / events / descriptionAdded value: +"Event envelopes, each {ts, source, severity, entity, text, fields}. ts may be ISO-8601, epoch seconds or epoch millis and is required; severity is normalised onto critical/error/warning/ info/unknown, so vendor spellings (fatal, red, warn, yellow, notice, green) are accepted. An entry that cannot be normalised is refused with its index, not skipped." - added
Input schema / properties / top_n / descriptionAdded value: +"How many ranked hypotheses come back (default 5). Spikes are capped separately at 20, true count in 'spikes_total'." - added
Input schema / properties / z_threshold / descriptionAdded value: +"Standard deviations above the mean bin count that mark a spike (default 2.0). Under 3 bins, or a flat series, yields none at any threshold — empty spikes is not \"calm\"."
- Changed
list_symptom_categories1 field changed- added
Input schema / additionalPropertiesAdded value: +false
2 tool updates
v1.8.8- First observed
incident_timeline - First observed
list_symptom_categories
TDQS
Scored across 14 tools
Most tools are clearly separated by lifecycle stage and action, but build_incident_timeline and record_case_timeline both perform event correlation, and plan_case, get_case_readiness, and get_case_knowledge all provide advisory information. The detailed descriptions do a good job of distinguishing them, but they require careful reading.
All 14 tool names use snake_case and begin with a clear verb (build_, list_, open_, get_, submit_, record_, grade_, plan_, close_). The pattern is highly predictable and consistent across reads and writes.
14 tools is well-scoped for a case-based investigation workflow that includes setup, evidence handling, grading, readiness, planning, knowledge, and closure. Each tool appears to earn its place rather than padding the surface.
The server covers the full investigation lifecycle from open_case through close_case, including evidence, gaps, hypotheses, timelines, grading, and readiness. Minor gaps exist around directly reading case evidence bodies or fetching events, but those are intentionally delegated to external data-source skills and the case folder.
Maintenance
Related MCP Connectors
Collision-first MCP diagnostics for MCP, API, webhook and agent failures. Returns structured evidence, bounded repair guidance, agent compatibility checks and safe recovery routing.
Discover software problems, analyze evidence, and create implementation-ready Build plans.
- causelyOAuthapp.causely
Causal reasoning for reliability: root cause, blast radius, and service health for agents.
Triage failing GitHub Actions jobs and see what self-heal repaired, in natural language.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceEnables users to investigate infrastructure incidents in plain English, correlate observability and deploy data with runbooks, and get evidence-backed root-cause proposals with approval-gated remediation.5-
- AlicenseNot gradedqualityBmaintenanceEnables log analysis through MCP tools for searching logs, retrieving error contexts, and summarizing incidents with self-verified root-cause hypotheses.5 npmMIT
- AlicenseAqualityAmaintenanceEnables AI-assisted management of vCenter Server and standalone ESXi hosts, including lifecycle, deployment, guest operations, cluster management, datastore browsing, alarms, and investigations through natural language.60MIT
- AlicenseNot gradedqualityCmaintenanceEnables MCP clients to interactively triage 4G/5G modem logs by summarizing logs, detecting fault signatures with evidence, retrieving relevant troubleshooting knowledge, and generating root-cause reports.MIT