Rootpath MCP Server
Allows the incident agent to inspect and act on a Dockerized microservice stack, using Docker Compose labels and environment data to map service topology, read service health/logs, and restart or roll back services during incident remediation.
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., "@Rootpath MCP Serverfrontend is throwing 50% errors — find the real root cause and fix it"
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.
Rootpath
The alert is never where the bug is. Rootpath is an incident agent that reasons over a FalkorDB graph of your services, deploys, feature flags, owners and past incidents. It follows the failure from the alert to where it starts, fixes it, checks the fix, and remembers. It plugs into the coding agent you already use (Claude Code, Codex, Cursor) over MCP, or runs on its own when an alert fires.
Graph Hacks: Context for AI Agents (WeMakeDevs × FalkorDB, Oct 2026) Tracks: 01 Agents That Act on Connected Data (primary) · 02 Agent Memory and Coordination
Website with live replays: https://iwhitebird.github.io/rootpath/ · Demo video: link

A real recorded run, replayed by the project website:
fraud-check gets slow after a flag flip, frontend alerts, and the agent follows the graph three hops
down. It rules out a coincidental deploy, recalls the matching past incident, turns the flag off,
verifies recovery, pages the owner and stores the incident. docs/replay.mp4 is
the same clip as video.

The problem
When production breaks, the first 20–40 minutes of an incident go to working out what changed, what's affected and who owns it. That means jumping between dashboards, logs, deploy history and Slack. AI agents mostly don't fix this. They either grep every log (slow, expensive, easy to fool with a coincidental deploy) or only diagnose without acting, verifying or learning.
The answer depends on how things connect:
the service that alerts is rarely the one that's broken;
a deploy only matters if it sits on the failing path;
a feature flag affects services it is never deployed to;
the right fix was usually already found the last time.
That is a graph problem.
Related MCP server: SentinelMCP
What it does
ALERT frontend 50% errors
● rank_suspects(frontend) graph: frontend → checkout → payment → fraud-check
fraud-check: slow, own deps healthy, flag fraud_model_v2 flipped 88s ago
ruled out: notify v1.2.1 deploy (not on the failing path)
● get_logs(fraud-check) latency 15ms → 1.9s right after the flip
● find_similar_incidents INC-027: same flag, same symptom, fixed by turning it off
● open_incident INC-043
● set_feature_flag(dry_run) plan: fraud_model_v2 true → false, affects fraud-check
● set_feature_flag executed
● verify_recovery(frontend) 0% errors after 7s ✓
● notify_owner(fraud-check) paged ananya (#team-risk)
● resolve_incident root cause → change chg-847f70af, stored in memory
done in 45s · 9 tool callsLocate: multi-hop traversal from the alerting service through
CALLSedges, combined with live health, recentDeploy/FlagChangenodes andalgo.betweenness. The deepest unhealthy node on the path with a fresh change wins. Changes outside the dependency graph are explicitly ruled out.Confirm: logs of the top suspect only, plus incident memory: a full-text and graph-overlap search over past
Incidentnodes, theirROOT_CAUSEand whatRESOLVED_BYthem.Act: roll back, restart or flip a flag. Every action is dry-run first and recorded as
(:Action)-[:BECAUSE]->(:Evidence), linked to the change it reverts.Verify: poll the user-facing service until it's healthy twice in a row.
Remember: the resolved incident, its root-cause change and the fix go back into the graph. The next similar alert is solved faster.
Explain: every tool call is a
STEPof anInvestigationnode. The UI replays exactly which nodes the agent looked at, in order.
Architecture
┌──────────────────────────── AGENT HOSTS (the brain) ─────────────────────────────┐
│ Claude Code + plugin Codex CLI Cursor / VS Code Headless responder │
│ /oncall /blast-radius config.toml mcp.json `rootpath watch`│
│ /postmortem + guard hook + AGENTS.md → claude -p │
└────────────┬─────────────────┬────────────────┬──────────────────────┬────────────┘
└─────────────────┴──── MCP (stdio) ┴──────────────────────┘
┌──────────────────────────── rootpath MCP server ─────────────────────────────┐
│ READ get_service_health · get_logs · get_blast_radius · recent_changes │
│ get_owner · find_similar_incidents · explain_incident · query_graph │
│ REASON rank_suspects (traversal + betweenness) · trace_dependency_path (SPpaths)│
│ ACT rollback_service · restart_service · set_feature_flag (dry-run first) │
│ LIFECYCLE open_incident · verify_recovery · notify_owner · resolve_incident │
└──────────┬────────────────────────────┬──────────────────────────────┬────────────┘
│ Cypher (RO for reasoning) │ ingest (idempotent MERGE) │ docker compose
┌──────────▼───────────┐ ┌────────────┴─────────────┐ ┌────────────▼────────────┐
│ FalkorDB │◄──│ compose labels + env │ │ 7 microservices + load │
│ services, calls, │ │ live /_stats (observed │ │ feature flags │
│ teams, people, flags,│ │ calls, health) │ │ change log (CI/CD+flags)│
│ deploys, incidents, │ │ teams.json · runbooks │ │ chaos scenarios │
│ actions, evidence, │ │ change log │ └─────────────────────────┘
│ investigations │ └───────────────────────────┘
└──────────▲───────────┘
└── Web UI (localhost:7100): live graph + numbered agent path + reportQuickstart (about 3 minutes)
Requirements:
Docker
Claude Code, logged in, for the headless agent. Any MCP host can use the tools.
There's no hosted copy of the stack, because the agent controls real Docker containers. The website is the hosted part: it replays recorded real incidents in the browser.
git clone <this repo> rootpath && cd rootpath
uv sync
uv run rootpath demo up # FalkorDB :6380 (browser :3005), 7 services, load generator, seeded history
uv run rootpath ui # http://localhost:7100Break something and let the agent fix it:
uv run rootpath chaos flag # or: bad-deploy | pool
uv run rootpath watch --once # alert fires → headless Claude Code investigates, fixes, verifiesOr do it all from the console at http://localhost:7100:
Break something picks any of the six scenarios.
graph / baseline switches which toolset the agent gets.
Run agent starts the headless agent.
While it runs, the path lights up step by step. Click a step to see what it looked at, or click any node for its properties. The Incident memory tab shows every incident with its root cause and fix, and compares mean time to resolve for humans and the agent. Changes lists recent deploys and flag flips.
Reset restores a healthy state but keeps the graph, so the next incident can find the memory
the last one wrote. Shift-click Reset for a fresh graph, or run uv run rootpath demo reset.
Scenario | What happens | Correct fix | Red herring |
| payment v2.4.1 ships a tokenizer bug → checkout and frontend 5xx | roll back payment | catalog deploy at the same moment |
|
| flag off | notify deploy at the same moment |
| inventory's DB pool is exhausted, with no change at all → checkout and catalog fail | restart inventory | none; recent-change heuristics alone fail here |
Use it from your agent
Claude Code (plugin): MCP server, /rootpath:oncall, /rootpath:blast-radius, /rootpath:postmortem, plus the safety hook.
/plugin marketplace add IWhitebird/rootpath
/plugin install rootpath@rootpath
# or, from a clone:
claude --plugin-dir /path/to/rootpathThen type /rootpath:oncall checkout is throwing 500s. Read tools are pre-approved. Real actions
go through Claude Code's permission prompt (human in the loop), and the guard hook denies any
real action that wasn't dry-run first, or anything at all during a change freeze (touch .oncall/FREEZE).
Codex CLI (~/.codex/config.toml); the playbook lives in AGENTS.md:
[mcp_servers.oncall]
command = "uv"
args = ["run", "--quiet", "--directory", "/abs/path/to/rootpath", "rootpath", "mcp"]
[mcp_servers.oncall.env]
FALKORDB_URL = "redis://localhost:6380"Cursor / VS Code / any MCP host: the same server, as a stdio command:
uv run --directory /abs/path/to/rootpath rootpath mcp.
Headless / autonomous: uv run rootpath watch polls health. When a user-facing service fails
twice in a row, it launches claude -p with only the oncall MCP tools (--strict-mcp-config --tools "")
and stores the run (tool calls, tokens, cost, report) on the Investigation node.
Use --autonomy propose for dry-run-only recommendations.
Does the graph matter? (benchmark)
uv run rootpath bench injects each failure into the live stack and runs the same headless
agent (Claude Opus 5.5 through Claude Code) twice, with the same remediation actions both times:
graph gets the FalkorDB reasoning and memory tools.
baseline gets what a plain observability stack gives you: health, logs and a flat change log.
Each of the 6 scenarios runs twice per mode at two telemetry levels: with tracing (stats say where
errors originate) and without (ONCALL_TELEMETRY=basic: error rate and latency only). That's 48
runs on the final code.
telemetry | mode | clean fix¹ | logs read before the fix | calls to root cause | agent time | cost |
with tracing | graph | 12/12 | 12 | 48 | 519 s | $1.68 |
with tracing | baseline | 11/12 | 21 | 46 | 687 s | $1.55 |
without tracing | graph | 12/12 | 12 | 48 | 532 s | $1.62 |
without tracing | baseline | 12/12 | 42 | 68 | 675 s | $1.80 |
¹ The expected action on the expected target (roll back payment, flag off, restart inventory), and no
other remediation action. Per-scenario tables and every tool sequence:
bench/RESULTS-full.md, bench/RESULTS-basic.md.
What we learned:
A frontier model with good telemetry usually finds the cause without a graph. Baseline took the right action in all 24 runs. On a 7-service system the answer is often readable from the health table.
The graph sends the agent straight to where the failure starts. It read 24 service logs before fixing, against 63 for baseline (62% fewer). Without tracing the gap widens to 12 vs 42, because baseline has to walk the call chain one log at a time.
That makes it faster, and without tracing cheaper. Agent time was 1051 s vs 1362 s in total. Cost was $3.30 vs $3.35, even though the graph agent also opens and resolves the incident, pages the owner and writes memory.
Wrong actions come from coincidences. In one flag-collision run, baseline first rolled back the healthy fraud-check release that happened to land minutes before the flag flip. That fixed nothing and cost 4 minutes before it found the flag. The graph agent made no wrong actions in 24 runs.
What changed between versions, honestly. The first version of
rank_suspectspointed at the right service but didn't pass along what the graph knew about it. In that run the graph agent itself once rolled back a healthy inventory release (thepool-after-deploytrap) without reading the runbook.rank_suspectsnow returns the top suspect's runbooks and past incidents with the ranking. The v1 results are kept inbench/archive/.Caveat: 2 runs per cell is a small sample, so read these as directional.
Website and incident replays
uv run rootpath record <scenario> --out site/data/<scenario>.json records a real incident end
to end: live health every second, every graph node and edge as it appears, and every agent step
with its timestamp and the nodes it touched. python3 site/build.py inlines the recordings and the
benchmark results into one self-contained site/index.html (a build output, not committed). The page replays the incidents in the
browser with a scrubbable timeline, so anyone can watch the agent work without Docker or an API key.
Pushing to GitHub publishes it through GitHub Pages; set Settings → Pages → Source to GitHub Actions once.
Tests
uv run pytest tests/test_unit.py # 17 fast tests, no Docker needed (also run in CI)
uv run pytest tests/test_integration.py # 14 end-to-end tests against the live demo stack (~7 min)The integration suite does three things against the live stack:
It injects every scenario and checks that
rank_suspectsfinds the service where the failure starts, with red herrings scored low.It takes the full fix loop through the real action tools: dry run, execute, verify, page the owner, resolve, explain, recall from memory.
It checks the guarantees: rollback never redeploys a release that was itself rolled back,
ONCALL_ALLOW_ACTIONS=0forces dry runs, the agent's Cypher is read-only, and bad input returns an error instead of crashing.
Graph data model
(:Team)-[:OWNS]->(:Service)-[:CALLS {declared, optional, observed}]->(:Service)
(:Person)-[:MEMBER_OF]->(:Team) (:Person)-[:ON_CALL_FOR]->(:Team)-[:ESCALATES_TO]->(:Team)
(:Runbook)-[:FOR]->(:Service)
(:Team)-[:OWNS]->(:Flag)-[:AFFECTS]->(:Service)
(:Change:Deploy {version, prev_version, at})-[:CHANGED]->(:Service)
(:Change:FlagChange {flag, from, to, at})-[:TOGGLED]->(:Flag)
(:Person)-[:AUTHORED]->(:Change) (:Deploy)-[:ROLLED_BACK]->(:Deploy)
(:Incident)-[:IMPACTED]->(:Service)
(:Incident)-[:ROOT_CAUSE]->(:Change | :Service)
(:Incident)-[:HAS_ACTION | RESOLVED_BY]->(:Action)-[:BECAUSE]->(:Evidence)
(:Action)-[:REVERTS]->(:Change) (:Action)-[:ON]->(:Service | :Flag) (:Action)-[:PRODUCED]->(:Change)
(:Incident)-[:NOTIFIED]->(:Notification)-[:TO]->(:Person)
(:Investigation)-[:FOR]->(:Incident)
(:Investigation)-[:STEP {n, tool, note, at}]->(any node the agent looked at)Where the data comes from: services, owners and declared calls come from the compose file's
labels and env. Observed calls and live health come from each service's /_stats. Teams and
on-call come from demo/teams.json, runbooks from Markdown front-matter, and deploys and flag flips
from the change log (the CI/CD + flag-service audit trail). Past incidents are seeded synthetic
history. All ingestion is idempotent MERGE. The agent's reasoning runs as read-only GRAPH.RO_QUERY
with a 2s timeout; only deterministic code writes.
The Cypher the product depends on
Candidate suspects: everything downstream of the alerting service, with distance:
MATCH p = (s:Service {name: $s})-[:CALLS*0..6]->(d:Service)
RETURN d.name AS service, min(length(p)) AS hopsChanges on those candidates, including flags that reach a service only through AFFECTS:
MATCH (c:Deploy)-[:CHANGED]->(d:Service) WHERE d.name IN $names AND c.at >= $since RETURN d.name, c
MATCH (x:FlagChange)-[:TOGGLED]->(f:Flag)-[:AFFECTS]->(d:Service) WHERE d.name IN $names AND x.at >= $since RETURN d.name, xGraph algorithms used as agent tools:
CALL algo.betweenness({nodeLabels: ['Service'], relationshipTypes: ['CALLS']}) YIELD node, score
MATCH (a:Service {name: $a}), (b:Service {name: $b})
CALL algo.SPpaths({sourceNode: a, targetNode: b, relTypes: ['CALLS'], pathCount: 1}) YIELD pathChanges ruled out because they aren't in the dependency graph of the symptom:
MATCH (c:Change) WHERE c.at >= $since
OPTIONAL MATCH (c)-[:CHANGED]->(s:Service)
OPTIONAL MATCH (c)-[:TOGGLED]->(:Flag)-[:AFFECTS]->(fs:Service)
WITH c, coalesce(s.name, fs.name) AS target WHERE NOT target IN $names
RETURN c, targetBlast radius (who is affected upstream) and ownership with escalation and runbooks:
MATCH p = (u:Service)-[:CALLS*1..6]->(s:Service {name: $s})
WITH u, min(length(p)) AS hops MATCH (t:Team)-[:OWNS]->(u) RETURN u.name, hops, u.internet_facing, t.name
MATCH (t:Team)-[:OWNS]->(s:Service {name: $s})
OPTIONAL MATCH (p:Person)-[:ON_CALL_FOR]->(t)
OPTIONAL MATCH (t)-[:ESCALATES_TO]->(e:Team)<-[:ON_CALL_FOR]-(ep:Person)
OPTIONAL MATCH (r:Runbook)-[:FOR]->(s)
RETURN t.name, p.handle, e.name, ep.handle, collect(r)Incident memory: a full-text index plus graph overlap, then root cause and fix:
CALL db.idx.fulltext.createNodeIndex('Incident', 'title', 'symptom', 'summary')
CALL db.idx.fulltext.queryNodes('Incident', 'checkout|timeout|fraud') YIELD node, score
MATCH (i:Incident)-[:IMPACTED|ROOT_CAUSE]->(:Service {name: $s}) RETURN i.id
MATCH (i:Incident) WHERE i.id IN $ids
OPTIONAL MATCH (i)-[:ROOT_CAUSE]->(rc) OPTIONAL MATCH (i)-[:RESOLVED_BY]->(a:Action)
RETURN i, collect(rc), collect(a)The safety guard (rootpath/guard.py) is itself a graph query: no real action unless a matching dry run exists.
MATCH (a:Action {kind: $kind, target: $target, dry_run: true}) WHERE a.at >= $since RETURN count(a)Safety
Reasoning is read-only (
GRAPH.RO_QUERY, timeout, row cap). The agent can't write arbitrary Cypher.Actions default to
dry_run=true, and the plugin hook enforces "dry run before real run" against the graph.ONCALL_ALLOW_ACTIONS=0forces every action to be a dry run, for read-only deployments.Change freeze:
touch .oncall/FREEZEorONCALL_CHANGE_FREEZE=1.The headless agent gets no shell, file or web tools, only the oncall MCP tools.
Every action is attributable: who, why, what it reverted, which investigation.
Related work
woodpecker-mcp: also stores a service dependency graph in FalkorDB and exposes topology, root-cause and blast-radius tools over MCP. It is analysis-only: no change correlation (deploys/flags), no remediation or verification, no incident memory.
AWS DevOps Agent, Datadog Bits AI SRE, Dynatrace Smartscape/Davis, Causely: graph- or topology-based commercial AI SRE. They are closed and tied to their own platform.
Resolve.ai, Cleric, Traversal: AI SRE startups.
Rootpath is open, self-hosted, uses FalkorDB as the reasoning substrate rather than as storage, acts and verifies, remembers, and runs inside whichever agent you already use.
Project layout
rootpath/ tools.py (agent tools) · mcp_server.py · ingest.py · seed.py · infra.py · responder.py
bench.py · record.py · web.py · guard.py · store.py · cli.py
demo/ docker-compose.yml · service/ (one configurable microservice) · teams.json · runbooks/ · flags/
skills/ oncall · blast-radius · postmortem (Claude Code plugin skills)
hooks/ hooks.json (PreToolUse guard)
.claude-plugin/ plugin.json (MCP server inline) · marketplace.json
prompts/ headless agent playbooks
ui/ index.html · console.js · console.css (operator console)
site/ src/ (website: index.html · site.js · site.css) · data/ (recorded incidents) · build.py
bench/ results-*.json and RESULTS-*.md (graph vs baseline)
tests/ test_unit.py · test_integration.py
docs/ screenshots, replay.gif / replay.mp4CLI
command | what it does |
| run, stop or reset the demo stack |
| inject a failure ( |
| live health table |
| operator console on :7100 |
| MCP server on stdio |
| alert watcher that launches the headless agent |
| graph vs baseline benchmark |
| record an incident for the website |
| call any agent tool directly |
| rebuild the graph from its sources |
AI assistance disclosure
Built during the hackathon with Claude Code (Claude Opus 5.5) as a pair programmer. It wrote substantial parts of the code, the UI and this README under my direction. Architecture, scope and product decisions, review, and testing against the running system were done by me. At runtime the agent itself is Claude (via Claude Code headless or any MCP host). There is no model training or fine-tuning anywhere in the project.
License
Apache-2.0. FalkorDB itself is licensed under SSPL.
Available Tools
17 toolsexplain_incidentBRead-only
The full evidence chain for an incident: impacted services, root cause, actions and why.
| Name | Required | Description | Default |
|---|---|---|---|
| incident_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered structurally. The description adds value by disclosing the shape of the returned evidence chain, which matters because there is no output schema. It still omits return format details, pagination, or any cost/latency context, so it clears the lower annotation-backed bar without going beyond it.
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?
One sentence with zero filler, and the key content (the evidence chain) is front-loaded immediately. It is tight and scannable, though the missing verb makes it slightly less directive than it could be.
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 read-only, single-parameter tool with no output schema, the description partially covers the return content, which is the main gap. It is still incomplete on parameter meaning and on routing relative to siblings, so it is adequate but with clear holes.
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?
The single parameter incident_id has 0% schema description coverage and the description never mentions it or its expected format. Unlike a zero-parameter tool, this definition needs the description to compensate for the undocumented parameter, and it does not.
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 names a specific resource (an incident) and the exact content returned: impacted services, root cause, actions and why. This gives an agent a concrete sense of what the tool produces. However, it is phrased as a bare noun phrase and never explicitly distinguishes itself from overlapping siblings like get_blast_radius or rank_suspects, so differentiation is left to inference.
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?
There is no when-to-use guidance, no prerequisites, and no mention of alternatives. With sixteen siblings including several that overlap on incident evidence (rank_suspects, get_blast_radius, recent_changes, find_similar_incidents), the agent gets no help deciding when this tool is the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_similar_incidentsARead-only
Search incident memory: full-text match on past symptoms, boosted when the past incident involved the same service. Returns root causes and what fixed them.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| service | No | ||
| symptom | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint=true, openWorldHint=false), and the description adds genuinely new behavior: the ranking is full-text with a service-affinity boost, and the response carries root causes and remediation. It does not mention pagination, empty-result behavior, or cost, but the ranking semantics are the non-obvious part and they are disclosed.
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?
Two sentences, zero filler, purpose and mechanism front-loaded before the return-value note. Every clause earns its place.
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, and the description compensates by naming what is returned (root causes and fixes). Combined with annotations covering the read-only profile, this is nearly complete for a 3-parameter search tool; only limit/result-count behavior is left ambiguous.
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 0%, so the description must carry the parameter burden. It explains the semantics of 'symptom' (full-text match target) and 'service' (boost signal, not a filter), which is real value beyond the schema, but 'limit' is never mentioned and defaults (limit=3, service=null) go unaddressed.
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: 'Search incident memory' with full-text match on past symptoms and a service-based boost. The mechanism plus the stated return (root causes and fixes) makes the tool's function unmistakable, though it never explicitly names a sibling like explain_incident or rank_suspects to sharpen the boundary.
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?
Usage is only implied: an agent can infer this is for triage-time recall of past incidents, but there is no statement of when to use it versus explain_incident, rank_suspects, or recent_changes, and no exclusions or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_blast_radiusBRead-only
Who is affected if service misbehaves (upstream callers) and what it depends on (downstream).
| Name | Required | Description | Default |
|---|---|---|---|
| service | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds useful scope context (it reports both directions of impact), but says nothing about graph traversal depth, result size, or whether the dependency data is live or cached.
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?
A single front-loaded sentence that defines the two outputs in the order an agent would reason about them, with no filler or redundancy.
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 read-only, single-parameter tool with no output schema, the description conveys what the answer contains (affected callers, dependencies) and implies no mutation. It is nearly sufficient, missing only a note on identifier format or result granularity.
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?
One parameter with 0% schema description coverage, so the schema alone leaves `service` undefined. The description implies it is the service whose impact is being analyzed via the phrase 'if `service` misbehaves', but never states the expected identifier form or namespace, so it only partially compensates.
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 analysis resource and scopes it precisely into two directional components: upstream callers (who is affected) and downstream dependencies (what it depends on). This lets an agent distinguish it from trace_dependency_path, though it never names or contrasts that sibling explicitly.
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 description is purely definitional; it never says when to reach for this tool versus trace_dependency_path, query_graph, or get_service_health, nor does it state prerequisites (e.g. that it is an incident-triage step). Usage can only be inferred from the sibling set.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_logsCRead-only
Recent log entries, de-duplicated: distinct messages with counts, plus the latest entries.
| Name | Required | Description | Default |
|---|---|---|---|
| lines | No | ||
| service | Yes | ||
| contains | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuine behavioral context beyond them: results are de-duplicated into distinct messages with counts plus the latest raw entries, which tells the agent what the response actually looks like. It omits any note on volume limits or windowing, keeping it short of a 5.
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?
A single compact sentence with no filler, and the de-duplication detail is front-loaded after the resource. It loses a point only because the colon-list structure reads as a data spec rather than a complete instruction.
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 0% parameter coverage, the description should explain the three inputs and the default 200-line window; it explains none of them. It partially covers the return shape, but an agent still cannot confidently construct a call from this text alone.
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 0% for three parameters (service, lines, contains), so the description carries the full explanatory burden but only vaguely gestures at them via 'recent' and 'distinct messages'. The required 'service' selector and the 'contains' substring filter are never explained anywhere.
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 identifies the resource (recent log entries) and its de-duplicated shape, so an agent can tell it retrieves logs rather than incidents like the sibling tools. However, it is a noun fragment with no verb, and it describes output content more than the operation, leaving purpose only implicitly stated.
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?
There is no guidance on when to reach for this tool versus the incident-oriented siblings (explain_incident, recent_changes, get_service_health), nor any prerequisite or exclusion. The agent must infer usage entirely from the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_ownerCRead-only
Owning team, who is on call, escalation path and runbooks for a service.
| Name | Required | Description | Default |
|---|---|---|---|
| service | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered structurally. The description adds no behavioral context beyond the field list — nothing about lookup failures, freshness of on-call data, or scope limitations.
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?
A single tight sentence with no filler. It is front-loaded with the most important returned attribute, though the missing verb makes the opening less orienting than it could be.
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 field enumeration usefully signals what comes back, and annotations cover the read-only nature. However, the parameter remains entirely unexplained and no usage context is given, so it is only minimally complete.
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 0% and the sole 'service' parameter is undocumented in both schema and description. The phrase 'for a service' loosely implies the input's role but gives no format or identifier semantics, so the description does not compensate for the gap.
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 reads as a list of returned fields (owning team, on-call, escalation path, runbooks) for a service rather than a clear verb+resource statement. An agent can infer it retrieves ownership metadata, and it is distinguishable from notify_owner, but the purpose is implied rather than stated.
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?
No guidance on when to use this tool versus siblings such as notify_owner or get_service_health. There is no mention of prerequisites, escalation context, or exclusions, leaving the agent to guess the trigger.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_service_healthCRead-only
Live health from the services' stats endpoints (last 20s).
| Name | Required | Description | Default |
|---|---|---|---|
| service | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds a genuinely useful trait the annotations lack: the 20-second freshness window. However, it does not explain what 'health' comprises or what happens when the optional service parameter is omitted.
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?
A single front-loaded sentence with no filler; the freshness window is stated up front. It is efficient, though arguably too terse to serve a tool with an undocumented parameter.
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, no meaningful annotations beyond read-only, and an undocumented optional parameter, the description leaves the agent guessing about return contents and parameter behavior. It needs more than one clause to be callable with confidence.
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 0% for the single 'service' parameter, so the description carries the burden and fails: it never says whether 'service' selects one service or all, nor what the null default means. 'The services'' plural phrasing actually muddies whether the parameter is required.
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 (get) and resource (live service health) plus the data source (services' stats endpoints), which is clear enough to distinguish from get_logs or query_graph. It stops short of naming a sibling or scope of which services are covered.
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?
There is no when-to-use guidance, no stated prerequisites, and no mention of alternatives such as get_logs or trace_dependency_path for deeper diagnosis. The agent must infer that this is the quick triage check.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
notify_ownerC
Page the on-call person of the owning team (Slack/Discord webhook if configured).
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | ||
| service | Yes | ||
| incident_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, idempotentHint=false, and destructiveHint=false. The description usefully adds the delivery channel (Slack/Discord webhook) and the conditional 'if configured', which warns the agent the page may silently no-op — real added value. It still omits whether repeat calls re-page the same person and whether any auth is required.
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?
A single front-loaded sentence with no wasted words and the key mechanism (webhook paging) placed before the caveat. It is terse to the point of under-specification, but that is a completeness issue rather than verbosity.
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 side-effecting notification tool with three undocumented parameters, no output schema, and only partial annotation coverage, the description is too thin. It does not explain failure behavior, throttling, or what the caller should supply for message/incident_id.
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 0% for all three parameters, so the description carries the full burden. It only loosely implies that 'service' selects the owning team; it says nothing about message content expectations or what incident_id does when supplied versus omitted.
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 (Page) and resource (the on-call person of the owning team), which is clearly distinct from read-style siblings like get_owner. It does not explicitly name or contrast itself with any sibling, so it stops short of the top score.
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?
There is no when-to-use guidance, no escalation-context cue, and no mention of alternatives such as get_owner (to look up a team) or open_incident (to record the incident). The usage context is only implied by the tool name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
open_incidentB
Open an incident in the graph (or return the one already open for these services).
| Name | Required | Description | Default |
|---|---|---|---|
| title | Yes | ||
| symptom | Yes | ||
| severity | No | SEV2 | |
| impacted_services | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already disclose readOnly=false, destructive=false, idempotent=false, so the safety profile is covered. The description adds real behavioral value the annotations don't: the call may return a pre-existing open incident for the same services rather than creating a new one. It stops short of saying whether notifications fire or what happens to the incident lifecycle.
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?
A single sentence with a front-loaded verb and a useful parenthetical; nothing is wasted. It is terse to the point of being thin, but structurally it is well formed.
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 mutation tool with no output schema and 0% parameter documentation, the description omits severity options, what the returned incident looks like, and whether side effects such as owner notification occur. An agent could invoke it, but not confidently or correctly on the first try.
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 0% across four parameters, and the description compensates only by implication ('for these services' gestures at impacted_services). Title, symptom, and the severity default of SEV2 with no enumerated levels are left entirely undocumented, so the description does not close the gap.
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 ('open') and resource ('incident') with a scope qualifier ('in the graph'), which distinguishes it from resolve_incident and explain_incident. It doesn't name those siblings, so it stops short of full differentiation, but the purpose is unambiguous.
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 parenthetical implies the correct context (when you want to open an incident for a set of services) and hints at the dedup case, but there is no explicit when-to-use/when-not guidance and no routing to alternatives like find_similar_incidents before opening.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_graphARead-only
Escape hatch: run your own read-only Cypher (RO_QUERY, 2s timeout, max 100 rows).
| Name | Required | Description | Default |
|---|---|---|---|
| cypher | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, but the description adds real operational context beyond them: a 2s timeout and a 100-row cap, plus the RO_QUERY read-only constraint. It does not describe error behavior or what happens on timeout/truncation, which keeps it from a 5.
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?
One sentence, front-loaded with the tool's role ('Escape hatch') and packed with the constraints an agent needs. Zero wasted words.
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 carries the return burden and does state the 100-row cap, so the agent knows roughly what to expect. Missing graph-schema/query-dialect context, which is significant for a free-form Cypher tool in a domain with many structured siblings.
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 0% and the single 'cypher' parameter has no description, so the description must compensate. It does establish that the parameter is a read-only Cypher string (RO_QUERY), which is useful, but it adds no syntax, dialect, or node/edge-naming guidance an agent would need to write a valid query.
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: run read-only Cypher queries. The phrase 'Escape hatch' signals this is the general-purpose fallback, which differentiates it from the task-specific siblings like trace_dependency_path or get_blast_radius, though no sibling is named explicitly.
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?
'Escape hatch' implies it should be used when the dedicated tools do not cover a need, which is meaningful implied guidance. However, there is no explicit statement of when to prefer this over the many sibling query tools, and no exclusion of use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rank_suspectsARead-only
Rank root-cause suspects for a symptom by walking the dependency graph downstream from it, combining live health, recent changes (deploys + flag flips), and betweenness centrality. Also returns the top suspect's runbooks and the past incidents caused there, with their fixes.
| Name | Required | Description | Default |
|---|---|---|---|
| window_minutes | No | ||
| symptom_service | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnlyHint=true, openWorldHint=false), so the bar is lower, yet the description adds real substance: it explains the downstream dependency walk, the blended signals, and that it also returns the top suspect's runbooks and past incidents with fixes. It doesn't state latency or result-size bounds, keeping it short of a 5.
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?
Two sentences, both load-bearing, with the core mechanism and the bonus return values front-loaded in a logical order. 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?
With no output schema, the description reasonably sketches what comes back (ranked suspects, runbooks, past incidents and fixes), but it leaves both input parameters unexplained and gives no hint of ranking scale or output shape, which is thin for a tool whose whole value is its ranked result.
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 0% for both parameters, so the description carries the full burden and drops it. 'symptom_service' is only loosely inferable from 'symptom', and window_minutes (default 60) is never explained as bounding the change-recency lookback.
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 (rank), resource (root-cause suspects), and the mechanism (dependency-graph walk combining live health, recent changes, centrality). This is clearly distinguishable from siblings like get_blast_radius or find_similar_incidents, which do not rank suspects.
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 description implies a triage/root-cause investigation context but never states when to reach for this over get_blast_radius, trace_dependency_path, or find_similar_incidents, nor any prerequisite input condition. Usage is inferable but not spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recent_changesBRead-only
Deploys and feature-flag flips in the time window, scoped through the graph to service
(plus everything it depends on, and flags that affect those services).
| Name | Required | Description | Default |
|---|---|---|---|
| minutes | No | ||
| service | No | ||
| include_dependencies | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds genuine behavioral context: results are scoped through the dependency graph, not just the named service, and feature flags affecting those services are included. It omits defaults (120 minutes), pagination, and return shape, but with annotations present this is adequate.
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?
A single dense sentence with the returned resource front-loaded and the scoping constraint trailing. No filler, no repetition of the tool name. Slightly heavy on nested parentheticals but earns its place.
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 convey what comes back, and it does name the returned entities. But for an investigation tool it lacks usage framing, default behavior for the null service case, and any note on ordering or volume limits, leaving material gaps.
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 0%, so the description carries the param burden. It implicitly maps all three parameters - 'time window' for minutes, 'scoped to `service`' for service, 'plus everything it depends on' for include_dependencies - which is better than nothing. However it gives no default values, units, or format, and never explains what happens when service is null.
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 names the resource precisely - deploys and feature-flag flips - and states the scoping semantics (graph traversal to `service` plus its dependencies). An agent can tell this apart from siblings like get_blast_radius or query_graph without opening the schema. It stops short of a clean verb (e.g. 'list'), but the content is unambiguous.
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?
There is no statement of when to use this tool versus alternatives such as rank_suspects, get_blast_radius, or explain_incident. The incident-investigation context is only implied by the sibling set. No prerequisites, no exclusions, no routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
resolve_incidentB
Close the incident and write what was learned into incident memory.
| Name | Required | Description | Default |
|---|---|---|---|
| summary | Yes | ||
| incident_id | Yes | ||
| root_cause_service | Yes | ||
| root_cause_change_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare this is a non-readonly, non-idempotent, non-destructive mutation, so the safety profile is covered. The description adds useful context that resolving also writes learnings into incident memory, but it does not disclose consequences of the non-idempotent flag (e.g., duplicate memory entries on retry) or permission requirements.
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?
One tight, front-loaded sentence with no wasted words. It is efficient, though given the undocumented parameter burden a little more detail would have earned its place.
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 state-changing, non-idempotent tool with no output schema and four undocumented parameters, the description is thin. It conveys the purpose and one side effect but omits required-input meaning, retry/idempotency behavior, and what resolution changes about the incident's state.
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 0% with 4 parameters (3 required), so the description carries the full burden of explaining them. It only loosely hints at 'summary' via 'what was learned' and never mentions incident_id or root_cause_service, leaving required inputs undocumented in both places.
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 ('Close') and resource ('the incident'), plus a secondary effect ('write what was learned into incident memory'). It reasonably differentiates from the sibling open_incident by implying finality, though it never names or contrasts with any sibling explicitly.
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?
Usage is implied: this is the tool you call when an incident is over and you have a root cause. There is no explicit when/when-not guidance, no prerequisites, and no mention of alternatives such as explain_incident or verify_recovery that an agent might confuse with it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
restart_serviceCDestructive
Restart a service's container (clears in-memory state such as stuck connection pools).
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| dry_run | No | ||
| service | Yes | ||
| incident_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, readOnlyHint=false and idempotentHint=false, so the safety profile is covered. The description usefully adds what state is lost (in-memory state such as connection pools), but it omits the notable fact that dry_run defaults to true, which materially changes what happens on a default call.
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?
A single front-loaded sentence with no filler; the core action leads and the clarifying parenthetical follows.
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 destructive, non-idempotent mutation with no output schema and 0% schema coverage, the description is too thin. It should at minimum explain the dry_run default and the required reason/incident_id, none of which appear.
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 0% across four parameters, and the description names none of them. Critically, it never mentions that dry_run defaults to true or that reason is required, so an agent gets no help on the parameters that govern behavior.
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 (restart) and resource (a service's container), and the parenthetical clarifies what restarting actually does. It is distinguishable from the sibling rollback_service, though it does not name that sibling explicitly, keeping it short of a 5.
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?
There is no guidance on when to restart versus when to roll back (rollback_service), or on preconditions such as confirming an incident. The only implied usage is the parenthetical example of stuck connection pools, which is a symptom, not a when-to-use rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
rollback_serviceCDestructive
Redeploy the version that ran before the latest deploy of service.
| Name | Required | Description | Default |
|---|---|---|---|
| reason | Yes | ||
| dry_run | No | ||
| service | Yes | ||
| incident_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and idempotentHint=false, so the mutation profile is covered structurally. The description adds real semantic value by explaining what 'rollback' concretely does (redeploy the previous version). However, it omits the critical behavioral fact that dry_run defaults to true, meaning the call does not actually mutate unless explicitly overridden — a safety-relevant detail given destructiveHint=true.
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?
A single front-loaded sentence with zero filler, which is efficient. It is arguably under-sized for a destructive four-parameter operation, but no sentence is wasted.
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 destructive mutation with no output schema and 0% parameter documentation, the description should cover permissions, reversibility, dry-run behavior, and the required reason/incident context. It covers none of these, leaving the agent materially under-informed before an irreversible action.
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 0% across four parameters, so the description must carry the burden and does not. Only `service` is implied by the prose; the required `reason` string, the `dry_run` default, and the optional `incident_id` linkage are entirely unexplained in both schema and description.
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: it redeploys the prior version of a named service, which is more precise than the bare name 'rollback_service'. It implicitly distinguishes itself from sibling restart_service (a restart vs. a redeploy of the previous version), but never names or contrasts with any sibling explicitly.
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?
There is no when-to-use guidance, no preconditions, and no mention of alternatives such as restart_service, verify_recovery, or explain_incident. The agent must infer that this is the escalation path after a bad deploy.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_feature_flagCDestructive
Turn a feature flag on or off (takes effect within a second, no deploy).
| Name | Required | Description | Default |
|---|---|---|---|
| flag | Yes | ||
| reason | Yes | ||
| dry_run | No | ||
| enabled | Yes | ||
| incident_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=false, destructiveHint=true, and idempotentHint=false, so the safety profile is covered structurally. The description adds real value beyond that by disclosing latency and mechanism ('takes effect within a second, no deploy'), but it omits critical behavior for a destructive write: that dry_run defaults to true and that a reason is required.
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?
One short, front-loaded sentence with no filler, and the parenthetical adds genuinely useful operational detail. It is arguably undersized for a destructive five-parameter tool, which is a sizing issue rather than wasted verbiage.
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 destructive, non-idempotent mutation with no output schema and zero parameter documentation, the description leaves too much out: the dry_run default that gates whether anything actually happens, why a reason/incident_id is required, and what the effect on live traffic is. Annotations cover safety but not invocation correctness.
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 0% across 5 parameters, so the description carries the full burden and largely fails. The phrase 'on or off' loosely maps to the enabled boolean, but flag, reason, incident_id, and especially dry_run (which defaults to true, meaning a naive call may not actually apply the change) are entirely unexplained.
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 ('turn on or off') and resource ('feature flag'), so an agent knows exactly what state change is being requested. It does not name any sibling or contrast itself with rollback_service/restart_service, but the action is unambiguous and clearly distinct from the read-oriented siblings.
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?
There is no when-to-use guidance, no stated prerequisites, and no mention of alternatives (e.g. flipping a flag vs. rolling back a service). The only contextual hint is 'no deploy', which implies this is the fast path, but the agent is left to infer the situation in which that matters.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
trace_dependency_pathBRead-only
Shortest call path between two services (algo.SPpaths), with live health per hop.
| Name | Required | Description | Default |
|---|---|---|---|
| to_service | Yes | ||
| from_service | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description adds one genuinely useful behavioral trait beyond that — that results include live health per hop — but says nothing about failure modes (e.g. unreachable or non-existent services) or how the path is computed.
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?
A single front-loaded sentence with no filler. The parenthetical 'algo.SPpaths' is internal jargon that adds little for an agent deciding whether to call the 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 convey what comes back; 'live health per hop' is a start but leaves the response shape, path-finding semantics (hop count vs. latency), and error behavior unspecified.
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 0% for two required parameters, so the description carries the burden — yet it never explains from_service/to_service. The parameter names are largely self-explanatory, which keeps this at an adequate 3 rather than lower, but no added meaning is provided.
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: computing the shortest call path between two named services, and adds the distinguishing detail that health is reported per hop. It does not explicitly contrast with siblings like get_blast_radius or query_graph, so it falls short of a 5.
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?
There is no when-to-use guidance, no prerequisites, and no named alternative. The agent must infer that this is the tool for path tracing rather than graph querying or blast-radius analysis purely from the name.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
verify_recoveryARead-only
Poll live health until service is healthy for two consecutive samples (or time out).
| Name | Required | Description | Default |
|---|---|---|---|
| service | Yes | ||
| timeout_seconds | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so safety is covered. The description does add real behavior beyond that: this is a blocking poll requiring two consecutive healthy samples, with a timeout exit. It omits the poll interval, whether the call blocks the caller, and whether a timeout is an error or a returned state.
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?
A single front-loaded sentence with the success criterion and the fallback clause; nothing is wasted and the key condition is not buried.
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 parameter descriptions, the description should say what a call yields on success versus timeout, and roughly how long polling takes between samples. It states the success condition clearly but leaves the return contract and cadence unstated.
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 0%, so the description must carry the load for both parameters. It names `service` and alludes to the timeout, but never explains the service identifier format or confirms the units of timeout_seconds (seconds, per the name and the default).
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 and resource: poll live health of a named service until it passes. The two-consecutive-samples criterion and the timeout fallback make the purpose concrete and distinguishable from a single-shot get_service_health, though it doesn't name that sibling explicitly.
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?
Usage is only implied: 'until healthy ... (or time out)' suggests this is a post-remediation confirmation step, but the description never states when to reach for it instead of get_service_health, and gives no exclusions or prerequisites.
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.
17 tool updates
v0.1.0- First observed
explain_incident - First observed
find_similar_incidents - First observed
get_blast_radius - First observed
get_logs - First observed
get_owner - First observed
get_service_health - First observed
notify_owner - First observed
open_incident - First observed
query_graph - First observed
rank_suspects - First observed
recent_changes - First observed
resolve_incident - First observed
restart_service - First observed
rollback_service - First observed
set_feature_flag - First observed
trace_dependency_path - First observed
verify_recovery
TDQS
Scored across 17 tools
Most tools have clearly distinct purposes organized around a diagnosis→remediate→verify workflow (rank_suspects, get_blast_radius, recent_changes, trace_dependency_path), so misselection is unlikely. Minor overlap exists between verify_recovery and get_service_health (both report health) and between rank_suspects and explain_incident/find_similar_incidents (all surface past-incident context), but descriptions disambiguate well enough.
Nearly all names follow a predictable snake_case verb_noun pattern (get_owner, open_incident, resolve_incident, restart_service, verify_recovery). A couple of noun-only names (recent_changes) break the pattern slightly, but the convention is clear and readable throughout.
17 tools is slightly above the ideal band, but each covers a genuinely distinct operation across a broad incident-response domain (detection, diagnosis, remediation, communication, verification) and none feels redundant. The surface is well-scoped for the complexity of the purpose.
The set covers the full incident lifecycle: diagnosis (rank_suspects, blast radius, changes, paths, ownership), memory search (find_similar_incidents, explain_incident), incident management (open/notify/resolve), remediation (rollback, restart, feature flag), verification (verify_recovery, health, logs), plus a query_graph escape hatch. No obvious dead ends for the stated purpose.
Maintenance
Related MCP Connectors
- causelyOAuthapp.causely
Causal reasoning for reliability: root cause, blast radius, and service health for agents.
Company brain for AI agents — temporal knowledge graph search, exploration, and durable memory.
AI Agent with Architectural Memory. Impact analysis (free), tests and code from the graph (pro).
Persistent knowledge graph for AI-augmented teams. Store decisions, findings, and standing rules across agent sessions with semantic search and typed connections. Includes cross-session memory, audit trail, workspace isolation, and secret detection. Built for teams running agents that need to remember. Free until launch with team tier as default, anon trial available.
Related MCP Servers
- AlicenseNot gradedqualityAmaintenanceEnables triggering, streaming, and reviewing autonomous production-incident investigations directly from your editor, with human-gated approval for any mutating actions.3 npmMIT
- FlicenseAqualityDmaintenanceEnables LLM-driven agents to autonomously detect, diagnose, repair, verify, and prevent software and hardware failures on local and remote systems. Includes built-in safety checks and automatic rollbacks.15-
- 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-
- FlicenseNot gradedqualityCmaintenanceEnables AI agents to autonomously investigate simulated production incidents by checking live service health, logs, deployments, and database status while retrieving relevant historical postmortems and runbooks to propose evidence-backed root causes.-