@taiga-ai/mcp-server 0.26.0-dev.488 → 0.26.0-dev.489
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.js +21 -3
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5161,10 +5161,13 @@ function standingSummary(standing) {
|
|
|
5161
5161
|
const severity = String(violation["severity"] ?? "unknown");
|
|
5162
5162
|
bySeverity[severity] = (bySeverity[severity] ?? 0) + 1;
|
|
5163
5163
|
}
|
|
5164
|
+
const stated = (state) => controls.filter((c) => c["state"] === state).length;
|
|
5164
5165
|
return {
|
|
5165
5166
|
controls: listed.length,
|
|
5166
5167
|
controlsInPolicies: controls.length,
|
|
5167
|
-
|
|
5168
|
+
controlsMet: stated("met"),
|
|
5169
|
+
controlsNotApplicable: stated("not_applicable"),
|
|
5170
|
+
controlsNotAssessed: stated("no_evidence"),
|
|
5168
5171
|
violations: violations.length,
|
|
5169
5172
|
bySeverity,
|
|
5170
5173
|
resolvedViolations: resolved
|
|
@@ -5232,11 +5235,12 @@ function registerMaintenanceTools(server, client) {
|
|
|
5232
5235
|
}));
|
|
5233
5236
|
server.registerTool("taiga_get_policy_standing", {
|
|
5234
5237
|
title: "Get a product's policy standing",
|
|
5235
|
-
description: "How a product stands against the organization's published policies: summary counts, when the documents were assessed, and each violated control with its violations (critical and high only, citing the policy sentence and the contradicting passage) and the work on each. state: breached (open scanner findings map to it, by findingsByTier; routine-only is not urgent) or diverged (the documents contradict it). live: false means the violation's initiative ended without fixing it: it needs a person or a new fix. raisedFor: false means the link is the backlog planner's: it said an initiative a person asked it for would close the violation, which may be a dedicated fix or broader work; true means a fix was raised for it (taiga_fix_policy_violation or the sweep).
|
|
5238
|
+
description: "How a product stands against the organization's published policies: summary counts, when the documents were assessed, and each violated control with its violations (critical and high only, citing the policy sentence and the contradicting passage) and the work on each. state: breached (open scanner findings map to it, by findingsByTier; routine-only is not urgent) or diverged (the documents contradict it). live: false means the violation's initiative ended without fixing it: it needs a person or a new fix. raisedFor: false means the link is the backlog planner's: it said an initiative a person asked it for would close the violation, which may be a dedicated fix or broader work; true means a fix was raised for it (taiga_fix_policy_violation or the sweep). summary counts the other controls: met or not applicable as the documents show it, or not assessed (no evidence either way, which is no pass). controlId reads one control: its state, the passage behind a verdict, its document violations and how many scanner findings breach it. full: true adds evidence and resolved ones. Fix with taiga_fix_policy_violation.",
|
|
5236
5239
|
inputSchema: z.object({
|
|
5237
5240
|
productId,
|
|
5238
5241
|
full: z.boolean().optional().describe("Carry each violation's evidence and policy excerpt, cut to about 1,500 characters each, and up to 20 resolved violations (default false)"),
|
|
5239
|
-
violationId: idInput("violation", "this tool lists them").optional().describe("Only this violation, in full and uncut: its evidence, policy excerpt and work")
|
|
5242
|
+
violationId: idInput("violation", "this tool lists them").optional().describe("Only this violation, in full and uncut: its evidence, policy excerpt and work"),
|
|
5243
|
+
controlId: z.string().trim().min(1).max(40).optional().describe("Only this control, such as SEC-5.1: whether it is met, not applicable, violated or not assessed, with the passage")
|
|
5240
5244
|
}),
|
|
5241
5245
|
annotations: READ_ONLY
|
|
5242
5246
|
}, (params) => runTool(async () => {
|
|
@@ -5248,6 +5252,20 @@ function registerMaintenanceTools(server, client) {
|
|
|
5248
5252
|
const note = standing.assessment?.state === "never" ? "Never assessed: the documents have not been checked against the policies yet, so nothing here is an all-clear. An assessment runs when the reality documents are derived or refreshed (taiga_refresh_reality_documents, paid work: ask first)." : null;
|
|
5249
5253
|
const resolvedAny = Array.isArray(standing.resolvedDivergences) && standing.resolvedDivergences.length > 0;
|
|
5250
5254
|
const wording = violations.length > 0 || resolvedAny ? { wordingNote: "A violation's evidence is from its assessedAt; its title and summary may be from when it was first recorded. Where they disagree, the evidence is current." } : {};
|
|
5255
|
+
if (params.controlId && params.violationId) return toolError("VALIDATION_ERROR", "Name either a control (controlId) or one violation (violationId), not both.");
|
|
5256
|
+
if (params.controlId) {
|
|
5257
|
+
const wanted = params.controlId.toUpperCase();
|
|
5258
|
+
const control = controls.find((c) => String(c.controlId).toUpperCase() === wanted);
|
|
5259
|
+
if (!control) return toolError("NOT_FOUND", "No control with that id in this product's policies; taiga_get_document (type, sections: []) lists a policy's controls.");
|
|
5260
|
+
const own = violations.filter((violation) => String(violation["controlId"]).toUpperCase() === wanted);
|
|
5261
|
+
return toolResult({
|
|
5262
|
+
...control,
|
|
5263
|
+
...control.state === "no_evidence" ? { meaning: "Not assessed: no finding or violation is recorded against it, and the documents were not found to show it met. That is no evidence either way, not a pass." } : {},
|
|
5264
|
+
violations: pickFields(own, VIOLATION_FIELDS),
|
|
5265
|
+
...Number(control.findingCount ?? 0) > 0 ? { findingsNote: `${String(control.findingCount)} open scanner finding${control.findingCount === 1 ? "" : "s"} breach it; taiga_list_findings (productId) lists them with the controls each breaches.` } : {},
|
|
5266
|
+
...own.length > 0 ? wording : {}
|
|
5267
|
+
});
|
|
5268
|
+
}
|
|
5251
5269
|
if (params.violationId) {
|
|
5252
5270
|
const one = [...violations, ...Array.isArray(standing.resolvedDivergences) ? standing.resolvedDivergences : []].find((violation) => violation["id"] === params.violationId);
|
|
5253
5271
|
if (!one) return toolError("NOT_FOUND", "No violation with that ID on this product; this tool without violationId lists them.");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taiga-ai/mcp-server",
|
|
3
|
-
"version": "0.26.0-dev.
|
|
3
|
+
"version": "0.26.0-dev.489",
|
|
4
4
|
"description": "Taiga for AI coding assistants: read products, policies, initiatives and runs, and operate the line, over MCP",
|
|
5
5
|
"mcpName": "ga.tai/mcp-server",
|
|
6
6
|
"type": "module",
|