@letpeoplework/lighthouse-mcp-core 0.6.0 → 1.0.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 CHANGED
@@ -60,57 +60,57 @@ var dateRangeProperties = {
60
60
  };
61
61
  var toolDefinitions = [
62
62
  {
63
- name: "lighthouse.health.check",
63
+ name: "lighthouse_health_check",
64
64
  description: "Check connectivity to Lighthouse and return whether the configured endpoint is reachable.",
65
65
  inputSchema: emptyInputSchema
66
66
  },
67
67
  {
68
- name: "lighthouse.version.get",
68
+ name: "lighthouse_version_get",
69
69
  description: "Retrieve the Lighthouse server version from the version endpoint.",
70
70
  inputSchema: emptyInputSchema
71
71
  },
72
72
  {
73
- name: "lighthouse.worktracking.list",
73
+ name: "lighthouse_worktracking_list",
74
74
  description: "List configured work-tracking system connections in Lighthouse.",
75
75
  inputSchema: emptyInputSchema
76
76
  },
77
77
  {
78
- name: "lighthouse.worktracking.get",
78
+ name: "lighthouse_worktracking_get",
79
79
  description: "Get a single work-tracking system connection by ID.",
80
80
  inputSchema: idInputSchema
81
81
  },
82
82
  {
83
- name: "lighthouse.team.list",
83
+ name: "lighthouse_team_list",
84
84
  description: "List all teams available in Lighthouse.",
85
85
  inputSchema: emptyInputSchema
86
86
  },
87
87
  {
88
- name: "lighthouse.team.get",
88
+ name: "lighthouse_team_get",
89
89
  description: "Get full details for one team by ID.",
90
90
  inputSchema: idInputSchema
91
91
  },
92
92
  {
93
- name: "lighthouse.team.refresh",
93
+ name: "lighthouse_team_refresh",
94
94
  description: "Trigger data refresh for a team by ID.",
95
95
  inputSchema: idInputSchema
96
96
  },
97
97
  {
98
- name: "lighthouse.portfolio.list",
98
+ name: "lighthouse_portfolio_list",
99
99
  description: "List all portfolios in Lighthouse.",
100
100
  inputSchema: emptyInputSchema
101
101
  },
102
102
  {
103
- name: "lighthouse.portfolio.get",
103
+ name: "lighthouse_portfolio_get",
104
104
  description: "Get full details for one portfolio by ID.",
105
105
  inputSchema: idInputSchema
106
106
  },
107
107
  {
108
- name: "lighthouse.portfolio.refresh",
108
+ name: "lighthouse_portfolio_refresh",
109
109
  description: "Trigger data refresh for a portfolio by ID.",
110
110
  inputSchema: idInputSchema
111
111
  },
112
112
  {
113
- name: "lighthouse.team.metrics.throughput",
113
+ name: "lighthouse_team_metrics_throughput",
114
114
  description: "Get throughput run-chart data for a team by ID, optionally filtered by start and end dates.",
115
115
  inputSchema: {
116
116
  type: "object",
@@ -123,7 +123,7 @@ var toolDefinitions = [
123
123
  }
124
124
  },
125
125
  {
126
- name: "lighthouse.team.metrics.cycleTimePercentiles",
126
+ name: "lighthouse_team_metrics_cycleTimePercentiles",
127
127
  description: "Get cycle-time percentiles for a team by ID, optionally filtered by start and end dates.",
128
128
  inputSchema: {
129
129
  type: "object",
@@ -136,7 +136,7 @@ var toolDefinitions = [
136
136
  }
137
137
  },
138
138
  {
139
- name: "lighthouse.portfolio.metrics.throughput",
139
+ name: "lighthouse_portfolio_metrics_throughput",
140
140
  description: "Get throughput run-chart data for a portfolio by ID, optionally filtered by start and end dates.",
141
141
  inputSchema: {
142
142
  type: "object",
@@ -149,7 +149,59 @@ var toolDefinitions = [
149
149
  }
150
150
  },
151
151
  {
152
- name: "lighthouse.feature.get",
152
+ name: "lighthouse_team_metrics_workItemAge",
153
+ description: "Get per-item work item age over time for a team by ID. Returns daily snapshots with each in-progress item's age in days derived from its startedDate. Items without a startedDate are omitted.",
154
+ inputSchema: {
155
+ type: "object",
156
+ properties: {
157
+ ...idInputSchema.properties,
158
+ ...dateRangeProperties
159
+ },
160
+ required: ["id"],
161
+ additionalProperties: false
162
+ }
163
+ },
164
+ {
165
+ name: "lighthouse_team_metrics_totalWorkItemAge",
166
+ description: "Get the total (summed) work item age over time for a team by ID. Returns daily totals of all in-progress item ages derived from startedDate. Items without a startedDate are not counted.",
167
+ inputSchema: {
168
+ type: "object",
169
+ properties: {
170
+ ...idInputSchema.properties,
171
+ ...dateRangeProperties
172
+ },
173
+ required: ["id"],
174
+ additionalProperties: false
175
+ }
176
+ },
177
+ {
178
+ name: "lighthouse_portfolio_metrics_workItemAge",
179
+ description: "Get per-item work item age over time for a portfolio by ID. Returns daily snapshots with each in-progress item's age in days derived from its startedDate. Items without a startedDate are omitted.",
180
+ inputSchema: {
181
+ type: "object",
182
+ properties: {
183
+ ...idInputSchema.properties,
184
+ ...dateRangeProperties
185
+ },
186
+ required: ["id"],
187
+ additionalProperties: false
188
+ }
189
+ },
190
+ {
191
+ name: "lighthouse_portfolio_metrics_totalWorkItemAge",
192
+ description: "Get the total (summed) work item age over time for a portfolio by ID. Returns daily totals of all in-progress item ages derived from startedDate. Items without a startedDate are not counted.",
193
+ inputSchema: {
194
+ type: "object",
195
+ properties: {
196
+ ...idInputSchema.properties,
197
+ ...dateRangeProperties
198
+ },
199
+ required: ["id"],
200
+ additionalProperties: false
201
+ }
202
+ },
203
+ {
204
+ name: "lighthouse_feature_get",
153
205
  description: "Get feature details by numeric IDs or external reference IDs.",
154
206
  inputSchema: {
155
207
  type: "object",
@@ -173,17 +225,17 @@ var toolDefinitions = [
173
225
  }
174
226
  },
175
227
  {
176
- name: "lighthouse.feature.workitems",
228
+ name: "lighthouse_feature_workitems",
177
229
  description: "Get work items linked to a feature by ID.",
178
230
  inputSchema: idInputSchema
179
231
  },
180
232
  {
181
- name: "lighthouse.delivery.list",
233
+ name: "lighthouse_delivery_list",
182
234
  description: "List deliveries for a portfolio by portfolio ID.",
183
235
  inputSchema: idInputSchema
184
236
  },
185
237
  {
186
- name: "lighthouse.forecast.manual",
238
+ name: "lighthouse_forecast_manual",
187
239
  description: "Run a manual forecast for a team by ID with optional remaining items and target date.",
188
240
  inputSchema: {
189
241
  type: "object",
@@ -203,7 +255,7 @@ var toolDefinitions = [
203
255
  }
204
256
  },
205
257
  {
206
- name: "lighthouse.forecast.backtest",
258
+ name: "lighthouse_forecast_backtest",
207
259
  description: "Run a forecast backtest for a team by ID using forecast and historical date ranges.",
208
260
  inputSchema: {
209
261
  type: "object",
@@ -288,43 +340,63 @@ var getDateRange = (argumentsPayload) => {
288
340
  };
289
341
  var isoDateStringSchema = import_zod.z.string().regex(/^\d{4}-\d{2}-\d{2}$/u, "Expected ISO date in YYYY-MM-DD format.");
290
342
  var toolInputSchemas = {
291
- "lighthouse.health.check": import_zod.z.object({}),
292
- "lighthouse.version.get": import_zod.z.object({}),
293
- "lighthouse.worktracking.list": import_zod.z.object({}),
294
- "lighthouse.worktracking.get": import_zod.z.object({ id: import_zod.z.number().int() }),
295
- "lighthouse.team.list": import_zod.z.object({}),
296
- "lighthouse.team.get": import_zod.z.object({ id: import_zod.z.number().int() }),
297
- "lighthouse.team.refresh": import_zod.z.object({ id: import_zod.z.number().int() }),
298
- "lighthouse.portfolio.list": import_zod.z.object({}),
299
- "lighthouse.portfolio.get": import_zod.z.object({ id: import_zod.z.number().int() }),
300
- "lighthouse.portfolio.refresh": import_zod.z.object({ id: import_zod.z.number().int() }),
301
- "lighthouse.team.metrics.throughput": import_zod.z.object({
343
+ lighthouse_health_check: import_zod.z.object({}),
344
+ lighthouse_version_get: import_zod.z.object({}),
345
+ lighthouse_worktracking_list: import_zod.z.object({}),
346
+ lighthouse_worktracking_get: import_zod.z.object({ id: import_zod.z.number().int() }),
347
+ lighthouse_team_list: import_zod.z.object({}),
348
+ lighthouse_team_get: import_zod.z.object({ id: import_zod.z.number().int() }),
349
+ lighthouse_team_refresh: import_zod.z.object({ id: import_zod.z.number().int() }),
350
+ lighthouse_portfolio_list: import_zod.z.object({}),
351
+ lighthouse_portfolio_get: import_zod.z.object({ id: import_zod.z.number().int() }),
352
+ lighthouse_portfolio_refresh: import_zod.z.object({ id: import_zod.z.number().int() }),
353
+ lighthouse_team_metrics_throughput: import_zod.z.object({
354
+ id: import_zod.z.number().int(),
355
+ startDate: isoDateStringSchema.optional(),
356
+ endDate: isoDateStringSchema.optional()
357
+ }),
358
+ lighthouse_team_metrics_cycleTimePercentiles: import_zod.z.object({
359
+ id: import_zod.z.number().int(),
360
+ startDate: isoDateStringSchema.optional(),
361
+ endDate: isoDateStringSchema.optional()
362
+ }),
363
+ lighthouse_team_metrics_workItemAge: import_zod.z.object({
302
364
  id: import_zod.z.number().int(),
303
365
  startDate: isoDateStringSchema.optional(),
304
366
  endDate: isoDateStringSchema.optional()
305
367
  }),
306
- "lighthouse.team.metrics.cycleTimePercentiles": import_zod.z.object({
368
+ lighthouse_team_metrics_totalWorkItemAge: import_zod.z.object({
307
369
  id: import_zod.z.number().int(),
308
370
  startDate: isoDateStringSchema.optional(),
309
371
  endDate: isoDateStringSchema.optional()
310
372
  }),
311
- "lighthouse.portfolio.metrics.throughput": import_zod.z.object({
373
+ lighthouse_portfolio_metrics_throughput: import_zod.z.object({
312
374
  id: import_zod.z.number().int(),
313
375
  startDate: isoDateStringSchema.optional(),
314
376
  endDate: isoDateStringSchema.optional()
315
377
  }),
316
- "lighthouse.feature.get": import_zod.z.object({
378
+ lighthouse_portfolio_metrics_workItemAge: import_zod.z.object({
379
+ id: import_zod.z.number().int(),
380
+ startDate: isoDateStringSchema.optional(),
381
+ endDate: isoDateStringSchema.optional()
382
+ }),
383
+ lighthouse_portfolio_metrics_totalWorkItemAge: import_zod.z.object({
384
+ id: import_zod.z.number().int(),
385
+ startDate: isoDateStringSchema.optional(),
386
+ endDate: isoDateStringSchema.optional()
387
+ }),
388
+ lighthouse_feature_get: import_zod.z.object({
317
389
  ids: import_zod.z.array(import_zod.z.number().int()).optional(),
318
390
  refs: import_zod.z.array(import_zod.z.string()).optional()
319
391
  }),
320
- "lighthouse.feature.workitems": import_zod.z.object({ id: import_zod.z.number().int() }),
321
- "lighthouse.delivery.list": import_zod.z.object({ id: import_zod.z.number().int() }),
322
- "lighthouse.forecast.manual": import_zod.z.object({
392
+ lighthouse_feature_workitems: import_zod.z.object({ id: import_zod.z.number().int() }),
393
+ lighthouse_delivery_list: import_zod.z.object({ id: import_zod.z.number().int() }),
394
+ lighthouse_forecast_manual: import_zod.z.object({
323
395
  id: import_zod.z.number().int(),
324
396
  remainingItems: import_zod.z.number().int().optional(),
325
397
  targetDate: isoDateStringSchema.optional()
326
398
  }),
327
- "lighthouse.forecast.backtest": import_zod.z.object({
399
+ lighthouse_forecast_backtest: import_zod.z.object({
328
400
  id: import_zod.z.number().int(),
329
401
  startDate: isoDateStringSchema,
330
402
  endDate: isoDateStringSchema,
@@ -332,12 +404,12 @@ var toolInputSchemas = {
332
404
  historicalEndDate: isoDateStringSchema
333
405
  })
334
406
  };
335
- var isReadOnlyTool = (toolName) => !toolName.endsWith(".refresh");
407
+ var isReadOnlyTool = (toolName) => !toolName.endsWith("_refresh");
336
408
  var createMcpCoreRuntime = (dependencies) => ({
337
409
  listTools: () => toolDefinitions,
338
410
  callTool: async (name, argumentsPayload) => {
339
411
  const client = dependencies.createClient();
340
- if (name === "lighthouse.health.check") {
412
+ if (name === "lighthouse_health_check") {
341
413
  const health = await client.checkConnectivity();
342
414
  if (health.category === "success") {
343
415
  return getSuccessToolResult("connectivity: success");
@@ -347,7 +419,7 @@ var createMcpCoreRuntime = (dependencies) => ({
347
419
  `connectivity: ${health.category}${healthReasonSuffix}`
348
420
  );
349
421
  }
350
- if (name === "lighthouse.version.get") {
422
+ if (name === "lighthouse_version_get") {
351
423
  const version = await client.getVersion();
352
424
  if (version.ok) {
353
425
  return getSuccessToolResult(`version: ${version.value}`);
@@ -356,7 +428,7 @@ var createMcpCoreRuntime = (dependencies) => ({
356
428
  `version: ${version.error.category} (${version.error.reason})`
357
429
  );
358
430
  }
359
- if (name === "lighthouse.worktracking.list") {
431
+ if (name === "lighthouse_worktracking_list") {
360
432
  const connections = await client.listWorkTrackingConnections();
361
433
  if (connections.ok) {
362
434
  return getSuccessToolResult(
@@ -367,7 +439,7 @@ var createMcpCoreRuntime = (dependencies) => ({
367
439
  `worktracking: ${connections.error.category} (${connections.error.reason})`
368
440
  );
369
441
  }
370
- if (name === "lighthouse.worktracking.get") {
442
+ if (name === "lighthouse_worktracking_get") {
371
443
  const id = getNumericId(argumentsPayload);
372
444
  if (id === null) {
373
445
  return getErrorToolResult("worktracking: invalid id");
@@ -382,7 +454,7 @@ var createMcpCoreRuntime = (dependencies) => ({
382
454
  `worktracking: ${connection.error.category} (${connection.error.reason})`
383
455
  );
384
456
  }
385
- if (name === "lighthouse.team.list") {
457
+ if (name === "lighthouse_team_list") {
386
458
  const teams = await client.listTeams();
387
459
  if (teams.ok) {
388
460
  return getSuccessToolResult(`teams: ${encodePayload(teams.value)}`);
@@ -391,7 +463,7 @@ var createMcpCoreRuntime = (dependencies) => ({
391
463
  `teams: ${teams.error.category} (${teams.error.reason})`
392
464
  );
393
465
  }
394
- if (name === "lighthouse.team.get") {
466
+ if (name === "lighthouse_team_get") {
395
467
  const id = getNumericId(argumentsPayload);
396
468
  if (id === null) {
397
469
  return getErrorToolResult("team: invalid id");
@@ -404,7 +476,7 @@ var createMcpCoreRuntime = (dependencies) => ({
404
476
  `team: ${team.error.category} (${team.error.reason})`
405
477
  );
406
478
  }
407
- if (name === "lighthouse.team.refresh") {
479
+ if (name === "lighthouse_team_refresh") {
408
480
  const id = getNumericId(argumentsPayload);
409
481
  if (id === null) {
410
482
  return getErrorToolResult("team: invalid id");
@@ -417,7 +489,7 @@ var createMcpCoreRuntime = (dependencies) => ({
417
489
  `team refresh: ${result.error.category} (${result.error.reason})`
418
490
  );
419
491
  }
420
- if (name === "lighthouse.portfolio.list") {
492
+ if (name === "lighthouse_portfolio_list") {
421
493
  const portfolios = await client.listPortfolios();
422
494
  if (portfolios.ok) {
423
495
  return getSuccessToolResult(
@@ -428,7 +500,7 @@ var createMcpCoreRuntime = (dependencies) => ({
428
500
  `portfolios: ${portfolios.error.category} (${portfolios.error.reason})`
429
501
  );
430
502
  }
431
- if (name === "lighthouse.portfolio.get") {
503
+ if (name === "lighthouse_portfolio_get") {
432
504
  const id = getNumericId(argumentsPayload);
433
505
  if (id === null) {
434
506
  return getErrorToolResult("portfolio: invalid id");
@@ -443,7 +515,7 @@ var createMcpCoreRuntime = (dependencies) => ({
443
515
  `portfolio: ${portfolio.error.category} (${portfolio.error.reason})`
444
516
  );
445
517
  }
446
- if (name === "lighthouse.portfolio.refresh") {
518
+ if (name === "lighthouse_portfolio_refresh") {
447
519
  const id = getNumericId(argumentsPayload);
448
520
  if (id === null) {
449
521
  return getErrorToolResult("portfolio: invalid id");
@@ -456,7 +528,7 @@ var createMcpCoreRuntime = (dependencies) => ({
456
528
  `portfolio refresh: ${result.error.category} (${result.error.reason})`
457
529
  );
458
530
  }
459
- if (name === "lighthouse.team.metrics.throughput") {
531
+ if (name === "lighthouse_team_metrics_throughput") {
460
532
  const id = getNumericId(argumentsPayload);
461
533
  if (id === null) {
462
534
  return getErrorToolResult("team metrics: invalid id");
@@ -472,7 +544,7 @@ var createMcpCoreRuntime = (dependencies) => ({
472
544
  `team metrics: ${result.error.category} (${result.error.reason})`
473
545
  );
474
546
  }
475
- if (name === "lighthouse.team.metrics.cycleTimePercentiles") {
547
+ if (name === "lighthouse_team_metrics_cycleTimePercentiles") {
476
548
  const id = getNumericId(argumentsPayload);
477
549
  if (id === null) {
478
550
  return getErrorToolResult("team metrics: invalid id");
@@ -488,7 +560,7 @@ var createMcpCoreRuntime = (dependencies) => ({
488
560
  `team metrics: ${result.error.category} (${result.error.reason})`
489
561
  );
490
562
  }
491
- if (name === "lighthouse.portfolio.metrics.throughput") {
563
+ if (name === "lighthouse_portfolio_metrics_throughput") {
492
564
  const id = getNumericId(argumentsPayload);
493
565
  if (id === null) {
494
566
  return getErrorToolResult("portfolio metrics: invalid id");
@@ -504,7 +576,74 @@ var createMcpCoreRuntime = (dependencies) => ({
504
576
  `portfolio metrics: ${result.error.category} (${result.error.reason})`
505
577
  );
506
578
  }
507
- if (name === "lighthouse.feature.get") {
579
+ if (name === "lighthouse_team_metrics_workItemAge") {
580
+ const id = getNumericId(argumentsPayload);
581
+ if (id === null) {
582
+ return getErrorToolResult("team metrics: invalid id");
583
+ }
584
+ const range = getDateRange(argumentsPayload);
585
+ const result = await client.getTeamWorkItemAgeOverTime(id, range);
586
+ if (result.ok) {
587
+ return getSuccessToolResult(
588
+ `team workItemAge: ${encodePayload(result.value)}`
589
+ );
590
+ }
591
+ return getErrorToolResult(
592
+ `team metrics: ${result.error.category} (${result.error.reason})`
593
+ );
594
+ }
595
+ if (name === "lighthouse_team_metrics_totalWorkItemAge") {
596
+ const id = getNumericId(argumentsPayload);
597
+ if (id === null) {
598
+ return getErrorToolResult("team metrics: invalid id");
599
+ }
600
+ const range = getDateRange(argumentsPayload);
601
+ const result = await client.getTeamTotalWorkItemAgeOverTime(id, range);
602
+ if (result.ok) {
603
+ return getSuccessToolResult(
604
+ `team totalWorkItemAge: ${encodePayload(result.value)}`
605
+ );
606
+ }
607
+ return getErrorToolResult(
608
+ `team metrics: ${result.error.category} (${result.error.reason})`
609
+ );
610
+ }
611
+ if (name === "lighthouse_portfolio_metrics_workItemAge") {
612
+ const id = getNumericId(argumentsPayload);
613
+ if (id === null) {
614
+ return getErrorToolResult("portfolio metrics: invalid id");
615
+ }
616
+ const range = getDateRange(argumentsPayload);
617
+ const result = await client.getPortfolioWorkItemAgeOverTime(id, range);
618
+ if (result.ok) {
619
+ return getSuccessToolResult(
620
+ `portfolio workItemAge: ${encodePayload(result.value)}`
621
+ );
622
+ }
623
+ return getErrorToolResult(
624
+ `portfolio metrics: ${result.error.category} (${result.error.reason})`
625
+ );
626
+ }
627
+ if (name === "lighthouse_portfolio_metrics_totalWorkItemAge") {
628
+ const id = getNumericId(argumentsPayload);
629
+ if (id === null) {
630
+ return getErrorToolResult("portfolio metrics: invalid id");
631
+ }
632
+ const range = getDateRange(argumentsPayload);
633
+ const result = await client.getPortfolioTotalWorkItemAgeOverTime(
634
+ id,
635
+ range
636
+ );
637
+ if (result.ok) {
638
+ return getSuccessToolResult(
639
+ `portfolio totalWorkItemAge: ${encodePayload(result.value)}`
640
+ );
641
+ }
642
+ return getErrorToolResult(
643
+ `portfolio metrics: ${result.error.category} (${result.error.reason})`
644
+ );
645
+ }
646
+ if (name === "lighthouse_feature_get") {
508
647
  const payload = isObjectRecord(argumentsPayload) ? argumentsPayload : {};
509
648
  const idsValue = payload.ids;
510
649
  const refsValue = payload.refs;
@@ -538,7 +677,7 @@ var createMcpCoreRuntime = (dependencies) => ({
538
677
  "features: provide ids (array of numbers) or refs (array of strings)"
539
678
  );
540
679
  }
541
- if (name === "lighthouse.feature.workitems") {
680
+ if (name === "lighthouse_feature_workitems") {
542
681
  const id = getNumericId(argumentsPayload);
543
682
  if (id === null) {
544
683
  return getErrorToolResult("feature workitems: invalid id");
@@ -553,7 +692,7 @@ var createMcpCoreRuntime = (dependencies) => ({
553
692
  `feature workitems: ${result.error.category} (${result.error.reason})`
554
693
  );
555
694
  }
556
- if (name === "lighthouse.delivery.list") {
695
+ if (name === "lighthouse_delivery_list") {
557
696
  const id = getNumericId(argumentsPayload);
558
697
  if (id === null) {
559
698
  return getErrorToolResult(
@@ -570,7 +709,7 @@ var createMcpCoreRuntime = (dependencies) => ({
570
709
  `delivery: ${result.error.category} (${result.error.reason})`
571
710
  );
572
711
  }
573
- if (name === "lighthouse.forecast.manual") {
712
+ if (name === "lighthouse_forecast_manual") {
574
713
  const id = getNumericId(argumentsPayload);
575
714
  if (id === null) {
576
715
  return getErrorToolResult("forecast: invalid id (team id required)");
@@ -589,7 +728,7 @@ var createMcpCoreRuntime = (dependencies) => ({
589
728
  `forecast: ${result.error.category} (${result.error.reason})`
590
729
  );
591
730
  }
592
- if (name === "lighthouse.forecast.backtest") {
731
+ if (name === "lighthouse_forecast_backtest") {
593
732
  const id = getNumericId(argumentsPayload);
594
733
  if (id === null) {
595
734
  return getErrorToolResult("backtest: invalid id (team id required)");
package/dist/index.d.cts CHANGED
@@ -15,7 +15,7 @@ type McpToolResult = {
15
15
  readonly content: readonly McpToolContent[];
16
16
  };
17
17
  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.portfolio.metrics.throughput" | "lighthouse.feature.get" | "lighthouse.feature.workitems" | "lighthouse.delivery.list" | "lighthouse.forecast.manual" | "lighthouse.forecast.backtest";
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_workItemAge" | "lighthouse_team_metrics_totalWorkItemAge" | "lighthouse_portfolio_metrics_throughput" | "lighthouse_portfolio_metrics_workItemAge" | "lighthouse_portfolio_metrics_totalWorkItemAge" | "lighthouse_feature_get" | "lighthouse_feature_workitems" | "lighthouse_delivery_list" | "lighthouse_forecast_manual" | "lighthouse_forecast_backtest";
19
19
  readonly description: string;
20
20
  readonly inputSchema: {
21
21
  readonly type: "object";
@@ -158,6 +158,58 @@ type McpRuntimeClient = {
158
158
  readonly reason: string;
159
159
  };
160
160
  }>;
161
+ readonly getTeamWorkItemAgeOverTime: (id: number, range?: {
162
+ readonly startDate: string;
163
+ readonly endDate: string;
164
+ }) => Promise<{
165
+ readonly ok: true;
166
+ readonly value: unknown;
167
+ } | {
168
+ readonly ok: false;
169
+ readonly error: {
170
+ readonly category: string;
171
+ readonly reason: string;
172
+ };
173
+ }>;
174
+ readonly getTeamTotalWorkItemAgeOverTime: (id: number, range?: {
175
+ readonly startDate: string;
176
+ readonly endDate: string;
177
+ }) => Promise<{
178
+ readonly ok: true;
179
+ readonly value: unknown;
180
+ } | {
181
+ readonly ok: false;
182
+ readonly error: {
183
+ readonly category: string;
184
+ readonly reason: string;
185
+ };
186
+ }>;
187
+ readonly getPortfolioWorkItemAgeOverTime: (id: number, range?: {
188
+ readonly startDate: string;
189
+ readonly endDate: string;
190
+ }) => Promise<{
191
+ readonly ok: true;
192
+ readonly value: unknown;
193
+ } | {
194
+ readonly ok: false;
195
+ readonly error: {
196
+ readonly category: string;
197
+ readonly reason: string;
198
+ };
199
+ }>;
200
+ readonly getPortfolioTotalWorkItemAgeOverTime: (id: number, range?: {
201
+ readonly startDate: string;
202
+ readonly endDate: string;
203
+ }) => Promise<{
204
+ readonly ok: true;
205
+ readonly value: unknown;
206
+ } | {
207
+ readonly ok: false;
208
+ readonly error: {
209
+ readonly category: string;
210
+ readonly reason: string;
211
+ };
212
+ }>;
161
213
  readonly getFeaturesByIds: (ids: readonly number[]) => Promise<{
162
214
  readonly ok: true;
163
215
  readonly value: readonly unknown[];
package/dist/index.d.ts CHANGED
@@ -15,7 +15,7 @@ type McpToolResult = {
15
15
  readonly content: readonly McpToolContent[];
16
16
  };
17
17
  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.portfolio.metrics.throughput" | "lighthouse.feature.get" | "lighthouse.feature.workitems" | "lighthouse.delivery.list" | "lighthouse.forecast.manual" | "lighthouse.forecast.backtest";
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_workItemAge" | "lighthouse_team_metrics_totalWorkItemAge" | "lighthouse_portfolio_metrics_throughput" | "lighthouse_portfolio_metrics_workItemAge" | "lighthouse_portfolio_metrics_totalWorkItemAge" | "lighthouse_feature_get" | "lighthouse_feature_workitems" | "lighthouse_delivery_list" | "lighthouse_forecast_manual" | "lighthouse_forecast_backtest";
19
19
  readonly description: string;
20
20
  readonly inputSchema: {
21
21
  readonly type: "object";
@@ -158,6 +158,58 @@ type McpRuntimeClient = {
158
158
  readonly reason: string;
159
159
  };
160
160
  }>;
161
+ readonly getTeamWorkItemAgeOverTime: (id: number, range?: {
162
+ readonly startDate: string;
163
+ readonly endDate: string;
164
+ }) => Promise<{
165
+ readonly ok: true;
166
+ readonly value: unknown;
167
+ } | {
168
+ readonly ok: false;
169
+ readonly error: {
170
+ readonly category: string;
171
+ readonly reason: string;
172
+ };
173
+ }>;
174
+ readonly getTeamTotalWorkItemAgeOverTime: (id: number, range?: {
175
+ readonly startDate: string;
176
+ readonly endDate: string;
177
+ }) => Promise<{
178
+ readonly ok: true;
179
+ readonly value: unknown;
180
+ } | {
181
+ readonly ok: false;
182
+ readonly error: {
183
+ readonly category: string;
184
+ readonly reason: string;
185
+ };
186
+ }>;
187
+ readonly getPortfolioWorkItemAgeOverTime: (id: number, range?: {
188
+ readonly startDate: string;
189
+ readonly endDate: string;
190
+ }) => Promise<{
191
+ readonly ok: true;
192
+ readonly value: unknown;
193
+ } | {
194
+ readonly ok: false;
195
+ readonly error: {
196
+ readonly category: string;
197
+ readonly reason: string;
198
+ };
199
+ }>;
200
+ readonly getPortfolioTotalWorkItemAgeOverTime: (id: number, range?: {
201
+ readonly startDate: string;
202
+ readonly endDate: string;
203
+ }) => Promise<{
204
+ readonly ok: true;
205
+ readonly value: unknown;
206
+ } | {
207
+ readonly ok: false;
208
+ readonly error: {
209
+ readonly category: string;
210
+ readonly reason: string;
211
+ };
212
+ }>;
161
213
  readonly getFeaturesByIds: (ids: readonly number[]) => Promise<{
162
214
  readonly ok: true;
163
215
  readonly value: readonly unknown[];
package/dist/index.js CHANGED
@@ -34,57 +34,57 @@ var dateRangeProperties = {
34
34
  };
35
35
  var toolDefinitions = [
36
36
  {
37
- name: "lighthouse.health.check",
37
+ name: "lighthouse_health_check",
38
38
  description: "Check connectivity to Lighthouse and return whether the configured endpoint is reachable.",
39
39
  inputSchema: emptyInputSchema
40
40
  },
41
41
  {
42
- name: "lighthouse.version.get",
42
+ name: "lighthouse_version_get",
43
43
  description: "Retrieve the Lighthouse server version from the version endpoint.",
44
44
  inputSchema: emptyInputSchema
45
45
  },
46
46
  {
47
- name: "lighthouse.worktracking.list",
47
+ name: "lighthouse_worktracking_list",
48
48
  description: "List configured work-tracking system connections in Lighthouse.",
49
49
  inputSchema: emptyInputSchema
50
50
  },
51
51
  {
52
- name: "lighthouse.worktracking.get",
52
+ name: "lighthouse_worktracking_get",
53
53
  description: "Get a single work-tracking system connection by ID.",
54
54
  inputSchema: idInputSchema
55
55
  },
56
56
  {
57
- name: "lighthouse.team.list",
57
+ name: "lighthouse_team_list",
58
58
  description: "List all teams available in Lighthouse.",
59
59
  inputSchema: emptyInputSchema
60
60
  },
61
61
  {
62
- name: "lighthouse.team.get",
62
+ name: "lighthouse_team_get",
63
63
  description: "Get full details for one team by ID.",
64
64
  inputSchema: idInputSchema
65
65
  },
66
66
  {
67
- name: "lighthouse.team.refresh",
67
+ name: "lighthouse_team_refresh",
68
68
  description: "Trigger data refresh for a team by ID.",
69
69
  inputSchema: idInputSchema
70
70
  },
71
71
  {
72
- name: "lighthouse.portfolio.list",
72
+ name: "lighthouse_portfolio_list",
73
73
  description: "List all portfolios in Lighthouse.",
74
74
  inputSchema: emptyInputSchema
75
75
  },
76
76
  {
77
- name: "lighthouse.portfolio.get",
77
+ name: "lighthouse_portfolio_get",
78
78
  description: "Get full details for one portfolio by ID.",
79
79
  inputSchema: idInputSchema
80
80
  },
81
81
  {
82
- name: "lighthouse.portfolio.refresh",
82
+ name: "lighthouse_portfolio_refresh",
83
83
  description: "Trigger data refresh for a portfolio by ID.",
84
84
  inputSchema: idInputSchema
85
85
  },
86
86
  {
87
- name: "lighthouse.team.metrics.throughput",
87
+ name: "lighthouse_team_metrics_throughput",
88
88
  description: "Get throughput run-chart data for a team by ID, optionally filtered by start and end dates.",
89
89
  inputSchema: {
90
90
  type: "object",
@@ -97,7 +97,7 @@ var toolDefinitions = [
97
97
  }
98
98
  },
99
99
  {
100
- name: "lighthouse.team.metrics.cycleTimePercentiles",
100
+ name: "lighthouse_team_metrics_cycleTimePercentiles",
101
101
  description: "Get cycle-time percentiles for a team by ID, optionally filtered by start and end dates.",
102
102
  inputSchema: {
103
103
  type: "object",
@@ -110,7 +110,7 @@ var toolDefinitions = [
110
110
  }
111
111
  },
112
112
  {
113
- name: "lighthouse.portfolio.metrics.throughput",
113
+ name: "lighthouse_portfolio_metrics_throughput",
114
114
  description: "Get throughput run-chart data for a portfolio by ID, optionally filtered by start and end dates.",
115
115
  inputSchema: {
116
116
  type: "object",
@@ -123,7 +123,59 @@ var toolDefinitions = [
123
123
  }
124
124
  },
125
125
  {
126
- name: "lighthouse.feature.get",
126
+ name: "lighthouse_team_metrics_workItemAge",
127
+ description: "Get per-item work item age over time for a team by ID. Returns daily snapshots with each in-progress item's age in days derived from its startedDate. Items without a startedDate are omitted.",
128
+ inputSchema: {
129
+ type: "object",
130
+ properties: {
131
+ ...idInputSchema.properties,
132
+ ...dateRangeProperties
133
+ },
134
+ required: ["id"],
135
+ additionalProperties: false
136
+ }
137
+ },
138
+ {
139
+ name: "lighthouse_team_metrics_totalWorkItemAge",
140
+ description: "Get the total (summed) work item age over time for a team by ID. Returns daily totals of all in-progress item ages derived from startedDate. Items without a startedDate are not counted.",
141
+ inputSchema: {
142
+ type: "object",
143
+ properties: {
144
+ ...idInputSchema.properties,
145
+ ...dateRangeProperties
146
+ },
147
+ required: ["id"],
148
+ additionalProperties: false
149
+ }
150
+ },
151
+ {
152
+ name: "lighthouse_portfolio_metrics_workItemAge",
153
+ description: "Get per-item work item age over time for a portfolio by ID. Returns daily snapshots with each in-progress item's age in days derived from its startedDate. Items without a startedDate are omitted.",
154
+ inputSchema: {
155
+ type: "object",
156
+ properties: {
157
+ ...idInputSchema.properties,
158
+ ...dateRangeProperties
159
+ },
160
+ required: ["id"],
161
+ additionalProperties: false
162
+ }
163
+ },
164
+ {
165
+ name: "lighthouse_portfolio_metrics_totalWorkItemAge",
166
+ description: "Get the total (summed) work item age over time for a portfolio by ID. Returns daily totals of all in-progress item ages derived from startedDate. Items without a startedDate are not counted.",
167
+ inputSchema: {
168
+ type: "object",
169
+ properties: {
170
+ ...idInputSchema.properties,
171
+ ...dateRangeProperties
172
+ },
173
+ required: ["id"],
174
+ additionalProperties: false
175
+ }
176
+ },
177
+ {
178
+ name: "lighthouse_feature_get",
127
179
  description: "Get feature details by numeric IDs or external reference IDs.",
128
180
  inputSchema: {
129
181
  type: "object",
@@ -147,17 +199,17 @@ var toolDefinitions = [
147
199
  }
148
200
  },
149
201
  {
150
- name: "lighthouse.feature.workitems",
202
+ name: "lighthouse_feature_workitems",
151
203
  description: "Get work items linked to a feature by ID.",
152
204
  inputSchema: idInputSchema
153
205
  },
154
206
  {
155
- name: "lighthouse.delivery.list",
207
+ name: "lighthouse_delivery_list",
156
208
  description: "List deliveries for a portfolio by portfolio ID.",
157
209
  inputSchema: idInputSchema
158
210
  },
159
211
  {
160
- name: "lighthouse.forecast.manual",
212
+ name: "lighthouse_forecast_manual",
161
213
  description: "Run a manual forecast for a team by ID with optional remaining items and target date.",
162
214
  inputSchema: {
163
215
  type: "object",
@@ -177,7 +229,7 @@ var toolDefinitions = [
177
229
  }
178
230
  },
179
231
  {
180
- name: "lighthouse.forecast.backtest",
232
+ name: "lighthouse_forecast_backtest",
181
233
  description: "Run a forecast backtest for a team by ID using forecast and historical date ranges.",
182
234
  inputSchema: {
183
235
  type: "object",
@@ -262,43 +314,63 @@ var getDateRange = (argumentsPayload) => {
262
314
  };
263
315
  var isoDateStringSchema = z.string().regex(/^\d{4}-\d{2}-\d{2}$/u, "Expected ISO date in YYYY-MM-DD format.");
264
316
  var toolInputSchemas = {
265
- "lighthouse.health.check": z.object({}),
266
- "lighthouse.version.get": z.object({}),
267
- "lighthouse.worktracking.list": z.object({}),
268
- "lighthouse.worktracking.get": z.object({ id: z.number().int() }),
269
- "lighthouse.team.list": z.object({}),
270
- "lighthouse.team.get": z.object({ id: z.number().int() }),
271
- "lighthouse.team.refresh": z.object({ id: z.number().int() }),
272
- "lighthouse.portfolio.list": z.object({}),
273
- "lighthouse.portfolio.get": z.object({ id: z.number().int() }),
274
- "lighthouse.portfolio.refresh": z.object({ id: z.number().int() }),
275
- "lighthouse.team.metrics.throughput": z.object({
317
+ lighthouse_health_check: z.object({}),
318
+ lighthouse_version_get: z.object({}),
319
+ lighthouse_worktracking_list: z.object({}),
320
+ lighthouse_worktracking_get: z.object({ id: z.number().int() }),
321
+ lighthouse_team_list: z.object({}),
322
+ lighthouse_team_get: z.object({ id: z.number().int() }),
323
+ lighthouse_team_refresh: z.object({ id: z.number().int() }),
324
+ lighthouse_portfolio_list: z.object({}),
325
+ lighthouse_portfolio_get: z.object({ id: z.number().int() }),
326
+ lighthouse_portfolio_refresh: z.object({ id: z.number().int() }),
327
+ lighthouse_team_metrics_throughput: z.object({
328
+ id: z.number().int(),
329
+ startDate: isoDateStringSchema.optional(),
330
+ endDate: isoDateStringSchema.optional()
331
+ }),
332
+ lighthouse_team_metrics_cycleTimePercentiles: z.object({
333
+ id: z.number().int(),
334
+ startDate: isoDateStringSchema.optional(),
335
+ endDate: isoDateStringSchema.optional()
336
+ }),
337
+ lighthouse_team_metrics_workItemAge: z.object({
276
338
  id: z.number().int(),
277
339
  startDate: isoDateStringSchema.optional(),
278
340
  endDate: isoDateStringSchema.optional()
279
341
  }),
280
- "lighthouse.team.metrics.cycleTimePercentiles": z.object({
342
+ lighthouse_team_metrics_totalWorkItemAge: z.object({
281
343
  id: z.number().int(),
282
344
  startDate: isoDateStringSchema.optional(),
283
345
  endDate: isoDateStringSchema.optional()
284
346
  }),
285
- "lighthouse.portfolio.metrics.throughput": z.object({
347
+ lighthouse_portfolio_metrics_throughput: z.object({
286
348
  id: z.number().int(),
287
349
  startDate: isoDateStringSchema.optional(),
288
350
  endDate: isoDateStringSchema.optional()
289
351
  }),
290
- "lighthouse.feature.get": z.object({
352
+ lighthouse_portfolio_metrics_workItemAge: z.object({
353
+ id: z.number().int(),
354
+ startDate: isoDateStringSchema.optional(),
355
+ endDate: isoDateStringSchema.optional()
356
+ }),
357
+ lighthouse_portfolio_metrics_totalWorkItemAge: z.object({
358
+ id: z.number().int(),
359
+ startDate: isoDateStringSchema.optional(),
360
+ endDate: isoDateStringSchema.optional()
361
+ }),
362
+ lighthouse_feature_get: z.object({
291
363
  ids: z.array(z.number().int()).optional(),
292
364
  refs: z.array(z.string()).optional()
293
365
  }),
294
- "lighthouse.feature.workitems": z.object({ id: z.number().int() }),
295
- "lighthouse.delivery.list": z.object({ id: z.number().int() }),
296
- "lighthouse.forecast.manual": z.object({
366
+ lighthouse_feature_workitems: z.object({ id: z.number().int() }),
367
+ lighthouse_delivery_list: z.object({ id: z.number().int() }),
368
+ lighthouse_forecast_manual: z.object({
297
369
  id: z.number().int(),
298
370
  remainingItems: z.number().int().optional(),
299
371
  targetDate: isoDateStringSchema.optional()
300
372
  }),
301
- "lighthouse.forecast.backtest": z.object({
373
+ lighthouse_forecast_backtest: z.object({
302
374
  id: z.number().int(),
303
375
  startDate: isoDateStringSchema,
304
376
  endDate: isoDateStringSchema,
@@ -306,12 +378,12 @@ var toolInputSchemas = {
306
378
  historicalEndDate: isoDateStringSchema
307
379
  })
308
380
  };
309
- var isReadOnlyTool = (toolName) => !toolName.endsWith(".refresh");
381
+ var isReadOnlyTool = (toolName) => !toolName.endsWith("_refresh");
310
382
  var createMcpCoreRuntime = (dependencies) => ({
311
383
  listTools: () => toolDefinitions,
312
384
  callTool: async (name, argumentsPayload) => {
313
385
  const client = dependencies.createClient();
314
- if (name === "lighthouse.health.check") {
386
+ if (name === "lighthouse_health_check") {
315
387
  const health = await client.checkConnectivity();
316
388
  if (health.category === "success") {
317
389
  return getSuccessToolResult("connectivity: success");
@@ -321,7 +393,7 @@ var createMcpCoreRuntime = (dependencies) => ({
321
393
  `connectivity: ${health.category}${healthReasonSuffix}`
322
394
  );
323
395
  }
324
- if (name === "lighthouse.version.get") {
396
+ if (name === "lighthouse_version_get") {
325
397
  const version = await client.getVersion();
326
398
  if (version.ok) {
327
399
  return getSuccessToolResult(`version: ${version.value}`);
@@ -330,7 +402,7 @@ var createMcpCoreRuntime = (dependencies) => ({
330
402
  `version: ${version.error.category} (${version.error.reason})`
331
403
  );
332
404
  }
333
- if (name === "lighthouse.worktracking.list") {
405
+ if (name === "lighthouse_worktracking_list") {
334
406
  const connections = await client.listWorkTrackingConnections();
335
407
  if (connections.ok) {
336
408
  return getSuccessToolResult(
@@ -341,7 +413,7 @@ var createMcpCoreRuntime = (dependencies) => ({
341
413
  `worktracking: ${connections.error.category} (${connections.error.reason})`
342
414
  );
343
415
  }
344
- if (name === "lighthouse.worktracking.get") {
416
+ if (name === "lighthouse_worktracking_get") {
345
417
  const id = getNumericId(argumentsPayload);
346
418
  if (id === null) {
347
419
  return getErrorToolResult("worktracking: invalid id");
@@ -356,7 +428,7 @@ var createMcpCoreRuntime = (dependencies) => ({
356
428
  `worktracking: ${connection.error.category} (${connection.error.reason})`
357
429
  );
358
430
  }
359
- if (name === "lighthouse.team.list") {
431
+ if (name === "lighthouse_team_list") {
360
432
  const teams = await client.listTeams();
361
433
  if (teams.ok) {
362
434
  return getSuccessToolResult(`teams: ${encodePayload(teams.value)}`);
@@ -365,7 +437,7 @@ var createMcpCoreRuntime = (dependencies) => ({
365
437
  `teams: ${teams.error.category} (${teams.error.reason})`
366
438
  );
367
439
  }
368
- if (name === "lighthouse.team.get") {
440
+ if (name === "lighthouse_team_get") {
369
441
  const id = getNumericId(argumentsPayload);
370
442
  if (id === null) {
371
443
  return getErrorToolResult("team: invalid id");
@@ -378,7 +450,7 @@ var createMcpCoreRuntime = (dependencies) => ({
378
450
  `team: ${team.error.category} (${team.error.reason})`
379
451
  );
380
452
  }
381
- if (name === "lighthouse.team.refresh") {
453
+ if (name === "lighthouse_team_refresh") {
382
454
  const id = getNumericId(argumentsPayload);
383
455
  if (id === null) {
384
456
  return getErrorToolResult("team: invalid id");
@@ -391,7 +463,7 @@ var createMcpCoreRuntime = (dependencies) => ({
391
463
  `team refresh: ${result.error.category} (${result.error.reason})`
392
464
  );
393
465
  }
394
- if (name === "lighthouse.portfolio.list") {
466
+ if (name === "lighthouse_portfolio_list") {
395
467
  const portfolios = await client.listPortfolios();
396
468
  if (portfolios.ok) {
397
469
  return getSuccessToolResult(
@@ -402,7 +474,7 @@ var createMcpCoreRuntime = (dependencies) => ({
402
474
  `portfolios: ${portfolios.error.category} (${portfolios.error.reason})`
403
475
  );
404
476
  }
405
- if (name === "lighthouse.portfolio.get") {
477
+ if (name === "lighthouse_portfolio_get") {
406
478
  const id = getNumericId(argumentsPayload);
407
479
  if (id === null) {
408
480
  return getErrorToolResult("portfolio: invalid id");
@@ -417,7 +489,7 @@ var createMcpCoreRuntime = (dependencies) => ({
417
489
  `portfolio: ${portfolio.error.category} (${portfolio.error.reason})`
418
490
  );
419
491
  }
420
- if (name === "lighthouse.portfolio.refresh") {
492
+ if (name === "lighthouse_portfolio_refresh") {
421
493
  const id = getNumericId(argumentsPayload);
422
494
  if (id === null) {
423
495
  return getErrorToolResult("portfolio: invalid id");
@@ -430,7 +502,7 @@ var createMcpCoreRuntime = (dependencies) => ({
430
502
  `portfolio refresh: ${result.error.category} (${result.error.reason})`
431
503
  );
432
504
  }
433
- if (name === "lighthouse.team.metrics.throughput") {
505
+ if (name === "lighthouse_team_metrics_throughput") {
434
506
  const id = getNumericId(argumentsPayload);
435
507
  if (id === null) {
436
508
  return getErrorToolResult("team metrics: invalid id");
@@ -446,7 +518,7 @@ var createMcpCoreRuntime = (dependencies) => ({
446
518
  `team metrics: ${result.error.category} (${result.error.reason})`
447
519
  );
448
520
  }
449
- if (name === "lighthouse.team.metrics.cycleTimePercentiles") {
521
+ if (name === "lighthouse_team_metrics_cycleTimePercentiles") {
450
522
  const id = getNumericId(argumentsPayload);
451
523
  if (id === null) {
452
524
  return getErrorToolResult("team metrics: invalid id");
@@ -462,7 +534,7 @@ var createMcpCoreRuntime = (dependencies) => ({
462
534
  `team metrics: ${result.error.category} (${result.error.reason})`
463
535
  );
464
536
  }
465
- if (name === "lighthouse.portfolio.metrics.throughput") {
537
+ if (name === "lighthouse_portfolio_metrics_throughput") {
466
538
  const id = getNumericId(argumentsPayload);
467
539
  if (id === null) {
468
540
  return getErrorToolResult("portfolio metrics: invalid id");
@@ -478,7 +550,74 @@ var createMcpCoreRuntime = (dependencies) => ({
478
550
  `portfolio metrics: ${result.error.category} (${result.error.reason})`
479
551
  );
480
552
  }
481
- if (name === "lighthouse.feature.get") {
553
+ if (name === "lighthouse_team_metrics_workItemAge") {
554
+ const id = getNumericId(argumentsPayload);
555
+ if (id === null) {
556
+ return getErrorToolResult("team metrics: invalid id");
557
+ }
558
+ const range = getDateRange(argumentsPayload);
559
+ const result = await client.getTeamWorkItemAgeOverTime(id, range);
560
+ if (result.ok) {
561
+ return getSuccessToolResult(
562
+ `team workItemAge: ${encodePayload(result.value)}`
563
+ );
564
+ }
565
+ return getErrorToolResult(
566
+ `team metrics: ${result.error.category} (${result.error.reason})`
567
+ );
568
+ }
569
+ if (name === "lighthouse_team_metrics_totalWorkItemAge") {
570
+ const id = getNumericId(argumentsPayload);
571
+ if (id === null) {
572
+ return getErrorToolResult("team metrics: invalid id");
573
+ }
574
+ const range = getDateRange(argumentsPayload);
575
+ const result = await client.getTeamTotalWorkItemAgeOverTime(id, range);
576
+ if (result.ok) {
577
+ return getSuccessToolResult(
578
+ `team totalWorkItemAge: ${encodePayload(result.value)}`
579
+ );
580
+ }
581
+ return getErrorToolResult(
582
+ `team metrics: ${result.error.category} (${result.error.reason})`
583
+ );
584
+ }
585
+ if (name === "lighthouse_portfolio_metrics_workItemAge") {
586
+ const id = getNumericId(argumentsPayload);
587
+ if (id === null) {
588
+ return getErrorToolResult("portfolio metrics: invalid id");
589
+ }
590
+ const range = getDateRange(argumentsPayload);
591
+ const result = await client.getPortfolioWorkItemAgeOverTime(id, range);
592
+ if (result.ok) {
593
+ return getSuccessToolResult(
594
+ `portfolio workItemAge: ${encodePayload(result.value)}`
595
+ );
596
+ }
597
+ return getErrorToolResult(
598
+ `portfolio metrics: ${result.error.category} (${result.error.reason})`
599
+ );
600
+ }
601
+ if (name === "lighthouse_portfolio_metrics_totalWorkItemAge") {
602
+ const id = getNumericId(argumentsPayload);
603
+ if (id === null) {
604
+ return getErrorToolResult("portfolio metrics: invalid id");
605
+ }
606
+ const range = getDateRange(argumentsPayload);
607
+ const result = await client.getPortfolioTotalWorkItemAgeOverTime(
608
+ id,
609
+ range
610
+ );
611
+ if (result.ok) {
612
+ return getSuccessToolResult(
613
+ `portfolio totalWorkItemAge: ${encodePayload(result.value)}`
614
+ );
615
+ }
616
+ return getErrorToolResult(
617
+ `portfolio metrics: ${result.error.category} (${result.error.reason})`
618
+ );
619
+ }
620
+ if (name === "lighthouse_feature_get") {
482
621
  const payload = isObjectRecord(argumentsPayload) ? argumentsPayload : {};
483
622
  const idsValue = payload.ids;
484
623
  const refsValue = payload.refs;
@@ -512,7 +651,7 @@ var createMcpCoreRuntime = (dependencies) => ({
512
651
  "features: provide ids (array of numbers) or refs (array of strings)"
513
652
  );
514
653
  }
515
- if (name === "lighthouse.feature.workitems") {
654
+ if (name === "lighthouse_feature_workitems") {
516
655
  const id = getNumericId(argumentsPayload);
517
656
  if (id === null) {
518
657
  return getErrorToolResult("feature workitems: invalid id");
@@ -527,7 +666,7 @@ var createMcpCoreRuntime = (dependencies) => ({
527
666
  `feature workitems: ${result.error.category} (${result.error.reason})`
528
667
  );
529
668
  }
530
- if (name === "lighthouse.delivery.list") {
669
+ if (name === "lighthouse_delivery_list") {
531
670
  const id = getNumericId(argumentsPayload);
532
671
  if (id === null) {
533
672
  return getErrorToolResult(
@@ -544,7 +683,7 @@ var createMcpCoreRuntime = (dependencies) => ({
544
683
  `delivery: ${result.error.category} (${result.error.reason})`
545
684
  );
546
685
  }
547
- if (name === "lighthouse.forecast.manual") {
686
+ if (name === "lighthouse_forecast_manual") {
548
687
  const id = getNumericId(argumentsPayload);
549
688
  if (id === null) {
550
689
  return getErrorToolResult("forecast: invalid id (team id required)");
@@ -563,7 +702,7 @@ var createMcpCoreRuntime = (dependencies) => ({
563
702
  `forecast: ${result.error.category} (${result.error.reason})`
564
703
  );
565
704
  }
566
- if (name === "lighthouse.forecast.backtest") {
705
+ if (name === "lighthouse_forecast_backtest") {
567
706
  const id = getNumericId(argumentsPayload);
568
707
  if (id === null) {
569
708
  return getErrorToolResult("backtest: invalid id (team id required)");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letpeoplework/lighthouse-mcp-core",
3
- "version": "0.6.0",
3
+ "version": "1.0.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": "0.8.0"
29
+ "@letpeoplework/lighthouse-client": "1.0.0"
30
30
  },
31
31
  "scripts": {
32
32
  "build": "tsup src/index.ts --format esm,cjs --dts --clean",