Skip to main content
Glama
RhombusSystems

Rhombus MCP Server

Official
create-camera-policy-tool.ts8.46 kB
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; import { z } from "zod"; import { RequestModifiers } from "../util.js"; import { createCameraPolicy } from "../api/create-camera-policy-tool-api.js"; import { ApiPayloadSchema, OUTPUT_SCHEMA } from "../types/create-camera-policy-tool-types.js"; import { postApi } from "../network.js"; import schema from "../types/schema.js"; const TOOL_NAME = "create-camera-policy-tool"; const TOOL_DESCRIPTION = ` A tool for creating a camera policy that walks users through a multi-step process. The step begins with the user providing a policy name, description, and organization UUID. Then, the user is presented with a form to configure the schedules for the policy. Finally, the user is presented with a form to assign the policy to cameras. Uses elicitation forms for rich user interaction. `; const TOOL_ARGS = { // Step 1: Policy creation name: z.string().describe("Policy name (for creating policy)"), description: z.string().describe("Policy description (for creating policy)"), orgUuid: z.string().describe("Organization UUID (for creating policy)"), // Step 2: Schedule configuration policyUuid: z.string().describe("Policy UUID (for configuring schedules)"), scheduleConfigs: z.string().describe("JSON string of schedule configurations"), // Step 3: Camera assignment cameraUuids: z.string().describe("Comma-separated camera UUIDs to assign policy to"), policyName: z.string().describe("Policy name (for reference)"), } as const; const TOOL_ARGS_SCHEMA = z.object(TOOL_ARGS); export type ToolArgs = z.infer<typeof TOOL_ARGS_SCHEMA>; const TOOL_HANDLER = async (args: ToolArgs, extra: any) => { const { name, description, orgUuid, policyUuid, scheduleConfigs, cameraUuids, policyName } = args; // Step 3: Camera assignment (if cameraUuids provided) if (cameraUuids?.trim()) { try { const cameraList = cameraUuids .split(",") .map((uuid: string) => uuid.trim()) .filter((uuid: string) => uuid); if (cameraList.length > 0) { const cameraPayload = { cameraBulkDetails: cameraList.map(cameraUuid => ({ uuid: cameraUuid, policyUuid: policyUuid, policyUuidUpdated: true, })), }; await postApi({ route: "/camera/updateDetailsBulkV2", body: cameraPayload, modifiers: extra._meta?.requestModifiers as RequestModifiers, sessionId: extra.sessionId, }); const jsonResultResponse = { needUserInput: false, message: `Excellent! Policy created and assigned to ${cameraList.length} camera(s)!`, policyUuid, policyName, }; return { content: [ { type: "text" as const, text: `🎉 Camera policy setup completely finished!\n\n✅ Policy "${policyName}" assigned to ${cameraList.length} camera(s)\n✅ Policy is now fully active\n\nYour cameras will now generate alerts according to the policy configuration.`, }, ], structuredContent: jsonResultResponse, }; } } catch (error) { return { content: [ { type: "text" as const, text: `Failed to assign policy to cameras: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } } // Step 2: Schedule configuration (if scheduleConfigs provided and non-empty) if (scheduleConfigs?.trim() && scheduleConfigs.trim() !== "[]") { try { const configs = JSON.parse(scheduleConfigs) as Array<{ scheduleUuid: string; activities: string[]; }>; // Only proceed if we have actual schedule configurations if (configs.length > 0) { const scheduledTriggers = configs.map(config => ({ scheduleUuid: config.scheduleUuid, triggerSet: config.activities.map(activity => ({ activity })), })); const payload = { policy: { uuid: policyUuid, scheduledTriggers }, }; const result = await postApi<schema["Policy_UpdateCameraPolicyWSResponse"]>({ route: "/policy/updateCameraPolicy", body: payload, modifiers: extra._meta?.requestModifiers as RequestModifiers, sessionId: extra.sessionId, }); if (result.error) { return { content: [ { type: "text" as const, text: `Failed to configure policy schedules: ${result.errorMsg || "Unknown error"}`, }, ], }; } // Success - now show camera assignment form const jsonResultResponse = { needUserInput: true, message: `Excellent! Policy schedules configured.\n\nFinal step: Please select which cameras should use this policy.`, requestType: "camera-assignment", submitAction: "create-camera-policy-tool", policyUuid, policyName, }; return { content: [ { type: "text" as const, text: JSON.stringify(jsonResultResponse), }, ], structuredContent: jsonResultResponse, }; } // If configs.length === 0, fall through to policy creation } catch (error) { return { content: [ { type: "text" as const, text: `Error configuring schedules: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } } // Step 1: Policy creation (if name provided) if (name?.trim()) { try { const payload = ApiPayloadSchema.parse({ policy: { name, description: description?.trim() ? description : undefined, orgUuid: orgUuid?.trim() ? orgUuid : undefined, scheduledTriggers: [], }, }); const result = await createCameraPolicy( payload, extra._meta?.requestModifiers as RequestModifiers, extra.sessionId ); if (result.error) { return { content: [ { type: "text" as const, text: `Failed to create camera policy: ${result.errorMsg || "Unknown error"}`, }, ], }; } console.error( `[createCameraPolicyTool] -- Proceeding with schedule-trigger-configuration form. Got result ${JSON.stringify(result)}` ); // Success - now show schedule configuration form const jsonResultResponse = { needUserInput: true, message: `Great! Your policy "${name}" was created with UUID: ${result.policyUuid}\n\nNext, let's configure when this policy should be active and what activities should trigger alerts.`, requestType: "schedule-trigger-configuration", submitAction: "create-camera-policy-tool", policyUuid: result.policyUuid, policyName: name, }; return { content: [ { type: "text" as const, text: JSON.stringify(jsonResultResponse), }, ], structuredContent: jsonResultResponse, }; } catch (error) { return { content: [ { type: "text" as const, text: `Error creating camera policy: ${error instanceof Error ? error.message : "Unknown error"}`, }, ], }; } } // Step 0: Show initial form (no args provided) return { content: [ { type: "text" as const, text: JSON.stringify({ needUserInput: true, message: "Please provide the following information to create your camera policy:\n\n1. **Policy Name** (required): A descriptive name for the policy\n2. **Policy Description** (optional): What this policy does\n3. **Organization UUID** (optional): Leave blank to use your current organization\n\nOnce you provide this information, I'll create the policy for you.", requestType: "policy-creation-form", submitAction: "create-camera-policy-tool", }), }, ], }; }; export function createTool(server: McpServer) { server.registerTool( TOOL_NAME, { description: TOOL_DESCRIPTION, inputSchema: TOOL_ARGS, outputSchema: OUTPUT_SCHEMA.shape, }, TOOL_HANDLER ); }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/RhombusSystems/rhombus-node-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server