@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,369 @@
|
|
|
1
|
+
import { apolloClient } from "../clients/graphql-client.js";
|
|
2
|
+
import { gql } from "@apollo/client";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { ReportingRequestBuilder } from "../clients/reporting-client.js";
|
|
5
|
+
import { GET_ALL_SENSORS, GET_FULL_TOPOLOGY } from "../clients/queries/topology.js";
|
|
6
|
+
import { executeSearchAssets } from "./butlr-search-assets.js";
|
|
7
|
+
import { getTimezoneForAsset, buildTimezoneMetadata, getLocalMidnight, } from "../utils/timezone-helpers.js";
|
|
8
|
+
import { createValidationError } from "../errors/mcp-errors.js";
|
|
9
|
+
import { rethrowIfGraphQLError } from "../utils/graphql-helpers.js";
|
|
10
|
+
const timeStringSchema = z.string().refine((val) => {
|
|
11
|
+
const isoMatch = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z?$/.test(val);
|
|
12
|
+
const relativeMatch = /^-\d+[dhm]$/.test(val);
|
|
13
|
+
const isNow = val === "now";
|
|
14
|
+
return isoMatch || relativeMatch || isNow;
|
|
15
|
+
}, {
|
|
16
|
+
message: "Time must be ISO-8601 format (2025-01-15T10:00:00Z), relative (-24h, -7d, -30m), or 'now'",
|
|
17
|
+
});
|
|
18
|
+
/** Shared shape — used by both registerTool (SDK schema) and full validation */
|
|
19
|
+
const trafficFlowInputShape = {
|
|
20
|
+
space_id_or_name: z
|
|
21
|
+
.string()
|
|
22
|
+
.min(1, "space_id_or_name cannot be empty")
|
|
23
|
+
.max(200)
|
|
24
|
+
.trim()
|
|
25
|
+
.describe("Space ID or search term"),
|
|
26
|
+
time_window: z
|
|
27
|
+
.enum(["20m", "1h", "today", "custom"])
|
|
28
|
+
.default("today")
|
|
29
|
+
.describe("Time period for traffic count"),
|
|
30
|
+
custom_start: z
|
|
31
|
+
.string()
|
|
32
|
+
.pipe(timeStringSchema)
|
|
33
|
+
.optional()
|
|
34
|
+
.describe("Custom start time (ISO-8601 or relative '-24h'). Required if time_window='custom'"),
|
|
35
|
+
custom_stop: z
|
|
36
|
+
.string()
|
|
37
|
+
.pipe(timeStringSchema)
|
|
38
|
+
.optional()
|
|
39
|
+
.describe("Custom stop time. Defaults to 'now'"),
|
|
40
|
+
};
|
|
41
|
+
export const TrafficFlowArgsSchema = z
|
|
42
|
+
.object(trafficFlowInputShape)
|
|
43
|
+
.strict()
|
|
44
|
+
.refine((data) => {
|
|
45
|
+
if (data.time_window === "custom" && !data.custom_start) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
return true;
|
|
49
|
+
}, {
|
|
50
|
+
message: "custom_start is required when time_window='custom'",
|
|
51
|
+
path: ["custom_start"],
|
|
52
|
+
});
|
|
53
|
+
const TRAFFIC_FLOW_DESCRIPTION = "Get entry and exit counts for spaces equipped with traffic-mode sensors (typically lobbies, building entrances, elevator banks). Returns total movements, net flow (entries - exits), and hourly breakdown in the space's local timezone. Designed for space activation analysis, security/compliance, and amenity demand forecasting.\n\n" +
|
|
54
|
+
"Primary Users:\n" +
|
|
55
|
+
"- Facilities Manager: Monitor building entry/exit patterns, optimize security staffing, validate badge system accuracy\n" +
|
|
56
|
+
"- Workplace Manager: Understand amenity traffic (café, gym, event spaces), measure activation of new spaces\n" +
|
|
57
|
+
"- Portfolio Manager: Analyze building utilization patterns for lease negotiations, assess occupancy vs. leased capacity\n" +
|
|
58
|
+
"- Security/Compliance: Validate occupancy limits for fire code compliance, monitor after-hours access\n\n" +
|
|
59
|
+
"Example Queries:\n" +
|
|
60
|
+
'1. "How many people entered the main lobby today?"\n' +
|
|
61
|
+
'2. "Show me entry/exit counts for the café in the last hour"\n' +
|
|
62
|
+
'3. "What was the peak traffic hour for Building 3 entrance today?"\n' +
|
|
63
|
+
'4. "How many people visited the fitness center yesterday?"\n' +
|
|
64
|
+
'5. "Show me lobby traffic for the last 20 minutes"\n' +
|
|
65
|
+
'6. "What\'s the net flow (entries - exits) for Floor 2 today?"\n' +
|
|
66
|
+
'7. "How many people entered the event space during lunch hour (12-1pm)?"\n' +
|
|
67
|
+
'8. "Compare today\'s building entrance traffic to typical Monday"\n\n' +
|
|
68
|
+
"When to Use:\n" +
|
|
69
|
+
"- Entry/exit counts for lobbies, building entrances, elevator banks, or amenities\n" +
|
|
70
|
+
"- Understand peak traffic hours for security, cleaning, or HVAC planning\n" +
|
|
71
|
+
"- Validate badge system accuracy against actual sensor counts\n" +
|
|
72
|
+
"- Measure activation/adoption of new spaces or amenities\n" +
|
|
73
|
+
"- Analyze compliance with occupancy limits (fire code, COVID density restrictions)\n\n" +
|
|
74
|
+
"When NOT to Use:\n" +
|
|
75
|
+
"- Current occupancy count (people currently in space) → use butlr_get_current_occupancy or butlr_space_busyness\n" +
|
|
76
|
+
"- Rooms without traffic-mode sensors → use butlr_get_current_occupancy (presence mode)\n" +
|
|
77
|
+
"- Spaces that don't have entry/exit chokepoints → traffic mode requires defined entrances\n\n" +
|
|
78
|
+
"CRE Context: Traffic counts are movements, not unique people - one person exiting/re-entering counts as 2 movements. Net flow helps detect sensor calibration issues (large negative net flow might indicate misconfigured entry/exit sensors).\n\n" +
|
|
79
|
+
"See Also: butlr_get_current_occupancy, butlr_space_busyness, butlr_search_assets, butlr_get_asset_details";
|
|
80
|
+
const GET_ROOM_SENSORS = gql `
|
|
81
|
+
query GetRoomSensors($roomId: ID!) {
|
|
82
|
+
room(id: $roomId) {
|
|
83
|
+
id
|
|
84
|
+
name
|
|
85
|
+
floorID
|
|
86
|
+
sensors {
|
|
87
|
+
id
|
|
88
|
+
mode
|
|
89
|
+
}
|
|
90
|
+
floor {
|
|
91
|
+
id
|
|
92
|
+
name
|
|
93
|
+
building {
|
|
94
|
+
id
|
|
95
|
+
name
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
`;
|
|
101
|
+
/**
|
|
102
|
+
* Execute traffic flow tool
|
|
103
|
+
*/
|
|
104
|
+
export async function executeTrafficFlow(args) {
|
|
105
|
+
let spaceId = args.space_id_or_name;
|
|
106
|
+
// If not an ID, search for the space
|
|
107
|
+
if (!spaceId.match(/^room_/)) {
|
|
108
|
+
if (process.env.DEBUG) {
|
|
109
|
+
console.error(`[traffic-flow] Searching for space: "${args.space_id_or_name}"`);
|
|
110
|
+
}
|
|
111
|
+
const searchResults = await executeSearchAssets({
|
|
112
|
+
query: args.space_id_or_name,
|
|
113
|
+
asset_types: ["room"], // Traffic is room-level
|
|
114
|
+
max_results: 5,
|
|
115
|
+
});
|
|
116
|
+
if (searchResults.matches.length === 0) {
|
|
117
|
+
throw new Error(`No rooms found matching "${args.space_id_or_name}". Try a different search term.`);
|
|
118
|
+
}
|
|
119
|
+
spaceId = searchResults.matches[0].id;
|
|
120
|
+
if (process.env.DEBUG) {
|
|
121
|
+
console.error(`[traffic-flow] Using best match: ${searchResults.matches[0].name} (${spaceId})`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// Query room details, topology for timezone, and all sensors
|
|
125
|
+
let room = null;
|
|
126
|
+
let roomPath = "";
|
|
127
|
+
let timezone;
|
|
128
|
+
let tzMetadata;
|
|
129
|
+
let trafficSensors = [];
|
|
130
|
+
try {
|
|
131
|
+
const [roomResult, topoResult, sensorsResult] = await Promise.all([
|
|
132
|
+
apolloClient.query({
|
|
133
|
+
query: GET_ROOM_SENSORS,
|
|
134
|
+
variables: { roomId: spaceId },
|
|
135
|
+
fetchPolicy: "network-only",
|
|
136
|
+
}),
|
|
137
|
+
apolloClient.query({
|
|
138
|
+
query: GET_FULL_TOPOLOGY,
|
|
139
|
+
fetchPolicy: "network-only",
|
|
140
|
+
}),
|
|
141
|
+
apolloClient.query({
|
|
142
|
+
query: GET_ALL_SENSORS,
|
|
143
|
+
fetchPolicy: "network-only",
|
|
144
|
+
}),
|
|
145
|
+
]);
|
|
146
|
+
if (!roomResult.data?.room) {
|
|
147
|
+
throw new Error(`Room ${spaceId} not found`);
|
|
148
|
+
}
|
|
149
|
+
room = roomResult.data.room;
|
|
150
|
+
const floor = room.floor;
|
|
151
|
+
const building = floor?.building;
|
|
152
|
+
roomPath = building ? `${building.name} > ${floor.name} > ${room.name}` : room.name;
|
|
153
|
+
// Get timezone for this room
|
|
154
|
+
const sites = topoResult.data?.sites?.data || [];
|
|
155
|
+
const buildings = sites.flatMap((s) => s.buildings || []);
|
|
156
|
+
const floors = buildings.flatMap((b) => b.floors || []);
|
|
157
|
+
const roomTimezone = getTimezoneForAsset(spaceId, "room", floors, buildings, sites);
|
|
158
|
+
if (!roomTimezone) {
|
|
159
|
+
throw new Error(`Could not determine timezone for room ${spaceId}`);
|
|
160
|
+
}
|
|
161
|
+
timezone = roomTimezone;
|
|
162
|
+
tzMetadata = buildTimezoneMetadata(timezone);
|
|
163
|
+
// Analyze traffic sensors for this room
|
|
164
|
+
const allSensors = sensorsResult.data?.sensors?.data || [];
|
|
165
|
+
const roomSensors = allSensors.filter((s) => (s.room_id || s.roomID) === spaceId);
|
|
166
|
+
// Non-entrance traffic sensors (room-level traffic counting)
|
|
167
|
+
trafficSensors = roomSensors.filter((s) => s.mode === "traffic" && s.is_entrance === false);
|
|
168
|
+
if (trafficSensors.length === 0) {
|
|
169
|
+
throw new Error(`Room "${room.name}" does not have traffic-mode sensors. Try butlr_get_current_occupancy for occupancy data instead.`);
|
|
170
|
+
}
|
|
171
|
+
if (process.env.DEBUG) {
|
|
172
|
+
console.error(`[traffic-flow] Found ${trafficSensors.length} traffic sensors for room`);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
rethrowIfGraphQLError(error);
|
|
177
|
+
throw error;
|
|
178
|
+
}
|
|
179
|
+
// Calculate time range
|
|
180
|
+
const timeWindow = args.time_window || "today";
|
|
181
|
+
let start;
|
|
182
|
+
let stop = "now";
|
|
183
|
+
let periodDescription;
|
|
184
|
+
let usedUtcFallback = false;
|
|
185
|
+
if (timeWindow === "custom") {
|
|
186
|
+
if (!args.custom_start) {
|
|
187
|
+
throw createValidationError("custom_start is required when time_window='custom'");
|
|
188
|
+
}
|
|
189
|
+
start = args.custom_start;
|
|
190
|
+
stop = args.custom_stop || "now";
|
|
191
|
+
periodDescription = "custom period";
|
|
192
|
+
}
|
|
193
|
+
else if (timeWindow === "20m") {
|
|
194
|
+
start = "-20m";
|
|
195
|
+
periodDescription = "last 20 minutes";
|
|
196
|
+
}
|
|
197
|
+
else if (timeWindow === "1h") {
|
|
198
|
+
start = "-1h";
|
|
199
|
+
periodDescription = "last hour";
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// today - use site's timezone for local midnight
|
|
203
|
+
const localMidnight = getLocalMidnight(new Date(), timezone);
|
|
204
|
+
if (isNaN(localMidnight.getTime())) {
|
|
205
|
+
// getLocalMidnight returns UTC midnight as fallback on error
|
|
206
|
+
usedUtcFallback = true;
|
|
207
|
+
}
|
|
208
|
+
// Detect if getLocalMidnight silently fell back to UTC by comparing
|
|
209
|
+
// the result against a plain UTC midnight (which is what the internal fallback does)
|
|
210
|
+
const utcMidnight = new Date();
|
|
211
|
+
utcMidnight.setUTCHours(0, 0, 0, 0);
|
|
212
|
+
if (timezone !== "UTC" && Math.abs(localMidnight.getTime() - utcMidnight.getTime()) < 1000) {
|
|
213
|
+
// The result suspiciously matches UTC midnight for a non-UTC timezone —
|
|
214
|
+
// likely the internal fallback fired
|
|
215
|
+
usedUtcFallback = true;
|
|
216
|
+
}
|
|
217
|
+
start = localMidnight.toISOString();
|
|
218
|
+
periodDescription = usedUtcFallback
|
|
219
|
+
? "today (UTC fallback)"
|
|
220
|
+
: `today (${tzMetadata.timezone_abbr})`;
|
|
221
|
+
if (process.env.DEBUG) {
|
|
222
|
+
console.error(`[traffic-flow] Today starts at ${start} (midnight ${usedUtcFallback ? "UTC fallback" : tzMetadata.timezone_abbr})`);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (process.env.DEBUG) {
|
|
226
|
+
console.error(`[traffic-flow] Querying traffic from ${start} to ${stop}`);
|
|
227
|
+
}
|
|
228
|
+
let trafficData = [];
|
|
229
|
+
try {
|
|
230
|
+
const response = await new ReportingRequestBuilder()
|
|
231
|
+
.assets("room", [spaceId])
|
|
232
|
+
.measurements(["traffic"])
|
|
233
|
+
.timeRange(start, stop)
|
|
234
|
+
.window("1h", "sum", timezone) // Sum traffic per hour, aligned to local timezone
|
|
235
|
+
.execute();
|
|
236
|
+
// Parse flat array response
|
|
237
|
+
// Traffic returns TWO data points per hour per sensor: "in" and "out"
|
|
238
|
+
if (!Array.isArray(response.data)) {
|
|
239
|
+
throw new Error("Expected array response from traffic query");
|
|
240
|
+
}
|
|
241
|
+
trafficData = response.data;
|
|
242
|
+
if (process.env.DEBUG) {
|
|
243
|
+
console.error(`[traffic-flow] Received ${trafficData.length} data points from ${trafficSensors.length} sensors`);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
rethrowIfGraphQLError(error);
|
|
248
|
+
if (process.env.DEBUG) {
|
|
249
|
+
console.error(`[traffic-flow] Failed to get traffic data:`, error);
|
|
250
|
+
}
|
|
251
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
252
|
+
throw new Error(`Failed to get traffic data for ${room.name}. ${msg}`);
|
|
253
|
+
}
|
|
254
|
+
// Parse traffic data: group by time, then by sensor, then aggregate
|
|
255
|
+
// Store time separately to preserve full ISO timestamp
|
|
256
|
+
const byHourSensor = new Map();
|
|
257
|
+
for (const point of trafficData) {
|
|
258
|
+
const key = `${point.time}:${point.sensor_id}`;
|
|
259
|
+
if (!byHourSensor.has(key)) {
|
|
260
|
+
byHourSensor.set(key, { time: point.time, in: 0, out: 0 });
|
|
261
|
+
}
|
|
262
|
+
const counts = byHourSensor.get(key);
|
|
263
|
+
if (point.field === "in") {
|
|
264
|
+
counts.in = point.value || 0;
|
|
265
|
+
}
|
|
266
|
+
else if (point.field === "out") {
|
|
267
|
+
counts.out = point.value || 0;
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
// Aggregate across sensors by hour (group by time only)
|
|
271
|
+
const byHour = new Map();
|
|
272
|
+
for (const [_key, data] of byHourSensor) {
|
|
273
|
+
const time = data.time; // Use actual time from data, not split key
|
|
274
|
+
if (!byHour.has(time)) {
|
|
275
|
+
byHour.set(time, { in: 0, out: 0 });
|
|
276
|
+
}
|
|
277
|
+
const hourCounts = byHour.get(time);
|
|
278
|
+
hourCounts.in += data.in;
|
|
279
|
+
hourCounts.out += data.out;
|
|
280
|
+
}
|
|
281
|
+
// Build hourly breakdown (keep UTC timestamps like unified tools)
|
|
282
|
+
const hourlyBreakdown = Array.from(byHour.entries())
|
|
283
|
+
.map(([time, counts]) => ({
|
|
284
|
+
hour_utc: time, // Full ISO timestamp from API
|
|
285
|
+
entries: Math.round(counts.in),
|
|
286
|
+
exits: Math.round(counts.out),
|
|
287
|
+
total_traffic: Math.round(counts.in + counts.out),
|
|
288
|
+
net_flow: Math.round(counts.in - counts.out),
|
|
289
|
+
}))
|
|
290
|
+
.sort((a, b) => a.hour_utc.localeCompare(b.hour_utc));
|
|
291
|
+
// Calculate totals
|
|
292
|
+
const totalEntries = hourlyBreakdown.reduce((sum, h) => sum + h.entries, 0);
|
|
293
|
+
const totalExits = hourlyBreakdown.reduce((sum, h) => sum + h.exits, 0);
|
|
294
|
+
const totalTraffic = totalEntries + totalExits;
|
|
295
|
+
const netFlow = totalEntries - totalExits;
|
|
296
|
+
// Find peak hour (by total traffic)
|
|
297
|
+
let peakHour = hourlyBreakdown.length > 0 ? hourlyBreakdown[0] : null;
|
|
298
|
+
for (const hour of hourlyBreakdown) {
|
|
299
|
+
if (hour.total_traffic > (peakHour?.total_traffic || 0)) {
|
|
300
|
+
peakHour = hour;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Build enhanced summary
|
|
304
|
+
const netFlowStr = netFlow >= 0 ? `+${netFlow}` : `${netFlow}`;
|
|
305
|
+
const summary = `${room.name}: ${totalTraffic.toLocaleString()} movements ${periodDescription} (${totalEntries.toLocaleString()} entries, ${totalExits.toLocaleString()} exits, net flow: ${netFlowStr})`;
|
|
306
|
+
// Build response with timezone metadata and in/out breakdown
|
|
307
|
+
const response = {
|
|
308
|
+
space: {
|
|
309
|
+
id: room.id,
|
|
310
|
+
name: room.name,
|
|
311
|
+
type: "room",
|
|
312
|
+
path: roomPath,
|
|
313
|
+
sensor_mode: "traffic",
|
|
314
|
+
...tzMetadata,
|
|
315
|
+
},
|
|
316
|
+
traffic: {
|
|
317
|
+
total_entries: totalEntries,
|
|
318
|
+
total_exits: totalExits,
|
|
319
|
+
total_traffic: totalTraffic,
|
|
320
|
+
net_flow: netFlow,
|
|
321
|
+
sensor_count: trafficSensors.length,
|
|
322
|
+
period: {
|
|
323
|
+
start_utc: start,
|
|
324
|
+
stop_utc: stop,
|
|
325
|
+
description: periodDescription,
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
hourly_breakdown: hourlyBreakdown,
|
|
329
|
+
peak_hour: peakHour
|
|
330
|
+
? {
|
|
331
|
+
hour_utc: peakHour.hour_utc,
|
|
332
|
+
total_traffic: peakHour.total_traffic,
|
|
333
|
+
entries: peakHour.entries,
|
|
334
|
+
exits: peakHour.exits,
|
|
335
|
+
net_flow: peakHour.net_flow,
|
|
336
|
+
}
|
|
337
|
+
: null,
|
|
338
|
+
summary,
|
|
339
|
+
timestamp: new Date().toISOString(),
|
|
340
|
+
timezone_note: "All timestamps are UTC (ISO-8601). Use site_timezone to interpret in local time.",
|
|
341
|
+
...(usedUtcFallback && {
|
|
342
|
+
warning: "Could not determine local timezone for this space; timestamps use UTC midnight as fallback. 'Today' may not align with the site's actual local day.",
|
|
343
|
+
}),
|
|
344
|
+
};
|
|
345
|
+
return response;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Register butlr_traffic_flow with an McpServer instance
|
|
349
|
+
*/
|
|
350
|
+
export function registerTrafficFlow(server) {
|
|
351
|
+
server.registerTool("butlr_traffic_flow", {
|
|
352
|
+
title: "Traffic Flow",
|
|
353
|
+
description: TRAFFIC_FLOW_DESCRIPTION,
|
|
354
|
+
inputSchema: trafficFlowInputShape,
|
|
355
|
+
annotations: {
|
|
356
|
+
readOnlyHint: true,
|
|
357
|
+
destructiveHint: false,
|
|
358
|
+
idempotentHint: false,
|
|
359
|
+
openWorldHint: true,
|
|
360
|
+
},
|
|
361
|
+
}, async (args) => {
|
|
362
|
+
const validated = TrafficFlowArgsSchema.parse(args);
|
|
363
|
+
const result = await executeTrafficFlow(validated);
|
|
364
|
+
return {
|
|
365
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
|
|
366
|
+
};
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=butlr-traffic-flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"butlr-traffic-flow.js","sourceRoot":"","sources":["../../src/tools/butlr-traffic-flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared response type interfaces for MCP tool outputs
|
|
3
|
+
*
|
|
4
|
+
* These types define the contract between tools and LLM consumers.
|
|
5
|
+
* Every tool response MUST be typed — no `any` on public API surfaces.
|
|
6
|
+
*/
|
|
7
|
+
import type { Capacity, Area } from "../clients/types.js";
|
|
8
|
+
import type { TimezoneMetadata } from "../utils/timezone-helpers.js";
|
|
9
|
+
/** Base measurement data shared between current-occupancy and timeseries tools */
|
|
10
|
+
export interface BaseMeasurementData {
|
|
11
|
+
available: boolean;
|
|
12
|
+
sensor_count?: number;
|
|
13
|
+
entrance_sensor_count?: number;
|
|
14
|
+
coverage_note?: string;
|
|
15
|
+
warning?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Single timeseries data point */
|
|
18
|
+
export interface TimeseriesPoint {
|
|
19
|
+
timestamp: string;
|
|
20
|
+
value: number;
|
|
21
|
+
}
|
|
22
|
+
/** Measurement data with timeseries array */
|
|
23
|
+
export interface TimeseriesMeasurementData extends BaseMeasurementData {
|
|
24
|
+
timeseries: TimeseriesPoint[];
|
|
25
|
+
}
|
|
26
|
+
/** Measurement data with a single current reading */
|
|
27
|
+
export interface CurrentMeasurementData extends BaseMeasurementData {
|
|
28
|
+
current_occupancy?: number;
|
|
29
|
+
timestamp?: string;
|
|
30
|
+
}
|
|
31
|
+
/** Measurement recommendation output */
|
|
32
|
+
export interface MeasurementRecommendation {
|
|
33
|
+
recommended_measurement: "presence" | "traffic" | "none";
|
|
34
|
+
recommendation_reason: string;
|
|
35
|
+
}
|
|
36
|
+
/** Asset identity block used in occupancy tool responses */
|
|
37
|
+
export interface AssetIdentifier {
|
|
38
|
+
asset_id: string;
|
|
39
|
+
asset_type: string;
|
|
40
|
+
asset_name?: string;
|
|
41
|
+
}
|
|
42
|
+
export interface AvailableRoom {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
path: string;
|
|
46
|
+
capacity: Capacity;
|
|
47
|
+
area?: Area;
|
|
48
|
+
tags?: string[];
|
|
49
|
+
/** The query window in minutes (NOT how long the room has been empty) */
|
|
50
|
+
data_window_minutes: number;
|
|
51
|
+
}
|
|
52
|
+
export interface BuildingContext {
|
|
53
|
+
building_name: string;
|
|
54
|
+
total_rooms: number;
|
|
55
|
+
available_rooms: number;
|
|
56
|
+
occupancy_percent: number;
|
|
57
|
+
}
|
|
58
|
+
export interface AvailableRoomsResponse {
|
|
59
|
+
summary: string;
|
|
60
|
+
available_rooms: AvailableRoom[];
|
|
61
|
+
total_available: number;
|
|
62
|
+
showing: number;
|
|
63
|
+
timestamp: string;
|
|
64
|
+
filtered_by?: Record<string, unknown>;
|
|
65
|
+
building_context?: BuildingContext;
|
|
66
|
+
warning?: string;
|
|
67
|
+
}
|
|
68
|
+
export interface SpaceBusynessResponse {
|
|
69
|
+
space: {
|
|
70
|
+
id: string;
|
|
71
|
+
name: string;
|
|
72
|
+
type: "room" | "zone";
|
|
73
|
+
path: string;
|
|
74
|
+
};
|
|
75
|
+
current: {
|
|
76
|
+
occupancy: number;
|
|
77
|
+
capacity: Capacity;
|
|
78
|
+
utilization_percent: number | null;
|
|
79
|
+
label: "quiet" | "moderate" | "busy" | null;
|
|
80
|
+
capacity_configured: boolean;
|
|
81
|
+
as_of: string;
|
|
82
|
+
};
|
|
83
|
+
trend?: {
|
|
84
|
+
typical_for_time: number;
|
|
85
|
+
vs_typical_percent: number;
|
|
86
|
+
trend_label: "lighter" | "typical" | "busier";
|
|
87
|
+
historical_context: string;
|
|
88
|
+
};
|
|
89
|
+
recommendation: string;
|
|
90
|
+
summary: string;
|
|
91
|
+
timestamp: string;
|
|
92
|
+
warning?: string;
|
|
93
|
+
}
|
|
94
|
+
export interface HourlyTraffic {
|
|
95
|
+
hour_utc: string;
|
|
96
|
+
entries: number;
|
|
97
|
+
exits: number;
|
|
98
|
+
total_traffic: number;
|
|
99
|
+
net_flow: number;
|
|
100
|
+
}
|
|
101
|
+
export interface TrafficFlowResponse {
|
|
102
|
+
space: {
|
|
103
|
+
id: string;
|
|
104
|
+
name: string;
|
|
105
|
+
type: "room";
|
|
106
|
+
path: string;
|
|
107
|
+
sensor_mode: "traffic";
|
|
108
|
+
} & TimezoneMetadata;
|
|
109
|
+
traffic: {
|
|
110
|
+
total_entries: number;
|
|
111
|
+
total_exits: number;
|
|
112
|
+
total_traffic: number;
|
|
113
|
+
net_flow: number;
|
|
114
|
+
sensor_count: number;
|
|
115
|
+
period: {
|
|
116
|
+
start_utc: string;
|
|
117
|
+
stop_utc: string;
|
|
118
|
+
description: string;
|
|
119
|
+
};
|
|
120
|
+
};
|
|
121
|
+
hourly_breakdown: HourlyTraffic[];
|
|
122
|
+
peak_hour: HourlyTraffic | null;
|
|
123
|
+
summary: string;
|
|
124
|
+
timestamp: string;
|
|
125
|
+
timezone_note: string;
|
|
126
|
+
warning?: string;
|
|
127
|
+
}
|
|
128
|
+
/** Ultra-compact tree node: [id, displayName] or [id, displayName, children] */
|
|
129
|
+
export type TopologyNode = [string, string] | [string, string, TopologyNode[]];
|
|
130
|
+
export interface ListTopologyResponse {
|
|
131
|
+
tree: TopologyNode[];
|
|
132
|
+
query_params: {
|
|
133
|
+
starting_depth: number;
|
|
134
|
+
traversal_depth: number;
|
|
135
|
+
asset_filter: string[] | "all";
|
|
136
|
+
};
|
|
137
|
+
timestamp: string;
|
|
138
|
+
warning?: string;
|
|
139
|
+
}
|
|
140
|
+
export interface EntityResult {
|
|
141
|
+
id: string;
|
|
142
|
+
_type: string;
|
|
143
|
+
error?: string;
|
|
144
|
+
[key: string]: unknown;
|
|
145
|
+
}
|
|
146
|
+
export interface FetchEntityDetailsResponse {
|
|
147
|
+
entities: EntityResult[];
|
|
148
|
+
requested_count: number;
|
|
149
|
+
fetched_count: number;
|
|
150
|
+
timestamp: string;
|
|
151
|
+
warning?: string;
|
|
152
|
+
}
|
|
153
|
+
export type AssetOccupancyTimeseries = AssetIdentifier & TimezoneMetadata & MeasurementRecommendation & {
|
|
154
|
+
presence: TimeseriesMeasurementData;
|
|
155
|
+
traffic: TimeseriesMeasurementData;
|
|
156
|
+
};
|
|
157
|
+
export interface OccupancyTimeseriesResponse {
|
|
158
|
+
assets: AssetOccupancyTimeseries[];
|
|
159
|
+
interval: string;
|
|
160
|
+
start: string;
|
|
161
|
+
stop: string;
|
|
162
|
+
timezone_note: string;
|
|
163
|
+
timestamp: string;
|
|
164
|
+
}
|
|
165
|
+
export type AssetCurrentOccupancy = AssetIdentifier & TimezoneMetadata & MeasurementRecommendation & {
|
|
166
|
+
presence: CurrentMeasurementData;
|
|
167
|
+
traffic: CurrentMeasurementData;
|
|
168
|
+
};
|
|
169
|
+
export interface CurrentOccupancyResponse {
|
|
170
|
+
assets: AssetCurrentOccupancy[];
|
|
171
|
+
timestamp: string;
|
|
172
|
+
timezone_note: string;
|
|
173
|
+
}
|
|
174
|
+
export type BatteryStatus = "critical" | "due_soon" | "healthy" | "unknown" | "no_battery";
|
|
175
|
+
export interface BatteryDetail {
|
|
176
|
+
sensor_id: string;
|
|
177
|
+
sensor_name: string;
|
|
178
|
+
mac_address: string;
|
|
179
|
+
path: string;
|
|
180
|
+
status: BatteryStatus;
|
|
181
|
+
battery_change_by_date: string;
|
|
182
|
+
days_remaining: number;
|
|
183
|
+
last_battery_change_date?: string;
|
|
184
|
+
next_battery_change_date?: string;
|
|
185
|
+
}
|
|
186
|
+
export interface FloorBreakdown {
|
|
187
|
+
floor_id: string;
|
|
188
|
+
floor_name: string;
|
|
189
|
+
sensors_online: number;
|
|
190
|
+
sensors_total: number;
|
|
191
|
+
percent_online: number;
|
|
192
|
+
batteries_critical: number;
|
|
193
|
+
batteries_due_soon: number;
|
|
194
|
+
}
|
|
195
|
+
export interface OfflineDevice {
|
|
196
|
+
type: "sensor" | "hive";
|
|
197
|
+
id: string;
|
|
198
|
+
name: string;
|
|
199
|
+
serial_number?: string;
|
|
200
|
+
mac_address?: string;
|
|
201
|
+
path: string;
|
|
202
|
+
last_heartbeat?: string;
|
|
203
|
+
hours_offline?: number;
|
|
204
|
+
}
|
|
205
|
+
export interface HardwareSnapshotResponse {
|
|
206
|
+
summary: string;
|
|
207
|
+
sensors: {
|
|
208
|
+
total: number;
|
|
209
|
+
online: number;
|
|
210
|
+
offline: number;
|
|
211
|
+
percent_online: number;
|
|
212
|
+
};
|
|
213
|
+
hives: {
|
|
214
|
+
total: number;
|
|
215
|
+
online: number;
|
|
216
|
+
offline: number;
|
|
217
|
+
percent_online: number;
|
|
218
|
+
};
|
|
219
|
+
battery_health: Record<string, number>;
|
|
220
|
+
scope: {
|
|
221
|
+
type: string;
|
|
222
|
+
id?: string;
|
|
223
|
+
name: string;
|
|
224
|
+
};
|
|
225
|
+
timestamp: string;
|
|
226
|
+
test_devices_excluded?: {
|
|
227
|
+
sensors: {
|
|
228
|
+
mirror: number;
|
|
229
|
+
placeholder: number;
|
|
230
|
+
total: number;
|
|
231
|
+
};
|
|
232
|
+
hives: {
|
|
233
|
+
fake: number;
|
|
234
|
+
placeholder: number;
|
|
235
|
+
total: number;
|
|
236
|
+
};
|
|
237
|
+
note: string;
|
|
238
|
+
};
|
|
239
|
+
battery_details?: BatteryDetail[];
|
|
240
|
+
battery_details_truncated?: boolean;
|
|
241
|
+
battery_details_total?: number;
|
|
242
|
+
breakdown_by_floor?: FloorBreakdown[];
|
|
243
|
+
offline_devices?: OfflineDevice[];
|
|
244
|
+
offline_devices_summary?: {
|
|
245
|
+
sensors_offline: number;
|
|
246
|
+
hives_offline: number;
|
|
247
|
+
total_offline: number;
|
|
248
|
+
showing: number;
|
|
249
|
+
};
|
|
250
|
+
offline_devices_truncated?: boolean;
|
|
251
|
+
offline_devices_total?: number;
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=responses.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responses.d.ts","sourceRoot":"","sources":["../../src/types/responses.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responses.js","sourceRoot":"","sources":["../../src/types/responses.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|