@letpeoplework/lighthouse-mcp-core 1.9.0 → 1.10.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
@@ -426,6 +426,119 @@ const REFINEMENT_TOOLS = /* @__PURE__ */ new Map([
426
426
  /** The handler of a refinement tool, or undefined for a tool that is not one. */
427
427
  const findRefinementTool = (name) => REFINEMENT_TOOLS.get(name);
428
428
  //#endregion
429
+ //#region src/reportTools.ts
430
+ const HOW_LIGHTHOUSE_SHOWS_IT = "Read the lighthouse-reports skill for how Lighthouse shows these values, and quote them as they come.";
431
+ const HOW_THE_ANSWER_READS = "The first block is Lighthouse's answer, unchanged; a second text block, `summary`,";
432
+ const LIST_LABEL = "reports";
433
+ const GET_LABEL = "report";
434
+ const NEEDS_A_SERVER = "Needs a Lighthouse newer than v26.10.10.1.";
435
+ const ownerIdProperty = (kind) => ({
436
+ type: "integer",
437
+ description: `The ${kind}'s numeric id.`
438
+ });
439
+ const reportIdProperty = {
440
+ type: "integer",
441
+ description: "The report's id, as its owner's report list names it under reports[].id."
442
+ };
443
+ const listInputSchema = (kind) => ({
444
+ type: "object",
445
+ properties: { id: ownerIdProperty(kind) },
446
+ required: ["id"],
447
+ additionalProperties: false
448
+ });
449
+ const getInputSchema = (kind) => ({
450
+ type: "object",
451
+ properties: {
452
+ id: ownerIdProperty(kind),
453
+ reportId: reportIdProperty
454
+ },
455
+ required: ["id", "reportId"],
456
+ additionalProperties: false
457
+ });
458
+ const listDescription = (kind) => `List the reports a ${kind} holds by ${kind} ID: each report's id, name, type (templateKey) and when it was created. ${HOW_THE_ANSWER_READS} names the ${kind} and counts its reports in the instance's terminology. ${HOW_LIGHTHOUSE_SHOWS_IT} ${NEEDS_A_SERVER}`;
459
+ const getDescription = (kind) => `Get one of a ${kind}'s reports by ${kind} ID and reportId, exactly as Lighthouse answers it: its Then side as Lighthouse froze it, its Now side read afresh up to today, and every value, a missing value with its reason. ${HOW_LIGHTHOUSE_SHOWS_IT} ${HOW_THE_ANSWER_READS} names the report, its ${kind} and its Then and Now windows. ${NEEDS_A_SERVER}`;
460
+ const reportToolDefinitions = [
461
+ {
462
+ name: "lighthouse_team_report_list",
463
+ description: listDescription("team"),
464
+ inputSchema: listInputSchema("team")
465
+ },
466
+ {
467
+ name: "lighthouse_team_report_get",
468
+ description: getDescription("team"),
469
+ inputSchema: getInputSchema("team")
470
+ },
471
+ {
472
+ name: "lighthouse_portfolio_report_list",
473
+ description: listDescription("portfolio"),
474
+ inputSchema: listInputSchema("portfolio")
475
+ },
476
+ {
477
+ name: "lighthouse_portfolio_report_get",
478
+ description: getDescription("portfolio"),
479
+ inputSchema: getInputSchema("portfolio")
480
+ }
481
+ ];
482
+ const listSchema = zod.z.object({ id: zod.z.number().int() });
483
+ const getSchema = zod.z.object({
484
+ id: zod.z.number().int(),
485
+ reportId: zod.z.number().int()
486
+ });
487
+ const reportInputSchemas = {
488
+ lighthouse_team_report_list: listSchema,
489
+ lighthouse_team_report_get: getSchema,
490
+ lighthouse_portfolio_report_list: listSchema,
491
+ lighthouse_portfolio_report_get: getSchema
492
+ };
493
+ const getReportId = (argumentsPayload) => {
494
+ const reportId = typeof argumentsPayload === "object" && argumentsPayload !== null ? argumentsPayload.reportId : void 0;
495
+ return typeof reportId === "number" && Number.isInteger(reportId) ? reportId : null;
496
+ };
497
+ const answerReportRead = async (client, owner, result, answer) => {
498
+ if (!result.ok) return getErrorToolResult(`${answer.label}: ${await (0, _letpeoplework_lighthouse_client.readReportRefusal)(client, result.error, owner.kind, answer.read)}`);
499
+ const ownerName = await (0, _letpeoplework_lighthouse_client.readReportOwner)(client, owner);
500
+ return withSummaryBlock(`${answer.label}: ${encodePayload(result.value)}`, answer.summarise(result.value, ownerName));
501
+ };
502
+ const invalid = (label, what) => getErrorToolResult(`${label}: invalid ${what}`);
503
+ const reportList = (kind) => async (argumentsPayload, client) => {
504
+ const id = getNumericId(argumentsPayload);
505
+ if (id === null) return invalid(LIST_LABEL, "id");
506
+ const owner = {
507
+ kind,
508
+ id
509
+ };
510
+ return answerReportRead(client, owner, await (0, _letpeoplework_lighthouse_client.readOwnersReports)(client, owner), {
511
+ label: LIST_LABEL,
512
+ read: "list",
513
+ summarise: _letpeoplework_lighthouse_client.summariseReportList
514
+ });
515
+ };
516
+ const reportGet = (kind) => async (argumentsPayload, client) => {
517
+ const id = getNumericId(argumentsPayload);
518
+ if (id === null) return invalid(GET_LABEL, "id");
519
+ const reportId = getReportId(argumentsPayload);
520
+ if (reportId === null) return invalid(GET_LABEL, "reportId");
521
+ const owner = {
522
+ kind,
523
+ id
524
+ };
525
+ const result = await (0, _letpeoplework_lighthouse_client.readOwnersReport)(client, owner, reportId);
526
+ const answered = await answerReportRead(client, owner, result, {
527
+ label: GET_LABEL,
528
+ read: "report",
529
+ summarise: _letpeoplework_lighthouse_client.summariseReport
530
+ });
531
+ return countedToolResult(answered, (0, _letpeoplework_lighthouse_client.reportOpenedOccurrencesOf)(result));
532
+ };
533
+ const REPORT_TOOLS = /* @__PURE__ */ new Map([
534
+ ["lighthouse_team_report_list", reportList("team")],
535
+ ["lighthouse_team_report_get", reportGet("team")],
536
+ ["lighthouse_portfolio_report_list", reportList("portfolio")],
537
+ ["lighthouse_portfolio_report_get", reportGet("portfolio")]
538
+ ]);
539
+ /** The handler of one of the report tools, or undefined for any other tool. */
540
+ const findReportTool = (name) => REPORT_TOOLS.get(name);
541
+ //#endregion
429
542
  //#region src/index.ts
430
543
  const getMcpCorePackageContract = () => ({
431
544
  name: "@letpeoplework/lighthouse-mcp-core",
@@ -1076,7 +1189,8 @@ const toolDefinitions = [
1076
1189
  name: "lighthouse_portfolio_metrics_processBehaviorChart",
1077
1190
  description: "Get one Process Behaviour Chart of a portfolio by ID, as Lighthouse computes it: its status (and statusReason when it is not Ready), the average and natural process limits, whether a baseline is configured, and every point (xValue, yValue) with the signals Lighthouse found on it (specialCauses: LargeChange, ModerateChange, ModerateShift, SmallShift; None means no signal) and whether it falls on a blackout day (isBlackout). metricType picks the chart: Throughput, Arrivals, Wip, WorkItemAge (the Total Work Item Age chart), CycleTime or FeatureSize. A point is a day, except on CycleTime, which has one point per finished work item, and FeatureSize, which has one per finished feature, each dated when it finished, so several can share a day. Use it for \"is something unusual going on\" and \"did our process change\"; never work a signal out yourself. Optionally filtered by start and end dates. A second text block, `summary: …`, states the answer as lh does, in the instance's terminology: the heading, the chart's title, and each signal with the days it fired, or that there are no signals; the facts are unchanged.",
1078
1191
  inputSchema: chartInputSchema(processBehaviorMetricTypes)
1079
- }
1192
+ },
1193
+ ...reportToolDefinitions
1080
1194
  ];
1081
1195
  const getDefinitionId = (argumentsPayload) => {
1082
1196
  if (typeof argumentsPayload !== "object" || argumentsPayload === null || Array.isArray(argumentsPayload)) return;
@@ -1363,6 +1477,7 @@ const toolInputSchemas = {
1363
1477
  lighthouse_team_refresh: zod.z.object({ id: zod.z.number().int() }),
1364
1478
  lighthouse_team_refinement_get: zod.z.object({ id: zod.z.number().int() }),
1365
1479
  ...refinementWriteInputSchemas,
1480
+ ...reportInputSchemas,
1366
1481
  lighthouse_portfolio_list: zod.z.object({}),
1367
1482
  lighthouse_portfolio_get: zod.z.object({ id: zod.z.number().int() }),
1368
1483
  lighthouse_portfolio_refresh: zod.z.object({ id: zod.z.number().int() }),
@@ -1589,6 +1704,8 @@ const answerToolCall = (dependencies) => async (name, argumentsPayload) => {
1589
1704
  }
1590
1705
  const refinementTool = findRefinementTool(name);
1591
1706
  if (refinementTool !== void 0) return refinementTool(argumentsPayload, client, dependencies);
1707
+ const reportTool = findReportTool(name);
1708
+ if (reportTool !== void 0) return reportTool(argumentsPayload, client);
1592
1709
  if (name === "lighthouse_portfolio_list") return answerOwnerList("portfolio", "portfolios", client.listPortfolios(), client);
1593
1710
  if (name === "lighthouse_portfolio_get") {
1594
1711
  const id = getNumericId(argumentsPayload);
package/dist/index.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import { DeliveryMetricsHistory, LighthouseApiResult, LighthouseClient, LighthouseVoterKeyStore, PortfolioDeliveries, RefinementMomentFacts, RefinementWordingSource, TeamRefinement, UsageDataOccurrence, UsageDataQuestionAnswer, UsageDataStep, VotedRow } from "@letpeoplework/lighthouse-client";
1
+ import { DeliveryMetricsHistory, LighthouseApiResult, LighthouseClient, LighthouseVoterKeyStore, PortfolioDeliveries, RefinementMomentFacts, RefinementWordingSource, ReportOwnerSource, ReportReads, TeamRefinement, UsageDataOccurrence, UsageDataQuestionAnswer, UsageDataStep, VotedRow } from "@letpeoplework/lighthouse-client";
2
2
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
3
  import "zod";
4
4
  import { ElicitRequestFormParams, ElicitResult } from "@modelcontextprotocol/sdk/types.js";
@@ -75,6 +75,9 @@ type ToolError = {
75
75
  };
76
76
  type RefinementToolClient = RefinementWordingSource<ToolError> & Pick<LighthouseClient, "getTeamRefinement" | "castRefinementVote" | "addRefinementComment" | "takeBackRefinementVote" | "getRefinementLog" | "getTerminology">;
77
77
  //#endregion
78
+ //#region src/reportTools.d.ts
79
+ type ReportToolClient = ReportReads & ReportOwnerSource;
80
+ //#endregion
78
81
  //#region src/index.d.ts
79
82
  export type McpCorePackageContract = {
80
83
  readonly name: "@letpeoplework/lighthouse-mcp-core";
@@ -83,7 +86,7 @@ export type McpCorePackageContract = {
83
86
  };
84
87
  export declare const getMcpCorePackageContract: () => McpCorePackageContract;
85
88
  export type McpToolDefinition = {
86
- readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_team_refinement_get" | "lighthouse_team_refinement_vote" | "lighthouse_team_refinement_comment" | "lighthouse_team_refinement_voteTakeBack" | "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_wip" | "lighthouse_team_metrics_sleRisk" | "lighthouse_team_metrics_processBehaviorChart" | "lighthouse_portfolio_metrics_processBehaviorChart" | "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";
89
+ readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_team_refinement_get" | "lighthouse_team_refinement_vote" | "lighthouse_team_refinement_comment" | "lighthouse_team_refinement_voteTakeBack" | "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_wip" | "lighthouse_team_metrics_sleRisk" | "lighthouse_team_metrics_processBehaviorChart" | "lighthouse_portfolio_metrics_processBehaviorChart" | "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" | "lighthouse_team_report_list" | "lighthouse_team_report_get" | "lighthouse_portfolio_report_list" | "lighthouse_portfolio_report_get";
87
90
  readonly description: string;
88
91
  readonly inputSchema: {
89
92
  readonly type: "object";
@@ -669,7 +672,7 @@ type McpRuntimeClient = {
669
672
  readonly reason: string;
670
673
  };
671
674
  }>;
672
- } & Omit<RefinementToolClient, "getTeam">;
675
+ } & Omit<RefinementToolClient, "getTeam"> & Omit<ReportToolClient, "getTeam" | "getPortfolio">;
673
676
  export type McpCoreRuntimeDependencies = {
674
677
  readonly createClient: () => McpRuntimeClient;
675
678
  /** Where usage data goes; without it a tool call does exactly what it always did. */
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { DeliveryMetricsHistory, LighthouseApiResult, LighthouseClient, LighthouseVoterKeyStore, PortfolioDeliveries, RefinementMomentFacts, RefinementWordingSource, TeamRefinement, UsageDataOccurrence, UsageDataQuestionAnswer, UsageDataStep, VotedRow } from "@letpeoplework/lighthouse-client";
1
+ import { DeliveryMetricsHistory, LighthouseApiResult, LighthouseClient, LighthouseVoterKeyStore, PortfolioDeliveries, RefinementMomentFacts, RefinementWordingSource, ReportOwnerSource, ReportReads, TeamRefinement, UsageDataOccurrence, UsageDataQuestionAnswer, UsageDataStep, VotedRow } from "@letpeoplework/lighthouse-client";
2
2
  import { ElicitRequestFormParams, ElicitResult } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { z } from "zod";
4
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -75,6 +75,9 @@ type ToolError = {
75
75
  };
76
76
  type RefinementToolClient = RefinementWordingSource<ToolError> & Pick<LighthouseClient, "getTeamRefinement" | "castRefinementVote" | "addRefinementComment" | "takeBackRefinementVote" | "getRefinementLog" | "getTerminology">;
77
77
  //#endregion
78
+ //#region src/reportTools.d.ts
79
+ type ReportToolClient = ReportReads & ReportOwnerSource;
80
+ //#endregion
78
81
  //#region src/index.d.ts
79
82
  export type McpCorePackageContract = {
80
83
  readonly name: "@letpeoplework/lighthouse-mcp-core";
@@ -83,7 +86,7 @@ export type McpCorePackageContract = {
83
86
  };
84
87
  export declare const getMcpCorePackageContract: () => McpCorePackageContract;
85
88
  export type McpToolDefinition = {
86
- readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_team_refinement_get" | "lighthouse_team_refinement_vote" | "lighthouse_team_refinement_comment" | "lighthouse_team_refinement_voteTakeBack" | "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_wip" | "lighthouse_team_metrics_sleRisk" | "lighthouse_team_metrics_processBehaviorChart" | "lighthouse_portfolio_metrics_processBehaviorChart" | "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";
89
+ readonly name: "lighthouse_health_check" | "lighthouse_version_get" | "lighthouse_worktracking_list" | "lighthouse_worktracking_get" | "lighthouse_team_list" | "lighthouse_team_get" | "lighthouse_team_refresh" | "lighthouse_team_refinement_get" | "lighthouse_team_refinement_vote" | "lighthouse_team_refinement_comment" | "lighthouse_team_refinement_voteTakeBack" | "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_wip" | "lighthouse_team_metrics_sleRisk" | "lighthouse_team_metrics_processBehaviorChart" | "lighthouse_portfolio_metrics_processBehaviorChart" | "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" | "lighthouse_team_report_list" | "lighthouse_team_report_get" | "lighthouse_portfolio_report_list" | "lighthouse_portfolio_report_get";
87
90
  readonly description: string;
88
91
  readonly inputSchema: {
89
92
  readonly type: "object";
@@ -669,7 +672,7 @@ type McpRuntimeClient = {
669
672
  readonly reason: string;
670
673
  };
671
674
  }>;
672
- } & Omit<RefinementToolClient, "getTeam">;
675
+ } & Omit<RefinementToolClient, "getTeam"> & Omit<ReportToolClient, "getTeam" | "getPortfolio">;
673
676
  export type McpCoreRuntimeDependencies = {
674
677
  readonly createClient: () => McpRuntimeClient;
675
678
  /** Where usage data goes; without it a tool call does exactly what it always did. */
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { LIGHTHOUSE_IS_REACHABLE, REFINEMENT_ANSWERS, describeAsOfHeading, describeBacktestActual, describeBacktestPeriod, describeBacktestSummary, describeBlackoutRuleCount, describeBlackoutRuleWriteConfirmation, describeBlockedDays, describeBlockedNow, describeConnectionSummary, describeCycleTimeDays, describeDeliveryCount, describeDeliveryMetricsHeading, describeFeatureListCount, describeFeatureWorkItemsHeading, describeInProgressNow, describeManualForecastLikelihood, describeManualForecastSummary, describeMetricSummary, describeMetricsHeading, describeMissingCondition, describeNothingToTakeBack, describeOwnerCount, describePercentilesOverTimeDays, describePortfolioSummary, describeProcessBehaviorChart, describeProcessBehaviorOverTimeDays, describeRecordedComment, describeRecordedVote, describeRefinementSummary, describeRefreshConfirmation, describeSleRiskNow, describeStaleNow, describeTakenBack, describeTeamSummary, describeThroughputDays, describeTimeInStateContributorDays, describeTimeInStateDays, describeTotalWorkItemAgeDays, describeVersion, describeWhatWipLeavesUnsaid, describeWorkItemAgeDays, describeWorkItemAgePercentiles, describeWorkTrackingSystemCount, getDefaultMetricsDateRange, isMissingItsCondition, isRefinementAnswer, keepVoterKey, myVoteOn, readAnswerWording, readBacktest, readBlackoutRules, readBlocked, readCycleTimeDefinitionName, readCycleTimePercentiles, readDeliveryMetricsHistory, readFeatureList, readFeatureWording, readFeatureWorkItems, readInProgressItems, readManualForecast, readNameOfMyVote, readOwnerList, readPercentilesOverTime, readPortfolio, readPortfolioDeliveries, readProcessBehaviorChart, readProcessBehaviorOverTime, readRefinementWording, readRunChart, readServiceLevelExpectation, readSleRisk, readSystemWipLimit, readTeam, readTerms, readTimeInStateBar, readTimeInStateContributors, readTotalWorkItemAge, readVoteRefusal, readWorkItemAge, readWorkItemAgePercentiles, readWorkTrackingConnections, readWrittenBlackoutRule, refinementDayVerdictOf, sizingMomentOf, summariseDeliveryMetricsHistory } from "@letpeoplework/lighthouse-client";
1
+ import { LIGHTHOUSE_IS_REACHABLE, REFINEMENT_ANSWERS, describeAsOfHeading, describeBacktestActual, describeBacktestPeriod, describeBacktestSummary, describeBlackoutRuleCount, describeBlackoutRuleWriteConfirmation, describeBlockedDays, describeBlockedNow, describeConnectionSummary, describeCycleTimeDays, describeDeliveryCount, describeDeliveryMetricsHeading, describeFeatureListCount, describeFeatureWorkItemsHeading, describeInProgressNow, describeManualForecastLikelihood, describeManualForecastSummary, describeMetricSummary, describeMetricsHeading, describeMissingCondition, describeNothingToTakeBack, describeOwnerCount, describePercentilesOverTimeDays, describePortfolioSummary, describeProcessBehaviorChart, describeProcessBehaviorOverTimeDays, describeRecordedComment, describeRecordedVote, describeRefinementSummary, describeRefreshConfirmation, describeSleRiskNow, describeStaleNow, describeTakenBack, describeTeamSummary, describeThroughputDays, describeTimeInStateContributorDays, describeTimeInStateDays, describeTotalWorkItemAgeDays, describeVersion, describeWhatWipLeavesUnsaid, describeWorkItemAgeDays, describeWorkItemAgePercentiles, describeWorkTrackingSystemCount, getDefaultMetricsDateRange, isMissingItsCondition, isRefinementAnswer, keepVoterKey, myVoteOn, readAnswerWording, readBacktest, readBlackoutRules, readBlocked, readCycleTimeDefinitionName, readCycleTimePercentiles, readDeliveryMetricsHistory, readFeatureList, readFeatureWording, readFeatureWorkItems, readInProgressItems, readManualForecast, readNameOfMyVote, readOwnerList, readOwnersReport, readOwnersReports, readPercentilesOverTime, readPortfolio, readPortfolioDeliveries, readProcessBehaviorChart, readProcessBehaviorOverTime, readRefinementWording, readReportOwner, readReportRefusal, readRunChart, readServiceLevelExpectation, readSleRisk, readSystemWipLimit, readTeam, readTerms, readTimeInStateBar, readTimeInStateContributors, readTotalWorkItemAge, readVoteRefusal, readWorkItemAge, readWorkItemAgePercentiles, readWorkTrackingConnections, readWrittenBlackoutRule, refinementDayVerdictOf, reportOpenedOccurrencesOf, sizingMomentOf, summariseDeliveryMetricsHistory, summariseReport, summariseReportList } from "@letpeoplework/lighthouse-client";
2
2
  import { ElicitResultSchema } from "@modelcontextprotocol/sdk/types.js";
3
3
  import { z } from "zod";
4
4
  import { encode } from "@toon-format/toon";
@@ -425,6 +425,119 @@ const REFINEMENT_TOOLS = /* @__PURE__ */ new Map([
425
425
  /** The handler of a refinement tool, or undefined for a tool that is not one. */
426
426
  const findRefinementTool = (name) => REFINEMENT_TOOLS.get(name);
427
427
  //#endregion
428
+ //#region src/reportTools.ts
429
+ const HOW_LIGHTHOUSE_SHOWS_IT = "Read the lighthouse-reports skill for how Lighthouse shows these values, and quote them as they come.";
430
+ const HOW_THE_ANSWER_READS = "The first block is Lighthouse's answer, unchanged; a second text block, `summary`,";
431
+ const LIST_LABEL = "reports";
432
+ const GET_LABEL = "report";
433
+ const NEEDS_A_SERVER = "Needs a Lighthouse newer than v26.10.10.1.";
434
+ const ownerIdProperty = (kind) => ({
435
+ type: "integer",
436
+ description: `The ${kind}'s numeric id.`
437
+ });
438
+ const reportIdProperty = {
439
+ type: "integer",
440
+ description: "The report's id, as its owner's report list names it under reports[].id."
441
+ };
442
+ const listInputSchema = (kind) => ({
443
+ type: "object",
444
+ properties: { id: ownerIdProperty(kind) },
445
+ required: ["id"],
446
+ additionalProperties: false
447
+ });
448
+ const getInputSchema = (kind) => ({
449
+ type: "object",
450
+ properties: {
451
+ id: ownerIdProperty(kind),
452
+ reportId: reportIdProperty
453
+ },
454
+ required: ["id", "reportId"],
455
+ additionalProperties: false
456
+ });
457
+ const listDescription = (kind) => `List the reports a ${kind} holds by ${kind} ID: each report's id, name, type (templateKey) and when it was created. ${HOW_THE_ANSWER_READS} names the ${kind} and counts its reports in the instance's terminology. ${HOW_LIGHTHOUSE_SHOWS_IT} ${NEEDS_A_SERVER}`;
458
+ const getDescription = (kind) => `Get one of a ${kind}'s reports by ${kind} ID and reportId, exactly as Lighthouse answers it: its Then side as Lighthouse froze it, its Now side read afresh up to today, and every value, a missing value with its reason. ${HOW_LIGHTHOUSE_SHOWS_IT} ${HOW_THE_ANSWER_READS} names the report, its ${kind} and its Then and Now windows. ${NEEDS_A_SERVER}`;
459
+ const reportToolDefinitions = [
460
+ {
461
+ name: "lighthouse_team_report_list",
462
+ description: listDescription("team"),
463
+ inputSchema: listInputSchema("team")
464
+ },
465
+ {
466
+ name: "lighthouse_team_report_get",
467
+ description: getDescription("team"),
468
+ inputSchema: getInputSchema("team")
469
+ },
470
+ {
471
+ name: "lighthouse_portfolio_report_list",
472
+ description: listDescription("portfolio"),
473
+ inputSchema: listInputSchema("portfolio")
474
+ },
475
+ {
476
+ name: "lighthouse_portfolio_report_get",
477
+ description: getDescription("portfolio"),
478
+ inputSchema: getInputSchema("portfolio")
479
+ }
480
+ ];
481
+ const listSchema = z.object({ id: z.number().int() });
482
+ const getSchema = z.object({
483
+ id: z.number().int(),
484
+ reportId: z.number().int()
485
+ });
486
+ const reportInputSchemas = {
487
+ lighthouse_team_report_list: listSchema,
488
+ lighthouse_team_report_get: getSchema,
489
+ lighthouse_portfolio_report_list: listSchema,
490
+ lighthouse_portfolio_report_get: getSchema
491
+ };
492
+ const getReportId = (argumentsPayload) => {
493
+ const reportId = typeof argumentsPayload === "object" && argumentsPayload !== null ? argumentsPayload.reportId : void 0;
494
+ return typeof reportId === "number" && Number.isInteger(reportId) ? reportId : null;
495
+ };
496
+ const answerReportRead = async (client, owner, result, answer) => {
497
+ if (!result.ok) return getErrorToolResult(`${answer.label}: ${await readReportRefusal(client, result.error, owner.kind, answer.read)}`);
498
+ const ownerName = await readReportOwner(client, owner);
499
+ return withSummaryBlock(`${answer.label}: ${encodePayload(result.value)}`, answer.summarise(result.value, ownerName));
500
+ };
501
+ const invalid = (label, what) => getErrorToolResult(`${label}: invalid ${what}`);
502
+ const reportList = (kind) => async (argumentsPayload, client) => {
503
+ const id = getNumericId(argumentsPayload);
504
+ if (id === null) return invalid(LIST_LABEL, "id");
505
+ const owner = {
506
+ kind,
507
+ id
508
+ };
509
+ return answerReportRead(client, owner, await readOwnersReports(client, owner), {
510
+ label: LIST_LABEL,
511
+ read: "list",
512
+ summarise: summariseReportList
513
+ });
514
+ };
515
+ const reportGet = (kind) => async (argumentsPayload, client) => {
516
+ const id = getNumericId(argumentsPayload);
517
+ if (id === null) return invalid(GET_LABEL, "id");
518
+ const reportId = getReportId(argumentsPayload);
519
+ if (reportId === null) return invalid(GET_LABEL, "reportId");
520
+ const owner = {
521
+ kind,
522
+ id
523
+ };
524
+ const result = await readOwnersReport(client, owner, reportId);
525
+ const answered = await answerReportRead(client, owner, result, {
526
+ label: GET_LABEL,
527
+ read: "report",
528
+ summarise: summariseReport
529
+ });
530
+ return countedToolResult(answered, reportOpenedOccurrencesOf(result));
531
+ };
532
+ const REPORT_TOOLS = /* @__PURE__ */ new Map([
533
+ ["lighthouse_team_report_list", reportList("team")],
534
+ ["lighthouse_team_report_get", reportGet("team")],
535
+ ["lighthouse_portfolio_report_list", reportList("portfolio")],
536
+ ["lighthouse_portfolio_report_get", reportGet("portfolio")]
537
+ ]);
538
+ /** The handler of one of the report tools, or undefined for any other tool. */
539
+ const findReportTool = (name) => REPORT_TOOLS.get(name);
540
+ //#endregion
428
541
  //#region src/index.ts
429
542
  const getMcpCorePackageContract = () => ({
430
543
  name: "@letpeoplework/lighthouse-mcp-core",
@@ -1075,7 +1188,8 @@ const toolDefinitions = [
1075
1188
  name: "lighthouse_portfolio_metrics_processBehaviorChart",
1076
1189
  description: "Get one Process Behaviour Chart of a portfolio by ID, as Lighthouse computes it: its status (and statusReason when it is not Ready), the average and natural process limits, whether a baseline is configured, and every point (xValue, yValue) with the signals Lighthouse found on it (specialCauses: LargeChange, ModerateChange, ModerateShift, SmallShift; None means no signal) and whether it falls on a blackout day (isBlackout). metricType picks the chart: Throughput, Arrivals, Wip, WorkItemAge (the Total Work Item Age chart), CycleTime or FeatureSize. A point is a day, except on CycleTime, which has one point per finished work item, and FeatureSize, which has one per finished feature, each dated when it finished, so several can share a day. Use it for \"is something unusual going on\" and \"did our process change\"; never work a signal out yourself. Optionally filtered by start and end dates. A second text block, `summary: …`, states the answer as lh does, in the instance's terminology: the heading, the chart's title, and each signal with the days it fired, or that there are no signals; the facts are unchanged.",
1077
1190
  inputSchema: chartInputSchema(processBehaviorMetricTypes)
1078
- }
1191
+ },
1192
+ ...reportToolDefinitions
1079
1193
  ];
1080
1194
  const getDefinitionId = (argumentsPayload) => {
1081
1195
  if (typeof argumentsPayload !== "object" || argumentsPayload === null || Array.isArray(argumentsPayload)) return;
@@ -1362,6 +1476,7 @@ const toolInputSchemas = {
1362
1476
  lighthouse_team_refresh: z.object({ id: z.number().int() }),
1363
1477
  lighthouse_team_refinement_get: z.object({ id: z.number().int() }),
1364
1478
  ...refinementWriteInputSchemas,
1479
+ ...reportInputSchemas,
1365
1480
  lighthouse_portfolio_list: z.object({}),
1366
1481
  lighthouse_portfolio_get: z.object({ id: z.number().int() }),
1367
1482
  lighthouse_portfolio_refresh: z.object({ id: z.number().int() }),
@@ -1588,6 +1703,8 @@ const answerToolCall = (dependencies) => async (name, argumentsPayload) => {
1588
1703
  }
1589
1704
  const refinementTool = findRefinementTool(name);
1590
1705
  if (refinementTool !== void 0) return refinementTool(argumentsPayload, client, dependencies);
1706
+ const reportTool = findReportTool(name);
1707
+ if (reportTool !== void 0) return reportTool(argumentsPayload, client);
1591
1708
  if (name === "lighthouse_portfolio_list") return answerOwnerList("portfolio", "portfolios", client.listPortfolios(), client);
1592
1709
  if (name === "lighthouse_portfolio_get") {
1593
1710
  const id = getNumericId(argumentsPayload);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@letpeoplework/lighthouse-mcp-core",
3
- "version": "1.9.0",
3
+ "version": "1.10.0",
4
4
  "description": "Shared MCP semantics for Lighthouse",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,7 +26,7 @@
26
26
  "registry": "https://registry.npmjs.org/"
27
27
  },
28
28
  "dependencies": {
29
- "@letpeoplework/lighthouse-client": "1.11.0",
29
+ "@letpeoplework/lighthouse-client": "1.12.0",
30
30
  "@modelcontextprotocol/sdk": "^1.26.0",
31
31
  "@toon-format/toon": "^4.0.0",
32
32
  "zod": "^4.0.0"