@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.
- package/LICENSE +21 -0
- package/README.md +195 -0
- package/dist/cache/occupancy-cache.d.ts +72 -0
- package/dist/cache/occupancy-cache.d.ts.map +1 -0
- package/dist/cache/occupancy-cache.js +166 -0
- package/dist/cache/occupancy-cache.js.map +1 -0
- package/dist/cache/topology-cache.d.ts +36 -0
- package/dist/cache/topology-cache.d.ts.map +1 -0
- package/dist/cache/topology-cache.js +74 -0
- package/dist/cache/topology-cache.js.map +1 -0
- package/dist/clients/auth-client.d.ts +22 -0
- package/dist/clients/auth-client.d.ts.map +1 -0
- package/dist/clients/auth-client.js +82 -0
- package/dist/clients/auth-client.js.map +1 -0
- package/dist/clients/graphql-client.d.ts +6 -0
- package/dist/clients/graphql-client.d.ts.map +1 -0
- package/dist/clients/graphql-client.js +106 -0
- package/dist/clients/graphql-client.js.map +1 -0
- package/dist/clients/queries/topology.d.ts +36 -0
- package/dist/clients/queries/topology.d.ts.map +1 -0
- package/dist/clients/queries/topology.js +252 -0
- package/dist/clients/queries/topology.js.map +1 -0
- package/dist/clients/reporting-client.d.ts +191 -0
- package/dist/clients/reporting-client.d.ts.map +1 -0
- package/dist/clients/reporting-client.js +353 -0
- package/dist/clients/reporting-client.js.map +1 -0
- package/dist/clients/stats-client.d.ts +119 -0
- package/dist/clients/stats-client.d.ts.map +1 -0
- package/dist/clients/stats-client.js +238 -0
- package/dist/clients/stats-client.js.map +1 -0
- package/dist/clients/types.d.ts +215 -0
- package/dist/clients/types.d.ts.map +1 -0
- package/dist/clients/types.js +6 -0
- package/dist/clients/types.js.map +1 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +3 -0
- package/dist/constants.js.map +1 -0
- package/dist/errors/mcp-errors.d.ts +63 -0
- package/dist/errors/mcp-errors.d.ts.map +1 -0
- package/dist/errors/mcp-errors.js +144 -0
- package/dist/errors/mcp-errors.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +43 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/butlr-available-rooms.d.ts +49 -0
- package/dist/tools/butlr-available-rooms.d.ts.map +1 -0
- package/dist/tools/butlr-available-rooms.js +492 -0
- package/dist/tools/butlr-available-rooms.js.map +1 -0
- package/dist/tools/butlr-fetch-entity-details.d.ts +42 -0
- package/dist/tools/butlr-fetch-entity-details.d.ts.map +1 -0
- package/dist/tools/butlr-fetch-entity-details.js +276 -0
- package/dist/tools/butlr-fetch-entity-details.js.map +1 -0
- package/dist/tools/butlr-get-asset-details.d.ts +51 -0
- package/dist/tools/butlr-get-asset-details.d.ts.map +1 -0
- package/dist/tools/butlr-get-asset-details.js +391 -0
- package/dist/tools/butlr-get-asset-details.js.map +1 -0
- package/dist/tools/butlr-get-current-occupancy.d.ts +21 -0
- package/dist/tools/butlr-get-current-occupancy.d.ts.map +1 -0
- package/dist/tools/butlr-get-current-occupancy.js +126 -0
- package/dist/tools/butlr-get-current-occupancy.js.map +1 -0
- package/dist/tools/butlr-get-occupancy-timeseries.d.ts +31 -0
- package/dist/tools/butlr-get-occupancy-timeseries.d.ts.map +1 -0
- package/dist/tools/butlr-get-occupancy-timeseries.js +145 -0
- package/dist/tools/butlr-get-occupancy-timeseries.js.map +1 -0
- package/dist/tools/butlr-hardware-snapshot.d.ts +55 -0
- package/dist/tools/butlr-hardware-snapshot.d.ts.map +1 -0
- package/dist/tools/butlr-hardware-snapshot.js +556 -0
- package/dist/tools/butlr-hardware-snapshot.js.map +1 -0
- package/dist/tools/butlr-list-topology.d.ts +27 -0
- package/dist/tools/butlr-list-topology.d.ts.map +1 -0
- package/dist/tools/butlr-list-topology.js +241 -0
- package/dist/tools/butlr-list-topology.js.map +1 -0
- package/dist/tools/butlr-search-assets.d.ts +53 -0
- package/dist/tools/butlr-search-assets.d.ts.map +1 -0
- package/dist/tools/butlr-search-assets.js +206 -0
- package/dist/tools/butlr-search-assets.js.map +1 -0
- package/dist/tools/butlr-space-busyness.d.ts +23 -0
- package/dist/tools/butlr-space-busyness.d.ts.map +1 -0
- package/dist/tools/butlr-space-busyness.js +304 -0
- package/dist/tools/butlr-space-busyness.js.map +1 -0
- package/dist/tools/butlr-traffic-flow.d.ts +39 -0
- package/dist/tools/butlr-traffic-flow.d.ts.map +1 -0
- package/dist/tools/butlr-traffic-flow.js +369 -0
- package/dist/tools/butlr-traffic-flow.js.map +1 -0
- package/dist/types/responses.d.ts +253 -0
- package/dist/types/responses.d.ts.map +1 -0
- package/dist/types/responses.js +8 -0
- package/dist/types/responses.js.map +1 -0
- package/dist/utils/asset-flattener.d.ts +50 -0
- package/dist/utils/asset-flattener.d.ts.map +1 -0
- package/dist/utils/asset-flattener.js +131 -0
- package/dist/utils/asset-flattener.js.map +1 -0
- package/dist/utils/asset-helpers.d.ts +8 -0
- package/dist/utils/asset-helpers.d.ts.map +1 -0
- package/dist/utils/asset-helpers.js +24 -0
- package/dist/utils/asset-helpers.js.map +1 -0
- package/dist/utils/field-validator.d.ts +29 -0
- package/dist/utils/field-validator.d.ts.map +1 -0
- package/dist/utils/field-validator.js +197 -0
- package/dist/utils/field-validator.js.map +1 -0
- package/dist/utils/fuzzy-match.d.ts +29 -0
- package/dist/utils/fuzzy-match.d.ts.map +1 -0
- package/dist/utils/fuzzy-match.js +70 -0
- package/dist/utils/fuzzy-match.js.map +1 -0
- package/dist/utils/graphql-helpers.d.ts +29 -0
- package/dist/utils/graphql-helpers.d.ts.map +1 -0
- package/dist/utils/graphql-helpers.js +43 -0
- package/dist/utils/graphql-helpers.js.map +1 -0
- package/dist/utils/natural-language.d.ts +73 -0
- package/dist/utils/natural-language.d.ts.map +1 -0
- package/dist/utils/natural-language.js +172 -0
- package/dist/utils/natural-language.js.map +1 -0
- package/dist/utils/occupancy-helpers.d.ts +63 -0
- package/dist/utils/occupancy-helpers.d.ts.map +1 -0
- package/dist/utils/occupancy-helpers.js +203 -0
- package/dist/utils/occupancy-helpers.js.map +1 -0
- package/dist/utils/path-builder.d.ts +10 -0
- package/dist/utils/path-builder.d.ts.map +1 -0
- package/dist/utils/path-builder.js +34 -0
- package/dist/utils/path-builder.js.map +1 -0
- package/dist/utils/time-range-validator.d.ts +13 -0
- package/dist/utils/time-range-validator.d.ts.map +1 -0
- package/dist/utils/time-range-validator.js +65 -0
- package/dist/utils/time-range-validator.js.map +1 -0
- package/dist/utils/timezone-helpers.d.ts +49 -0
- package/dist/utils/timezone-helpers.d.ts.map +1 -0
- package/dist/utils/timezone-helpers.js +209 -0
- package/dist/utils/timezone-helpers.js.map +1 -0
- package/dist/utils/tree-formatter.d.ts +23 -0
- package/dist/utils/tree-formatter.d.ts.map +1 -0
- package/dist/utils/tree-formatter.js +258 -0
- package/dist/utils/tree-formatter.js.map +1 -0
- 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":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,8BAA8B,CAAC;AAC1E,OAAO,EAAE,kBAAkB,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACzF,OAAO,EAAE,qBAAqB,EAAE,MAAM,6BAA6B,CAAC;AAGpE,gFAAgF;AAChF,MAAM,wBAAwB,GAAG;IAC/B,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,GAAG,CAAC,iCAAiC,CAAC;SACtC,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;SAChD,GAAG,CAAC,KAAK,CAAC;SACV,QAAQ,EAAE;SACV,QAAQ,CAAC,uBAAuB,CAAC;IAEpC,YAAY,EAAE,CAAC;SACZ,MAAM,EAAE;SACR,GAAG,CAAC,iCAAiC,CAAC;SACtC,GAAG,CAAC,CAAC,EAAE,wCAAwC,CAAC;SAChD,GAAG,CAAC,KAAK,CAAC;SACV,QAAQ,EAAE;SACV,QAAQ,CAAC,uBAAuB,CAAC;IAEpC,IAAI,EAAE,CAAC;SACJ,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,qBAAqB,CAAC,CAAC,IAAI,EAAE,CAAC;SACtD,GAAG,CAAC,CAAC,EAAE,4BAA4B,CAAC;SACpC,QAAQ,EAAE;SACV,QAAQ,CAAC,qBAAqB,CAAC;IAElC,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,KAAK,CAAC,2BAA2B,EAAE,iDAAiD,CAAC;SACrF,QAAQ,EAAE;SACV,QAAQ,CAAC,4BAA4B,CAAC;IAEzC,QAAQ,EAAE,CAAC;SACR,MAAM,EAAE;SACR,KAAK,CACJ,gCAAgC,EAChC,2DAA2D,CAC5D;SACA,QAAQ,EAAE;SACV,QAAQ,CAAC,yBAAyB,CAAC;IAEtC,WAAW,EAAE,CAAC;SACX,MAAM,EAAE;SACR,GAAG,EAAE;SACL,GAAG,CAAC,CAAC,CAAC;SACN,GAAG,CAAC,GAAG,CAAC;SACR,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,uCAAuC,CAAC;CACrD,CAAC;AAEF,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC;KACtC,MAAM,CAAC,wBAAwB,CAAC;KAChC,MAAM,EAAE;KACR,MAAM,CACL,CAAC,IAAI,EAAE,EAAE;IACP,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvE,OAAO,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC;IAChD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,EACD;IACE,OAAO,EAAE,kDAAkD;IAC3D,IAAI,EAAE,CAAC,cAAc,CAAC;CACvB,CACF,CAAC;AAEJ,MAAM,2BAA2B,GAC/B,mSAAmS;IACnS,kBAAkB;IAClB,sHAAsH;IACtH,gHAAgH;IAChH,iHAAiH;IACjH,oHAAoH;IACpH,oBAAoB;IACpB,qEAAqE;IACrE,iEAAiE;IACjE,0DAA0D;IAC1D,4DAA4D;IAC5D,0DAA0D;IAC1D,oEAAoE;IACpE,4DAA4D;IAC5D,4DAA4D;IAC5D,gBAAgB;IAChB,uEAAuE;IACvE,qDAAqD;IACrD,wEAAwE;IACxE,sEAAsE;IACtE,wEAAwE;IACxE,oBAAoB;IACpB,0EAA0E;IAC1E,6FAA6F;IAC7F,mFAAmF;IACnF,uFAAuF;IACvF,sMAAsM;IACtM,qFAAqF,CAAC;AAIxF,MAAM,kBAAkB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B7B,CAAC;AAEF,MAAM,qBAAqB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BhC,CAAC;AAEF,MAAM,gBAAgB,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6B3B,CAAC;AAEF,MAAM,aAAa,GAAG,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCxB,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAwB;IAClE,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CACX,yDAAyD,EACzD,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAC9B,CAAC;IACJ,CAAC;IAED,6BAA6B;IAC7B,IAAI,KAAK,GAAW,EAAE,CAAC;IACvB,IAAI,SAAS,GAAe,EAAE,CAAC;IAC/B,IAAI,MAAM,GAAY,EAAE,CAAC;IAEzB,IAAI,CAAC;QACH,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,uBAAuB;YACvB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAmB;gBACxD,KAAK,EAAE,kBAAkB;gBACzB,SAAS,EAAE,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE;gBACrC,WAAW,EAAE,cAAc;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;gBACxB,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,CAAC,QAAQ,YAAY,CAAC,CAAC;YACtD,CAAC;YAED,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAAC;YACtC,MAAM,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC7B,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7E,CAAC;aAAM,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YAC5B,0BAA0B;YAC1B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAyB;gBAC9D,KAAK,EAAE,qBAAqB;gBAC5B,SAAS,EAAE,EAAE,UAAU,EAAE,IAAI,CAAC,WAAW,EAAE;gBAC3C,WAAW,EAAE,cAAc;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;gBAC3B,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,CAAC,WAAW,YAAY,CAAC,CAAC;YAC5D,CAAC;YAED,SAAS,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACnC,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,EAAE,CAAC;YAC3C,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7C,gBAAgB;YAChB,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAAyB;gBAC9D,KAAK,EAAE,gBAAgB;gBACvB,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE;gBAC9B,WAAW,EAAE,cAAc;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,UAAU,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACzD,CAAC;YAED,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC;YAE/B,0DAA0D;YAC1D,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACxB,IAAI,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;wBACxB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;oBACtC,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,6BAA6B;YAC7B,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,KAAK,CAEpC;gBACD,KAAK,EAAE,aAAa;gBACpB,WAAW,EAAE,cAAc;aAC5B,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;gBAC9B,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;YACzD,CAAC;YAED,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;YACrE,MAAM,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;YAClD,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,qBAAqB,CAAC,KAAK,CAAC,CAAC;QAC7B,MAAM,KAAK,CAAC;IACd,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,MAAM,yBAAyB,CAAC,CAAC;IAClF,CAAC;IAED,+EAA+E;IAC/E,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QACvE,MAAM,oBAAoB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC;QAE1E,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACpC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,YAAa,CAAC,CAAC;QACvF,CAAC;QAED,IAAI,IAAI,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;YACpC,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,IAAI,IAAI,CAAC,YAAa,CAAC,CAAC;QACvF,CAAC;QAED,IAAI,oBAAoB,GAAG,CAAC,EAAE,CAAC;YAC7B,QAAQ,CAAC,IAAI,CACX,GAAG,oBAAoB,kEAAkE,CAC1F,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,gDAAgD;QAChD,MAAM,QAAQ,GAA2B;YACvC,OAAO,EAAE,0BAA0B,CAAC;gBAClC,KAAK,EAAE,CAAC;gBACR,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;aACzB,CAAC;YACF,eAAe,EAAE,EAAE;YACnB,eAAe,EAAE,CAAC;YAClB,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACjC,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;QAC9B,CAAC;QAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACxC,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,sCAAsC;IACtC,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAEvC,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,4CAA4C,OAAO,CAAC,MAAM,QAAQ,CAAC,CAAC;IACpF,CAAC;IAED,oBAAoB;IACpB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,YAAY,GAA2B,EAAE,CAAC;IAEhD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAI,MAAM,EAAE,CAAC;YACX,YAAY,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC;QAC1C,CAAC;IACH,CAAC;IAED,uBAAuB;IACvB,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC;IACtE,IAAI,oBAAoB,GAAG,KAAK,CAAC;IAEjC,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACtB,OAAO,CAAC,KAAK,CACX,oCAAoC,eAAe,CAAC,MAAM,sBAAsB,CACjF,CAAC;QACJ,CAAC;QAED,IAAI,CAAC;YACH,MAAM,aAAa,GAAG,MAAM,mBAAmB,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;YAEzE,mCAAmC;YACnC,MAAM,YAAY,GAAG,EAAE,CAAC;YACxB,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;gBAClC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACnB,YAAY,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC;oBAC3C,YAAY,CAAC,IAAI,CAAC;wBAChB,OAAO,EAAE,KAAK,CAAC,QAAQ;wBACvB,SAAS,EAAE,KAAK,CAAC,KAAK;wBACtB,SAAS,EAAE,MAAM;wBACjB,SAAS,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC;qBACjC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YAED,sBAAsB,CAAC,YAAY,CAAC,CAAC;QACvC,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CAAC,iDAAiD,EAAE,KAAK,CAAC,CAAC;YACxE,oBAAoB,GAAG,IAAI,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,2FAA2F;IAC3F,IAAI,oBAAoB,IAAI,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,KAAK,CACb,sGAAsG;YACpG,uDAAuD,CAC1D,CAAC;IACJ,CAAC;IAED,+EAA+E;IAC/E,+BAA+B;IAC/B,MAAM,cAAc,GAAoB,EAAE,CAAC;IAE3C,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC;QAEhD,IAAI,SAAS,KAAK,CAAC,EAAE,CAAC;YACpB,aAAa;YACb,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC;YACxD,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YAElF,IAAI,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACrB,IAAI,KAAK,EAAE,CAAC;gBACV,IAAI,GAAG,GAAG,KAAK,CAAC,IAAI,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;gBACtC,IAAI,QAAQ,EAAE,CAAC;oBACb,IAAI,GAAG,GAAG,QAAQ,CAAC,IAAI,MAAM,IAAI,EAAE,CAAC;gBACtC,CAAC;YACH,CAAC;YAED,cAAc,CAAC,IAAI,CAAC;gBAClB,EAAE,EAAE,IAAI,CAAC,EAAE;gBACX,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,IAAI;gBACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,mBAAmB,EAAE,CAAC;aACvB,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,wEAAwE;IACxE,IAAI,oBAAoB,EAAE,CAAC;QACzB,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC;QAC7E,IAAI,gBAAgB,GAAG,CAAC,EAAE,CAAC;YACzB,QAAQ,CAAC,IAAI,CACX,kCAAkC,gBAAgB,YAAY;gBAC5D,qDAAqD,CACxD,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,CAAC,KAAK,CAAC,qBAAqB,cAAc,CAAC,MAAM,gCAAgC,CAAC,CAAC;IAC5F,CAAC;IAED,qDAAqD;IACrD,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAC/E,MAAM,cAAc,GAAG,cAAc,CAAC,MAAM,CAAC;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,IAAI,EAAE,CAAC;IAC1C,MAAM,YAAY,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;IAEzD,2BAA2B;IAC3B,MAAM,UAAU,GAAG,cAAc;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC;SAC3B,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAa,CAAC;IAC9C,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3E,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE3E,uCAAuC;IACvC,IAAI,eAA4C,CAAC;IACjD,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;QACrB,MAAM,QAAQ,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,WAAW,CAAC,CAAC;QAClE,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,CAAC;YAChC,MAAM,aAAa,GAAG,UAAU,GAAG,cAAc,CAAC,MAAM,CAAC;YACzD,MAAM,gBAAgB,GAAG,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,aAAa,GAAG,UAAU,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAE7F,eAAe,GAAG;gBAChB,aAAa,EAAE,QAAQ,CAAC,IAAI;gBAC5B,WAAW,EAAE,UAAU;gBACvB,eAAe,EAAE,cAAc,CAAC,MAAM;gBACtC,iBAAiB,EAAE,gBAAgB;aACpC,CAAC;QACJ,CAAC;IACH,CAAC;IAED,gBAAgB;IAChB,MAAM,OAAO,GAAG,0BAA0B,CAAC;QACzC,KAAK,EAAE,YAAY,CAAC,MAAM;QAC1B,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACxB,WAAW,EAAE,MAAM;QACnB,WAAW,EAAE,MAAM;KACpB,CAAC,CAAC;IAEH,iBAAiB;IACjB,MAAM,QAAQ,GAA2B;QACvC,OAAO;QACP,eAAe,EAAE,YAAY;QAC7B,eAAe,EAAE,cAAc;QAC/B,OAAO,EAAE,YAAY,CAAC,MAAM;QAC5B,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACjC,QAAQ,CAAC,WAAW,GAAG,IAAI,CAAC;IAC9B,CAAC;IAED,IAAI,eAAe,EAAE,CAAC;QACpB,QAAQ,CAAC,gBAAgB,GAAG,eAAe,CAAC;IAC9C,CAAC;IAED,IAAI,oBAAoB,EAAE,CAAC;QACzB,QAAQ,CAAC,IAAI,CACX,iGAAiG,CAClG,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,QAAQ,CAAC,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,MAAiB;IACtD,MAAM,CAAC,YAAY,CACjB,uBAAuB,EACvB;QACE,KAAK,EAAE,iBAAiB;QACxB,WAAW,EAAE,2BAA2B;QACxC,WAAW,EAAE,wBAAwB;QACrC,WAAW,EAAE;YACX,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACb,MAAM,SAAS,GAAG,wBAAwB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC,SAAS,CAAC,CAAC;QACtD,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;SAC5E,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
|
|
@@ -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"}
|