@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,241 @@
|
|
|
1
|
+
import { apolloClient } from "../clients/graphql-client.js";
|
|
2
|
+
import { GET_FULL_TOPOLOGY, GET_ALL_SENSORS, GET_ALL_HIVES } from "../clients/queries/topology.js";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { getCachedTopology, setCachedTopology, generateTopologyCacheKey, } from "../cache/topology-cache.js";
|
|
5
|
+
import { formatTopologyTree } from "../utils/tree-formatter.js";
|
|
6
|
+
import { isProductionSensor, isProductionHive, rethrowIfGraphQLError, } from "../utils/graphql-helpers.js";
|
|
7
|
+
const LIST_TOPOLOGY_DESCRIPTION = "Display org hierarchy tree with flexible depth control. Can show full tree, specific subtrees, or flat lists. " +
|
|
8
|
+
"Supports filtering by parent asset IDs. Depth levels: 0=sites, 1=buildings, 2=floors, 3=rooms/zones, 4=hives, 5=sensors. " +
|
|
9
|
+
"Use starting_depth to choose which level to show, and traversal_depth to control how many levels below to include.";
|
|
10
|
+
/** Shared shape — used by both registerTool (SDK schema) and full validation */
|
|
11
|
+
const listTopologyInputShape = {
|
|
12
|
+
asset_ids: z
|
|
13
|
+
.array(z.string())
|
|
14
|
+
.optional()
|
|
15
|
+
.describe("Optional: Parent asset IDs to show tree for. If empty, shows all sites. " +
|
|
16
|
+
"Examples: ['site_123'], ['building_456'], ['floor_789']"),
|
|
17
|
+
starting_depth: z
|
|
18
|
+
.number()
|
|
19
|
+
.default(0)
|
|
20
|
+
.describe("Depth level to start showing assets. 0=sites, 1=buildings, 2=floors, 3=rooms/zones, 4=hives, 5=sensors. " +
|
|
21
|
+
"Use with traversal_depth=0 to show only assets at this level (flat list)."),
|
|
22
|
+
traversal_depth: z
|
|
23
|
+
.number()
|
|
24
|
+
.default(0)
|
|
25
|
+
.describe("How many levels below starting_depth to traverse. 0=starting level only, 1=one level below, etc. " +
|
|
26
|
+
"Default is 0 to minimize token usage. Use 10 for full tree."),
|
|
27
|
+
};
|
|
28
|
+
export const ListTopologyArgsSchema = z.object(listTopologyInputShape).strict();
|
|
29
|
+
/**
|
|
30
|
+
* Execute butlr_list_topology tool
|
|
31
|
+
*/
|
|
32
|
+
export async function executeListTopology(args = {}) {
|
|
33
|
+
const startingDepth = args.starting_depth ?? 0;
|
|
34
|
+
const traversalDepth = args.traversal_depth ?? 0;
|
|
35
|
+
const assetIds = args.asset_ids ?? [];
|
|
36
|
+
if (process.env.DEBUG) {
|
|
37
|
+
console.error(`[butlr-list-topology] Fetching topology: starting_depth=${startingDepth}, traversal_depth=${traversalDepth}, assets=${assetIds.length || "all"}`);
|
|
38
|
+
}
|
|
39
|
+
// Use a cache key that includes devices
|
|
40
|
+
const cacheKey = generateTopologyCacheKey(process.env.BUTLR_ORG_ID || "default", true, // include devices
|
|
41
|
+
true, // include zones
|
|
42
|
+
undefined);
|
|
43
|
+
// Try to get cached topology
|
|
44
|
+
let sites = [];
|
|
45
|
+
let partialData = false;
|
|
46
|
+
const cached = getCachedTopology(cacheKey);
|
|
47
|
+
if (cached && cached.data && cached.data.sites) {
|
|
48
|
+
if (process.env.DEBUG) {
|
|
49
|
+
console.error("[butlr-list-topology] Using cached topology");
|
|
50
|
+
}
|
|
51
|
+
sites = cached.data.sites;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
// Fetch fresh topology
|
|
55
|
+
if (process.env.DEBUG) {
|
|
56
|
+
console.error("[butlr-list-topology] Fetching fresh topology");
|
|
57
|
+
}
|
|
58
|
+
try {
|
|
59
|
+
const result = await apolloClient.query({
|
|
60
|
+
query: GET_FULL_TOPOLOGY,
|
|
61
|
+
fetchPolicy: "network-only",
|
|
62
|
+
});
|
|
63
|
+
// Apollo can return both data and errors - only fail if we have no data
|
|
64
|
+
if (!result.data || !result.data.sites || !result.data.sites.data) {
|
|
65
|
+
// If we have error but no data, throw
|
|
66
|
+
if (result.error) {
|
|
67
|
+
throw result.error;
|
|
68
|
+
}
|
|
69
|
+
throw new Error("Invalid response structure from API");
|
|
70
|
+
}
|
|
71
|
+
// Track whether the topology data is partial (errors alongside data)
|
|
72
|
+
partialData = !!result.error;
|
|
73
|
+
if (partialData && process.env.DEBUG) {
|
|
74
|
+
console.error(`[butlr-list-topology] Warning: GraphQL errors present, data may be partial`);
|
|
75
|
+
}
|
|
76
|
+
sites = result.data.sites.data;
|
|
77
|
+
// Query all sensors and hives separately (nested fields are broken)
|
|
78
|
+
if (process.env.DEBUG) {
|
|
79
|
+
console.error("[butlr-list-topology] Fetching all sensors and hives...");
|
|
80
|
+
}
|
|
81
|
+
const [sensorsResult, hivesResult] = await Promise.all([
|
|
82
|
+
apolloClient.query({
|
|
83
|
+
query: GET_ALL_SENSORS,
|
|
84
|
+
fetchPolicy: "network-only",
|
|
85
|
+
}),
|
|
86
|
+
apolloClient.query({
|
|
87
|
+
query: GET_ALL_HIVES,
|
|
88
|
+
fetchPolicy: "network-only",
|
|
89
|
+
}),
|
|
90
|
+
]);
|
|
91
|
+
// Filter out test/placeholder devices from topology listing
|
|
92
|
+
// (Note: These filters are ONLY for topology display, not occupancy queries)
|
|
93
|
+
const allSensors = (sensorsResult.data?.sensors?.data || []).filter(isProductionSensor);
|
|
94
|
+
const allHives = (hivesResult.data?.hives?.data || []).filter(isProductionHive);
|
|
95
|
+
if (process.env.DEBUG) {
|
|
96
|
+
console.error(`[butlr-list-topology] Got ${allSensors.length} production sensors, ${allHives.length} production hives (test/placeholder devices filtered)`);
|
|
97
|
+
}
|
|
98
|
+
// Merge sensors and hives into topology by floor_id
|
|
99
|
+
sites = mergeSensorsAndHivesIntoTopology(sites, allSensors, allHives);
|
|
100
|
+
// Only cache complete topology data — partial results should be re-fetched
|
|
101
|
+
if (!partialData) {
|
|
102
|
+
setCachedTopology(cacheKey, { sites });
|
|
103
|
+
if (process.env.DEBUG) {
|
|
104
|
+
console.error(`[butlr-list-topology] Cached topology with ${sites.length} sites`);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if (process.env.DEBUG) {
|
|
108
|
+
console.error(`[butlr-list-topology] Skipping cache — topology data is partial`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
rethrowIfGraphQLError(error);
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// Filter topology by asset_ids if provided
|
|
117
|
+
let filteredSites = sites;
|
|
118
|
+
if (assetIds.length > 0) {
|
|
119
|
+
filteredSites = filterTopologyByAssets(sites, assetIds);
|
|
120
|
+
}
|
|
121
|
+
// Format as tree with depth controls
|
|
122
|
+
const tree = formatTopologyTree(filteredSites, startingDepth, traversalDepth);
|
|
123
|
+
const response = {
|
|
124
|
+
tree,
|
|
125
|
+
query_params: {
|
|
126
|
+
starting_depth: startingDepth,
|
|
127
|
+
traversal_depth: traversalDepth,
|
|
128
|
+
asset_filter: assetIds.length > 0 ? assetIds : "all",
|
|
129
|
+
},
|
|
130
|
+
timestamp: new Date().toISOString(),
|
|
131
|
+
};
|
|
132
|
+
if (partialData) {
|
|
133
|
+
response.warning =
|
|
134
|
+
"Topology data may be incomplete — the API returned partial results due to upstream errors.";
|
|
135
|
+
}
|
|
136
|
+
return response;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Merge sensors and hives into topology structure
|
|
140
|
+
* Groups by floor_id and nests under appropriate floors
|
|
141
|
+
*/
|
|
142
|
+
function mergeSensorsAndHivesIntoTopology(sites, allSensors, allHives) {
|
|
143
|
+
// Group sensors by floor_id
|
|
144
|
+
const sensorsByFloor = {};
|
|
145
|
+
for (const sensor of allSensors) {
|
|
146
|
+
const floorId = sensor.floor_id || sensor.floorID;
|
|
147
|
+
if (floorId) {
|
|
148
|
+
if (!sensorsByFloor[floorId]) {
|
|
149
|
+
sensorsByFloor[floorId] = [];
|
|
150
|
+
}
|
|
151
|
+
sensorsByFloor[floorId].push(sensor);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Group hives by floor_id
|
|
155
|
+
const hivesByFloor = {};
|
|
156
|
+
for (const hive of allHives) {
|
|
157
|
+
const floorId = hive.floor_id || hive.floorID;
|
|
158
|
+
if (floorId) {
|
|
159
|
+
if (!hivesByFloor[floorId]) {
|
|
160
|
+
hivesByFloor[floorId] = [];
|
|
161
|
+
}
|
|
162
|
+
hivesByFloor[floorId].push(hive);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Merge into topology
|
|
166
|
+
for (const site of sites) {
|
|
167
|
+
for (const building of site.buildings || []) {
|
|
168
|
+
for (const floor of building.floors || []) {
|
|
169
|
+
// Add sensors and hives to this floor
|
|
170
|
+
floor.sensors = sensorsByFloor[floor.id] || [];
|
|
171
|
+
floor.hives = hivesByFloor[floor.id] || [];
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return sites;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Filter topology to only include assets matching the provided IDs
|
|
179
|
+
* Returns a subset of the topology tree
|
|
180
|
+
*/
|
|
181
|
+
function filterTopologyByAssets(sites, assetIds) {
|
|
182
|
+
const idSet = new Set(assetIds);
|
|
183
|
+
const filtered = [];
|
|
184
|
+
for (const site of sites) {
|
|
185
|
+
if (idSet.has(site.id)) {
|
|
186
|
+
filtered.push(site);
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
const matchedBuildings = [];
|
|
190
|
+
for (const building of site.buildings || []) {
|
|
191
|
+
if (idSet.has(building.id)) {
|
|
192
|
+
matchedBuildings.push(building);
|
|
193
|
+
continue;
|
|
194
|
+
}
|
|
195
|
+
const matchedFloors = [];
|
|
196
|
+
for (const floor of building.floors || []) {
|
|
197
|
+
if (idSet.has(floor.id)) {
|
|
198
|
+
matchedFloors.push(floor);
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const hasMatchedRoom = floor.rooms?.some((r) => idSet.has(r.id));
|
|
202
|
+
const hasMatchedZone = floor.zones?.some((z) => idSet.has(z.id));
|
|
203
|
+
const hasMatchedHive = floor.hives?.some((h) => idSet.has(h.id));
|
|
204
|
+
const hasMatchedSensor = floor.sensors?.some((s) => idSet.has(s.id));
|
|
205
|
+
if (hasMatchedRoom || hasMatchedZone || hasMatchedHive || hasMatchedSensor) {
|
|
206
|
+
matchedFloors.push(floor);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
if (matchedFloors.length > 0) {
|
|
210
|
+
matchedBuildings.push({ ...building, floors: matchedFloors });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (matchedBuildings.length > 0) {
|
|
214
|
+
filtered.push({ ...site, buildings: matchedBuildings });
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return filtered;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Register butlr_list_topology with an McpServer instance
|
|
221
|
+
*/
|
|
222
|
+
export function registerListTopology(server) {
|
|
223
|
+
server.registerTool("butlr_list_topology", {
|
|
224
|
+
title: "List Topology",
|
|
225
|
+
description: LIST_TOPOLOGY_DESCRIPTION,
|
|
226
|
+
inputSchema: listTopologyInputShape,
|
|
227
|
+
annotations: {
|
|
228
|
+
readOnlyHint: true,
|
|
229
|
+
destructiveHint: false,
|
|
230
|
+
idempotentHint: true,
|
|
231
|
+
openWorldHint: true,
|
|
232
|
+
},
|
|
233
|
+
}, async (args) => {
|
|
234
|
+
const validated = ListTopologyArgsSchema.parse(args);
|
|
235
|
+
const result = await executeListTopology(validated);
|
|
236
|
+
return {
|
|
237
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
238
|
+
};
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=butlr-list-topology.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"butlr-list-topology.js","sourceRoot":"","sources":["../../src/tools/butlr-list-topology.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
export declare const SearchAssetsArgsSchema: z.ZodEffects<z.ZodObject<{
|
|
4
|
+
query: z.ZodEffects<z.ZodString, string, string>;
|
|
5
|
+
asset_types: z.ZodOptional<z.ZodArray<z.ZodEnum<["site", "building", "floor", "room", "zone", "sensor", "hive"]>, "many">>;
|
|
6
|
+
max_results: z.ZodDefault<z.ZodNumber>;
|
|
7
|
+
}, "strict", z.ZodTypeAny, {
|
|
8
|
+
query: string;
|
|
9
|
+
max_results: number;
|
|
10
|
+
asset_types?: ("site" | "building" | "floor" | "room" | "zone" | "sensor" | "hive")[] | undefined;
|
|
11
|
+
}, {
|
|
12
|
+
query: string;
|
|
13
|
+
asset_types?: ("site" | "building" | "floor" | "room" | "zone" | "sensor" | "hive")[] | undefined;
|
|
14
|
+
max_results?: number | undefined;
|
|
15
|
+
}>, {
|
|
16
|
+
query: string;
|
|
17
|
+
max_results: number;
|
|
18
|
+
asset_types?: ("site" | "building" | "floor" | "room" | "zone" | "sensor" | "hive")[] | undefined;
|
|
19
|
+
}, {
|
|
20
|
+
query: string;
|
|
21
|
+
asset_types?: ("site" | "building" | "floor" | "room" | "zone" | "sensor" | "hive")[] | undefined;
|
|
22
|
+
max_results?: number | undefined;
|
|
23
|
+
}>;
|
|
24
|
+
export type SearchAssetsArgs = z.output<typeof SearchAssetsArgsSchema>;
|
|
25
|
+
/**
|
|
26
|
+
* Search result with minimal fields
|
|
27
|
+
*/
|
|
28
|
+
export interface SearchResult {
|
|
29
|
+
id: string;
|
|
30
|
+
name: string;
|
|
31
|
+
type: string;
|
|
32
|
+
path: string;
|
|
33
|
+
match_score: number;
|
|
34
|
+
site_id?: string;
|
|
35
|
+
building_id?: string;
|
|
36
|
+
floor_id?: string;
|
|
37
|
+
room_id?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Execute search_assets tool
|
|
41
|
+
*/
|
|
42
|
+
export declare function executeSearchAssets(args: SearchAssetsArgs): Promise<{
|
|
43
|
+
query: string;
|
|
44
|
+
matches: SearchResult[];
|
|
45
|
+
total_matches: number;
|
|
46
|
+
searched_assets: number;
|
|
47
|
+
timestamp: string;
|
|
48
|
+
}>;
|
|
49
|
+
/**
|
|
50
|
+
* Register butlr_search_assets with an McpServer instance
|
|
51
|
+
*/
|
|
52
|
+
export declare function registerSearchAssets(server: McpServer): void;
|
|
53
|
+
//# sourceMappingURL=butlr-search-assets.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"butlr-search-assets.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-search-assets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAkDxB,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;EAehC,CAAC;AAgCJ,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IAEpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,gBAAgB;;;;;;GAgI/D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB5D"}
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { apolloClient } from "../clients/graphql-client.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { GET_FULL_TOPOLOGY } from "../clients/queries/topology.js";
|
|
4
|
+
import { getCachedTopology, setCachedTopology, generateTopologyCacheKey, } from "../cache/topology-cache.js";
|
|
5
|
+
import { flattenTopology } from "../utils/asset-flattener.js";
|
|
6
|
+
import { searchAssets } from "../utils/fuzzy-match.js";
|
|
7
|
+
import { buildAssetPath } from "../utils/path-builder.js";
|
|
8
|
+
import { rethrowIfGraphQLError } from "../utils/graphql-helpers.js";
|
|
9
|
+
const VALID_ASSET_TYPES = ["site", "building", "floor", "room", "zone", "sensor", "hive"];
|
|
10
|
+
/** Shared shape — used by both registerTool (SDK schema) and full validation */
|
|
11
|
+
const searchAssetsInputShape = {
|
|
12
|
+
query: z
|
|
13
|
+
.string()
|
|
14
|
+
.min(1, "query cannot be empty")
|
|
15
|
+
.max(500, "query too long (max: 500 chars)")
|
|
16
|
+
.trim()
|
|
17
|
+
.refine((val) => val.length >= 2, "query must be at least 2 characters (after trimming whitespace)")
|
|
18
|
+
.describe("Search term to match against asset names"),
|
|
19
|
+
asset_types: z
|
|
20
|
+
.array(z.enum(VALID_ASSET_TYPES, {
|
|
21
|
+
errorMap: () => ({
|
|
22
|
+
message: `asset_type must be one of: ${VALID_ASSET_TYPES.join(", ")}`,
|
|
23
|
+
}),
|
|
24
|
+
}))
|
|
25
|
+
.min(1, "asset_types array cannot be empty (omit field to search all types)")
|
|
26
|
+
.max(VALID_ASSET_TYPES.length)
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Optional: Filter to specific asset types"),
|
|
29
|
+
max_results: z
|
|
30
|
+
.number()
|
|
31
|
+
.int("max_results must be an integer")
|
|
32
|
+
.min(1, "max_results must be at least 1")
|
|
33
|
+
.max(100, "max_results cannot exceed 100")
|
|
34
|
+
.default(20)
|
|
35
|
+
.describe("Maximum number of results to return"),
|
|
36
|
+
};
|
|
37
|
+
export const SearchAssetsArgsSchema = z
|
|
38
|
+
.object(searchAssetsInputShape)
|
|
39
|
+
.strict()
|
|
40
|
+
.refine((data) => {
|
|
41
|
+
if (data.asset_types) {
|
|
42
|
+
const unique = new Set(data.asset_types);
|
|
43
|
+
return unique.size === data.asset_types.length;
|
|
44
|
+
}
|
|
45
|
+
return true;
|
|
46
|
+
}, {
|
|
47
|
+
message: "asset_types contains duplicate values",
|
|
48
|
+
path: ["asset_types"],
|
|
49
|
+
});
|
|
50
|
+
const SEARCH_ASSETS_DESCRIPTION = "Search for Butlr assets (sites, buildings, floors, rooms, zones, sensors, hives) by name using fuzzy matching. Essential prerequisite tool for finding asset IDs before calling other tools. Returns minimal matched results with breadcrumb paths, match scores, and parent context. Searches across all asset types by default, with optional filters.\n\n" +
|
|
51
|
+
"Primary Users:\n" +
|
|
52
|
+
"- All Users: Find asset IDs by human-readable names before using other tools\n" +
|
|
53
|
+
"- IT Manager: Find sensors by MAC address for troubleshooting\n" +
|
|
54
|
+
"- Field Technician: Locate sensors/hives by name or serial number before site visits\n" +
|
|
55
|
+
"- Workplace Manager: Find rooms/spaces by common names (e.g., 'café', 'huddle room 3')\n\n" +
|
|
56
|
+
"Example Queries:\n" +
|
|
57
|
+
'1. "Find the main lobby" → returns room_lobby_123\n' +
|
|
58
|
+
'2. "Search for café or coffee shop" → fuzzy matches "Café Barista", "Coffee Bar"\n' +
|
|
59
|
+
'3. "Find Floor 6 in SF Tower" → returns floor_sf_tower_6\n' +
|
|
60
|
+
'4. "Search for sensors with MAC address starting with 00:1A" → matches sensors by MAC\n' +
|
|
61
|
+
'5. "Find all conference rooms" → searches room names containing "conference"\n' +
|
|
62
|
+
'6. "Locate hive with serial number HV-2023-001" → finds hive by serial\n' +
|
|
63
|
+
'7. "Search for Chicago office" → finds site/building matching "Chicago"\n' +
|
|
64
|
+
'8. "Find focus rooms on Floor 3" → searches for rooms with "focus" in name\n\n' +
|
|
65
|
+
"When to Use:\n" +
|
|
66
|
+
"- Know a space's name but not its ID (e.g., 'Café Barista' → room_cafe_123)\n" +
|
|
67
|
+
"- Looking for sensors/hives by MAC address or serial number\n" +
|
|
68
|
+
"- Find all assets of a specific type (e.g., all sites, all conference rooms)\n" +
|
|
69
|
+
"- Exploring org topology and don't know exact asset names\n" +
|
|
70
|
+
"- Want to find spaces with partial/fuzzy names (e.g., 'cafe' matches 'Café Barista')\n\n" +
|
|
71
|
+
"When NOT to Use:\n" +
|
|
72
|
+
"- Already have asset IDs and need detailed info → use butlr_get_asset_details directly\n" +
|
|
73
|
+
"- Want to browse full organizational hierarchy → use butlr_list_topology instead\n" +
|
|
74
|
+
"- Need to analyze occupancy or sensor data → use this tool first to find IDs, then use data tools\n\n" +
|
|
75
|
+
"Search Features: Fuzzy matching (handles typos), multi-field search (name, MAC, serial), score threshold (≥70), type filtering, result limiting (default 20, max 100)\n\n" +
|
|
76
|
+
"Example Workflow: butlr_search_assets(query: 'café') → get room_cafe_123 → butlr_space_busyness(space_id_or_name: 'room_cafe_123')\n\n" +
|
|
77
|
+
"See Also: butlr_get_asset_details, butlr_list_topology, butlr_fetch_entity_details";
|
|
78
|
+
/**
|
|
79
|
+
* Execute search_assets tool
|
|
80
|
+
*/
|
|
81
|
+
export async function executeSearchAssets(args) {
|
|
82
|
+
const maxResults = args.max_results;
|
|
83
|
+
if (process.env.DEBUG) {
|
|
84
|
+
console.error(`[search-assets] Searching for "${args.query}"` +
|
|
85
|
+
(args.asset_types ? ` in types: ${args.asset_types.join(",")}` : "") +
|
|
86
|
+
` (max: ${maxResults})`);
|
|
87
|
+
}
|
|
88
|
+
// Use a generic cache key for full topology (we'll search across it)
|
|
89
|
+
const cacheKey = generateTopologyCacheKey(process.env.BUTLR_ORG_ID || "default", true, // include devices for comprehensive search
|
|
90
|
+
true, // include zones
|
|
91
|
+
undefined);
|
|
92
|
+
// Try to get cached topology
|
|
93
|
+
let sites = [];
|
|
94
|
+
const cached = getCachedTopology(cacheKey);
|
|
95
|
+
if (cached && cached.data && cached.data.sites) {
|
|
96
|
+
if (process.env.DEBUG) {
|
|
97
|
+
console.error("[search-assets] Using cached topology for search");
|
|
98
|
+
}
|
|
99
|
+
sites = cached.data.sites;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
// Fetch fresh topology
|
|
103
|
+
if (process.env.DEBUG) {
|
|
104
|
+
console.error("[search-assets] Fetching fresh topology for search");
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
const result = await apolloClient.query({
|
|
108
|
+
query: GET_FULL_TOPOLOGY,
|
|
109
|
+
fetchPolicy: "network-only",
|
|
110
|
+
});
|
|
111
|
+
// Apollo can return both data and errors - only fail if we have no data
|
|
112
|
+
if (!result.data || !result.data.sites || !result.data.sites.data) {
|
|
113
|
+
// If we have error but no data, throw
|
|
114
|
+
if (result.error) {
|
|
115
|
+
throw result.error;
|
|
116
|
+
}
|
|
117
|
+
throw new Error("Invalid response structure from API");
|
|
118
|
+
}
|
|
119
|
+
// Track whether the topology data is partial (errors alongside data)
|
|
120
|
+
const partialData = !!result.error;
|
|
121
|
+
if (partialData && process.env.DEBUG) {
|
|
122
|
+
console.error(`[search-assets] Warning: GraphQL errors present, data may be partial`);
|
|
123
|
+
}
|
|
124
|
+
sites = result.data.sites.data;
|
|
125
|
+
// Only cache complete topology data — partial results should be re-fetched
|
|
126
|
+
if (!partialData) {
|
|
127
|
+
setCachedTopology(cacheKey, { sites });
|
|
128
|
+
if (process.env.DEBUG) {
|
|
129
|
+
console.error(`[search-assets] Cached topology with ${sites.length} sites`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
else if (process.env.DEBUG) {
|
|
133
|
+
console.error(`[search-assets] Skipping cache — topology data is partial`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
catch (error) {
|
|
137
|
+
rethrowIfGraphQLError(error);
|
|
138
|
+
throw error;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Flatten topology into searchable list
|
|
142
|
+
const flattened = flattenTopology(sites);
|
|
143
|
+
if (process.env.DEBUG) {
|
|
144
|
+
console.error(`[search-assets] Flattened ${flattened.length} total assets`);
|
|
145
|
+
}
|
|
146
|
+
// Filter by asset types if specified
|
|
147
|
+
let searchableAssets = flattened;
|
|
148
|
+
if (args.asset_types && args.asset_types.length > 0) {
|
|
149
|
+
searchableAssets = flattened.filter((asset) => args.asset_types.includes(asset.type));
|
|
150
|
+
if (process.env.DEBUG) {
|
|
151
|
+
console.error(`[search-assets] Filtered to ${searchableAssets.length} assets of types: ${args.asset_types.join(",")}`);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
// Perform fuzzy search
|
|
155
|
+
// Search on name, mac_address (sensors), and serialNumber (hives)
|
|
156
|
+
const matches = searchAssets(searchableAssets, args.query, {
|
|
157
|
+
matchFields: ["name", "mac_address", "serialNumber"],
|
|
158
|
+
minScore: 70,
|
|
159
|
+
maxResults,
|
|
160
|
+
});
|
|
161
|
+
if (process.env.DEBUG) {
|
|
162
|
+
console.error(`[search-assets] Found ${matches.length} matches`);
|
|
163
|
+
}
|
|
164
|
+
// Format results with minimal fields
|
|
165
|
+
const results = matches.map((match) => ({
|
|
166
|
+
id: match.asset.id,
|
|
167
|
+
name: match.asset.name,
|
|
168
|
+
type: match.asset.type,
|
|
169
|
+
path: buildAssetPath(match.asset),
|
|
170
|
+
match_score: match.score,
|
|
171
|
+
site_id: match.asset.site_id,
|
|
172
|
+
building_id: match.asset.building_id,
|
|
173
|
+
floor_id: match.asset.floor_id,
|
|
174
|
+
room_id: match.asset.room_id,
|
|
175
|
+
}));
|
|
176
|
+
return {
|
|
177
|
+
query: args.query,
|
|
178
|
+
matches: results,
|
|
179
|
+
total_matches: results.length,
|
|
180
|
+
searched_assets: searchableAssets.length,
|
|
181
|
+
timestamp: new Date().toISOString(),
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Register butlr_search_assets with an McpServer instance
|
|
186
|
+
*/
|
|
187
|
+
export function registerSearchAssets(server) {
|
|
188
|
+
server.registerTool("butlr_search_assets", {
|
|
189
|
+
title: "Search Butlr Assets",
|
|
190
|
+
description: SEARCH_ASSETS_DESCRIPTION,
|
|
191
|
+
inputSchema: searchAssetsInputShape,
|
|
192
|
+
annotations: {
|
|
193
|
+
readOnlyHint: true,
|
|
194
|
+
destructiveHint: false,
|
|
195
|
+
idempotentHint: true,
|
|
196
|
+
openWorldHint: true,
|
|
197
|
+
},
|
|
198
|
+
}, async (args) => {
|
|
199
|
+
const validated = SearchAssetsArgsSchema.parse(args);
|
|
200
|
+
const result = await executeSearchAssets(validated);
|
|
201
|
+
return {
|
|
202
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
203
|
+
};
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
//# sourceMappingURL=butlr-search-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"butlr-search-assets.js","sourceRoot":"","sources":["../../src/tools/butlr-search-assets.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import type { SpaceBusynessResponse } from "../types/responses.js";
|
|
4
|
+
export declare const SpaceBusynessArgsSchema: z.ZodObject<{
|
|
5
|
+
space_id_or_name: z.ZodString;
|
|
6
|
+
include_trend: z.ZodDefault<z.ZodBoolean>;
|
|
7
|
+
}, "strict", z.ZodTypeAny, {
|
|
8
|
+
space_id_or_name: string;
|
|
9
|
+
include_trend: boolean;
|
|
10
|
+
}, {
|
|
11
|
+
space_id_or_name: string;
|
|
12
|
+
include_trend?: boolean | undefined;
|
|
13
|
+
}>;
|
|
14
|
+
export type SpaceBusynessArgs = z.output<typeof SpaceBusynessArgsSchema>;
|
|
15
|
+
/**
|
|
16
|
+
* Execute space busyness tool
|
|
17
|
+
*/
|
|
18
|
+
export declare function executeSpaceBusyness(args: SpaceBusynessArgs): Promise<SpaceBusynessResponse>;
|
|
19
|
+
/**
|
|
20
|
+
* Register butlr_space_busyness with an McpServer instance
|
|
21
|
+
*/
|
|
22
|
+
export declare function registerSpaceBusyness(server: McpServer): void;
|
|
23
|
+
//# sourceMappingURL=butlr-space-busyness.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"butlr-space-busyness.d.ts","sourceRoot":"","sources":["../../src/tools/butlr-space-busyness.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGzE,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAcxB,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AA+BnE,eAAO,MAAM,uBAAuB;;;;;;;;;EAA6C,CAAC;AAgClF,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAyDzE;;GAEG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE,iBAAiB,kCAiMjE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAsB7D"}
|