video-walls-tool
List or create video walls to combine multiple camera feeds into a single monitoring view.
Instructions
This tool interacts with Rhombus video walls. Rhombus video walls are a collection of camera feeds combined into a single view, allowing users to monitor multiple cameras.
The layout of created video walls is automatically determined by the number of cameras in video wall settings "numVisibleDevicesAtOnce".
Output filtering (all tools):
includeFields(string[]): Dot-notation paths to keep in the response (e.g."vehicleEvents.vehicleLicensePlate"). Omit to return all fields.filterBy(array): Predicates to filter array items. Each entry:{field, op, value}where op is one of= != > >= < <= contains. All conditions are ANDed. Example:[{field:"vehicleLicensePlate", op:"=", value:"ABC123"}]WARNING: some tool responses exceed 400k characters — use these params to request only the data you need.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| requestType | Yes | The type of request to make. | |
| videoWallCreateOptions | Yes | The options for creating a video wall. This is required if your requestType === `create` | |
| includeFields | Yes | Dot-notation field paths to include in the response (e.g. "vehicleEvents.vehicleLicensePlate"). Pass null to return all fields. WARNING: some responses can exceed 400k characters — use includeFields to request only the data you need. For high-volume tools this may be required to get a complete answer. | |
| filterBy | Yes | Filter array items in the response by field values. All conditions are ANDed. Example: [{field: "vehicleLicensePlate", op: "=", value: "ABC123"}, {field: "confidence", op: ">", value: 0.8}] Use alongside includeFields to get only the specific records and fields you need. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| error | No | If this field exists, then an error occured and contains the error message. | |
| needUserInput | No | If this field exists and is true, then the tool requires additional input from the user. | |
| commandForUser | No | If this field exists, then the tool requires additional input from the user. | |
| videoWalls | No | If requestType is `list`, then this field will be populated with the list of video walls. | |
| videoWall | No | If requestType is `get`, then this field will be populated with the video wall. | |
| uuid | No | The uuid of the created video wall. |
Implementation Reference
- src/tools/video-walls-tool.ts:26-62 (handler)Main handler for 'video-walls-tool'. Dispatches to 'create' (calls handleCreateVideoWallRequest) or 'list' (calls getVideoWalls) based on requestType.
const TOOL_HANDLER = async (args: ToolArgs, extra: unknown) => { const { requestType, videoWallCreateOptions } = args; const { requestModifiers, sessionId } = extractFromToolExtra(extra); switch (requestType) { case "create": if (!videoWallCreateOptions) { return createToolTextContent( JSON.stringify({ error: "videoWallCreateOptions is required. Please try again.", }), ); } return createToolStructuredContent<OutputSchema>( await handleCreateVideoWallRequest( videoWallCreateOptions, requestModifiers, sessionId, ), ); case "list": return createToolStructuredContent<OutputSchema>( await getVideoWalls(requestModifiers, sessionId), ); default: } return { content: [ { type: "text" as const, text: "Invalid entity type. Please try again.", }, ], }; }; - src/tools/video-walls-tool.ts:64-74 (registration)Registers the tool named 'video-walls-tool' with the MCP server, including input/output schemas and the handler.
export function createTool(server: McpServer) { server.registerTool( TOOL_NAME, { description: TOOL_DESCRIPTION, inputSchema: TOOL_ARGS, outputSchema: OUTPUT_SCHEMA.shape, }, TOOL_HANDLER, ); } - Output schema for the video-walls-tool, defining error, needUserInput, commandForUser, videoWalls, videoWall, and uuid fields.
export const OUTPUT_SCHEMA = z.object({ error: z .optional(z.string()) .describe( "If this field exists, then an error occured and contains the error message.", ), needUserInput: z .boolean() .optional() .describe( "If this field exists and is true, then the tool requires additional input from the user.", ), commandForUser: z .string() .optional() .describe( "If this field exists, then the tool requires additional input from the user.", ), videoWalls: z .array(z.any()) .describe( "If requestType is `list`, then this field will be populated with the list of video walls.", ) .optional(), videoWall: z .array(z.any()) .describe( "If requestType is `get`, then this field will be populated with the video wall.", ) .optional(), uuid: z.string().describe("The uuid of the created video wall.").optional(), }); export type OutputSchema = z.infer<typeof OUTPUT_SCHEMA>; - Input schema for the video-walls-tool: requestType (list/create), videoWallCreateOptions, includeFields, filterBy.
export const TOOL_ARGS = { requestType: z .enum(["list", "create"]) .describe("The type of request to make."), videoWallCreateOptions: CreateVideoWallOptions, includeFields: INCLUDE_FIELDS_ARG, filterBy: FILTER_BY_ARG, }; - src/api/create-tool-api.ts:177-209 (helper)Handles create video wall logic: validates displayName and deviceList, prompts user if missing, otherwise calls createVideoWall API.
export async function handleCreateVideoWallRequest( videoWallCreateOptions: CreateVideoWallOptions, requestModifiers: RequestModifiers, sessionId?: string, ): Promise<OutputSchema> { logger.info("🔨 Creating video wall"); if (!videoWallCreateOptions?.displayName) { return { needUserInput: true, commandForUser: "What should the name of the video wall be?", }; } else if ((videoWallCreateOptions?.deviceList || []).length === 0) { return { needUserInput: true, commandForUser: "Which cameras would you like on this video wall?", }; } else { logger.info( "Creating video wall with options: ", JSON.stringify(videoWallCreateOptions), ); const response = await createVideoWall( videoWallCreateOptions, requestModifiers, sessionId, ); return { uuid: response?.uuid ?? undefined, error: response?.errorMsg ?? undefined, }; } }