@letpeoplework/lighthouse-mcp-core 1.5.0 → 1.7.0
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 +270 -2
- package/dist/index.d.cts +64 -1
- package/dist/index.d.ts +64 -1
- package/dist/index.js +272 -2
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -25,6 +25,7 @@ __export(index_exports, {
|
|
|
25
25
|
registerMcpTools: () => registerMcpTools
|
|
26
26
|
});
|
|
27
27
|
module.exports = __toCommonJS(index_exports);
|
|
28
|
+
var import_lighthouse_client = require("@letpeoplework/lighthouse-client");
|
|
28
29
|
var import_toon = require("@toon-format/toon");
|
|
29
30
|
var import_zod = require("zod");
|
|
30
31
|
var getMcpCorePackageContract = () => ({
|
|
@@ -65,6 +66,31 @@ var throughputFilterViewProperty = {
|
|
|
65
66
|
description: `Forecast-filter view (Lighthouse v26.5.24.10+). "filtered" applies the team's exclusion rule to throughput. Omit or "raw" returns unfiltered data.`
|
|
66
67
|
}
|
|
67
68
|
};
|
|
69
|
+
var percentilesOverTimeProperties = {
|
|
70
|
+
metricType: {
|
|
71
|
+
type: "string",
|
|
72
|
+
enum: ["CycleTime", "WorkItemAge"],
|
|
73
|
+
description: 'Percentile family to read. Defaults to "CycleTime" when omitted.'
|
|
74
|
+
},
|
|
75
|
+
horizon: {
|
|
76
|
+
type: "number",
|
|
77
|
+
description: "Cycle-time horizon in days (30, 60 or 90). Ignored for WorkItemAge, which is always as-of-today and has no horizon dimension."
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
var processBehaviorOverTimeProperties = {
|
|
81
|
+
metricType: {
|
|
82
|
+
type: "string",
|
|
83
|
+
enum: [
|
|
84
|
+
"Throughput",
|
|
85
|
+
"WorkItemAge",
|
|
86
|
+
"Wip",
|
|
87
|
+
"CycleTime",
|
|
88
|
+
"Arrivals",
|
|
89
|
+
"FeatureSize"
|
|
90
|
+
],
|
|
91
|
+
description: 'Process-behaviour family to read. Defaults to "Throughput" when omitted. "FeatureSize" is portfolio-only \u2014 a team never records it and returns an empty series.'
|
|
92
|
+
}
|
|
93
|
+
};
|
|
68
94
|
var cumulativeStateProperty = {
|
|
69
95
|
state: {
|
|
70
96
|
type: "string",
|
|
@@ -202,7 +228,7 @@ var toolDefinitions = [
|
|
|
202
228
|
},
|
|
203
229
|
{
|
|
204
230
|
name: "lighthouse_team_metrics_workItemAgePercentiles",
|
|
205
|
-
description: "Get work-item age percentiles for a team by ID, optionally filtered by start and end dates.",
|
|
231
|
+
description: "Get work-item age percentiles for a team by ID, optionally filtered by start and end dates. Ages are measured as of the last day of the selected range, not as of today \u2014 a historical range reports how old the items were at the end of that period, so do not present the result as the team's current ages unless the range ends today.",
|
|
206
232
|
inputSchema: {
|
|
207
233
|
type: "object",
|
|
208
234
|
properties: {
|
|
@@ -215,7 +241,7 @@ var toolDefinitions = [
|
|
|
215
241
|
},
|
|
216
242
|
{
|
|
217
243
|
name: "lighthouse_portfolio_metrics_workItemAgePercentiles",
|
|
218
|
-
description: "Get work-item age percentiles for a portfolio by ID, optionally filtered by start and end dates.",
|
|
244
|
+
description: "Get work-item age percentiles for a portfolio by ID, optionally filtered by start and end dates. Ages are measured as of the last day of the selected range, not as of today \u2014 a historical range reports how old the items were at the end of that period, so do not present the result as the portfolio's current ages unless the range ends today.",
|
|
219
245
|
inputSchema: {
|
|
220
246
|
type: "object",
|
|
221
247
|
properties: {
|
|
@@ -252,6 +278,62 @@ var toolDefinitions = [
|
|
|
252
278
|
additionalProperties: false
|
|
253
279
|
}
|
|
254
280
|
},
|
|
281
|
+
{
|
|
282
|
+
name: "lighthouse_team_metrics_percentilesOverTime",
|
|
283
|
+
description: "Get the percentiles-over-time trend for a team by ID: the p50/p70/p85/p95 quartet recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only \u2014 Lighthouse never backfills days it did not observe, so a recently upgraded server returns an empty series until it has recorded some. Use metricType to pick the family and horizon to pick the cycle-time window.",
|
|
284
|
+
inputSchema: {
|
|
285
|
+
type: "object",
|
|
286
|
+
properties: {
|
|
287
|
+
...idInputSchema.properties,
|
|
288
|
+
...dateRangeProperties,
|
|
289
|
+
...percentilesOverTimeProperties
|
|
290
|
+
},
|
|
291
|
+
required: ["id"],
|
|
292
|
+
additionalProperties: false
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
name: "lighthouse_portfolio_metrics_percentilesOverTime",
|
|
297
|
+
description: "Get the percentiles-over-time trend for a portfolio by ID: the p50/p70/p85/p95 quartet recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only \u2014 Lighthouse never backfills days it did not observe, so a recently upgraded server returns an empty series until it has recorded some. Use metricType to pick the family and horizon to pick the cycle-time window.",
|
|
298
|
+
inputSchema: {
|
|
299
|
+
type: "object",
|
|
300
|
+
properties: {
|
|
301
|
+
...idInputSchema.properties,
|
|
302
|
+
...dateRangeProperties,
|
|
303
|
+
...percentilesOverTimeProperties
|
|
304
|
+
},
|
|
305
|
+
required: ["id"],
|
|
306
|
+
additionalProperties: false
|
|
307
|
+
}
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
name: "lighthouse_team_metrics_processBehaviorOverTime",
|
|
311
|
+
description: "Get the process-behaviour-limits-over-time trend for a team by ID: the upper limit, average and lower limit (UNPL/Average/LNPL) recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only, and days without a usable baseline are absent rather than zeroed \u2014 an empty series means nothing was recorded, never a process pinned at zero.",
|
|
312
|
+
inputSchema: {
|
|
313
|
+
type: "object",
|
|
314
|
+
properties: {
|
|
315
|
+
...idInputSchema.properties,
|
|
316
|
+
...dateRangeProperties,
|
|
317
|
+
...processBehaviorOverTimeProperties
|
|
318
|
+
},
|
|
319
|
+
required: ["id"],
|
|
320
|
+
additionalProperties: false
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
{
|
|
324
|
+
name: "lighthouse_portfolio_metrics_processBehaviorOverTime",
|
|
325
|
+
description: "Get the process-behaviour-limits-over-time trend for a portfolio by ID: the upper limit, average and lower limit (UNPL/Average/LNPL) recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only, and days without a usable baseline are absent rather than zeroed \u2014 an empty series means nothing was recorded, never a process pinned at zero. FeatureSize is available here and not on teams.",
|
|
326
|
+
inputSchema: {
|
|
327
|
+
type: "object",
|
|
328
|
+
properties: {
|
|
329
|
+
...idInputSchema.properties,
|
|
330
|
+
...dateRangeProperties,
|
|
331
|
+
...processBehaviorOverTimeProperties
|
|
332
|
+
},
|
|
333
|
+
required: ["id"],
|
|
334
|
+
additionalProperties: false
|
|
335
|
+
}
|
|
336
|
+
},
|
|
255
337
|
{
|
|
256
338
|
name: "lighthouse_portfolio_metrics_throughput",
|
|
257
339
|
description: "Get throughput run-chart data for a portfolio by ID, optionally filtered by start and end dates.",
|
|
@@ -351,6 +433,23 @@ var toolDefinitions = [
|
|
|
351
433
|
description: "List deliveries for a portfolio by portfolio ID.",
|
|
352
434
|
inputSchema: idInputSchema
|
|
353
435
|
},
|
|
436
|
+
{
|
|
437
|
+
name: "lighthouse_delivery_metrics",
|
|
438
|
+
description: `Get a delivery's recorded trend by delivery ID: one row per day with total, done and remaining work, the epic count and the likelihood. Set detail to "epics" for the per-epic breakdown and the forecast distribution, which are far larger. Forward-only, so it starts at the first recorded snapshot. Requires Lighthouse newer than v26.5.29.5.`,
|
|
439
|
+
inputSchema: {
|
|
440
|
+
type: "object",
|
|
441
|
+
properties: {
|
|
442
|
+
id: { type: "number", description: "Delivery ID." },
|
|
443
|
+
detail: {
|
|
444
|
+
type: "string",
|
|
445
|
+
enum: ["epics"],
|
|
446
|
+
description: 'Omit for one row per day. "epics" returns the whole recorded payload.'
|
|
447
|
+
}
|
|
448
|
+
},
|
|
449
|
+
required: ["id"],
|
|
450
|
+
additionalProperties: false
|
|
451
|
+
}
|
|
452
|
+
},
|
|
354
453
|
{
|
|
355
454
|
name: "lighthouse_blackout_list",
|
|
356
455
|
description: "List the recurring blackout rules (recurring non-working days excluded from forecasts). Requires Lighthouse newer than v26.5.29.5.",
|
|
@@ -610,6 +709,30 @@ var getThroughputFilterView = (argumentsPayload) => {
|
|
|
610
709
|
const view = argumentsPayload.view;
|
|
611
710
|
return view === "raw" || view === "filtered" ? view : void 0;
|
|
612
711
|
};
|
|
712
|
+
var percentilesOverTimeMetricTypes = ["CycleTime", "WorkItemAge"];
|
|
713
|
+
var getPercentilesOverTimeMetricType = (argumentsPayload) => {
|
|
714
|
+
const raw = getStringArgument(argumentsPayload, "metricType");
|
|
715
|
+
return percentilesOverTimeMetricTypes.find((candidate) => candidate === raw);
|
|
716
|
+
};
|
|
717
|
+
var processBehaviorMetricTypes = [
|
|
718
|
+
"Throughput",
|
|
719
|
+
"WorkItemAge",
|
|
720
|
+
"Wip",
|
|
721
|
+
"CycleTime",
|
|
722
|
+
"Arrivals",
|
|
723
|
+
"FeatureSize"
|
|
724
|
+
];
|
|
725
|
+
var getProcessBehaviorMetricType = (argumentsPayload) => {
|
|
726
|
+
const raw = getStringArgument(argumentsPayload, "metricType");
|
|
727
|
+
return processBehaviorMetricTypes.find((candidate) => candidate === raw);
|
|
728
|
+
};
|
|
729
|
+
var getHorizonArgument = (argumentsPayload) => {
|
|
730
|
+
if (!isObjectRecord(argumentsPayload)) {
|
|
731
|
+
return void 0;
|
|
732
|
+
}
|
|
733
|
+
const horizon = argumentsPayload.horizon;
|
|
734
|
+
return typeof horizon === "number" && Number.isInteger(horizon) ? horizon : void 0;
|
|
735
|
+
};
|
|
613
736
|
var getApplyFilterOverride = (argumentsPayload) => {
|
|
614
737
|
if (!isObjectRecord(argumentsPayload)) {
|
|
615
738
|
return void 0;
|
|
@@ -677,6 +800,46 @@ var toolInputSchemas = {
|
|
|
677
800
|
startDate: isoDateStringSchema.optional(),
|
|
678
801
|
endDate: isoDateStringSchema.optional()
|
|
679
802
|
}),
|
|
803
|
+
lighthouse_team_metrics_percentilesOverTime: import_zod.z.object({
|
|
804
|
+
id: import_zod.z.number().int(),
|
|
805
|
+
startDate: isoDateStringSchema.optional(),
|
|
806
|
+
endDate: isoDateStringSchema.optional(),
|
|
807
|
+
metricType: import_zod.z.enum(["CycleTime", "WorkItemAge"]).optional(),
|
|
808
|
+
horizon: import_zod.z.number().int().optional()
|
|
809
|
+
}),
|
|
810
|
+
lighthouse_portfolio_metrics_percentilesOverTime: import_zod.z.object({
|
|
811
|
+
id: import_zod.z.number().int(),
|
|
812
|
+
startDate: isoDateStringSchema.optional(),
|
|
813
|
+
endDate: isoDateStringSchema.optional(),
|
|
814
|
+
metricType: import_zod.z.enum(["CycleTime", "WorkItemAge"]).optional(),
|
|
815
|
+
horizon: import_zod.z.number().int().optional()
|
|
816
|
+
}),
|
|
817
|
+
lighthouse_team_metrics_processBehaviorOverTime: import_zod.z.object({
|
|
818
|
+
id: import_zod.z.number().int(),
|
|
819
|
+
startDate: isoDateStringSchema.optional(),
|
|
820
|
+
endDate: isoDateStringSchema.optional(),
|
|
821
|
+
metricType: import_zod.z.enum([
|
|
822
|
+
"Throughput",
|
|
823
|
+
"WorkItemAge",
|
|
824
|
+
"Wip",
|
|
825
|
+
"CycleTime",
|
|
826
|
+
"Arrivals",
|
|
827
|
+
"FeatureSize"
|
|
828
|
+
]).optional()
|
|
829
|
+
}),
|
|
830
|
+
lighthouse_portfolio_metrics_processBehaviorOverTime: import_zod.z.object({
|
|
831
|
+
id: import_zod.z.number().int(),
|
|
832
|
+
startDate: isoDateStringSchema.optional(),
|
|
833
|
+
endDate: isoDateStringSchema.optional(),
|
|
834
|
+
metricType: import_zod.z.enum([
|
|
835
|
+
"Throughput",
|
|
836
|
+
"WorkItemAge",
|
|
837
|
+
"Wip",
|
|
838
|
+
"CycleTime",
|
|
839
|
+
"Arrivals",
|
|
840
|
+
"FeatureSize"
|
|
841
|
+
]).optional()
|
|
842
|
+
}),
|
|
680
843
|
lighthouse_team_metrics_workItemAge: import_zod.z.object({
|
|
681
844
|
id: import_zod.z.number().int(),
|
|
682
845
|
startDate: isoDateStringSchema.optional(),
|
|
@@ -744,6 +907,10 @@ var toolInputSchemas = {
|
|
|
744
907
|
}),
|
|
745
908
|
lighthouse_feature_workitems: import_zod.z.object({ id: import_zod.z.number().int() }),
|
|
746
909
|
lighthouse_delivery_list: import_zod.z.object({ id: import_zod.z.number().int() }),
|
|
910
|
+
lighthouse_delivery_metrics: import_zod.z.object({
|
|
911
|
+
id: import_zod.z.number().int(),
|
|
912
|
+
detail: import_zod.z.literal("epics").optional()
|
|
913
|
+
}),
|
|
747
914
|
lighthouse_blackout_list: import_zod.z.object({}),
|
|
748
915
|
lighthouse_blackout_create: recurringBlackoutRuleInputSchema,
|
|
749
916
|
lighthouse_blackout_update: recurringBlackoutRuleInputSchema.extend({
|
|
@@ -991,6 +1158,88 @@ var createMcpCoreRuntime = (dependencies) => ({
|
|
|
991
1158
|
`portfolio metrics: ${result.error.category} (${result.error.reason})`
|
|
992
1159
|
);
|
|
993
1160
|
}
|
|
1161
|
+
if (name === "lighthouse_team_metrics_percentilesOverTime") {
|
|
1162
|
+
const id = getNumericId(argumentsPayload);
|
|
1163
|
+
if (id === null) {
|
|
1164
|
+
return getErrorToolResult("team metrics: invalid id");
|
|
1165
|
+
}
|
|
1166
|
+
const range = getDateRange(argumentsPayload);
|
|
1167
|
+
const result = await client.getTeamPercentilesOverTime(
|
|
1168
|
+
id,
|
|
1169
|
+
range,
|
|
1170
|
+
getPercentilesOverTimeMetricType(argumentsPayload),
|
|
1171
|
+
getHorizonArgument(argumentsPayload)
|
|
1172
|
+
);
|
|
1173
|
+
if (result.ok) {
|
|
1174
|
+
return getSuccessToolResult(
|
|
1175
|
+
`team percentilesOverTime: ${encodePayload(result.value)}`
|
|
1176
|
+
);
|
|
1177
|
+
}
|
|
1178
|
+
return getErrorToolResult(
|
|
1179
|
+
`team metrics: ${result.error.category} (${result.error.reason})`
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
if (name === "lighthouse_portfolio_metrics_percentilesOverTime") {
|
|
1183
|
+
const id = getNumericId(argumentsPayload);
|
|
1184
|
+
if (id === null) {
|
|
1185
|
+
return getErrorToolResult("portfolio metrics: invalid id");
|
|
1186
|
+
}
|
|
1187
|
+
const range = getDateRange(argumentsPayload);
|
|
1188
|
+
const result = await client.getPortfolioPercentilesOverTime(
|
|
1189
|
+
id,
|
|
1190
|
+
range,
|
|
1191
|
+
getPercentilesOverTimeMetricType(argumentsPayload),
|
|
1192
|
+
getHorizonArgument(argumentsPayload)
|
|
1193
|
+
);
|
|
1194
|
+
if (result.ok) {
|
|
1195
|
+
return getSuccessToolResult(
|
|
1196
|
+
`portfolio percentilesOverTime: ${encodePayload(result.value)}`
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1199
|
+
return getErrorToolResult(
|
|
1200
|
+
`portfolio metrics: ${result.error.category} (${result.error.reason})`
|
|
1201
|
+
);
|
|
1202
|
+
}
|
|
1203
|
+
if (name === "lighthouse_team_metrics_processBehaviorOverTime") {
|
|
1204
|
+
const id = getNumericId(argumentsPayload);
|
|
1205
|
+
if (id === null) {
|
|
1206
|
+
return getErrorToolResult("team metrics: invalid id");
|
|
1207
|
+
}
|
|
1208
|
+
const range = getDateRange(argumentsPayload);
|
|
1209
|
+
const result = await client.getTeamProcessBehaviorOverTime(
|
|
1210
|
+
id,
|
|
1211
|
+
range,
|
|
1212
|
+
getProcessBehaviorMetricType(argumentsPayload)
|
|
1213
|
+
);
|
|
1214
|
+
if (result.ok) {
|
|
1215
|
+
return getSuccessToolResult(
|
|
1216
|
+
`team processBehaviorOverTime: ${encodePayload(result.value)}`
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
1219
|
+
return getErrorToolResult(
|
|
1220
|
+
`team metrics: ${result.error.category} (${result.error.reason})`
|
|
1221
|
+
);
|
|
1222
|
+
}
|
|
1223
|
+
if (name === "lighthouse_portfolio_metrics_processBehaviorOverTime") {
|
|
1224
|
+
const id = getNumericId(argumentsPayload);
|
|
1225
|
+
if (id === null) {
|
|
1226
|
+
return getErrorToolResult("portfolio metrics: invalid id");
|
|
1227
|
+
}
|
|
1228
|
+
const range = getDateRange(argumentsPayload);
|
|
1229
|
+
const result = await client.getPortfolioProcessBehaviorOverTime(
|
|
1230
|
+
id,
|
|
1231
|
+
range,
|
|
1232
|
+
getProcessBehaviorMetricType(argumentsPayload)
|
|
1233
|
+
);
|
|
1234
|
+
if (result.ok) {
|
|
1235
|
+
return getSuccessToolResult(
|
|
1236
|
+
`portfolio processBehaviorOverTime: ${encodePayload(result.value)}`
|
|
1237
|
+
);
|
|
1238
|
+
}
|
|
1239
|
+
return getErrorToolResult(
|
|
1240
|
+
`portfolio metrics: ${result.error.category} (${result.error.reason})`
|
|
1241
|
+
);
|
|
1242
|
+
}
|
|
994
1243
|
if (name === "lighthouse_team_metrics_cumulativeStateTime") {
|
|
995
1244
|
const id = getNumericId(argumentsPayload);
|
|
996
1245
|
if (id === null) {
|
|
@@ -1262,6 +1511,25 @@ var createMcpCoreRuntime = (dependencies) => ({
|
|
|
1262
1511
|
`delivery: ${result.error.category} (${result.error.reason})`
|
|
1263
1512
|
);
|
|
1264
1513
|
}
|
|
1514
|
+
if (name === "lighthouse_delivery_metrics") {
|
|
1515
|
+
const id = getNumericId(argumentsPayload);
|
|
1516
|
+
if (id === null) {
|
|
1517
|
+
return getErrorToolResult(
|
|
1518
|
+
"delivery metrics: invalid id (delivery id required)"
|
|
1519
|
+
);
|
|
1520
|
+
}
|
|
1521
|
+
const wantsEpics = argumentsPayload?.detail === "epics";
|
|
1522
|
+
const result = await client.getDeliveryMetricsHistory(id);
|
|
1523
|
+
if (!result.ok) {
|
|
1524
|
+
return getErrorToolResult(
|
|
1525
|
+
`delivery metrics: ${result.error.category} (${result.error.reason})`
|
|
1526
|
+
);
|
|
1527
|
+
}
|
|
1528
|
+
const payload = wantsEpics ? result.value : (0, import_lighthouse_client.summariseDeliveryMetricsHistory)(result.value);
|
|
1529
|
+
return getSuccessToolResult(
|
|
1530
|
+
`delivery metrics: ${encodePayload(payload)}`
|
|
1531
|
+
);
|
|
1532
|
+
}
|
|
1265
1533
|
if (name === "lighthouse_blackout_list") {
|
|
1266
1534
|
const result = await client.getRecurringBlackoutRules();
|
|
1267
1535
|
if (result.ok) {
|
package/dist/index.d.cts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DeliveryMetricsHistory } from '@letpeoplework/lighthouse-client';
|
|
1
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
3
|
|
|
3
4
|
type McpCorePackageContract = {
|
|
@@ -15,7 +16,7 @@ type McpToolResult = {
|
|
|
15
16
|
readonly content: readonly McpToolContent[];
|
|
16
17
|
};
|
|
17
18
|
type McpToolDefinition = {
|
|
18
|
-
readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_portfolio_list" | "lighthouse_portfolio_get" | "lighthouse_portfolio_refresh" | "lighthouse_team_metrics_throughput" | "lighthouse_team_metrics_cycleTimePercentiles" | "lighthouse_team_metrics_workItemAgePercentiles" | "lighthouse_portfolio_metrics_workItemAgePercentiles" | "lighthouse_team_metrics_workItemAge" | "lighthouse_team_metrics_totalWorkItemAge" | "lighthouse_portfolio_metrics_throughput" | "lighthouse_portfolio_metrics_workItemAge" | "lighthouse_portfolio_metrics_totalWorkItemAge" | "lighthouse_team_metrics_blockedCountHistory" | "lighthouse_portfolio_metrics_blockedCountHistory" | "lighthouse_team_metrics_cumulativeStateTime" | "lighthouse_team_metrics_cumulativeStateTimeItems" | "lighthouse_team_metrics_cumulativeStateTimeCandidates" | "lighthouse_portfolio_metrics_cumulativeStateTime" | "lighthouse_portfolio_metrics_cumulativeStateTimeItems" | "lighthouse_portfolio_metrics_cumulativeStateTimeCandidates" | "lighthouse_feature_get" | "lighthouse_feature_workitems" | "lighthouse_delivery_list" | "lighthouse_blackout_list" | "lighthouse_blackout_create" | "lighthouse_blackout_update" | "lighthouse_blackout_delete" | "lighthouse_forecast_manual" | "lighthouse_forecast_backtest";
|
|
19
|
+
readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_portfolio_list" | "lighthouse_portfolio_get" | "lighthouse_portfolio_refresh" | "lighthouse_team_metrics_throughput" | "lighthouse_team_metrics_cycleTimePercentiles" | "lighthouse_team_metrics_workItemAgePercentiles" | "lighthouse_portfolio_metrics_workItemAgePercentiles" | "lighthouse_team_metrics_workItemAge" | "lighthouse_team_metrics_totalWorkItemAge" | "lighthouse_portfolio_metrics_throughput" | "lighthouse_portfolio_metrics_workItemAge" | "lighthouse_portfolio_metrics_totalWorkItemAge" | "lighthouse_team_metrics_blockedCountHistory" | "lighthouse_portfolio_metrics_blockedCountHistory" | "lighthouse_team_metrics_percentilesOverTime" | "lighthouse_portfolio_metrics_percentilesOverTime" | "lighthouse_team_metrics_processBehaviorOverTime" | "lighthouse_portfolio_metrics_processBehaviorOverTime" | "lighthouse_team_metrics_cumulativeStateTime" | "lighthouse_team_metrics_cumulativeStateTimeItems" | "lighthouse_team_metrics_cumulativeStateTimeCandidates" | "lighthouse_portfolio_metrics_cumulativeStateTime" | "lighthouse_portfolio_metrics_cumulativeStateTimeItems" | "lighthouse_portfolio_metrics_cumulativeStateTimeCandidates" | "lighthouse_feature_get" | "lighthouse_feature_workitems" | "lighthouse_delivery_list" | "lighthouse_delivery_metrics" | "lighthouse_blackout_list" | "lighthouse_blackout_create" | "lighthouse_blackout_update" | "lighthouse_blackout_delete" | "lighthouse_forecast_manual" | "lighthouse_forecast_backtest";
|
|
19
20
|
readonly description: string;
|
|
20
21
|
readonly inputSchema: {
|
|
21
22
|
readonly type: "object";
|
|
@@ -262,6 +263,58 @@ type McpRuntimeClient = {
|
|
|
262
263
|
readonly reason: string;
|
|
263
264
|
};
|
|
264
265
|
}>;
|
|
266
|
+
readonly getTeamPercentilesOverTime: (id: number, range?: {
|
|
267
|
+
readonly startDate: string;
|
|
268
|
+
readonly endDate: string;
|
|
269
|
+
}, metricType?: "CycleTime" | "WorkItemAge", horizon?: number) => Promise<{
|
|
270
|
+
readonly ok: true;
|
|
271
|
+
readonly value: readonly unknown[];
|
|
272
|
+
} | {
|
|
273
|
+
readonly ok: false;
|
|
274
|
+
readonly error: {
|
|
275
|
+
readonly category: string;
|
|
276
|
+
readonly reason: string;
|
|
277
|
+
};
|
|
278
|
+
}>;
|
|
279
|
+
readonly getPortfolioPercentilesOverTime: (id: number, range?: {
|
|
280
|
+
readonly startDate: string;
|
|
281
|
+
readonly endDate: string;
|
|
282
|
+
}, metricType?: "CycleTime" | "WorkItemAge", horizon?: number) => Promise<{
|
|
283
|
+
readonly ok: true;
|
|
284
|
+
readonly value: readonly unknown[];
|
|
285
|
+
} | {
|
|
286
|
+
readonly ok: false;
|
|
287
|
+
readonly error: {
|
|
288
|
+
readonly category: string;
|
|
289
|
+
readonly reason: string;
|
|
290
|
+
};
|
|
291
|
+
}>;
|
|
292
|
+
readonly getTeamProcessBehaviorOverTime: (id: number, range?: {
|
|
293
|
+
readonly startDate: string;
|
|
294
|
+
readonly endDate: string;
|
|
295
|
+
}, metricType?: "Throughput" | "WorkItemAge" | "Wip" | "CycleTime" | "Arrivals" | "FeatureSize") => Promise<{
|
|
296
|
+
readonly ok: true;
|
|
297
|
+
readonly value: readonly unknown[];
|
|
298
|
+
} | {
|
|
299
|
+
readonly ok: false;
|
|
300
|
+
readonly error: {
|
|
301
|
+
readonly category: string;
|
|
302
|
+
readonly reason: string;
|
|
303
|
+
};
|
|
304
|
+
}>;
|
|
305
|
+
readonly getPortfolioProcessBehaviorOverTime: (id: number, range?: {
|
|
306
|
+
readonly startDate: string;
|
|
307
|
+
readonly endDate: string;
|
|
308
|
+
}, metricType?: "Throughput" | "WorkItemAge" | "Wip" | "CycleTime" | "Arrivals" | "FeatureSize") => Promise<{
|
|
309
|
+
readonly ok: true;
|
|
310
|
+
readonly value: readonly unknown[];
|
|
311
|
+
} | {
|
|
312
|
+
readonly ok: false;
|
|
313
|
+
readonly error: {
|
|
314
|
+
readonly category: string;
|
|
315
|
+
readonly reason: string;
|
|
316
|
+
};
|
|
317
|
+
}>;
|
|
265
318
|
readonly getTeamCumulativeStateTime: (id: number, range?: {
|
|
266
319
|
readonly startDate: string;
|
|
267
320
|
readonly endDate: string;
|
|
@@ -380,6 +433,16 @@ type McpRuntimeClient = {
|
|
|
380
433
|
readonly reason: string;
|
|
381
434
|
};
|
|
382
435
|
}>;
|
|
436
|
+
readonly getDeliveryMetricsHistory: (deliveryId: number) => Promise<{
|
|
437
|
+
readonly ok: true;
|
|
438
|
+
readonly value: DeliveryMetricsHistory;
|
|
439
|
+
} | {
|
|
440
|
+
readonly ok: false;
|
|
441
|
+
readonly error: {
|
|
442
|
+
readonly category: string;
|
|
443
|
+
readonly reason: string;
|
|
444
|
+
};
|
|
445
|
+
}>;
|
|
383
446
|
readonly createDelivery: (portfolioId: number, payload: Readonly<Record<string, unknown>>) => Promise<{
|
|
384
447
|
readonly ok: true;
|
|
385
448
|
readonly value: unknown;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { DeliveryMetricsHistory } from '@letpeoplework/lighthouse-client';
|
|
1
2
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
3
|
|
|
3
4
|
type McpCorePackageContract = {
|
|
@@ -15,7 +16,7 @@ type McpToolResult = {
|
|
|
15
16
|
readonly content: readonly McpToolContent[];
|
|
16
17
|
};
|
|
17
18
|
type McpToolDefinition = {
|
|
18
|
-
readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_portfolio_list" | "lighthouse_portfolio_get" | "lighthouse_portfolio_refresh" | "lighthouse_team_metrics_throughput" | "lighthouse_team_metrics_cycleTimePercentiles" | "lighthouse_team_metrics_workItemAgePercentiles" | "lighthouse_portfolio_metrics_workItemAgePercentiles" | "lighthouse_team_metrics_workItemAge" | "lighthouse_team_metrics_totalWorkItemAge" | "lighthouse_portfolio_metrics_throughput" | "lighthouse_portfolio_metrics_workItemAge" | "lighthouse_portfolio_metrics_totalWorkItemAge" | "lighthouse_team_metrics_blockedCountHistory" | "lighthouse_portfolio_metrics_blockedCountHistory" | "lighthouse_team_metrics_cumulativeStateTime" | "lighthouse_team_metrics_cumulativeStateTimeItems" | "lighthouse_team_metrics_cumulativeStateTimeCandidates" | "lighthouse_portfolio_metrics_cumulativeStateTime" | "lighthouse_portfolio_metrics_cumulativeStateTimeItems" | "lighthouse_portfolio_metrics_cumulativeStateTimeCandidates" | "lighthouse_feature_get" | "lighthouse_feature_workitems" | "lighthouse_delivery_list" | "lighthouse_blackout_list" | "lighthouse_blackout_create" | "lighthouse_blackout_update" | "lighthouse_blackout_delete" | "lighthouse_forecast_manual" | "lighthouse_forecast_backtest";
|
|
19
|
+
readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_portfolio_list" | "lighthouse_portfolio_get" | "lighthouse_portfolio_refresh" | "lighthouse_team_metrics_throughput" | "lighthouse_team_metrics_cycleTimePercentiles" | "lighthouse_team_metrics_workItemAgePercentiles" | "lighthouse_portfolio_metrics_workItemAgePercentiles" | "lighthouse_team_metrics_workItemAge" | "lighthouse_team_metrics_totalWorkItemAge" | "lighthouse_portfolio_metrics_throughput" | "lighthouse_portfolio_metrics_workItemAge" | "lighthouse_portfolio_metrics_totalWorkItemAge" | "lighthouse_team_metrics_blockedCountHistory" | "lighthouse_portfolio_metrics_blockedCountHistory" | "lighthouse_team_metrics_percentilesOverTime" | "lighthouse_portfolio_metrics_percentilesOverTime" | "lighthouse_team_metrics_processBehaviorOverTime" | "lighthouse_portfolio_metrics_processBehaviorOverTime" | "lighthouse_team_metrics_cumulativeStateTime" | "lighthouse_team_metrics_cumulativeStateTimeItems" | "lighthouse_team_metrics_cumulativeStateTimeCandidates" | "lighthouse_portfolio_metrics_cumulativeStateTime" | "lighthouse_portfolio_metrics_cumulativeStateTimeItems" | "lighthouse_portfolio_metrics_cumulativeStateTimeCandidates" | "lighthouse_feature_get" | "lighthouse_feature_workitems" | "lighthouse_delivery_list" | "lighthouse_delivery_metrics" | "lighthouse_blackout_list" | "lighthouse_blackout_create" | "lighthouse_blackout_update" | "lighthouse_blackout_delete" | "lighthouse_forecast_manual" | "lighthouse_forecast_backtest";
|
|
19
20
|
readonly description: string;
|
|
20
21
|
readonly inputSchema: {
|
|
21
22
|
readonly type: "object";
|
|
@@ -262,6 +263,58 @@ type McpRuntimeClient = {
|
|
|
262
263
|
readonly reason: string;
|
|
263
264
|
};
|
|
264
265
|
}>;
|
|
266
|
+
readonly getTeamPercentilesOverTime: (id: number, range?: {
|
|
267
|
+
readonly startDate: string;
|
|
268
|
+
readonly endDate: string;
|
|
269
|
+
}, metricType?: "CycleTime" | "WorkItemAge", horizon?: number) => Promise<{
|
|
270
|
+
readonly ok: true;
|
|
271
|
+
readonly value: readonly unknown[];
|
|
272
|
+
} | {
|
|
273
|
+
readonly ok: false;
|
|
274
|
+
readonly error: {
|
|
275
|
+
readonly category: string;
|
|
276
|
+
readonly reason: string;
|
|
277
|
+
};
|
|
278
|
+
}>;
|
|
279
|
+
readonly getPortfolioPercentilesOverTime: (id: number, range?: {
|
|
280
|
+
readonly startDate: string;
|
|
281
|
+
readonly endDate: string;
|
|
282
|
+
}, metricType?: "CycleTime" | "WorkItemAge", horizon?: number) => Promise<{
|
|
283
|
+
readonly ok: true;
|
|
284
|
+
readonly value: readonly unknown[];
|
|
285
|
+
} | {
|
|
286
|
+
readonly ok: false;
|
|
287
|
+
readonly error: {
|
|
288
|
+
readonly category: string;
|
|
289
|
+
readonly reason: string;
|
|
290
|
+
};
|
|
291
|
+
}>;
|
|
292
|
+
readonly getTeamProcessBehaviorOverTime: (id: number, range?: {
|
|
293
|
+
readonly startDate: string;
|
|
294
|
+
readonly endDate: string;
|
|
295
|
+
}, metricType?: "Throughput" | "WorkItemAge" | "Wip" | "CycleTime" | "Arrivals" | "FeatureSize") => Promise<{
|
|
296
|
+
readonly ok: true;
|
|
297
|
+
readonly value: readonly unknown[];
|
|
298
|
+
} | {
|
|
299
|
+
readonly ok: false;
|
|
300
|
+
readonly error: {
|
|
301
|
+
readonly category: string;
|
|
302
|
+
readonly reason: string;
|
|
303
|
+
};
|
|
304
|
+
}>;
|
|
305
|
+
readonly getPortfolioProcessBehaviorOverTime: (id: number, range?: {
|
|
306
|
+
readonly startDate: string;
|
|
307
|
+
readonly endDate: string;
|
|
308
|
+
}, metricType?: "Throughput" | "WorkItemAge" | "Wip" | "CycleTime" | "Arrivals" | "FeatureSize") => Promise<{
|
|
309
|
+
readonly ok: true;
|
|
310
|
+
readonly value: readonly unknown[];
|
|
311
|
+
} | {
|
|
312
|
+
readonly ok: false;
|
|
313
|
+
readonly error: {
|
|
314
|
+
readonly category: string;
|
|
315
|
+
readonly reason: string;
|
|
316
|
+
};
|
|
317
|
+
}>;
|
|
265
318
|
readonly getTeamCumulativeStateTime: (id: number, range?: {
|
|
266
319
|
readonly startDate: string;
|
|
267
320
|
readonly endDate: string;
|
|
@@ -380,6 +433,16 @@ type McpRuntimeClient = {
|
|
|
380
433
|
readonly reason: string;
|
|
381
434
|
};
|
|
382
435
|
}>;
|
|
436
|
+
readonly getDeliveryMetricsHistory: (deliveryId: number) => Promise<{
|
|
437
|
+
readonly ok: true;
|
|
438
|
+
readonly value: DeliveryMetricsHistory;
|
|
439
|
+
} | {
|
|
440
|
+
readonly ok: false;
|
|
441
|
+
readonly error: {
|
|
442
|
+
readonly category: string;
|
|
443
|
+
readonly reason: string;
|
|
444
|
+
};
|
|
445
|
+
}>;
|
|
383
446
|
readonly createDelivery: (portfolioId: number, payload: Readonly<Record<string, unknown>>) => Promise<{
|
|
384
447
|
readonly ok: true;
|
|
385
448
|
readonly value: unknown;
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// src/index.ts
|
|
2
|
+
import {
|
|
3
|
+
summariseDeliveryMetricsHistory
|
|
4
|
+
} from "@letpeoplework/lighthouse-client";
|
|
2
5
|
import { encode } from "@toon-format/toon";
|
|
3
6
|
import { z } from "zod";
|
|
4
7
|
var getMcpCorePackageContract = () => ({
|
|
@@ -39,6 +42,31 @@ var throughputFilterViewProperty = {
|
|
|
39
42
|
description: `Forecast-filter view (Lighthouse v26.5.24.10+). "filtered" applies the team's exclusion rule to throughput. Omit or "raw" returns unfiltered data.`
|
|
40
43
|
}
|
|
41
44
|
};
|
|
45
|
+
var percentilesOverTimeProperties = {
|
|
46
|
+
metricType: {
|
|
47
|
+
type: "string",
|
|
48
|
+
enum: ["CycleTime", "WorkItemAge"],
|
|
49
|
+
description: 'Percentile family to read. Defaults to "CycleTime" when omitted.'
|
|
50
|
+
},
|
|
51
|
+
horizon: {
|
|
52
|
+
type: "number",
|
|
53
|
+
description: "Cycle-time horizon in days (30, 60 or 90). Ignored for WorkItemAge, which is always as-of-today and has no horizon dimension."
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
var processBehaviorOverTimeProperties = {
|
|
57
|
+
metricType: {
|
|
58
|
+
type: "string",
|
|
59
|
+
enum: [
|
|
60
|
+
"Throughput",
|
|
61
|
+
"WorkItemAge",
|
|
62
|
+
"Wip",
|
|
63
|
+
"CycleTime",
|
|
64
|
+
"Arrivals",
|
|
65
|
+
"FeatureSize"
|
|
66
|
+
],
|
|
67
|
+
description: 'Process-behaviour family to read. Defaults to "Throughput" when omitted. "FeatureSize" is portfolio-only \u2014 a team never records it and returns an empty series.'
|
|
68
|
+
}
|
|
69
|
+
};
|
|
42
70
|
var cumulativeStateProperty = {
|
|
43
71
|
state: {
|
|
44
72
|
type: "string",
|
|
@@ -176,7 +204,7 @@ var toolDefinitions = [
|
|
|
176
204
|
},
|
|
177
205
|
{
|
|
178
206
|
name: "lighthouse_team_metrics_workItemAgePercentiles",
|
|
179
|
-
description: "Get work-item age percentiles for a team by ID, optionally filtered by start and end dates.",
|
|
207
|
+
description: "Get work-item age percentiles for a team by ID, optionally filtered by start and end dates. Ages are measured as of the last day of the selected range, not as of today \u2014 a historical range reports how old the items were at the end of that period, so do not present the result as the team's current ages unless the range ends today.",
|
|
180
208
|
inputSchema: {
|
|
181
209
|
type: "object",
|
|
182
210
|
properties: {
|
|
@@ -189,7 +217,7 @@ var toolDefinitions = [
|
|
|
189
217
|
},
|
|
190
218
|
{
|
|
191
219
|
name: "lighthouse_portfolio_metrics_workItemAgePercentiles",
|
|
192
|
-
description: "Get work-item age percentiles for a portfolio by ID, optionally filtered by start and end dates.",
|
|
220
|
+
description: "Get work-item age percentiles for a portfolio by ID, optionally filtered by start and end dates. Ages are measured as of the last day of the selected range, not as of today \u2014 a historical range reports how old the items were at the end of that period, so do not present the result as the portfolio's current ages unless the range ends today.",
|
|
193
221
|
inputSchema: {
|
|
194
222
|
type: "object",
|
|
195
223
|
properties: {
|
|
@@ -226,6 +254,62 @@ var toolDefinitions = [
|
|
|
226
254
|
additionalProperties: false
|
|
227
255
|
}
|
|
228
256
|
},
|
|
257
|
+
{
|
|
258
|
+
name: "lighthouse_team_metrics_percentilesOverTime",
|
|
259
|
+
description: "Get the percentiles-over-time trend for a team by ID: the p50/p70/p85/p95 quartet recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only \u2014 Lighthouse never backfills days it did not observe, so a recently upgraded server returns an empty series until it has recorded some. Use metricType to pick the family and horizon to pick the cycle-time window.",
|
|
260
|
+
inputSchema: {
|
|
261
|
+
type: "object",
|
|
262
|
+
properties: {
|
|
263
|
+
...idInputSchema.properties,
|
|
264
|
+
...dateRangeProperties,
|
|
265
|
+
...percentilesOverTimeProperties
|
|
266
|
+
},
|
|
267
|
+
required: ["id"],
|
|
268
|
+
additionalProperties: false
|
|
269
|
+
}
|
|
270
|
+
},
|
|
271
|
+
{
|
|
272
|
+
name: "lighthouse_portfolio_metrics_percentilesOverTime",
|
|
273
|
+
description: "Get the percentiles-over-time trend for a portfolio by ID: the p50/p70/p85/p95 quartet recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only \u2014 Lighthouse never backfills days it did not observe, so a recently upgraded server returns an empty series until it has recorded some. Use metricType to pick the family and horizon to pick the cycle-time window.",
|
|
274
|
+
inputSchema: {
|
|
275
|
+
type: "object",
|
|
276
|
+
properties: {
|
|
277
|
+
...idInputSchema.properties,
|
|
278
|
+
...dateRangeProperties,
|
|
279
|
+
...percentilesOverTimeProperties
|
|
280
|
+
},
|
|
281
|
+
required: ["id"],
|
|
282
|
+
additionalProperties: false
|
|
283
|
+
}
|
|
284
|
+
},
|
|
285
|
+
{
|
|
286
|
+
name: "lighthouse_team_metrics_processBehaviorOverTime",
|
|
287
|
+
description: "Get the process-behaviour-limits-over-time trend for a team by ID: the upper limit, average and lower limit (UNPL/Average/LNPL) recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only, and days without a usable baseline are absent rather than zeroed \u2014 an empty series means nothing was recorded, never a process pinned at zero.",
|
|
288
|
+
inputSchema: {
|
|
289
|
+
type: "object",
|
|
290
|
+
properties: {
|
|
291
|
+
...idInputSchema.properties,
|
|
292
|
+
...dateRangeProperties,
|
|
293
|
+
...processBehaviorOverTimeProperties
|
|
294
|
+
},
|
|
295
|
+
required: ["id"],
|
|
296
|
+
additionalProperties: false
|
|
297
|
+
}
|
|
298
|
+
},
|
|
299
|
+
{
|
|
300
|
+
name: "lighthouse_portfolio_metrics_processBehaviorOverTime",
|
|
301
|
+
description: "Get the process-behaviour-limits-over-time trend for a portfolio by ID: the upper limit, average and lower limit (UNPL/Average/LNPL) recorded on each captured day, optionally filtered by start and end dates. Recording is forward-only, and days without a usable baseline are absent rather than zeroed \u2014 an empty series means nothing was recorded, never a process pinned at zero. FeatureSize is available here and not on teams.",
|
|
302
|
+
inputSchema: {
|
|
303
|
+
type: "object",
|
|
304
|
+
properties: {
|
|
305
|
+
...idInputSchema.properties,
|
|
306
|
+
...dateRangeProperties,
|
|
307
|
+
...processBehaviorOverTimeProperties
|
|
308
|
+
},
|
|
309
|
+
required: ["id"],
|
|
310
|
+
additionalProperties: false
|
|
311
|
+
}
|
|
312
|
+
},
|
|
229
313
|
{
|
|
230
314
|
name: "lighthouse_portfolio_metrics_throughput",
|
|
231
315
|
description: "Get throughput run-chart data for a portfolio by ID, optionally filtered by start and end dates.",
|
|
@@ -325,6 +409,23 @@ var toolDefinitions = [
|
|
|
325
409
|
description: "List deliveries for a portfolio by portfolio ID.",
|
|
326
410
|
inputSchema: idInputSchema
|
|
327
411
|
},
|
|
412
|
+
{
|
|
413
|
+
name: "lighthouse_delivery_metrics",
|
|
414
|
+
description: `Get a delivery's recorded trend by delivery ID: one row per day with total, done and remaining work, the epic count and the likelihood. Set detail to "epics" for the per-epic breakdown and the forecast distribution, which are far larger. Forward-only, so it starts at the first recorded snapshot. Requires Lighthouse newer than v26.5.29.5.`,
|
|
415
|
+
inputSchema: {
|
|
416
|
+
type: "object",
|
|
417
|
+
properties: {
|
|
418
|
+
id: { type: "number", description: "Delivery ID." },
|
|
419
|
+
detail: {
|
|
420
|
+
type: "string",
|
|
421
|
+
enum: ["epics"],
|
|
422
|
+
description: 'Omit for one row per day. "epics" returns the whole recorded payload.'
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
required: ["id"],
|
|
426
|
+
additionalProperties: false
|
|
427
|
+
}
|
|
428
|
+
},
|
|
328
429
|
{
|
|
329
430
|
name: "lighthouse_blackout_list",
|
|
330
431
|
description: "List the recurring blackout rules (recurring non-working days excluded from forecasts). Requires Lighthouse newer than v26.5.29.5.",
|
|
@@ -584,6 +685,30 @@ var getThroughputFilterView = (argumentsPayload) => {
|
|
|
584
685
|
const view = argumentsPayload.view;
|
|
585
686
|
return view === "raw" || view === "filtered" ? view : void 0;
|
|
586
687
|
};
|
|
688
|
+
var percentilesOverTimeMetricTypes = ["CycleTime", "WorkItemAge"];
|
|
689
|
+
var getPercentilesOverTimeMetricType = (argumentsPayload) => {
|
|
690
|
+
const raw = getStringArgument(argumentsPayload, "metricType");
|
|
691
|
+
return percentilesOverTimeMetricTypes.find((candidate) => candidate === raw);
|
|
692
|
+
};
|
|
693
|
+
var processBehaviorMetricTypes = [
|
|
694
|
+
"Throughput",
|
|
695
|
+
"WorkItemAge",
|
|
696
|
+
"Wip",
|
|
697
|
+
"CycleTime",
|
|
698
|
+
"Arrivals",
|
|
699
|
+
"FeatureSize"
|
|
700
|
+
];
|
|
701
|
+
var getProcessBehaviorMetricType = (argumentsPayload) => {
|
|
702
|
+
const raw = getStringArgument(argumentsPayload, "metricType");
|
|
703
|
+
return processBehaviorMetricTypes.find((candidate) => candidate === raw);
|
|
704
|
+
};
|
|
705
|
+
var getHorizonArgument = (argumentsPayload) => {
|
|
706
|
+
if (!isObjectRecord(argumentsPayload)) {
|
|
707
|
+
return void 0;
|
|
708
|
+
}
|
|
709
|
+
const horizon = argumentsPayload.horizon;
|
|
710
|
+
return typeof horizon === "number" && Number.isInteger(horizon) ? horizon : void 0;
|
|
711
|
+
};
|
|
587
712
|
var getApplyFilterOverride = (argumentsPayload) => {
|
|
588
713
|
if (!isObjectRecord(argumentsPayload)) {
|
|
589
714
|
return void 0;
|
|
@@ -651,6 +776,46 @@ var toolInputSchemas = {
|
|
|
651
776
|
startDate: isoDateStringSchema.optional(),
|
|
652
777
|
endDate: isoDateStringSchema.optional()
|
|
653
778
|
}),
|
|
779
|
+
lighthouse_team_metrics_percentilesOverTime: z.object({
|
|
780
|
+
id: z.number().int(),
|
|
781
|
+
startDate: isoDateStringSchema.optional(),
|
|
782
|
+
endDate: isoDateStringSchema.optional(),
|
|
783
|
+
metricType: z.enum(["CycleTime", "WorkItemAge"]).optional(),
|
|
784
|
+
horizon: z.number().int().optional()
|
|
785
|
+
}),
|
|
786
|
+
lighthouse_portfolio_metrics_percentilesOverTime: z.object({
|
|
787
|
+
id: z.number().int(),
|
|
788
|
+
startDate: isoDateStringSchema.optional(),
|
|
789
|
+
endDate: isoDateStringSchema.optional(),
|
|
790
|
+
metricType: z.enum(["CycleTime", "WorkItemAge"]).optional(),
|
|
791
|
+
horizon: z.number().int().optional()
|
|
792
|
+
}),
|
|
793
|
+
lighthouse_team_metrics_processBehaviorOverTime: z.object({
|
|
794
|
+
id: z.number().int(),
|
|
795
|
+
startDate: isoDateStringSchema.optional(),
|
|
796
|
+
endDate: isoDateStringSchema.optional(),
|
|
797
|
+
metricType: z.enum([
|
|
798
|
+
"Throughput",
|
|
799
|
+
"WorkItemAge",
|
|
800
|
+
"Wip",
|
|
801
|
+
"CycleTime",
|
|
802
|
+
"Arrivals",
|
|
803
|
+
"FeatureSize"
|
|
804
|
+
]).optional()
|
|
805
|
+
}),
|
|
806
|
+
lighthouse_portfolio_metrics_processBehaviorOverTime: z.object({
|
|
807
|
+
id: z.number().int(),
|
|
808
|
+
startDate: isoDateStringSchema.optional(),
|
|
809
|
+
endDate: isoDateStringSchema.optional(),
|
|
810
|
+
metricType: z.enum([
|
|
811
|
+
"Throughput",
|
|
812
|
+
"WorkItemAge",
|
|
813
|
+
"Wip",
|
|
814
|
+
"CycleTime",
|
|
815
|
+
"Arrivals",
|
|
816
|
+
"FeatureSize"
|
|
817
|
+
]).optional()
|
|
818
|
+
}),
|
|
654
819
|
lighthouse_team_metrics_workItemAge: z.object({
|
|
655
820
|
id: z.number().int(),
|
|
656
821
|
startDate: isoDateStringSchema.optional(),
|
|
@@ -718,6 +883,10 @@ var toolInputSchemas = {
|
|
|
718
883
|
}),
|
|
719
884
|
lighthouse_feature_workitems: z.object({ id: z.number().int() }),
|
|
720
885
|
lighthouse_delivery_list: z.object({ id: z.number().int() }),
|
|
886
|
+
lighthouse_delivery_metrics: z.object({
|
|
887
|
+
id: z.number().int(),
|
|
888
|
+
detail: z.literal("epics").optional()
|
|
889
|
+
}),
|
|
721
890
|
lighthouse_blackout_list: z.object({}),
|
|
722
891
|
lighthouse_blackout_create: recurringBlackoutRuleInputSchema,
|
|
723
892
|
lighthouse_blackout_update: recurringBlackoutRuleInputSchema.extend({
|
|
@@ -965,6 +1134,88 @@ var createMcpCoreRuntime = (dependencies) => ({
|
|
|
965
1134
|
`portfolio metrics: ${result.error.category} (${result.error.reason})`
|
|
966
1135
|
);
|
|
967
1136
|
}
|
|
1137
|
+
if (name === "lighthouse_team_metrics_percentilesOverTime") {
|
|
1138
|
+
const id = getNumericId(argumentsPayload);
|
|
1139
|
+
if (id === null) {
|
|
1140
|
+
return getErrorToolResult("team metrics: invalid id");
|
|
1141
|
+
}
|
|
1142
|
+
const range = getDateRange(argumentsPayload);
|
|
1143
|
+
const result = await client.getTeamPercentilesOverTime(
|
|
1144
|
+
id,
|
|
1145
|
+
range,
|
|
1146
|
+
getPercentilesOverTimeMetricType(argumentsPayload),
|
|
1147
|
+
getHorizonArgument(argumentsPayload)
|
|
1148
|
+
);
|
|
1149
|
+
if (result.ok) {
|
|
1150
|
+
return getSuccessToolResult(
|
|
1151
|
+
`team percentilesOverTime: ${encodePayload(result.value)}`
|
|
1152
|
+
);
|
|
1153
|
+
}
|
|
1154
|
+
return getErrorToolResult(
|
|
1155
|
+
`team metrics: ${result.error.category} (${result.error.reason})`
|
|
1156
|
+
);
|
|
1157
|
+
}
|
|
1158
|
+
if (name === "lighthouse_portfolio_metrics_percentilesOverTime") {
|
|
1159
|
+
const id = getNumericId(argumentsPayload);
|
|
1160
|
+
if (id === null) {
|
|
1161
|
+
return getErrorToolResult("portfolio metrics: invalid id");
|
|
1162
|
+
}
|
|
1163
|
+
const range = getDateRange(argumentsPayload);
|
|
1164
|
+
const result = await client.getPortfolioPercentilesOverTime(
|
|
1165
|
+
id,
|
|
1166
|
+
range,
|
|
1167
|
+
getPercentilesOverTimeMetricType(argumentsPayload),
|
|
1168
|
+
getHorizonArgument(argumentsPayload)
|
|
1169
|
+
);
|
|
1170
|
+
if (result.ok) {
|
|
1171
|
+
return getSuccessToolResult(
|
|
1172
|
+
`portfolio percentilesOverTime: ${encodePayload(result.value)}`
|
|
1173
|
+
);
|
|
1174
|
+
}
|
|
1175
|
+
return getErrorToolResult(
|
|
1176
|
+
`portfolio metrics: ${result.error.category} (${result.error.reason})`
|
|
1177
|
+
);
|
|
1178
|
+
}
|
|
1179
|
+
if (name === "lighthouse_team_metrics_processBehaviorOverTime") {
|
|
1180
|
+
const id = getNumericId(argumentsPayload);
|
|
1181
|
+
if (id === null) {
|
|
1182
|
+
return getErrorToolResult("team metrics: invalid id");
|
|
1183
|
+
}
|
|
1184
|
+
const range = getDateRange(argumentsPayload);
|
|
1185
|
+
const result = await client.getTeamProcessBehaviorOverTime(
|
|
1186
|
+
id,
|
|
1187
|
+
range,
|
|
1188
|
+
getProcessBehaviorMetricType(argumentsPayload)
|
|
1189
|
+
);
|
|
1190
|
+
if (result.ok) {
|
|
1191
|
+
return getSuccessToolResult(
|
|
1192
|
+
`team processBehaviorOverTime: ${encodePayload(result.value)}`
|
|
1193
|
+
);
|
|
1194
|
+
}
|
|
1195
|
+
return getErrorToolResult(
|
|
1196
|
+
`team metrics: ${result.error.category} (${result.error.reason})`
|
|
1197
|
+
);
|
|
1198
|
+
}
|
|
1199
|
+
if (name === "lighthouse_portfolio_metrics_processBehaviorOverTime") {
|
|
1200
|
+
const id = getNumericId(argumentsPayload);
|
|
1201
|
+
if (id === null) {
|
|
1202
|
+
return getErrorToolResult("portfolio metrics: invalid id");
|
|
1203
|
+
}
|
|
1204
|
+
const range = getDateRange(argumentsPayload);
|
|
1205
|
+
const result = await client.getPortfolioProcessBehaviorOverTime(
|
|
1206
|
+
id,
|
|
1207
|
+
range,
|
|
1208
|
+
getProcessBehaviorMetricType(argumentsPayload)
|
|
1209
|
+
);
|
|
1210
|
+
if (result.ok) {
|
|
1211
|
+
return getSuccessToolResult(
|
|
1212
|
+
`portfolio processBehaviorOverTime: ${encodePayload(result.value)}`
|
|
1213
|
+
);
|
|
1214
|
+
}
|
|
1215
|
+
return getErrorToolResult(
|
|
1216
|
+
`portfolio metrics: ${result.error.category} (${result.error.reason})`
|
|
1217
|
+
);
|
|
1218
|
+
}
|
|
968
1219
|
if (name === "lighthouse_team_metrics_cumulativeStateTime") {
|
|
969
1220
|
const id = getNumericId(argumentsPayload);
|
|
970
1221
|
if (id === null) {
|
|
@@ -1236,6 +1487,25 @@ var createMcpCoreRuntime = (dependencies) => ({
|
|
|
1236
1487
|
`delivery: ${result.error.category} (${result.error.reason})`
|
|
1237
1488
|
);
|
|
1238
1489
|
}
|
|
1490
|
+
if (name === "lighthouse_delivery_metrics") {
|
|
1491
|
+
const id = getNumericId(argumentsPayload);
|
|
1492
|
+
if (id === null) {
|
|
1493
|
+
return getErrorToolResult(
|
|
1494
|
+
"delivery metrics: invalid id (delivery id required)"
|
|
1495
|
+
);
|
|
1496
|
+
}
|
|
1497
|
+
const wantsEpics = argumentsPayload?.detail === "epics";
|
|
1498
|
+
const result = await client.getDeliveryMetricsHistory(id);
|
|
1499
|
+
if (!result.ok) {
|
|
1500
|
+
return getErrorToolResult(
|
|
1501
|
+
`delivery metrics: ${result.error.category} (${result.error.reason})`
|
|
1502
|
+
);
|
|
1503
|
+
}
|
|
1504
|
+
const payload = wantsEpics ? result.value : summariseDeliveryMetricsHistory(result.value);
|
|
1505
|
+
return getSuccessToolResult(
|
|
1506
|
+
`delivery metrics: ${encodePayload(payload)}`
|
|
1507
|
+
);
|
|
1508
|
+
}
|
|
1239
1509
|
if (name === "lighthouse_blackout_list") {
|
|
1240
1510
|
const result = await client.getRecurringBlackoutRules();
|
|
1241
1511
|
if (result.ok) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@letpeoplework/lighthouse-mcp-core",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "Shared MCP semantics for Lighthouse",
|
|
5
5
|
"repository": "https://github.com/LetPeopleWork/lighthouse-clients",
|
|
6
6
|
"type": "module",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"@modelcontextprotocol/sdk": "^1.26.0",
|
|
27
27
|
"@toon-format/toon": "^2.1.0",
|
|
28
28
|
"zod": "^3.24.1",
|
|
29
|
-
"@letpeoplework/lighthouse-client": "1.
|
|
29
|
+
"@letpeoplework/lighthouse-client": "1.8.0"
|
|
30
30
|
},
|
|
31
31
|
"scripts": {
|
|
32
32
|
"build": "tsup src/index.ts --format esm,cjs --dts --clean",
|