@butlr/butlr-mcp-server 0.1.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.
Files changed (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +195 -0
  3. package/dist/cache/occupancy-cache.d.ts +72 -0
  4. package/dist/cache/occupancy-cache.d.ts.map +1 -0
  5. package/dist/cache/occupancy-cache.js +166 -0
  6. package/dist/cache/occupancy-cache.js.map +1 -0
  7. package/dist/cache/topology-cache.d.ts +36 -0
  8. package/dist/cache/topology-cache.d.ts.map +1 -0
  9. package/dist/cache/topology-cache.js +74 -0
  10. package/dist/cache/topology-cache.js.map +1 -0
  11. package/dist/clients/auth-client.d.ts +22 -0
  12. package/dist/clients/auth-client.d.ts.map +1 -0
  13. package/dist/clients/auth-client.js +82 -0
  14. package/dist/clients/auth-client.js.map +1 -0
  15. package/dist/clients/graphql-client.d.ts +6 -0
  16. package/dist/clients/graphql-client.d.ts.map +1 -0
  17. package/dist/clients/graphql-client.js +106 -0
  18. package/dist/clients/graphql-client.js.map +1 -0
  19. package/dist/clients/queries/topology.d.ts +36 -0
  20. package/dist/clients/queries/topology.d.ts.map +1 -0
  21. package/dist/clients/queries/topology.js +252 -0
  22. package/dist/clients/queries/topology.js.map +1 -0
  23. package/dist/clients/reporting-client.d.ts +191 -0
  24. package/dist/clients/reporting-client.d.ts.map +1 -0
  25. package/dist/clients/reporting-client.js +353 -0
  26. package/dist/clients/reporting-client.js.map +1 -0
  27. package/dist/clients/stats-client.d.ts +119 -0
  28. package/dist/clients/stats-client.d.ts.map +1 -0
  29. package/dist/clients/stats-client.js +238 -0
  30. package/dist/clients/stats-client.js.map +1 -0
  31. package/dist/clients/types.d.ts +215 -0
  32. package/dist/clients/types.d.ts.map +1 -0
  33. package/dist/clients/types.js +6 -0
  34. package/dist/clients/types.js.map +1 -0
  35. package/dist/constants.d.ts +3 -0
  36. package/dist/constants.d.ts.map +1 -0
  37. package/dist/constants.js +3 -0
  38. package/dist/constants.js.map +1 -0
  39. package/dist/errors/mcp-errors.d.ts +63 -0
  40. package/dist/errors/mcp-errors.d.ts.map +1 -0
  41. package/dist/errors/mcp-errors.js +144 -0
  42. package/dist/errors/mcp-errors.js.map +1 -0
  43. package/dist/index.d.ts +3 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +43 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/tools/butlr-available-rooms.d.ts +49 -0
  48. package/dist/tools/butlr-available-rooms.d.ts.map +1 -0
  49. package/dist/tools/butlr-available-rooms.js +492 -0
  50. package/dist/tools/butlr-available-rooms.js.map +1 -0
  51. package/dist/tools/butlr-fetch-entity-details.d.ts +42 -0
  52. package/dist/tools/butlr-fetch-entity-details.d.ts.map +1 -0
  53. package/dist/tools/butlr-fetch-entity-details.js +276 -0
  54. package/dist/tools/butlr-fetch-entity-details.js.map +1 -0
  55. package/dist/tools/butlr-get-asset-details.d.ts +51 -0
  56. package/dist/tools/butlr-get-asset-details.d.ts.map +1 -0
  57. package/dist/tools/butlr-get-asset-details.js +391 -0
  58. package/dist/tools/butlr-get-asset-details.js.map +1 -0
  59. package/dist/tools/butlr-get-current-occupancy.d.ts +21 -0
  60. package/dist/tools/butlr-get-current-occupancy.d.ts.map +1 -0
  61. package/dist/tools/butlr-get-current-occupancy.js +126 -0
  62. package/dist/tools/butlr-get-current-occupancy.js.map +1 -0
  63. package/dist/tools/butlr-get-occupancy-timeseries.d.ts +31 -0
  64. package/dist/tools/butlr-get-occupancy-timeseries.d.ts.map +1 -0
  65. package/dist/tools/butlr-get-occupancy-timeseries.js +145 -0
  66. package/dist/tools/butlr-get-occupancy-timeseries.js.map +1 -0
  67. package/dist/tools/butlr-hardware-snapshot.d.ts +55 -0
  68. package/dist/tools/butlr-hardware-snapshot.d.ts.map +1 -0
  69. package/dist/tools/butlr-hardware-snapshot.js +556 -0
  70. package/dist/tools/butlr-hardware-snapshot.js.map +1 -0
  71. package/dist/tools/butlr-list-topology.d.ts +27 -0
  72. package/dist/tools/butlr-list-topology.d.ts.map +1 -0
  73. package/dist/tools/butlr-list-topology.js +241 -0
  74. package/dist/tools/butlr-list-topology.js.map +1 -0
  75. package/dist/tools/butlr-search-assets.d.ts +53 -0
  76. package/dist/tools/butlr-search-assets.d.ts.map +1 -0
  77. package/dist/tools/butlr-search-assets.js +206 -0
  78. package/dist/tools/butlr-search-assets.js.map +1 -0
  79. package/dist/tools/butlr-space-busyness.d.ts +23 -0
  80. package/dist/tools/butlr-space-busyness.d.ts.map +1 -0
  81. package/dist/tools/butlr-space-busyness.js +304 -0
  82. package/dist/tools/butlr-space-busyness.js.map +1 -0
  83. package/dist/tools/butlr-traffic-flow.d.ts +39 -0
  84. package/dist/tools/butlr-traffic-flow.d.ts.map +1 -0
  85. package/dist/tools/butlr-traffic-flow.js +369 -0
  86. package/dist/tools/butlr-traffic-flow.js.map +1 -0
  87. package/dist/types/responses.d.ts +253 -0
  88. package/dist/types/responses.d.ts.map +1 -0
  89. package/dist/types/responses.js +8 -0
  90. package/dist/types/responses.js.map +1 -0
  91. package/dist/utils/asset-flattener.d.ts +50 -0
  92. package/dist/utils/asset-flattener.d.ts.map +1 -0
  93. package/dist/utils/asset-flattener.js +131 -0
  94. package/dist/utils/asset-flattener.js.map +1 -0
  95. package/dist/utils/asset-helpers.d.ts +8 -0
  96. package/dist/utils/asset-helpers.d.ts.map +1 -0
  97. package/dist/utils/asset-helpers.js +24 -0
  98. package/dist/utils/asset-helpers.js.map +1 -0
  99. package/dist/utils/field-validator.d.ts +29 -0
  100. package/dist/utils/field-validator.d.ts.map +1 -0
  101. package/dist/utils/field-validator.js +197 -0
  102. package/dist/utils/field-validator.js.map +1 -0
  103. package/dist/utils/fuzzy-match.d.ts +29 -0
  104. package/dist/utils/fuzzy-match.d.ts.map +1 -0
  105. package/dist/utils/fuzzy-match.js +70 -0
  106. package/dist/utils/fuzzy-match.js.map +1 -0
  107. package/dist/utils/graphql-helpers.d.ts +29 -0
  108. package/dist/utils/graphql-helpers.d.ts.map +1 -0
  109. package/dist/utils/graphql-helpers.js +43 -0
  110. package/dist/utils/graphql-helpers.js.map +1 -0
  111. package/dist/utils/natural-language.d.ts +73 -0
  112. package/dist/utils/natural-language.d.ts.map +1 -0
  113. package/dist/utils/natural-language.js +172 -0
  114. package/dist/utils/natural-language.js.map +1 -0
  115. package/dist/utils/occupancy-helpers.d.ts +63 -0
  116. package/dist/utils/occupancy-helpers.d.ts.map +1 -0
  117. package/dist/utils/occupancy-helpers.js +203 -0
  118. package/dist/utils/occupancy-helpers.js.map +1 -0
  119. package/dist/utils/path-builder.d.ts +10 -0
  120. package/dist/utils/path-builder.d.ts.map +1 -0
  121. package/dist/utils/path-builder.js +34 -0
  122. package/dist/utils/path-builder.js.map +1 -0
  123. package/dist/utils/time-range-validator.d.ts +13 -0
  124. package/dist/utils/time-range-validator.d.ts.map +1 -0
  125. package/dist/utils/time-range-validator.js +65 -0
  126. package/dist/utils/time-range-validator.js.map +1 -0
  127. package/dist/utils/timezone-helpers.d.ts +49 -0
  128. package/dist/utils/timezone-helpers.d.ts.map +1 -0
  129. package/dist/utils/timezone-helpers.js +209 -0
  130. package/dist/utils/timezone-helpers.js.map +1 -0
  131. package/dist/utils/tree-formatter.d.ts +23 -0
  132. package/dist/utils/tree-formatter.d.ts.map +1 -0
  133. package/dist/utils/tree-formatter.js +258 -0
  134. package/dist/utils/tree-formatter.js.map +1 -0
  135. package/package.json +93 -0
@@ -0,0 +1,556 @@
1
+ import { apolloClient } from "../clients/graphql-client.js";
2
+ import { gql } from "@apollo/client";
3
+ import { z } from "zod";
4
+ import { GET_ALL_SENSORS, GET_ALL_HIVES } from "../clients/queries/topology.js";
5
+ import { buildHardwareSummary, daysBetween, hoursBetween } from "../utils/natural-language.js";
6
+ import { isProductionSensor, isProductionHive, rethrowIfGraphQLError, } from "../utils/graphql-helpers.js";
7
+ /** Shared shape — used by both registerTool and full validation */
8
+ const hardwareSnapshotInputShape = {
9
+ scope_type: z
10
+ .enum(["org", "site", "building", "floor"])
11
+ .default("org")
12
+ .describe("Scope of the health check"),
13
+ scope_id: z
14
+ .string()
15
+ .min(1, "scope_id cannot be empty")
16
+ .optional()
17
+ .describe("Required if scope_type is not 'org'"),
18
+ include_battery_details: z
19
+ .boolean()
20
+ .default(false)
21
+ .describe("Include list of sensors needing battery service"),
22
+ battery_status_filter: z
23
+ .enum(["critical", "due_soon", "healthy", "all"])
24
+ .default("all")
25
+ .describe("Filter battery details by status"),
26
+ limit: z
27
+ .number()
28
+ .int("limit must be an integer")
29
+ .min(1, "limit must be at least 1")
30
+ .max(500, "limit cannot exceed 500")
31
+ .default(20)
32
+ .describe("Max devices in battery_details list"),
33
+ offline_devices_limit: z
34
+ .number()
35
+ .int("offline_devices_limit must be an integer")
36
+ .min(1)
37
+ .max(500)
38
+ .default(20)
39
+ .describe("Max offline devices to show"),
40
+ };
41
+ export const HardwareSnapshotArgsSchema = z
42
+ .object(hardwareSnapshotInputShape)
43
+ .strict()
44
+ .refine((data) => {
45
+ if (data.scope_type !== "org" && !data.scope_id) {
46
+ return false;
47
+ }
48
+ return true;
49
+ }, {
50
+ message: "scope_id is required when scope_type is not 'org'",
51
+ path: ["scope_id"],
52
+ });
53
+ const HARDWARE_SNAPSHOT_DESCRIPTION = "Get unified device health check combining online/offline status and battery health across your entire portfolio or specific locations. Provides proactive maintenance insights for facilities teams managing IoT sensor infrastructure.\n\n" +
54
+ "Primary Users:\n" +
55
+ "- IT Manager: Monitor sensor/hive uptime, track device health KPIs, report on system reliability\n" +
56
+ "- Field Technician: Identify devices needing maintenance before site visits, prioritize battery replacements\n" +
57
+ "- Facilities Manager: Verify system health before quarterly reviews, validate sensor coverage\n\n" +
58
+ "Example Queries:\n" +
59
+ '1. "Show me all offline sensors in Building 2 East Tower"\n' +
60
+ '2. "Which sensors need battery replacements in the next 7 days?"\n' +
61
+ '3. "Give me a hardware health snapshot for the SF office"\n' +
62
+ '4. "Are there any sensors that haven\'t reported in 24 hours?"\n' +
63
+ '5. "What\'s the battery status for Floor 3?"\n' +
64
+ '6. "How many hives are offline organization-wide?"\n' +
65
+ '7. "Show me sensors with overdue battery changes (critical status)"\n' +
66
+ '8. "I\'m planning a site visit to Chicago - what devices need attention?"\n\n' +
67
+ "When to Use:\n" +
68
+ "- Quick overview of device health for planning maintenance\n" +
69
+ "- Preparing for site visits (know which devices need service)\n" +
70
+ "- Proactive battery alerts before sensor failures impact data quality\n" +
71
+ "- Reporting uptime metrics or system reliability to leadership\n" +
72
+ "- Troubleshooting missing data issues (check if sensors are online)\n\n" +
73
+ "When NOT to Use:\n" +
74
+ "- Need detailed config for specific sensor → use butlr_get_asset_details with include_devices: true\n" +
75
+ "- Searching for sensor by name/MAC → use butlr_search_assets first with asset_types: ['sensor']\n" +
76
+ "- Historical device uptime trends → this tool shows current snapshot only\n\n" +
77
+ "CRE Context: Battery-powered sensors typically last 1-2 years depending on mode. Proactive battery management prevents data gaps that could impact space utilization reporting and right-sizing decisions.\n\n" +
78
+ "See Also: butlr_search_assets, butlr_get_asset_details, butlr_list_topology";
79
+ /**
80
+ * GraphQL query for topology (without devices - they're queried separately)
81
+ */
82
+ const GET_TOPOLOGY_FOR_HEALTH = gql `
83
+ query GetTopologyForHealth {
84
+ sites {
85
+ data {
86
+ id
87
+ name
88
+ buildings {
89
+ id
90
+ name
91
+ site_id
92
+ floors {
93
+ id
94
+ name
95
+ building_id
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ `;
102
+ /**
103
+ * Calculate battery status for a sensor
104
+ * Exported for unit testing
105
+ */
106
+ export function getBatteryStatus(sensor, currentDate = new Date()) {
107
+ // Wired sensors don't use batteries
108
+ if (sensor.power_type === "Wired") {
109
+ return "no_battery";
110
+ }
111
+ // No battery_change_by_date means we don't have battery tracking
112
+ if (!sensor.battery_change_by_date) {
113
+ return "unknown";
114
+ }
115
+ const changeByDate = new Date(sensor.battery_change_by_date);
116
+ const daysRemaining = daysBetween(currentDate, changeByDate);
117
+ if (daysRemaining < 0) {
118
+ return "critical"; // Overdue!
119
+ }
120
+ else if (daysRemaining <= 30) {
121
+ return "due_soon"; // Within 30 days
122
+ }
123
+ else {
124
+ return "healthy";
125
+ }
126
+ }
127
+ /**
128
+ * Build hierarchy context for a sensor/hive
129
+ */
130
+ function buildDevicePath(device, floors, buildings, sites) {
131
+ const deviceFloorId = device.floor_id || device.floorID;
132
+ const floor = floors.find((f) => f.id === deviceFloorId);
133
+ if (!floor)
134
+ return device.name;
135
+ const building = buildings.find((b) => b.id === floor.building_id);
136
+ if (!building)
137
+ return `${floor.name} > ${device.name}`;
138
+ const site = sites.find((s) => s.id === building.site_id);
139
+ if (!site)
140
+ return `${building.name} > ${floor.name} > ${device.name}`;
141
+ return `${site.name} > ${building.name} > ${floor.name} > ${device.name}`;
142
+ }
143
+ /**
144
+ * Filter production devices from raw API responses, excluding test/mirror/placeholder devices.
145
+ * Returns production devices and counts of excluded test devices.
146
+ */
147
+ function filterProductionDevices(rawSensors, rawHives) {
148
+ const sensors = rawSensors.filter(isProductionSensor);
149
+ const hives = rawHives.filter(isProductionHive);
150
+ const mirrorSensors = rawSensors.filter((s) => s.mac_address?.startsWith("mi-rr-or") || s.mac_address?.startsWith("fa-ke")).length;
151
+ const emptySensors = rawSensors.filter((s) => !s.mac_address || s.mac_address.trim() === "").length;
152
+ const fakeHives = rawHives.filter((h) => h.serialNumber?.toLowerCase().startsWith("fake")).length;
153
+ const emptyHives = rawHives.filter((h) => !h.serialNumber || h.serialNumber.trim() === "").length;
154
+ return {
155
+ sensors,
156
+ hives,
157
+ testCounts: {
158
+ sensors: {
159
+ mirror: mirrorSensors,
160
+ placeholder: emptySensors,
161
+ total_test: mirrorSensors + emptySensors,
162
+ },
163
+ hives: { fake: fakeHives, placeholder: emptyHives, total_test: fakeHives + emptyHives },
164
+ },
165
+ };
166
+ }
167
+ /**
168
+ * Group devices by floor ID and merge into floor objects
169
+ */
170
+ function assignDevicesToFloors(sensors, hives, floors) {
171
+ const sensorsByFloor = {};
172
+ const hivesByFloor = {};
173
+ for (const sensor of sensors) {
174
+ const floorId = sensor.floor_id || sensor.floorID;
175
+ if (floorId) {
176
+ if (!sensorsByFloor[floorId])
177
+ sensorsByFloor[floorId] = [];
178
+ sensorsByFloor[floorId].push(sensor);
179
+ }
180
+ }
181
+ for (const hive of hives) {
182
+ const floorId = hive.floor_id || hive.floorID;
183
+ if (floorId) {
184
+ if (!hivesByFloor[floorId])
185
+ hivesByFloor[floorId] = [];
186
+ hivesByFloor[floorId].push(hive);
187
+ }
188
+ }
189
+ for (const floor of floors) {
190
+ floor.sensors = sensorsByFloor[floor.id] || [];
191
+ floor.hives = hivesByFloor[floor.id] || [];
192
+ }
193
+ }
194
+ /**
195
+ * Execute hardware snapshot tool
196
+ */
197
+ export async function executeHardwareSnapshot(args) {
198
+ const scopeType = args.scope_type;
199
+ if (process.env.DEBUG) {
200
+ console.error(`[hardware-snapshot] Querying device health for scope: ${scopeType}${args.scope_id ? `:${args.scope_id}` : ""}`);
201
+ }
202
+ let floors = [];
203
+ let buildings = [];
204
+ let sites = [];
205
+ let scopeName = "";
206
+ let testDeviceCounts = null;
207
+ try {
208
+ // Fetch all devices org-wide (API doesn't support scope-filtered device queries)
209
+ const [sensorsResult, hivesResult] = await Promise.all([
210
+ apolloClient.query({
211
+ query: GET_ALL_SENSORS,
212
+ fetchPolicy: "network-only",
213
+ }),
214
+ apolloClient.query({
215
+ query: GET_ALL_HIVES,
216
+ fetchPolicy: "network-only",
217
+ }),
218
+ ]);
219
+ const allSensorsRaw = sensorsResult.data?.sensors?.data || [];
220
+ const allHivesRaw = hivesResult.data?.hives?.data || [];
221
+ if (scopeType === "org") {
222
+ const topoResult = await apolloClient.query({
223
+ query: GET_TOPOLOGY_FOR_HEALTH,
224
+ fetchPolicy: "network-only",
225
+ });
226
+ if (!topoResult.data?.sites?.data) {
227
+ throw new Error("Invalid response structure from API");
228
+ }
229
+ sites = topoResult.data.sites.data;
230
+ buildings = sites.flatMap((s) => s.buildings || []);
231
+ floors = buildings.flatMap((b) => b.floors || []);
232
+ scopeName = "Organization";
233
+ }
234
+ else if (scopeType === "site") {
235
+ const siteResult = await apolloClient.query({
236
+ query: gql `
237
+ query GetSite($id: ID!) {
238
+ site(id: $id) {
239
+ id
240
+ name
241
+ buildings {
242
+ id
243
+ name
244
+ site_id
245
+ floors {
246
+ id
247
+ name
248
+ building_id
249
+ }
250
+ }
251
+ }
252
+ }
253
+ `,
254
+ variables: { id: args.scope_id },
255
+ fetchPolicy: "network-only",
256
+ });
257
+ if (!siteResult.data?.site) {
258
+ throw new Error(`Site ${args.scope_id} not found`);
259
+ }
260
+ sites = [siteResult.data.site];
261
+ buildings = sites[0].buildings || [];
262
+ floors = buildings.flatMap((b) => b.floors || []);
263
+ scopeName = sites[0].name;
264
+ }
265
+ else if (scopeType === "building") {
266
+ const buildingResult = await apolloClient.query({
267
+ query: gql `
268
+ query GetBuilding($id: ID!) {
269
+ building(id: $id) {
270
+ id
271
+ name
272
+ site_id
273
+ floors {
274
+ id
275
+ name
276
+ building_id
277
+ }
278
+ }
279
+ }
280
+ `,
281
+ variables: { id: args.scope_id },
282
+ fetchPolicy: "network-only",
283
+ });
284
+ if (!buildingResult.data?.building) {
285
+ throw new Error(`Building ${args.scope_id} not found`);
286
+ }
287
+ buildings = [buildingResult.data.building];
288
+ floors = buildings[0].floors || [];
289
+ scopeName = buildings[0].name;
290
+ }
291
+ else if (scopeType === "floor") {
292
+ const floorResult = await apolloClient.query({
293
+ query: gql `
294
+ query GetFloor($id: ID!) {
295
+ floor(id: $id) {
296
+ id
297
+ name
298
+ building_id
299
+ }
300
+ }
301
+ `,
302
+ variables: { id: args.scope_id },
303
+ fetchPolicy: "network-only",
304
+ });
305
+ if (!floorResult.data?.floor) {
306
+ throw new Error(`Floor ${args.scope_id} not found`);
307
+ }
308
+ floors = [floorResult.data.floor];
309
+ scopeName = floors[0].name;
310
+ }
311
+ // Filter production devices and assign to scoped floors
312
+ const { sensors: prodSensors, hives: prodHives, testCounts, } = filterProductionDevices(allSensorsRaw, allHivesRaw);
313
+ assignDevicesToFloors(prodSensors, prodHives, floors);
314
+ // Only include test device counts for org scope (where they're meaningful)
315
+ if (scopeType === "org") {
316
+ testDeviceCounts = testCounts;
317
+ }
318
+ }
319
+ catch (error) {
320
+ rethrowIfGraphQLError(error);
321
+ throw error;
322
+ }
323
+ // Collect scoped sensors and hives (only devices on floors within this scope)
324
+ const allSensors = floors.flatMap((f) => f.sensors || []);
325
+ const allHives = floors.flatMap((f) => f.hives || []);
326
+ if (process.env.DEBUG) {
327
+ console.error(`[hardware-snapshot] Found ${allSensors.length} sensors, ${allHives.length} hives`);
328
+ }
329
+ // Calculate sensor statistics
330
+ const sensorsOnline = allSensors.filter((s) => s.is_online).length;
331
+ const sensorsOffline = allSensors.length - sensorsOnline;
332
+ const sensorsPercentOnline = allSensors.length > 0 ? parseFloat(((sensorsOnline / allSensors.length) * 100).toFixed(1)) : 0;
333
+ // Calculate hive statistics
334
+ const hivesOnline = allHives.filter((h) => h.isOnline).length;
335
+ const hivesOffline = allHives.length - hivesOnline;
336
+ const hivesPercentOnline = allHives.length > 0 ? parseFloat(((hivesOnline / allHives.length) * 100).toFixed(1)) : 0;
337
+ // Calculate battery health
338
+ const batteryStatusCounts = {
339
+ critical: 0,
340
+ due_soon: 0,
341
+ healthy: 0,
342
+ unknown: 0,
343
+ no_battery: 0,
344
+ };
345
+ const batteryDetails = [];
346
+ for (const sensor of allSensors) {
347
+ const status = getBatteryStatus(sensor);
348
+ batteryStatusCounts[status]++;
349
+ // If user requested battery details and this sensor matches filter
350
+ if (args.include_battery_details) {
351
+ const statusFilter = args.battery_status_filter || "all";
352
+ if (statusFilter === "all" || statusFilter === status) {
353
+ const now = new Date();
354
+ const changeByDate = sensor.battery_change_by_date
355
+ ? new Date(sensor.battery_change_by_date)
356
+ : null;
357
+ const daysRemaining = changeByDate ? daysBetween(now, changeByDate) : 0;
358
+ batteryDetails.push({
359
+ sensor_id: sensor.id,
360
+ sensor_name: sensor.name,
361
+ mac_address: sensor.mac_address, // Human-readable identifier
362
+ path: buildDevicePath(sensor, floors, buildings, sites),
363
+ status,
364
+ battery_change_by_date: sensor.battery_change_by_date || "N/A",
365
+ days_remaining: daysRemaining,
366
+ last_battery_change_date: sensor.last_battery_change_date,
367
+ next_battery_change_date: sensor.next_battery_change_date,
368
+ });
369
+ }
370
+ }
371
+ }
372
+ // Sort battery details by urgency (most urgent first)
373
+ batteryDetails.sort((a, b) => a.days_remaining - b.days_remaining);
374
+ // Limit battery details
375
+ const limit = args.limit || 20;
376
+ const limitedBatteryDetails = batteryDetails.slice(0, limit);
377
+ // Build summary
378
+ const summary = buildHardwareSummary({
379
+ sensorsOnline,
380
+ sensorsTotal: allSensors.length,
381
+ hivesOnline,
382
+ hivesTotal: allHives.length,
383
+ batteriesCritical: batteryStatusCounts.critical,
384
+ batteriesDueSoon: batteryStatusCounts.due_soon,
385
+ });
386
+ // Build floor breakdown if multiple floors
387
+ const breakdownByFloor = [];
388
+ if (floors.length > 1) {
389
+ for (const floor of floors) {
390
+ const floorSensors = allSensors.filter((s) => (s.floor_id || s.floorID) === floor.id);
391
+ const floorSensorsOnline = floorSensors.filter((s) => s.is_online).length;
392
+ const floorBatteriesCritical = floorSensors.filter((s) => getBatteryStatus(s) === "critical").length;
393
+ const floorBatteriesDueSoon = floorSensors.filter((s) => getBatteryStatus(s) === "due_soon").length;
394
+ breakdownByFloor.push({
395
+ floor_id: floor.id,
396
+ floor_name: floor.name,
397
+ sensors_online: floorSensorsOnline,
398
+ sensors_total: floorSensors.length,
399
+ percent_online: floorSensors.length > 0
400
+ ? parseFloat(((floorSensorsOnline / floorSensors.length) * 100).toFixed(1))
401
+ : 0,
402
+ batteries_critical: floorBatteriesCritical,
403
+ batteries_due_soon: floorBatteriesDueSoon,
404
+ });
405
+ }
406
+ }
407
+ // Build offline devices list
408
+ const offlineDevices = [];
409
+ const now = new Date();
410
+ for (const sensor of allSensors) {
411
+ if (!sensor.is_online) {
412
+ // Use isOnline consistently, heartbeat is optional enrichment
413
+ const lastHeartbeat = sensor.last_heartbeat
414
+ ? new Date(sensor.last_heartbeat * 1000)
415
+ : undefined;
416
+ const hoursOffline = lastHeartbeat ? hoursBetween(lastHeartbeat, now) : undefined;
417
+ offlineDevices.push({
418
+ type: "sensor",
419
+ id: sensor.id,
420
+ name: sensor.name,
421
+ mac_address: sensor.mac_address,
422
+ path: buildDevicePath(sensor, floors, buildings, sites),
423
+ last_heartbeat: lastHeartbeat?.toISOString(),
424
+ hours_offline: hoursOffline,
425
+ });
426
+ }
427
+ }
428
+ for (const hive of allHives) {
429
+ if (!hive.isOnline) {
430
+ // Use isOnline consistently, heartbeat is optional enrichment
431
+ const lastHeartbeat = hive.lastHeartbeat ? new Date(hive.lastHeartbeat * 1000) : undefined;
432
+ const hoursOffline = lastHeartbeat ? hoursBetween(lastHeartbeat, now) : undefined;
433
+ offlineDevices.push({
434
+ type: "hive",
435
+ id: hive.id,
436
+ name: hive.name,
437
+ serial_number: hive.serialNumber,
438
+ path: buildDevicePath(hive, floors, buildings, sites),
439
+ last_heartbeat: lastHeartbeat?.toISOString(),
440
+ hours_offline: hoursOffline,
441
+ });
442
+ }
443
+ }
444
+ // Sort offline devices by hours offline (SHORTEST first for devices with heartbeat data)
445
+ // Devices without heartbeat go to end
446
+ offlineDevices.sort((a, b) => {
447
+ if (a.hours_offline === undefined && b.hours_offline === undefined)
448
+ return 0;
449
+ if (a.hours_offline === undefined)
450
+ return 1; // No heartbeat goes to end
451
+ if (b.hours_offline === undefined)
452
+ return -1; // No heartbeat goes to end
453
+ return a.hours_offline - b.hours_offline; // Shortest offline first
454
+ });
455
+ // Count offline devices by type
456
+ const offlineSensorCount = offlineDevices.filter((d) => d.type === "sensor").length;
457
+ const offlineHiveCount = offlineDevices.filter((d) => d.type === "hive").length;
458
+ // Build enhanced summary with truncation info
459
+ const offlineDeviceLimit = args.offline_devices_limit || 20;
460
+ let enhancedSummary = summary;
461
+ if (offlineDevices.length > offlineDeviceLimit) {
462
+ enhancedSummary += ` Showing ${offlineDeviceLimit} most recently offline devices (${offlineSensorCount} sensors, ${offlineHiveCount} hives offline).`;
463
+ }
464
+ // Build response
465
+ const response = {
466
+ summary: enhancedSummary,
467
+ sensors: {
468
+ total: allSensors.length,
469
+ online: sensorsOnline,
470
+ offline: sensorsOffline,
471
+ percent_online: sensorsPercentOnline,
472
+ },
473
+ hives: {
474
+ total: allHives.length,
475
+ online: hivesOnline,
476
+ offline: hivesOffline,
477
+ percent_online: hivesPercentOnline,
478
+ },
479
+ battery_health: batteryStatusCounts,
480
+ scope: {
481
+ type: scopeType,
482
+ id: args.scope_id,
483
+ name: scopeName,
484
+ },
485
+ timestamp: new Date().toISOString(),
486
+ };
487
+ // Add test device breakdown if any exist
488
+ if (testDeviceCounts !== null) {
489
+ const totalTestSensors = testDeviceCounts.sensors.total_test;
490
+ const totalTestHives = testDeviceCounts.hives.total_test;
491
+ if (totalTestSensors > 0 || totalTestHives > 0) {
492
+ response.test_devices_excluded = {
493
+ sensors: {
494
+ mirror: testDeviceCounts.sensors.mirror,
495
+ placeholder: testDeviceCounts.sensors.placeholder,
496
+ total: totalTestSensors,
497
+ },
498
+ hives: {
499
+ fake: testDeviceCounts.hives.fake,
500
+ placeholder: testDeviceCounts.hives.placeholder,
501
+ total: totalTestHives,
502
+ },
503
+ note: `Totals exclude ${totalTestSensors} test/placeholder sensors and ${totalTestHives} test hives. These devices still produce occupancy data.`,
504
+ };
505
+ }
506
+ }
507
+ // Conditionally add optional fields
508
+ if (args.include_battery_details && limitedBatteryDetails.length > 0) {
509
+ response.battery_details = limitedBatteryDetails;
510
+ if (batteryDetails.length > limit) {
511
+ response.battery_details_truncated = true;
512
+ response.battery_details_total = batteryDetails.length;
513
+ }
514
+ }
515
+ if (breakdownByFloor.length > 0) {
516
+ response.breakdown_by_floor = breakdownByFloor;
517
+ }
518
+ if (offlineDevices.length > 0) {
519
+ const limitedOffline = offlineDevices.slice(0, offlineDeviceLimit);
520
+ response.offline_devices = limitedOffline;
521
+ response.offline_devices_summary = {
522
+ sensors_offline: offlineSensorCount,
523
+ hives_offline: offlineHiveCount,
524
+ total_offline: offlineDevices.length,
525
+ showing: limitedOffline.length,
526
+ };
527
+ if (offlineDevices.length > offlineDeviceLimit) {
528
+ response.offline_devices_truncated = true;
529
+ response.offline_devices_total = offlineDevices.length;
530
+ }
531
+ }
532
+ return response;
533
+ }
534
+ /**
535
+ * Register butlr_hardware_snapshot with an McpServer instance
536
+ */
537
+ export function registerHardwareSnapshot(server) {
538
+ server.registerTool("butlr_hardware_snapshot", {
539
+ title: "Butlr Hardware Health Snapshot",
540
+ description: HARDWARE_SNAPSHOT_DESCRIPTION,
541
+ inputSchema: hardwareSnapshotInputShape,
542
+ annotations: {
543
+ readOnlyHint: true,
544
+ destructiveHint: false,
545
+ idempotentHint: false, // Real-time data changes between calls
546
+ openWorldHint: true,
547
+ },
548
+ }, async (args) => {
549
+ const validated = HardwareSnapshotArgsSchema.parse(args);
550
+ const result = await executeHardwareSnapshot(validated);
551
+ return {
552
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
553
+ };
554
+ });
555
+ }
556
+ //# sourceMappingURL=butlr-hardware-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butlr-hardware-snapshot.js","sourceRoot":"","sources":["../../src/tools/butlr-hardware-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import type { ListTopologyResponse } from "../types/responses.js";
4
+ export declare const ListTopologyArgsSchema: z.ZodObject<{
5
+ asset_ids: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
6
+ starting_depth: z.ZodDefault<z.ZodNumber>;
7
+ traversal_depth: z.ZodDefault<z.ZodNumber>;
8
+ }, "strict", z.ZodTypeAny, {
9
+ starting_depth: number;
10
+ traversal_depth: number;
11
+ asset_ids?: string[] | undefined;
12
+ }, {
13
+ asset_ids?: string[] | undefined;
14
+ starting_depth?: number | undefined;
15
+ traversal_depth?: number | undefined;
16
+ }>;
17
+ type ListTopologyArgs = z.output<typeof ListTopologyArgsSchema>;
18
+ /**
19
+ * Execute butlr_list_topology tool
20
+ */
21
+ export declare function executeListTopology(args?: ListTopologyArgs): Promise<ListTopologyResponse>;
22
+ /**
23
+ * Register butlr_list_topology with an McpServer instance
24
+ */
25
+ export declare function registerListTopology(server: McpServer): void;
26
+ export {};
27
+ //# sourceMappingURL=butlr-list-topology.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butlr-list-topology.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-list-topology.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAazE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAYxB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAkClE,eAAO,MAAM,sBAAsB;;;;;;;;;;;;EAA4C,CAAC;AAEhF,KAAK,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEhE;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,GAAE,gBAAyC,GAC9C,OAAO,CAAC,oBAAoB,CAAC,CAiI/B;AAoGD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB5D"}