@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,492 @@
1
+ import { apolloClient } from "../clients/graphql-client.js";
2
+ import { gql } from "@apollo/client";
3
+ import { z } from "zod";
4
+ import { getCurrentOccupancy } from "../clients/reporting-client.js";
5
+ import { buildAvailableRoomsSummary } from "../utils/natural-language.js";
6
+ import { getCachedOccupancy, setBulkCachedOccupancy } from "../cache/occupancy-cache.js";
7
+ import { rethrowIfGraphQLError } from "../utils/graphql-helpers.js";
8
+ /** Shared shape — used by both registerTool (SDK schema) and full validation */
9
+ const availableRoomsInputShape = {
10
+ min_capacity: z
11
+ .number()
12
+ .int("min_capacity must be an integer")
13
+ .min(1, "min_capacity must be at least 1 person")
14
+ .max(10000)
15
+ .optional()
16
+ .describe("Minimum room capacity"),
17
+ max_capacity: z
18
+ .number()
19
+ .int("max_capacity must be an integer")
20
+ .min(1, "max_capacity must be at least 1 person")
21
+ .max(10000)
22
+ .optional()
23
+ .describe("Maximum room capacity"),
24
+ tags: z
25
+ .array(z.string().min(1, "Tag cannot be empty").trim())
26
+ .min(1, "tags array cannot be empty")
27
+ .optional()
28
+ .describe("Filter by room tags"),
29
+ building_id: z
30
+ .string()
31
+ .regex(/^building_[a-zA-Z0-9_-]+$/, "building_id must match pattern: 'building_<id>'")
32
+ .optional()
33
+ .describe("Limit to specific building"),
34
+ floor_id: z
35
+ .string()
36
+ .regex(/^(floor|space)_[a-zA-Z0-9_-]+$/, "floor_id must match pattern: 'floor_<id>' or 'space_<id>'")
37
+ .optional()
38
+ .describe("Limit to specific floor"),
39
+ max_results: z
40
+ .number()
41
+ .int()
42
+ .min(1)
43
+ .max(200)
44
+ .default(50)
45
+ .describe("Maximum rooms to return (default: 50)"),
46
+ };
47
+ export const AvailableRoomsArgsSchema = z
48
+ .object(availableRoomsInputShape)
49
+ .strict()
50
+ .refine((data) => {
51
+ if (data.min_capacity !== undefined && data.max_capacity !== undefined) {
52
+ return data.min_capacity <= data.max_capacity;
53
+ }
54
+ return true;
55
+ }, {
56
+ message: "min_capacity cannot be greater than max_capacity",
57
+ path: ["min_capacity"],
58
+ });
59
+ const AVAILABLE_ROOMS_DESCRIPTION = "Find meeting rooms and collaboration spaces currently unoccupied (occupancy = 0), with optional filters for capacity and room tags. Designed for workplace experience teams and hoteling/room booking integrations. Returns real-time availability based on last 5 minutes of occupancy data.\n\n" +
60
+ "Primary Users:\n" +
61
+ "- Workplace Manager: Monitor meeting room availability, optimize room booking systems, improve employee experience\n" +
62
+ "- Executive Assistant: Find available conference rooms for urgent meetings, check capacity for client visits\n" +
63
+ "- Facilities Coordinator: Validate room availability before events, troubleshoot booking system discrepancies\n" +
64
+ "- Portfolio Manager: Assess meeting room utilization vs. demand, identify underutilized rooms for right-sizing\n\n" +
65
+ "Example Queries:\n" +
66
+ '1. "Are there any conference rooms free right now in Building 3?"\n' +
67
+ '2. "Find available rooms with capacity for at least 8 people"\n' +
68
+ '3. "Show me available video-equipped conference rooms"\n' +
69
+ '4. "Which meeting rooms on Floor 6 are currently empty?"\n' +
70
+ '5. "Find available flex spaces or collaboration areas"\n' +
71
+ '6. "Are there any private focus rooms available (capacity 1-2)?"\n' +
72
+ '7. "Show me all empty rooms in the San Francisco office"\n' +
73
+ '8. "Find available rooms between 6-12 person capacity"\n\n' +
74
+ "When to Use:\n" +
75
+ "- Real-time room availability for immediate use (next 5-10 minutes)\n" +
76
+ "- Filter by capacity (e.g., rooms for 6-8 people)\n" +
77
+ "- Filter by room types using tags (conference, collaboration, focus)\n" +
78
+ "- Validating room booking system accuracy against actual occupancy\n" +
79
+ "- Analyzing meeting room demand vs. supply across buildings/floors\n\n" +
80
+ "When NOT to Use:\n" +
81
+ "- Future availability predictions → this tool shows current state only\n" +
82
+ "- Understanding why rooms are underutilized → use butlr_space_busyness or timeseries data\n" +
83
+ "- Analyzing utilization patterns over time → use butlr_get_occupancy_timeseries\n" +
84
+ "- Booking/reserving rooms → this is read-only; integrate with your booking system\n\n" +
85
+ "CRE Context: Meeting rooms are expensive real estate (avg $150-300/sqft in Class A offices). This tool helps validate booking system accuracy and identify 'ghost bookings' (booked but unused).\n\n" +
86
+ "See Also: butlr_space_busyness, butlr_get_occupancy_timeseries, butlr_search_assets";
87
+ const GET_ROOMS_BY_FLOOR = gql `
88
+ query GetRoomsByFloor($floorId: ID!) {
89
+ floor(id: $floorId) {
90
+ id
91
+ name
92
+ building_id
93
+ rooms {
94
+ id
95
+ name
96
+ floorID
97
+ roomType
98
+ capacity {
99
+ max
100
+ mid
101
+ }
102
+ area {
103
+ value
104
+ unit
105
+ }
106
+ coordinates
107
+ customID
108
+ }
109
+ building {
110
+ id
111
+ name
112
+ site_id
113
+ }
114
+ }
115
+ }
116
+ `;
117
+ const GET_ROOMS_BY_BUILDING = gql `
118
+ query GetRoomsByBuilding($buildingId: ID!) {
119
+ building(id: $buildingId) {
120
+ id
121
+ name
122
+ site_id
123
+ floors {
124
+ id
125
+ name
126
+ building_id
127
+ rooms {
128
+ id
129
+ name
130
+ floorID
131
+ roomType
132
+ capacity {
133
+ max
134
+ mid
135
+ }
136
+ area {
137
+ value
138
+ unit
139
+ }
140
+ coordinates
141
+ customID
142
+ }
143
+ }
144
+ }
145
+ }
146
+ `;
147
+ const GET_ROOMS_BY_TAG = gql `
148
+ query GetRoomsByTag($tags: [String!]!) {
149
+ roomsByTag(tags: $tags) {
150
+ id
151
+ name
152
+ floorID
153
+ roomType
154
+ capacity {
155
+ max
156
+ mid
157
+ }
158
+ area {
159
+ value
160
+ unit
161
+ }
162
+ coordinates
163
+ customID
164
+ floor {
165
+ id
166
+ name
167
+ building_id
168
+ building {
169
+ id
170
+ name
171
+ site_id
172
+ }
173
+ }
174
+ }
175
+ }
176
+ `;
177
+ const GET_ALL_ROOMS = gql `
178
+ query GetAllRooms {
179
+ sites {
180
+ data {
181
+ id
182
+ name
183
+ buildings {
184
+ id
185
+ name
186
+ site_id
187
+ floors {
188
+ id
189
+ name
190
+ building_id
191
+ rooms {
192
+ id
193
+ name
194
+ floorID
195
+ roomType
196
+ capacity {
197
+ max
198
+ mid
199
+ }
200
+ area {
201
+ value
202
+ unit
203
+ }
204
+ coordinates
205
+ customID
206
+ }
207
+ }
208
+ }
209
+ }
210
+ }
211
+ }
212
+ `;
213
+ /**
214
+ * Execute available rooms tool
215
+ */
216
+ export async function executeAvailableRooms(args) {
217
+ if (process.env.DEBUG) {
218
+ console.error(`[available-rooms] Finding available rooms with filters:`, JSON.stringify(args, null, 2));
219
+ }
220
+ // Query rooms based on scope
221
+ let rooms = [];
222
+ let buildings = [];
223
+ let floors = [];
224
+ try {
225
+ if (args.floor_id) {
226
+ // Query specific floor
227
+ const result = await apolloClient.query({
228
+ query: GET_ROOMS_BY_FLOOR,
229
+ variables: { floorId: args.floor_id },
230
+ fetchPolicy: "network-only",
231
+ });
232
+ if (!result.data?.floor) {
233
+ throw new Error(`Floor ${args.floor_id} not found`);
234
+ }
235
+ rooms = result.data.floor.rooms || [];
236
+ floors = [result.data.floor];
237
+ buildings = result.data.floor.building ? [result.data.floor.building] : [];
238
+ }
239
+ else if (args.building_id) {
240
+ // Query specific building
241
+ const result = await apolloClient.query({
242
+ query: GET_ROOMS_BY_BUILDING,
243
+ variables: { buildingId: args.building_id },
244
+ fetchPolicy: "network-only",
245
+ });
246
+ if (!result.data?.building) {
247
+ throw new Error(`Building ${args.building_id} not found`);
248
+ }
249
+ buildings = [result.data.building];
250
+ floors = result.data.building.floors || [];
251
+ rooms = floors.flatMap((f) => f.rooms || []);
252
+ }
253
+ else if (args.tags && args.tags.length > 0) {
254
+ // Query by tags
255
+ const result = await apolloClient.query({
256
+ query: GET_ROOMS_BY_TAG,
257
+ variables: { tags: args.tags },
258
+ fetchPolicy: "network-only",
259
+ });
260
+ if (!result.data?.roomsByTag) {
261
+ throw new Error("Invalid response structure from API");
262
+ }
263
+ rooms = result.data.roomsByTag;
264
+ // Extract floors and buildings from room.floor references
265
+ for (const room of rooms) {
266
+ if (room.floor) {
267
+ floors.push(room.floor);
268
+ if (room.floor.building) {
269
+ buildings.push(room.floor.building);
270
+ }
271
+ }
272
+ }
273
+ }
274
+ else {
275
+ // Query all rooms (org-wide)
276
+ const result = await apolloClient.query({
277
+ query: GET_ALL_ROOMS,
278
+ fetchPolicy: "network-only",
279
+ });
280
+ if (!result.data?.sites?.data) {
281
+ throw new Error("Invalid response structure from API");
282
+ }
283
+ buildings = result.data.sites.data.flatMap((s) => s.buildings || []);
284
+ floors = buildings.flatMap((b) => b.floors || []);
285
+ rooms = floors.flatMap((f) => f.rooms || []);
286
+ }
287
+ }
288
+ catch (error) {
289
+ rethrowIfGraphQLError(error);
290
+ throw error;
291
+ }
292
+ if (process.env.DEBUG) {
293
+ console.error(`[available-rooms] Found ${rooms.length} rooms before filtering`);
294
+ }
295
+ // Apply capacity filters and track rooms excluded due to missing capacity data
296
+ const warnings = [];
297
+ if (args.min_capacity !== undefined || args.max_capacity !== undefined) {
298
+ const roomsWithoutCapacity = rooms.filter((r) => !r.capacity?.max).length;
299
+ if (args.min_capacity !== undefined) {
300
+ rooms = rooms.filter((r) => r.capacity?.max && r.capacity.max >= args.min_capacity);
301
+ }
302
+ if (args.max_capacity !== undefined) {
303
+ rooms = rooms.filter((r) => r.capacity?.max && r.capacity.max <= args.max_capacity);
304
+ }
305
+ if (roomsWithoutCapacity > 0) {
306
+ warnings.push(`${roomsWithoutCapacity} room(s) excluded because they have no capacity data configured.`);
307
+ }
308
+ }
309
+ if (rooms.length === 0) {
310
+ // No rooms match filters — unified return shape
311
+ const response = {
312
+ summary: buildAvailableRoomsSummary({
313
+ count: 0,
314
+ roomType: args.tags?.[0],
315
+ }),
316
+ available_rooms: [],
317
+ total_available: 0,
318
+ showing: 0,
319
+ timestamp: new Date().toISOString(),
320
+ };
321
+ if (Object.keys(args).length > 0) {
322
+ response.filtered_by = args;
323
+ }
324
+ if (warnings.length > 0) {
325
+ response.warning = warnings.join(" ");
326
+ }
327
+ return response;
328
+ }
329
+ // Get current occupancy for all rooms
330
+ const roomIds = rooms.map((r) => r.id);
331
+ if (process.env.DEBUG) {
332
+ console.error(`[available-rooms] Querying occupancy for ${roomIds.length} rooms`);
333
+ }
334
+ // Check cache first
335
+ const now = new Date();
336
+ const occupancyMap = {};
337
+ for (const roomId of roomIds) {
338
+ const cached = getCachedOccupancy(roomId, now);
339
+ if (cached) {
340
+ occupancyMap[roomId] = cached.occupancy;
341
+ }
342
+ }
343
+ // Query uncached rooms
344
+ const uncachedRoomIds = roomIds.filter((id) => !(id in occupancyMap));
345
+ let occupancyFetchFailed = false;
346
+ if (uncachedRoomIds.length > 0) {
347
+ if (process.env.DEBUG) {
348
+ console.error(`[available-rooms] Cache miss for ${uncachedRoomIds.length} rooms, querying API`);
349
+ }
350
+ try {
351
+ const occupancyData = await getCurrentOccupancy("room", uncachedRoomIds);
352
+ // Store in occupancy map and cache
353
+ const cacheEntries = [];
354
+ for (const point of occupancyData) {
355
+ if (point.asset_id) {
356
+ occupancyMap[point.asset_id] = point.value;
357
+ cacheEntries.push({
358
+ assetId: point.asset_id,
359
+ occupancy: point.value,
360
+ assetType: "room",
361
+ timestamp: new Date(point.start),
362
+ });
363
+ }
364
+ }
365
+ setBulkCachedOccupancy(cacheEntries);
366
+ }
367
+ catch (error) {
368
+ console.error(`[available-rooms] Failed to get occupancy data:`, error);
369
+ occupancyFetchFailed = true;
370
+ }
371
+ }
372
+ // When occupancy fetch failed and we have no cached data, we cannot determine availability
373
+ if (occupancyFetchFailed && Object.keys(occupancyMap).length === 0) {
374
+ throw new Error("Unable to determine room availability: occupancy data fetch failed and no cached data is available. " +
375
+ "Please retry or check the Butlr reporting API status.");
376
+ }
377
+ // Filter to available rooms — only include rooms with confirmed zero occupancy
378
+ // (exclude rooms with no data)
379
+ const availableRooms = [];
380
+ for (const room of rooms) {
381
+ const occupancy = occupancyMap[room.id] ?? null;
382
+ if (occupancy === 0) {
383
+ // Build path
384
+ const floor = floors.find((f) => f.id === room.floorID);
385
+ const building = floor ? buildings.find((b) => b.id === floor.building_id) : null;
386
+ let path = room.name;
387
+ if (floor) {
388
+ path = `${floor.name} > ${room.name}`;
389
+ if (building) {
390
+ path = `${building.name} > ${path}`;
391
+ }
392
+ }
393
+ availableRooms.push({
394
+ id: room.id,
395
+ name: room.name,
396
+ path,
397
+ capacity: room.capacity,
398
+ area: room.area,
399
+ data_window_minutes: 5,
400
+ });
401
+ }
402
+ }
403
+ // If occupancy fetch partially failed, note how many rooms have no data
404
+ if (occupancyFetchFailed) {
405
+ const roomsWithoutData = rooms.filter((r) => !(r.id in occupancyMap)).length;
406
+ if (roomsWithoutData > 0) {
407
+ warnings.push(`Occupancy data unavailable for ${roomsWithoutData} room(s). ` +
408
+ `Only rooms with confirmed zero occupancy are shown.`);
409
+ }
410
+ }
411
+ if (process.env.DEBUG) {
412
+ console.error(`[available-rooms] ${availableRooms.length} rooms available (occupancy=0)`);
413
+ }
414
+ // Sort by capacity (largest first) and limit results
415
+ availableRooms.sort((a, b) => (b.capacity?.max || 0) - (a.capacity?.max || 0));
416
+ const totalAvailable = availableRooms.length;
417
+ const maxResults = args.max_results ?? 50;
418
+ const limitedRooms = availableRooms.slice(0, maxResults);
419
+ // Calculate capacity range
420
+ const capacities = availableRooms
421
+ .map((r) => r.capacity?.max)
422
+ .filter((c) => c !== undefined);
423
+ const minCap = capacities.length > 0 ? Math.min(...capacities) : undefined;
424
+ const maxCap = capacities.length > 0 ? Math.max(...capacities) : undefined;
425
+ // Build building context if applicable
426
+ let buildingContext;
427
+ if (args.building_id) {
428
+ const building = buildings.find((b) => b.id === args.building_id);
429
+ if (building) {
430
+ const totalRooms = rooms.length;
431
+ const occupiedRooms = totalRooms - availableRooms.length;
432
+ const occupancyPercent = totalRooms > 0 ? Math.round((occupiedRooms / totalRooms) * 100) : 0;
433
+ buildingContext = {
434
+ building_name: building.name,
435
+ total_rooms: totalRooms,
436
+ available_rooms: availableRooms.length,
437
+ occupancy_percent: occupancyPercent,
438
+ };
439
+ }
440
+ }
441
+ // Build summary
442
+ const summary = buildAvailableRoomsSummary({
443
+ count: limitedRooms.length,
444
+ roomType: args.tags?.[0],
445
+ minCapacity: minCap,
446
+ maxCapacity: maxCap,
447
+ });
448
+ // Build response
449
+ const response = {
450
+ summary,
451
+ available_rooms: limitedRooms,
452
+ total_available: totalAvailable,
453
+ showing: limitedRooms.length,
454
+ timestamp: new Date().toISOString(),
455
+ };
456
+ if (Object.keys(args).length > 0) {
457
+ response.filtered_by = args;
458
+ }
459
+ if (buildingContext) {
460
+ response.building_context = buildingContext;
461
+ }
462
+ if (occupancyFetchFailed) {
463
+ warnings.push("Could not retrieve real-time occupancy data for all rooms. Room availability may be incomplete.");
464
+ }
465
+ if (warnings.length > 0) {
466
+ response.warning = warnings.join(" ");
467
+ }
468
+ return response;
469
+ }
470
+ /**
471
+ * Register butlr_available_rooms with an McpServer instance
472
+ */
473
+ export function registerAvailableRooms(server) {
474
+ server.registerTool("butlr_available_rooms", {
475
+ title: "Available Rooms",
476
+ description: AVAILABLE_ROOMS_DESCRIPTION,
477
+ inputSchema: availableRoomsInputShape,
478
+ annotations: {
479
+ readOnlyHint: true,
480
+ destructiveHint: false,
481
+ idempotentHint: false,
482
+ openWorldHint: true,
483
+ },
484
+ }, async (args) => {
485
+ const validated = AvailableRoomsArgsSchema.parse(args);
486
+ const result = await executeAvailableRooms(validated);
487
+ return {
488
+ content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
489
+ };
490
+ });
491
+ }
492
+ //# sourceMappingURL=butlr-available-rooms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butlr-available-rooms.js","sourceRoot":"","sources":["../../src/tools/butlr-available-rooms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { z } from "zod";
3
+ import type { FetchEntityDetailsResponse } from "../types/responses.js";
4
+ export declare const FetchEntityDetailsArgsSchema: z.ZodObject<{
5
+ ids: z.ZodArray<z.ZodString, "many">;
6
+ site_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
7
+ building_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
8
+ floor_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
9
+ room_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
10
+ zone_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
11
+ sensor_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
12
+ hive_fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
13
+ }, "strict", z.ZodTypeAny, {
14
+ ids: string[];
15
+ site_fields?: string[] | undefined;
16
+ building_fields?: string[] | undefined;
17
+ floor_fields?: string[] | undefined;
18
+ room_fields?: string[] | undefined;
19
+ zone_fields?: string[] | undefined;
20
+ sensor_fields?: string[] | undefined;
21
+ hive_fields?: string[] | undefined;
22
+ }, {
23
+ ids: string[];
24
+ site_fields?: string[] | undefined;
25
+ building_fields?: string[] | undefined;
26
+ floor_fields?: string[] | undefined;
27
+ room_fields?: string[] | undefined;
28
+ zone_fields?: string[] | undefined;
29
+ sensor_fields?: string[] | undefined;
30
+ hive_fields?: string[] | undefined;
31
+ }>;
32
+ type FetchEntityDetailsArgs = z.output<typeof FetchEntityDetailsArgsSchema>;
33
+ /**
34
+ * Execute butlr_fetch_entity_details tool
35
+ */
36
+ export declare function executeFetchEntityDetails(args: FetchEntityDetailsArgs): Promise<FetchEntityDetailsResponse>;
37
+ /**
38
+ * Register butlr_fetch_entity_details with an McpServer instance
39
+ */
40
+ export declare function registerFetchEntityDetails(server: McpServer): void;
41
+ export {};
42
+ //# sourceMappingURL=butlr-fetch-entity-details.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"butlr-fetch-entity-details.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-fetch-entity-details.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAKxB,OAAO,KAAK,EAAE,0BAA0B,EAAgB,MAAM,uBAAuB,CAAC;AAuDtF,eAAO,MAAM,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;EAAkD,CAAC;AAE5F,KAAK,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,4BAA4B,CAAC,CAAC;AAyF5E;;GAEG;AACH,wBAAsB,yBAAyB,CAC7C,IAAI,EAAE,sBAAsB,GAC3B,OAAO,CAAC,0BAA0B,CAAC,CA0IrC;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsBlE"}