@neat.is/mcp 0.9.8-dev.20260828 → 0.9.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +64 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +64 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -747,6 +747,60 @@ async function getIncidentHistory(client2, input) {
|
|
|
747
747
|
});
|
|
748
748
|
}, `Node ${input.nodeId} not found in the graph.`);
|
|
749
749
|
}
|
|
750
|
+
async function getIncidentCard(client2, input) {
|
|
751
|
+
return withMissingNodeFallback(
|
|
752
|
+
client2,
|
|
753
|
+
input.project,
|
|
754
|
+
async () => {
|
|
755
|
+
const qs = input.errorId ? `?errorId=${encodeURIComponent(input.errorId)}` : "";
|
|
756
|
+
const card = await client2.get(
|
|
757
|
+
projectPath(input.project, `/graph/incident-card/${encodeURIComponent(input.nodeId)}${qs}`)
|
|
758
|
+
);
|
|
759
|
+
const lines = [];
|
|
760
|
+
lines.push(` incident ${card.id} [${card.incidentKind}] at ${card.at}`);
|
|
761
|
+
lines.push(` ${card.message}`);
|
|
762
|
+
if (card.locus) {
|
|
763
|
+
const l = card.locus;
|
|
764
|
+
lines.push(
|
|
765
|
+
` locus: ${l.symbol ? `${l.symbol} ` : ""}${l.file}${l.lineStart ? `:${l.lineStart}` : ""} [${l.provenance}]`
|
|
766
|
+
);
|
|
767
|
+
} else {
|
|
768
|
+
lines.push(" locus: none recovered \u2014 service grain");
|
|
769
|
+
}
|
|
770
|
+
if (card.rootCause) {
|
|
771
|
+
const rc = card.rootCause;
|
|
772
|
+
lines.push(
|
|
773
|
+
` root cause: ${rc.node}${rc.classification ? ` (${rc.classification})` : ""} \u2014 ${rc.reason} [confidence ${rc.confidence.toFixed(2)}]`
|
|
774
|
+
);
|
|
775
|
+
lines.push(` chain: ${rc.chain.map((h) => `${h.node} [${h.provenance}]`).join(" \u2192 ")}`);
|
|
776
|
+
if (rc.fix) lines.push(` fix: ${rc.fix}`);
|
|
777
|
+
} else {
|
|
778
|
+
lines.push(" root cause: none reachable");
|
|
779
|
+
}
|
|
780
|
+
if (card.blastRadius) {
|
|
781
|
+
lines.push(
|
|
782
|
+
` blast radius: ${card.blastRadius.totalAffected} node(s); nearest ${card.blastRadius.nearest.map((n) => n.node).join(", ")}`
|
|
783
|
+
);
|
|
784
|
+
}
|
|
785
|
+
if (card.policies && card.policies.length > 0) {
|
|
786
|
+
lines.push(
|
|
787
|
+
` policies: ${card.policies.map((p) => `[${p.severity}] ${p.policyName}`).join("; ")}`
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
if (card.divergence && card.divergence.length > 0) {
|
|
791
|
+
lines.push(
|
|
792
|
+
` divergence: ${card.divergence.map((d) => `${d.type} (${d.summary})`).join("; ")}`
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
return formatToolResponse({
|
|
796
|
+
summary: card.headline,
|
|
797
|
+
block: lines.join("\n"),
|
|
798
|
+
provenance: Provenance.OBSERVED
|
|
799
|
+
});
|
|
800
|
+
},
|
|
801
|
+
`No incident card available for ${input.nodeId}.`
|
|
802
|
+
);
|
|
803
|
+
}
|
|
750
804
|
async function semanticSearch(client2, input) {
|
|
751
805
|
try {
|
|
752
806
|
const result = await client2.get(
|
|
@@ -1303,6 +1357,16 @@ registerTool(
|
|
|
1303
1357
|
},
|
|
1304
1358
|
async (input) => getIncidentHistory(client, { ...input, project: projectFor(input) })
|
|
1305
1359
|
);
|
|
1360
|
+
registerTool(
|
|
1361
|
+
"get_incident_card",
|
|
1362
|
+
"One self-sufficient work order for an incident on a node (ADR-221): the incident fused with its root-cause chain, blast radius, governing policies, and node divergence \u2014 each claim provenance-stamped, so you can act without grepping. Give a node id (a service, file, or symbol); omit errorId for the node's most-recent incident, or pass errorId to pin one.",
|
|
1363
|
+
{
|
|
1364
|
+
nodeId: z.string().describe("Graph node id the incident is on (service/file/symbol)"),
|
|
1365
|
+
errorId: z.string().optional().describe("Pin a specific incident by its id; omit for the most recent"),
|
|
1366
|
+
project: projectField
|
|
1367
|
+
},
|
|
1368
|
+
async (input) => getIncidentCard(client, { ...input, project: projectFor(input) })
|
|
1369
|
+
);
|
|
1306
1370
|
registerTool(
|
|
1307
1371
|
"semantic_search",
|
|
1308
1372
|
"Search nodes by natural-language query. Uses embedding vectors when an embedder is available (Ollama nomic-embed-text \u2192 in-process MiniLM \u2192 substring fallback) \u2014 phrase the query the way you would describe what you want.",
|