@taiga-ai/mcp-server 0.26.0-dev.495 → 0.26.0-dev.501
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 +243 -19
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -562,6 +562,31 @@ function lenientList(item) {
|
|
|
562
562
|
return list;
|
|
563
563
|
}
|
|
564
564
|
//#endregion
|
|
565
|
+
//#region ../../packages/types/dist/wire-fields.js
|
|
566
|
+
/**
|
|
567
|
+
* Zod fields shared by more than one wire schema, so a change to the rule
|
|
568
|
+
* lands once rather than at every schema that carries the field.
|
|
569
|
+
*/
|
|
570
|
+
/**
|
|
571
|
+
* Reusable optional-UUID field for nested schemas (e.g. discriminated-union
|
|
572
|
+
* members that all accept an optional resource id). Centralising the rule
|
|
573
|
+
* means a future change (UUID v7-only, error-message tweak) lands in one
|
|
574
|
+
* place instead of N call sites.
|
|
575
|
+
*/
|
|
576
|
+
const optionalUuid = z.string().uuid().optional();
|
|
577
|
+
/**
|
|
578
|
+
* A source line anchor on a finding, or nothing.
|
|
579
|
+
*
|
|
580
|
+
* 0 means "no line anchor" -- a dependency in go.mod, a checkov rule on a
|
|
581
|
+
* whole file -- and the scanners emit 0 for it. Rejecting it with `.min(1)`
|
|
582
|
+
* bounced the WHOLE hardening report of staging run 01a07123 (52 findings,
|
|
583
|
+
* `/findings/46/lineNumber too_small`), so the UI never saw the phase
|
|
584
|
+
* (PRO-1481). Normalized to absent, never stored as 0. One schema for every
|
|
585
|
+
* wire shape that carries a line (findings, narrative, residual findings) so
|
|
586
|
+
* the next tightening cannot land on one of them and not the others.
|
|
587
|
+
*/
|
|
588
|
+
const optionalLineAnchor = z.number().int().min(0).optional().transform((v) => v ? v : void 0);
|
|
589
|
+
//#endregion
|
|
565
590
|
//#region ../../packages/types/dist/tenants.js
|
|
566
591
|
const TENANT_DOCUMENT_TYPES = [
|
|
567
592
|
"policy_security",
|
|
@@ -1432,6 +1457,149 @@ function hardeningCoverage(result) {
|
|
|
1432
1457
|
gaps
|
|
1433
1458
|
};
|
|
1434
1459
|
}
|
|
1460
|
+
z.discriminatedUnion("kind", [
|
|
1461
|
+
z.object({
|
|
1462
|
+
type: z.literal("narrative"),
|
|
1463
|
+
kind: z.literal("decision"),
|
|
1464
|
+
what: z.string().min(1).max(2e3),
|
|
1465
|
+
why: z.string().min(1).max(2e3),
|
|
1466
|
+
stepId: optionalUuid
|
|
1467
|
+
}),
|
|
1468
|
+
z.object({
|
|
1469
|
+
type: z.literal("narrative"),
|
|
1470
|
+
kind: z.literal("tradeoff"),
|
|
1471
|
+
picked: z.string().min(1).max(2e3),
|
|
1472
|
+
over: z.string().min(1).max(2e3),
|
|
1473
|
+
reason: z.string().min(1).max(2e3),
|
|
1474
|
+
stepId: optionalUuid
|
|
1475
|
+
}),
|
|
1476
|
+
z.object({
|
|
1477
|
+
type: z.literal("narrative"),
|
|
1478
|
+
kind: z.literal("assumption"),
|
|
1479
|
+
what: z.string().min(1).max(2e3),
|
|
1480
|
+
current_choice: z.string().min(1).max(2e3),
|
|
1481
|
+
stepId: optionalUuid
|
|
1482
|
+
}),
|
|
1483
|
+
z.object({
|
|
1484
|
+
type: z.literal("narrative"),
|
|
1485
|
+
kind: z.literal("attention"),
|
|
1486
|
+
what: z.string().min(1).max(2e3),
|
|
1487
|
+
currently_handling: z.string().min(1).max(2e3),
|
|
1488
|
+
stepId: optionalUuid
|
|
1489
|
+
}),
|
|
1490
|
+
z.object({
|
|
1491
|
+
type: z.literal("narrative"),
|
|
1492
|
+
kind: z.literal("scope_change"),
|
|
1493
|
+
what: z.string().min(1).max(2e3),
|
|
1494
|
+
reason: z.string().min(1).max(2e3),
|
|
1495
|
+
stepId: optionalUuid
|
|
1496
|
+
}),
|
|
1497
|
+
z.object({
|
|
1498
|
+
type: z.literal("narrative"),
|
|
1499
|
+
kind: z.literal("risk"),
|
|
1500
|
+
what: z.string().min(1).max(2e3),
|
|
1501
|
+
stepId: optionalUuid
|
|
1502
|
+
}),
|
|
1503
|
+
z.object({
|
|
1504
|
+
type: z.literal("narrative"),
|
|
1505
|
+
kind: z.literal("outcome"),
|
|
1506
|
+
capability: z.string().min(1).max(2e3),
|
|
1507
|
+
stepId: optionalUuid
|
|
1508
|
+
}),
|
|
1509
|
+
z.object({
|
|
1510
|
+
type: z.literal("narrative"),
|
|
1511
|
+
kind: z.literal("agent_update"),
|
|
1512
|
+
agent: z.string().min(1).max(120),
|
|
1513
|
+
state: z.string().min(1).max(60),
|
|
1514
|
+
activity: z.string().max(200).optional(),
|
|
1515
|
+
message: z.string().max(2e3).optional(),
|
|
1516
|
+
stepId: optionalUuid
|
|
1517
|
+
}),
|
|
1518
|
+
z.object({
|
|
1519
|
+
type: z.literal("narrative"),
|
|
1520
|
+
kind: z.literal("activity"),
|
|
1521
|
+
verb: z.enum([
|
|
1522
|
+
"exploring",
|
|
1523
|
+
"drafting",
|
|
1524
|
+
"testing",
|
|
1525
|
+
"reviewing",
|
|
1526
|
+
"preparing"
|
|
1527
|
+
]),
|
|
1528
|
+
target: z.string().min(1).max(2e3),
|
|
1529
|
+
stepId: optionalUuid
|
|
1530
|
+
}),
|
|
1531
|
+
z.object({
|
|
1532
|
+
type: z.literal("narrative"),
|
|
1533
|
+
kind: z.literal("setup_required"),
|
|
1534
|
+
category: z.enum([
|
|
1535
|
+
"env_var",
|
|
1536
|
+
"secret",
|
|
1537
|
+
"third_party_account",
|
|
1538
|
+
"api_key",
|
|
1539
|
+
"oauth_app",
|
|
1540
|
+
"dns_record",
|
|
1541
|
+
"billing_approval",
|
|
1542
|
+
"cloud_permission",
|
|
1543
|
+
"manual_config"
|
|
1544
|
+
]),
|
|
1545
|
+
title: z.string().min(1).max(300),
|
|
1546
|
+
instructions: z.string().min(1).max(2e3),
|
|
1547
|
+
key: z.string().regex(/^[A-Za-z_][A-Za-z0-9_.]*$/).max(255).optional(),
|
|
1548
|
+
isSecret: z.boolean().default(false),
|
|
1549
|
+
target: z.enum([
|
|
1550
|
+
"github_secret",
|
|
1551
|
+
"github_env",
|
|
1552
|
+
"cloud_env",
|
|
1553
|
+
"secrets_manager",
|
|
1554
|
+
"local_env",
|
|
1555
|
+
"external"
|
|
1556
|
+
]).optional(),
|
|
1557
|
+
providerDocUrl: z.string().url().max(1e3).refine((u) => /^https?:\/\//i.test(u), { message: "providerDocUrl must use http or https scheme" }).optional(),
|
|
1558
|
+
providerActionUrl: z.string().url().max(1e3).refine((u) => /^https?:\/\//i.test(u), { message: "providerActionUrl must use http or https scheme" }).optional(),
|
|
1559
|
+
phase: z.enum([
|
|
1560
|
+
"prereq",
|
|
1561
|
+
"wiring",
|
|
1562
|
+
"followup"
|
|
1563
|
+
]).optional(),
|
|
1564
|
+
suggestedValue: z.string().max(2e3).optional(),
|
|
1565
|
+
stepId: optionalUuid
|
|
1566
|
+
}),
|
|
1567
|
+
z.object({
|
|
1568
|
+
type: z.literal("narrative"),
|
|
1569
|
+
kind: z.literal("quality_finding"),
|
|
1570
|
+
source: z.enum([
|
|
1571
|
+
"tests",
|
|
1572
|
+
"self_review",
|
|
1573
|
+
"hardening",
|
|
1574
|
+
"pr_review",
|
|
1575
|
+
"ci_fix",
|
|
1576
|
+
"post_remediation"
|
|
1577
|
+
]),
|
|
1578
|
+
severity: z.enum([
|
|
1579
|
+
"blocking",
|
|
1580
|
+
"advisory",
|
|
1581
|
+
"info",
|
|
1582
|
+
"pass"
|
|
1583
|
+
]),
|
|
1584
|
+
title: z.string().min(1).max(2e3),
|
|
1585
|
+
body: z.string().max(2e3).optional(),
|
|
1586
|
+
filePath: z.string().max(500).optional(),
|
|
1587
|
+
lineNumber: optionalLineAnchor,
|
|
1588
|
+
stepId: optionalUuid,
|
|
1589
|
+
stats: z.object({
|
|
1590
|
+
testsTotal: z.number().int().min(0).optional(),
|
|
1591
|
+
testsPassed: z.number().int().min(0).optional(),
|
|
1592
|
+
testsFailed: z.number().int().min(0).optional(),
|
|
1593
|
+
testsAdded: z.number().int().min(0).optional(),
|
|
1594
|
+
coveragePct: z.number().min(0).max(100).optional(),
|
|
1595
|
+
coverageDelta: z.number().optional(),
|
|
1596
|
+
blockingFindings: z.number().int().min(0).optional(),
|
|
1597
|
+
advisoryFindings: z.number().int().min(0).optional(),
|
|
1598
|
+
criticalsAddressed: z.number().int().min(0).optional(),
|
|
1599
|
+
cycles: z.number().int().min(0).optional()
|
|
1600
|
+
}).optional()
|
|
1601
|
+
})
|
|
1602
|
+
]).options.map((option) => option.shape.kind.value);
|
|
1435
1603
|
[...BUILD_RUN_ACTIVE_STATUSES.filter((s) => s !== "reviewing")];
|
|
1436
1604
|
//#endregion
|
|
1437
1605
|
//#region ../../packages/types/dist/agents.js
|
|
@@ -1751,6 +1919,7 @@ const ENVIRONMENT_TYPES = [
|
|
|
1751
1919
|
const MAINTENANCE_FINDING_KINDS = [
|
|
1752
1920
|
"vulnerable_dependency",
|
|
1753
1921
|
"outdated_dependency",
|
|
1922
|
+
"license_violation",
|
|
1754
1923
|
"secret",
|
|
1755
1924
|
"sast",
|
|
1756
1925
|
"iac_misconfig"
|
|
@@ -1775,7 +1944,11 @@ const CODE_REMEDIATION_KINDS = [
|
|
|
1775
1944
|
"iac_misconfig"
|
|
1776
1945
|
];
|
|
1777
1946
|
new Map(Object.entries({
|
|
1778
|
-
deps: [
|
|
1947
|
+
deps: [
|
|
1948
|
+
"vulnerable_dependency",
|
|
1949
|
+
"outdated_dependency",
|
|
1950
|
+
"license_violation"
|
|
1951
|
+
],
|
|
1779
1952
|
secrets: ["secret"],
|
|
1780
1953
|
sast: ["sast"],
|
|
1781
1954
|
iac: ["iac_misconfig"]
|
|
@@ -1862,6 +2035,19 @@ function lockfileScope(path, groups) {
|
|
|
1862
2035
|
}
|
|
1863
2036
|
}
|
|
1864
2037
|
/**
|
|
2038
|
+
* The kinds that are a package in a lockfile (PRO-2862): the ones with a
|
|
2039
|
+
* dependency scope, a relation and an inventory entry. A code kind reuses the
|
|
2040
|
+
* dependency columns for its rule and category and has none of those.
|
|
2041
|
+
*/
|
|
2042
|
+
const DEPENDENCY_FINDING_KINDS = [
|
|
2043
|
+
"vulnerable_dependency",
|
|
2044
|
+
"outdated_dependency",
|
|
2045
|
+
"license_violation"
|
|
2046
|
+
];
|
|
2047
|
+
function isDependencyFindingKind(kind) {
|
|
2048
|
+
return DEPENDENCY_FINDING_KINDS.includes(kind);
|
|
2049
|
+
}
|
|
2050
|
+
/**
|
|
1865
2051
|
* Whether a dependency finding sits only in development dependencies, in at
|
|
1866
2052
|
* least one runtime dependency set, or in lockfiles that do not say. Decided
|
|
1867
2053
|
* per lockfile (`lockfileScope`) and combined pessimistically: one runtime
|
|
@@ -1872,8 +2058,12 @@ function lockfileScope(path, groups) {
|
|
|
1872
2058
|
* install script in any group.
|
|
1873
2059
|
*/
|
|
1874
2060
|
function dependencyScope(finding) {
|
|
1875
|
-
if (finding.kind
|
|
1876
|
-
|
|
2061
|
+
if (!isDependencyFindingKind(finding.kind)) return "unknown";
|
|
2062
|
+
return scopeFromGroups(finding.dependencyGroups);
|
|
2063
|
+
}
|
|
2064
|
+
/** The scope read from per-lockfile groups alone: for an inventory record, which is a package by construction. */
|
|
2065
|
+
function scopeFromGroups(dependencyGroups) {
|
|
2066
|
+
const entries = Object.entries(dependencyGroups ?? {});
|
|
1877
2067
|
if (entries.length === 0) return "unknown";
|
|
1878
2068
|
return combineScopes(entries.map(([path, groups]) => lockfileScope(path, Array.isArray(groups) ? groups : [])));
|
|
1879
2069
|
}
|
|
@@ -1891,8 +2081,12 @@ function combineScopes(scopes) {
|
|
|
1891
2081
|
* remediation step already finds every resolved copy and its parent itself.
|
|
1892
2082
|
*/
|
|
1893
2083
|
function dependencyRelation(finding) {
|
|
1894
|
-
if (finding.kind
|
|
1895
|
-
|
|
2084
|
+
if (!isDependencyFindingKind(finding.kind)) return "unknown";
|
|
2085
|
+
return relationFromLockfiles(finding.dependencyRelation);
|
|
2086
|
+
}
|
|
2087
|
+
/** The relation read from per-lockfile answers alone: for an inventory record, which is a package by construction. */
|
|
2088
|
+
function relationFromLockfiles(dependencyRelation) {
|
|
2089
|
+
const values = Object.values(dependencyRelation ?? {});
|
|
1896
2090
|
if (values.includes("direct")) return "direct";
|
|
1897
2091
|
if (values.length > 0 && values.every((v) => v === "transitive")) return "transitive";
|
|
1898
2092
|
return "unknown";
|
|
@@ -5178,6 +5372,11 @@ const FINDING_ROW_FIELDS = [
|
|
|
5178
5372
|
* read off the row; remediableBy stays as the sweep recorded it.
|
|
5179
5373
|
*/
|
|
5180
5374
|
function withFixability(row) {
|
|
5375
|
+
if (row["kind"] === "license_violation") return {
|
|
5376
|
+
...row,
|
|
5377
|
+
fixable: false,
|
|
5378
|
+
fixNote: "A license violation has no fix version: review the license or replace the package; taiga_fix_finding refuses it."
|
|
5379
|
+
};
|
|
5181
5380
|
if ((row["kind"] === "vulnerable_dependency" || row["kind"] === "outdated_dependency") && !row["recommendedVersion"] && row["remediableBy"] === "coding_agent") return {
|
|
5182
5381
|
...row,
|
|
5183
5382
|
fixable: false,
|
|
@@ -5195,7 +5394,7 @@ function withDependencyScope(row, { keepGroups = false } = {}) {
|
|
|
5195
5394
|
...row,
|
|
5196
5395
|
dependencyRelation: void 0
|
|
5197
5396
|
} : lean;
|
|
5198
|
-
if (!(row["kind"]
|
|
5397
|
+
if (!isDependencyFindingKind(String(row["kind"]))) return rest;
|
|
5199
5398
|
const kind = row["kind"];
|
|
5200
5399
|
return {
|
|
5201
5400
|
...rest,
|
|
@@ -5400,8 +5599,8 @@ function registerMaintenanceTools(server, client) {
|
|
|
5400
5599
|
...control,
|
|
5401
5600
|
...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." } : {},
|
|
5402
5601
|
...control.assessment == null && (control.state === "breached" || control.state === "diverged") ? { assessmentNote: "No met or not-applicable verdict is shown: an open finding or violation against the control outranks one." } : {},
|
|
5602
|
+
...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. violations below are the documents' only.` } : {},
|
|
5403
5603
|
violations: pickFields(own, VIOLATION_FIELDS),
|
|
5404
|
-
...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.` } : {},
|
|
5405
5604
|
...own.length > 0 ? wording : {}
|
|
5406
5605
|
});
|
|
5407
5606
|
}
|
|
@@ -6317,7 +6516,7 @@ function registerContextTools(server, client) {
|
|
|
6317
6516
|
if (!client.hasCapability("products:read")) return;
|
|
6318
6517
|
server.registerTool("taiga_get_product_context", {
|
|
6319
6518
|
title: "Get product context",
|
|
6320
|
-
description: `Read where a product stands in one call; the first read for any product question. Name it by ID, slug or git remote URL. Returns product (in setup, readiness and next move), factory with its instructions, specification and architecture outlines (section ids, sizes), policies with section counts, a count of initiatives per board column (done and canceled too) and up to ${BACKLOG_IN_CONTEXT} open ones, a person's turn first (taiga_list_initiatives lists
|
|
6519
|
+
description: `Read where a product stands in one call; the first read for any product question. Name it by ID, slug or git remote URL. Returns product (in setup, readiness and next move), factory with its instructions, specification and architecture outlines (section ids, sizes), policies with section counts, a count of initiatives per board column (done and canceled too) and up to ${BACKLOG_IN_CONTEXT} open ones, a person's turn first (taiga_list_initiatives lists them all, newest first), repositories, the latest five runs (taiga_list_runs has more), and counts for Action Required, open findings and policy violations. A part that failed is under unavailable, one the key cannot read under notGranted; neither shows as empty. documents: budget returns whole sections up to about ${DOCUMENT_BUDGET / 1e3}k characters each, full returns all.`,
|
|
6321
6520
|
inputSchema: z.object({
|
|
6322
6521
|
productId: productId.optional(),
|
|
6323
6522
|
slug: slug.optional(),
|
|
@@ -21990,6 +22189,8 @@ const MISSING_DOCUMENTS_HOW = "An imported product gets them from its import (ta
|
|
|
21990
22189
|
* allowDuplicateName says the person means it.
|
|
21991
22190
|
*/
|
|
21992
22191
|
const allowDuplicateName = z.boolean().optional().describe("Create it even when one with the same name exists (default false: refused, naming the existing one)");
|
|
22192
|
+
/** The same choice on a rename (PRO-2823). */
|
|
22193
|
+
const allowDuplicateRename = z.boolean().optional().describe("Rename it even when another has the new name (default false: refused, naming the existing one)");
|
|
21993
22194
|
/**
|
|
21994
22195
|
* A product name is refused when taken in its own factory only; the same name
|
|
21995
22196
|
* in another factory is allowed and the slug takes a suffix. A review read the
|
|
@@ -22072,13 +22273,25 @@ function registerSetupTools(server, client) {
|
|
|
22072
22273
|
}));
|
|
22073
22274
|
server.registerTool("taiga_rename_factory", {
|
|
22074
22275
|
title: "Rename a factory",
|
|
22075
|
-
description: "Rename a factory. Its slug follows the new name, so links to it change; products, members, knowledge and instructions stay as they are.",
|
|
22276
|
+
description: "Rename a factory. Its slug follows the new name, so links to it change; products, members, knowledge and instructions stay as they are. A name another factory has is refused, as on create.",
|
|
22076
22277
|
inputSchema: z.object({
|
|
22077
22278
|
factoryId,
|
|
22078
|
-
name: z.string().trim().min(1).max(255).describe("The new name")
|
|
22279
|
+
name: z.string().trim().min(1).max(255).describe("The new name"),
|
|
22280
|
+
allowDuplicateName: allowDuplicateRename
|
|
22079
22281
|
}),
|
|
22080
22282
|
annotations: OPERATE_SETTING
|
|
22081
|
-
}, (params) => runTool(async () =>
|
|
22283
|
+
}, (params) => runTool(async () => {
|
|
22284
|
+
try {
|
|
22285
|
+
return toolResult(pickFields([(await client.updateFactory(params.factoryId, {
|
|
22286
|
+
name: params.name,
|
|
22287
|
+
refuseDuplicateName: !params.allowDuplicateName
|
|
22288
|
+
})).data], FACTORY_FIELDS)[0]);
|
|
22289
|
+
} catch (error) {
|
|
22290
|
+
const refused = duplicateName("factory", error, "in this organization");
|
|
22291
|
+
if (refused) return refused;
|
|
22292
|
+
throw error;
|
|
22293
|
+
}
|
|
22294
|
+
}));
|
|
22082
22295
|
server.registerTool("taiga_preview_product_move", {
|
|
22083
22296
|
title: "Preview moving a product to another factory",
|
|
22084
22297
|
description: "Show who gains and who loses access if a product moves to another factory: the source factory's members lose it, the target's gain it; people in both, the product's own members, and owners and admins keep it, named with why. Show it to the person before taiga_move_product.",
|
|
@@ -22160,21 +22373,32 @@ function registerSetupTools(server, client) {
|
|
|
22160
22373
|
inputSchema: z.object({
|
|
22161
22374
|
productId,
|
|
22162
22375
|
name: z.string().trim().min(1).max(255).optional().describe("A new name"),
|
|
22376
|
+
allowDuplicateName: allowDuplicateRename,
|
|
22163
22377
|
...buildScope,
|
|
22164
22378
|
deploymentNotes: deploymentNotes.nullable().optional(),
|
|
22165
22379
|
emitDesignStandards: z.boolean().nullable().optional().describe("Inherit the organization's design standards; null follows the default")
|
|
22166
22380
|
}),
|
|
22167
22381
|
annotations: OPERATE_SETTING
|
|
22168
22382
|
}, (params) => runTool(async () => {
|
|
22169
|
-
const { productId: id, ...changes } = params;
|
|
22383
|
+
const { productId: id, allowDuplicateName: allowed, ...changes } = params;
|
|
22170
22384
|
if (Object.values(changes).every((value) => value === void 0)) return toolError("VALIDATION_ERROR", "Change at least one setting.");
|
|
22171
22385
|
const contradiction = notesWithNothingToDescribe(params);
|
|
22172
22386
|
if (contradiction) return contradiction;
|
|
22173
|
-
|
|
22387
|
+
let updated;
|
|
22388
|
+
try {
|
|
22389
|
+
updated = (await client.updateProduct(id, {
|
|
22390
|
+
...changes,
|
|
22391
|
+
...changes.name !== void 0 ? { refuseDuplicateName: !allowed } : {}
|
|
22392
|
+
})).data;
|
|
22393
|
+
} catch (error) {
|
|
22394
|
+
const refused = duplicateName("product", error, "in this factory");
|
|
22395
|
+
if (refused) return refused;
|
|
22396
|
+
throw error;
|
|
22397
|
+
}
|
|
22174
22398
|
const warnings = missingNotesWarning(updated);
|
|
22175
22399
|
return toolResult({
|
|
22176
|
-
...
|
|
22177
|
-
...
|
|
22400
|
+
...warnings.length > 0 ? { warnings } : {},
|
|
22401
|
+
...await productRow(client, updated)
|
|
22178
22402
|
});
|
|
22179
22403
|
}));
|
|
22180
22404
|
server.registerTool("taiga_refresh_reality_documents", {
|
|
@@ -22822,7 +23046,7 @@ const SERVER_INSTRUCTIONS = [
|
|
|
22822
23046
|
"Taiga is a policy-aware software delivery platform. Use these tools (taiga_*) for anything about a Taiga",
|
|
22823
23047
|
"product: its initiatives, runs, policies, findings, deployments or setup.",
|
|
22824
23048
|
"",
|
|
22825
|
-
"**Which read.** Where a product stands (counts,
|
|
23049
|
+
"**Which read.** Where a product stands (counts, first rows): taiga_get_product_context, by remote URL, slug",
|
|
22826
23050
|
"or ID. What waits on people: taiga_list_action_required. A policy: taiga_get_organization_document (sections:",
|
|
22827
23051
|
"[], or a control id such as SEC-5.1), or the taiga://documents/{type} resources. Findings: taiga_list_findings.",
|
|
22828
23052
|
"One initiative or run: taiga_get_initiative, taiga_get_run. What this key may call: taiga_whoami.",
|
|
@@ -22830,10 +23054,10 @@ const SERVER_INSTRUCTIONS = [
|
|
|
22830
23054
|
"**Words.** An initiative is a unit of work, on a board of columns (backlog, todo, queue, plan, build, done,",
|
|
22831
23055
|
"canceled); plan and build are stations, and the line starts the next queued initiative when both are empty. A",
|
|
22832
23056
|
"run is one coding-agent attempt; hardening is its security pass; handed back means a person must act. A gate is",
|
|
22833
|
-
"a person's review; a sweep is a scan for findings; standing is how a product meets
|
|
22834
|
-
"up a new product, from a web conversation or an import.
|
|
23057
|
+
"a person's review; a sweep is a scan for findings; standing is how a product meets policy. Discovery sets",
|
|
23058
|
+
"up a new product, from a web conversation or an import. Factories own products.",
|
|
22835
23059
|
"",
|
|
22836
|
-
"**IDs** are UUIDs; the product, factory and initiative lists take query (product and factory misses name the",
|
|
23060
|
+
"**IDs** are UUIDs; the product, factory and initiative lists take query (product and factory misses may name the",
|
|
22837
23061
|
"closest). A NOT_FOUND names the tool that lists the right ones. Lists page with nextCursor. outcome, situation",
|
|
22838
23062
|
"and nextStep are one-sentence summaries; setup writes return readiness. Product documents have two timelines:",
|
|
22839
23063
|
"plan (intent) and reality (from the code).",
|
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.501",
|
|
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",
|