rhombus-node-mcp 0.1.56 → 0.1.57
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/dist/api/access-control-tool-api.js +231 -32
- package/dist/api/alarm-monitoring-tool-api.js +50 -1
- package/dist/api/automated-prompts-tool-api.js +9 -17
- package/dist/api/camera-policy-tool-api.js +122 -0
- package/dist/api/camera-tool-api.js +3 -5
- package/dist/api/camera-uptime-tool-api.js +62 -25
- package/dist/api/clips-tool-api.js +45 -9
- package/dist/api/create-tool-api.js +55 -7
- package/dist/api/door-tool-api.js +74 -13
- package/dist/api/entity-lookup-tool-api.js +8 -1
- package/dist/api/events-tool-api.js +79 -6
- package/dist/api/faces-tool-api.js +112 -7
- package/dist/api/get-accessible-apps.js +68 -6
- package/dist/api/get-entity-tool-api.js +12 -12
- package/dist/api/get-org-information-tool-api.js +2 -2
- package/dist/api/guest-management-tool-api.js +75 -1
- package/dist/api/location-tool-api.js +120 -28
- package/dist/api/lpr-tool-api.js +71 -16
- package/dist/api/policy-alerts-tool-api.js +7 -3
- package/dist/api/report-tool-api.js +4 -1
- package/dist/api/rules-tool-api.js +6 -16
- package/dist/api/schedule-tool-api.js +107 -0
- package/dist/api/search-tool-api.js +5 -13
- package/dist/api/update-tool-api.js +96 -1
- package/dist/api/user-tool-api.js +58 -13
- package/dist/createServer.js +18 -6
- package/dist/filtering-utils.js +421 -29
- package/dist/index.js +1 -1
- package/dist/network/network.js +122 -10
- package/dist/network/org-reference-cache.js +74 -0
- package/dist/telemetry/tracingProxy.js +4 -0
- package/dist/tools/entity-lookup-tool.js +6 -4
- package/dist/tools/get-entity-tool.js +40 -20
- package/dist/tools/get-org-information-tool.js +30 -2
- package/dist/tools/time-conversion-tool.js +59 -36
- package/dist/tools/time-tool.js +12 -3
- package/dist/tools/user-tool.js +100 -2
- package/dist/tools-console/access-anomaly-tool.js +2 -19
- package/dist/tools-console/access-control-tool.js +328 -2
- package/dist/tools-console/alarm-monitoring-tool.js +72 -2
- package/dist/tools-console/analytics-tool.js +2 -2
- package/dist/tools-console/badge-timeline-tool.js +2 -21
- package/dist/tools-console/camera-policy-tool.js +252 -0
- package/dist/tools-console/camera-tool.js +111 -89
- package/dist/tools-console/clips-tool.js +21 -31
- package/dist/tools-console/count-tool.js +8 -0
- package/dist/tools-console/create-camera-policy-tool.js +302 -122
- package/dist/tools-console/door-schedule-exception-tool.js +2 -33
- package/dist/tools-console/door-tool.js +130 -2
- package/dist/tools-console/elements-access-anomaly-tool.js +2 -19
- package/dist/tools-console/elements-badge-timeline-tool.js +2 -21
- package/dist/tools-console/elements-lost-badge-tool.js +2 -17
- package/dist/tools-console/elements-tool.js +2 -29
- package/dist/tools-console/events-tool.js +22 -101
- package/dist/tools-console/faces-tool.js +254 -28
- package/dist/tools-console/guest-management-tool.js +127 -2
- package/dist/tools-console/location-tool.js +156 -35
- package/dist/tools-console/lost-badge-tool.js +2 -17
- package/dist/tools-console/lpr-tool.js +89 -23
- package/dist/tools-console/netbox-access-anomaly-tool.js +2 -19
- package/dist/tools-console/netbox-badge-timeline-tool.js +2 -21
- package/dist/tools-console/netbox-lost-badge-tool.js +2 -17
- package/dist/tools-console/netbox-tool.js +2 -29
- package/dist/tools-console/onguard-tool.js +2 -30
- package/dist/tools-console/person-tracking-tool.js +2 -2
- package/dist/tools-console/policy-alerts-tool.js +5 -29
- package/dist/tools-console/reboot-cameras-tool.js +17 -2
- package/dist/tools-console/report-tool.js +10 -40
- package/dist/tools-console/schedule-tool.js +190 -0
- package/dist/tools-console/update-tool.js +298 -168
- package/dist/tools-console/video-walls-tool.js +93 -21
- package/dist/types/access-anomaly-tool-types.js +22 -2
- package/dist/types/access-control-tool-types.js +116 -1
- package/dist/types/alarm-monitoring-tool-types.js +42 -1
- package/dist/types/badge-timeline-tool-types.js +18 -3
- package/dist/types/camera-policy-tool-types.js +104 -0
- package/dist/types/camera-tool-types.js +80 -1
- package/dist/types/clips-tool-types.js +27 -3
- package/dist/types/create-camera-policy-tool-types.js +275 -26
- package/dist/types/door-schedule-exception-tool-types.js +20 -6
- package/dist/types/door-tool-types.js +36 -4
- package/dist/types/entity-lookup-tool-types.js +6 -1
- package/dist/types/events-tools-types.js +24 -16
- package/dist/types/faces-tools-types.js +106 -3
- package/dist/types/get-entity-tool-types.js +76 -12
- package/dist/types/guest-management-tool-types.js +103 -1
- package/dist/types/location-tool-types.js +100 -14
- package/dist/types/lost-badge-tool-types.js +17 -2
- package/dist/types/lpr-tool-types.js +47 -8
- package/dist/types/onguard-tool-types.js +21 -1
- package/dist/types/policy-alerts-tool-types.js +1 -1
- package/dist/types/report-tool-types.js +29 -1
- package/dist/types/schedule-tool-types.js +370 -0
- package/dist/types/schema.js +479 -9
- package/dist/types/time-conversion-tool-types.js +3 -4
- package/dist/types/update-tool-types.js +40 -18
- package/dist/types/user-tool-types.js +44 -1
- package/dist/types/video-walls-tool-types.js +30 -2
- package/dist/types/zod-schemas.js +5128 -996
- package/dist/util.js +62 -3
- package/dist/utils/entity-name-match.js +11 -0
- package/package.json +3 -1
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
export const TOOL_ARGS = {
|
|
3
|
-
time_to_convert: z
|
|
4
|
-
z.string(),
|
|
5
|
-
|
|
6
|
-
]).describe("The time to convert. This can be either an ISO 8601 timestamp string (e.g., '2023-10-05T14:48:00.000Z') or a Unix timestamp in milliseconds."),
|
|
3
|
+
time_to_convert: z
|
|
4
|
+
.union([z.string(), z.number()])
|
|
5
|
+
.describe("The time(s) to convert. Either an ISO 8601 timestamp string (e.g. '2023-10-05T14:48:00.000Z' or '2023-10-05T14:48:00-07:00'), a Unix timestamp in milliseconds, or a comma-separated list of several such values (converted in order)."),
|
|
7
6
|
};
|
|
8
7
|
const TOOL_ARGS_SCHEMA = z.object(TOOL_ARGS);
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
2
|
+
/**
|
|
3
|
+
* The entity types this tool can actually update.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately narrow. It previously listed climate-sensor, door-controller,
|
|
6
|
+
* environmental-gateway, audio-gateway and badge-reader, none of which had a
|
|
7
|
+
* handler — every one returned "not yet implemented. Coming soon!". Because the
|
|
8
|
+
* chatbot adapts MCP tools with `strict: false`, an enum is advisory: nothing
|
|
9
|
+
* stopped the model picking one of those, and each attempt burned a turn on a
|
|
10
|
+
* guaranteed dead end. Add a value here only once its handler exists.
|
|
11
|
+
*/
|
|
12
|
+
export const ENTITY_TYPE = z.enum(["camera", "doorbell-camera"]);
|
|
12
13
|
// Camera-specific update schemas
|
|
13
14
|
export const CameraVideoSettings = z.object({
|
|
14
15
|
hdr_enabled: z.boolean().optional().describe("Enable HDR (High Dynamic Range)"),
|
|
@@ -20,7 +21,7 @@ export const CameraVideoSettings = z.object({
|
|
|
20
21
|
.describe("Image brightness adjustment (-255 to 255)"),
|
|
21
22
|
img_contrast: z.number().min(0).max(128).optional().describe("Image contrast (0 to 128)"),
|
|
22
23
|
img_saturation: z.number().min(0).max(255).optional().describe("Image saturation (0 to 255)"),
|
|
23
|
-
img_sharpness: z.number().min(0).max(
|
|
24
|
+
img_sharpness: z.number().min(0).max(11).optional().describe("Image sharpness (0 to 11; 6 works for most situations)"),
|
|
24
25
|
resolution: z
|
|
25
26
|
.object({
|
|
26
27
|
width: z.number().int().positive().optional(),
|
|
@@ -59,9 +60,9 @@ export const CameraVideoSettings = z.object({
|
|
|
59
60
|
night_img_sharpness: z
|
|
60
61
|
.number()
|
|
61
62
|
.min(0)
|
|
62
|
-
.max(
|
|
63
|
+
.max(11)
|
|
63
64
|
.optional()
|
|
64
|
-
.describe("Night mode sharpness (0 to
|
|
65
|
+
.describe("Night mode sharpness (0 to 11; 6 works for most situations)"),
|
|
65
66
|
});
|
|
66
67
|
export const CameraAudioSettings = z.object({
|
|
67
68
|
audio_record: z.boolean().optional().describe("Enable audio recording"),
|
|
@@ -95,21 +96,37 @@ export const CameraDeviceSettings = z.object({
|
|
|
95
96
|
});
|
|
96
97
|
// Input schema for the tool
|
|
97
98
|
export const TOOL_ARGS = {
|
|
98
|
-
entityType: ENTITY_TYPE.describe("Type of entity to update"
|
|
99
|
-
|
|
99
|
+
entityType: ENTITY_TYPE.describe("Type of entity to update. Only 'camera' and 'doorbell-camera' can be updated through this tool; " +
|
|
100
|
+
"for climate sensors, door controllers, environmental gateways, audio gateways and badge readers, tell the " +
|
|
101
|
+
"user the change has to be made in the Rhombus Console rather than attempting it here."),
|
|
102
|
+
entityUuid: z
|
|
103
|
+
.string()
|
|
104
|
+
.nullable()
|
|
105
|
+
.describe('UUID of the entity to update. Faceted UUIDs are supported (e.g. "cameraUuid.v0" / "cameraUuid.v1") to target a specific camera facet; defaults to "v0" when no facet is given.'),
|
|
100
106
|
// Camera-specific update fields
|
|
107
|
+
// These three arrive as free-form JSON strings, so the field schemas below are
|
|
108
|
+
// NOT part of the input schema the model sees — this description text is the
|
|
109
|
+
// only range guidance it ever gets. Keep it in sync with CameraVideoSettings /
|
|
110
|
+
// CameraAudioSettings / CameraDeviceSettings.
|
|
111
|
+
//
|
|
112
|
+
// Promoting them to real object schemas would NOT make out-of-range values
|
|
113
|
+
// impossible: the chatbot sends MCP tools to OpenAI with `strict: false`
|
|
114
|
+
// (chatbot src/mcp/toolAdapters.ts), so there is no constrained decoding, and
|
|
115
|
+
// even under `strict: true` JSON Schema `minimum`/`maximum` are not enforced
|
|
116
|
+
// keywords. Range checking is therefore ALWAYS the tool's job — which is why
|
|
117
|
+
// parseSettingsBlock reports the field, the bound, and the received value.
|
|
101
118
|
cameraVideoSettings: z
|
|
102
119
|
.string()
|
|
103
120
|
.nullable()
|
|
104
|
-
.describe(
|
|
121
|
+
.describe(`JSON string of video settings to update for camera. Values outside these ranges are REJECTED — img_brightness: -255 to 255 · img_contrast: 0 to 128 · img_saturation: 0 to 255 · img_sharpness: 0 to 11 (6 is typical — NOT a 0-100 scale) · wdr_strength: 0 to 128 (64 is typical) · zero_motion_video_bitrate_percent: 0 to 100 · hdr_enabled / wdr_enabled / video_persist_disabled: booleans · resolution: {"width": n, "height": n}. The night-mode fields (night_img_brightness, night_img_contrast, night_img_saturation, night_img_sharpness) take the same ranges as their daytime counterparts. Example for a dark image: '{"img_brightness": 0, "wdr_strength": 64}'; for a washed-out image: '{"img_brightness": -50, "img_contrast": 80}'; for a blurry image: '{"img_sharpness": 8}'. Saturation matters — 0 yields grayscale; most cameras look best mid-range, tune from there.`),
|
|
105
122
|
cameraAudioSettings: z
|
|
106
123
|
.string()
|
|
107
124
|
.nullable()
|
|
108
|
-
.describe(
|
|
125
|
+
.describe(`JSON string of audio settings to update for camera. audio_record / device_mic_enabled / device_speaker_enabled: booleans · audio_internal_mic_volume: 0 to 100 · audio_internal_speaker_volume: 0 to 100. Example: '{"audio_record": true, "audio_internal_mic_volume": 80}'.`),
|
|
109
126
|
cameraDeviceSettings: z
|
|
110
127
|
.string()
|
|
111
128
|
.nullable()
|
|
112
|
-
.describe(
|
|
129
|
+
.describe(`JSON string of device settings to update for camera (name, timezone, LED). camera_name / camera_timezone: strings · led_intensity: 0 to 100 · led_mode: one of "auto", "always_on", "always_off" · led_stealth_mode: boolean. LED control uses EXACTLY these underscore field names (not camelCase): LED off = '{"led_stealth_mode": true}' (recommended) or '{"led_mode": "always_off"}'; LED on = '{"led_stealth_mode": false}' or '{"led_mode": "always_on"}' or '{"led_mode": "auto"}'.`),
|
|
113
130
|
// Step tracking for multi-step updates
|
|
114
131
|
step: z
|
|
115
132
|
.enum(["entity-selection", "settings-configuration", "confirmation"])
|
|
@@ -129,6 +146,11 @@ export const OUTPUT_SCHEMA = z.object({
|
|
|
129
146
|
success: z.boolean().optional(),
|
|
130
147
|
error: z.string().optional(),
|
|
131
148
|
updatedSettings: z.any().optional(),
|
|
149
|
+
// Doorbell writes are verified by reading /doorbellcamera/getConfig back;
|
|
150
|
+
// these carry the before values and anything the read-back contradicted.
|
|
151
|
+
previousSettings: z.any().optional(),
|
|
152
|
+
settingsNotApplied: z.any().optional(),
|
|
153
|
+
settingsNotVerified: z.any().optional(),
|
|
132
154
|
});
|
|
133
155
|
// API payload types
|
|
134
156
|
export const UpdateCameraConfigPayload = z.object({
|
|
@@ -5,6 +5,9 @@ export var UserToolRequestType;
|
|
|
5
5
|
UserToolRequestType["FIND_BY_EMAIL"] = "find-by-email";
|
|
6
6
|
UserToolRequestType["GET_PERMISSIONS"] = "get-permissions";
|
|
7
7
|
UserToolRequestType["GET_PERMISSION_GROUPS"] = "get-permission-groups";
|
|
8
|
+
UserToolRequestType["CREATE_USER"] = "create-user";
|
|
9
|
+
UserToolRequestType["UPDATE_USER"] = "update-user";
|
|
10
|
+
UserToolRequestType["DELETE_USER"] = "delete-user";
|
|
8
11
|
})(UserToolRequestType || (UserToolRequestType = {}));
|
|
9
12
|
// NOTE: `includeFields` and `filterBy` are NOT declared here — the
|
|
10
13
|
// `createFilteringProxy` wrapper automatically injects them into every tool's
|
|
@@ -15,7 +18,27 @@ export const TOOL_ARGS = {
|
|
|
15
18
|
email: z
|
|
16
19
|
.string()
|
|
17
20
|
.nullable()
|
|
18
|
-
.describe("The email address of the user
|
|
21
|
+
.describe("The email address of the user. Required for 'find-by-email' and 'create-user'. For 'create-user' this is where the invitation is sent, so read it back to the user before creating — a typo invites a stranger into the organization."),
|
|
22
|
+
userUuid: z
|
|
23
|
+
.string()
|
|
24
|
+
.nullable()
|
|
25
|
+
.describe("The UUID of the user. Required for 'update-user' and 'delete-user'. Get it from 'list-users' or 'find-by-email' — do not guess one."),
|
|
26
|
+
userName: z
|
|
27
|
+
.string()
|
|
28
|
+
.nullable()
|
|
29
|
+
.describe("The user's display name. Required for 'create-user'; for 'update-user' it is the new name (omit to leave it unchanged)."),
|
|
30
|
+
permissionGroupUuid: z
|
|
31
|
+
.string()
|
|
32
|
+
.nullable()
|
|
33
|
+
.describe("UUID of the permission group (role) to assign. Required for 'create-user'; for 'update-user' it is the new role (omit to leave the role unchanged). Get it from 'get-permission-groups' with includeFields ['permissionGroups.uuid','permissionGroups.name','permissionGroups.description']. A role decides what the person can see and do, so confirm the role NAME with the user rather than picking one."),
|
|
34
|
+
suppressWelcomeEmail: z
|
|
35
|
+
.boolean()
|
|
36
|
+
.nullable()
|
|
37
|
+
.describe("Only for 'create-user'. Creating a user emails them an invitation by default. Set true only when the user explicitly asks not to notify the new person."),
|
|
38
|
+
confirmDelete: z
|
|
39
|
+
.boolean()
|
|
40
|
+
.nullable()
|
|
41
|
+
.describe("Required to be true for 'delete-user'. Deleting a user revokes their console access and their credentials, and cannot be undone, so it refuses without explicit confirmation."),
|
|
19
42
|
};
|
|
20
43
|
const TOOL_ARGS_SCHEMA = z.object(TOOL_ARGS);
|
|
21
44
|
// Permission level assigned to a resource for a role. Typed loosely as string
|
|
@@ -106,5 +129,25 @@ export const OUTPUT_SCHEMA = z.object({
|
|
|
106
129
|
.array(PermissionGroupSchema)
|
|
107
130
|
.optional()
|
|
108
131
|
.describe("List of permission groups in the organization."),
|
|
132
|
+
created: z
|
|
133
|
+
.object({ success: z.boolean().optional(), uuid: z.string().optional() })
|
|
134
|
+
.optional()
|
|
135
|
+
.describe("Result of 'create-user'."),
|
|
136
|
+
updated: z
|
|
137
|
+
.object({ success: z.boolean().optional(), uuid: z.string().optional() })
|
|
138
|
+
.optional()
|
|
139
|
+
.describe("Result of 'update-user'."),
|
|
140
|
+
deleted: z
|
|
141
|
+
.object({ success: z.boolean().optional(), uuid: z.string().optional() })
|
|
142
|
+
.optional()
|
|
143
|
+
.describe("Result of 'delete-user'."),
|
|
144
|
+
note: z
|
|
145
|
+
.string()
|
|
146
|
+
.optional()
|
|
147
|
+
.describe("A caveat about this result that the user needs to be told."),
|
|
148
|
+
warningMsg: z
|
|
149
|
+
.string()
|
|
150
|
+
.optional()
|
|
151
|
+
.describe("A warning from the Rhombus API — the call succeeded, but with a caveat."),
|
|
109
152
|
error: z.string().optional().describe("An error message if the request failed."),
|
|
110
153
|
});
|
|
@@ -28,9 +28,21 @@ export const CreateVideoWallOptions = z
|
|
|
28
28
|
.describe("The options for creating a video wall. This is required if your requestType === `create`");
|
|
29
29
|
export const TOOL_ARGS = {
|
|
30
30
|
requestType: z
|
|
31
|
-
.enum(["list", "create"])
|
|
31
|
+
.enum(["list", "create", "update", "delete"])
|
|
32
32
|
.describe("The type of request to make."),
|
|
33
33
|
videoWallCreateOptions: CreateVideoWallOptions,
|
|
34
|
+
videoWallUuid: z
|
|
35
|
+
.string()
|
|
36
|
+
.nullable()
|
|
37
|
+
.describe("The uuid of the video wall to act on. Required for `update` and `delete`. Get it from `list` — do not guess one."),
|
|
38
|
+
displayName: z
|
|
39
|
+
.string()
|
|
40
|
+
.nullable()
|
|
41
|
+
.describe("Only for `update`: a new name for the wall. Omit to leave the name unchanged."),
|
|
42
|
+
deviceList: z
|
|
43
|
+
.array(z.string())
|
|
44
|
+
.nullable()
|
|
45
|
+
.describe("Only for `update`: the camera uuids the wall should contain AFTER the update. This REPLACES the wall's current cameras rather than adding to them, so include the ones being kept. To add or remove a few, read the wall with `list` first and send the full resulting set. The grid layout is recomputed from the new count."),
|
|
34
46
|
includeFields: INCLUDE_FIELDS_ARG,
|
|
35
47
|
filterBy: FILTER_BY_ARG,
|
|
36
48
|
};
|
|
@@ -53,7 +65,23 @@ export const OUTPUT_SCHEMA = z.object({
|
|
|
53
65
|
.optional(),
|
|
54
66
|
videoWall: z
|
|
55
67
|
.array(z.any())
|
|
56
|
-
.describe("
|
|
68
|
+
.describe("Unused — no current requestType populates this field. Use `videoWalls` (from 'list') or `uuid` (from 'create').")
|
|
57
69
|
.optional(),
|
|
58
70
|
uuid: z.string().describe("The uuid of the created video wall.").optional(),
|
|
71
|
+
updated: z
|
|
72
|
+
.object({ success: z.boolean().optional(), uuid: z.string().optional() })
|
|
73
|
+
.optional()
|
|
74
|
+
.describe("Result of an `update` request."),
|
|
75
|
+
deleted: z
|
|
76
|
+
.object({ success: z.boolean().optional(), uuid: z.string().optional() })
|
|
77
|
+
.optional()
|
|
78
|
+
.describe("Result of a `delete` request."),
|
|
79
|
+
note: z
|
|
80
|
+
.string()
|
|
81
|
+
.optional()
|
|
82
|
+
.describe("A caveat about this result that the user needs to be told."),
|
|
83
|
+
warningMsg: z
|
|
84
|
+
.string()
|
|
85
|
+
.optional()
|
|
86
|
+
.describe("A warning from the Rhombus API — the call succeeded, but with a caveat."),
|
|
59
87
|
});
|