create-category
Add new categories to organize PI Dashboard resources by specifying name, organization ID, and optional settings like labels, help text, and filter configurations.
Instructions
Create a new category
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| description | Yes | Unique name of a category | |
| orgId | Yes | Organization ID | |
| label | No | Alternative text for the category | |
| helpText | No | Help text to describe the category | |
| categoryObjectsPosition | No | Position of category objects panel | |
| cascadeFilters | No | Enable cascading filters |
Implementation Reference
- build/index.js:655-683 (handler)The asynchronous handler function that executes the core logic of the 'create-category' tool. It constructs a payload from the input parameters (adding optional fields if provided) and sends a POST request to the '/categories' endpoint using the shared 'authenticatedRequest' helper. It returns success or error markdown content.
}, async ({ description, orgId, label, helpText, categoryObjectsPosition, cascadeFilters }) => { try { const payload = { description, orgId }; if (label !== undefined) payload.label = label; if (helpText !== undefined) payload.helpText = helpText; if (categoryObjectsPosition !== undefined) payload.categoryObjectsPosition = categoryObjectsPosition; if (cascadeFilters !== undefined) payload.cascadeFilters = cascadeFilters; const result = await authenticatedRequest("/categories", "POST", payload); return { content: [{ type: "text", text: `Category created successfully:\n${JSON.stringify(result, null, 2)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `Error creating category: ${getErrorMessage(error)}` }] }; } }); - build/index.js:649-654 (schema)The Zod input schema defining the parameters for the 'create-category' tool, including required fields 'description' and 'orgId', and optional fields for customization.
description: z.string().describe("Unique name of a category"), orgId: z.number().describe("Organization ID"), label: z.string().optional().describe("Alternative text for the category"), helpText: z.string().optional().describe("Help text to describe the category"), categoryObjectsPosition: z.enum(["RIGHT", "TOP"]).optional().describe("Position of category objects panel"), cascadeFilters: z.boolean().optional().describe("Enable cascading filters") - build/index.js:648-683 (registration)The full registration of the 'create-category' tool via McpServer.tool(), specifying name, description, input schema, and inline handler function.
server.tool("create-category", "Create a new category", { description: z.string().describe("Unique name of a category"), orgId: z.number().describe("Organization ID"), label: z.string().optional().describe("Alternative text for the category"), helpText: z.string().optional().describe("Help text to describe the category"), categoryObjectsPosition: z.enum(["RIGHT", "TOP"]).optional().describe("Position of category objects panel"), cascadeFilters: z.boolean().optional().describe("Enable cascading filters") }, async ({ description, orgId, label, helpText, categoryObjectsPosition, cascadeFilters }) => { try { const payload = { description, orgId }; if (label !== undefined) payload.label = label; if (helpText !== undefined) payload.helpText = helpText; if (categoryObjectsPosition !== undefined) payload.categoryObjectsPosition = categoryObjectsPosition; if (cascadeFilters !== undefined) payload.cascadeFilters = cascadeFilters; const result = await authenticatedRequest("/categories", "POST", payload); return { content: [{ type: "text", text: `Category created successfully:\n${JSON.stringify(result, null, 2)}` }] }; } catch (error) { return { isError: true, content: [{ type: "text", text: `Error creating category: ${getErrorMessage(error)}` }] }; } }); - build/index.js:57-125 (helper)Shared helper function 'authenticatedRequest' used by the handler to perform the actual HTTP POST request to create the category, handling authentication, query params, and response parsing.
async function authenticatedRequest(endpoint, method = "GET", body = null, queryParams = {}) { if (!apiUrlSet) { throw new Error("API URL not set. Please set the API URL using the set-api-url tool."); } if (!authToken) { throw new Error("Not authenticated. Please authenticate first."); } // Build URL with query parameters let url = `${API_BASE_URL}${endpoint}`; // Add orgId if available if (orgId !== null) { queryParams.orgId = orgId.toString(); } // Add query parameters if any if (Object.keys(queryParams).length > 0) { const queryString = Object.entries(queryParams) .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(value)}`) .join("&"); url = `${url}?${queryString}`; } logInfo(`Making ${method} request to ${url}`); const headers = { "Authorization": `bearer ${authToken}`, "Content-Type": "application/json" }; const options = { method, headers }; if (body !== null && ["POST", "PUT"].includes(method)) { options.body = JSON.stringify(body); logInfo(`Request body: ${JSON.stringify(body)}`); } try { const response = await fetch(url, options); if (!response.ok) { const errorText = await response.text(); logError(`API request failed with status ${response.status}: ${errorText}`); throw new Error(`API request failed with status ${response.status}: ${response.statusText}`); } // Check if the response is JSON or binary const contentType = response.headers.get("content-type") || ""; if (contentType.includes("application/json")) { const jsonData = await response.json(); logInfo(`Received JSON response: ${JSON.stringify(jsonData).substring(0, 200)}...`); return jsonData; } else if (contentType.includes("text/csv")) { // For binary/file responses, return a base64 encoded string const buffer = await response.arrayBuffer(); const base64 = Buffer.from(buffer).toString("base64"); logInfo(`Received binary response of type ${contentType}, length: ${base64.length}`); return { contentType, data: base64 }; } else { // Otherwise, return as text const text = await response.text(); logInfo(`Received text response: ${text.substring(0, 200)}...`); return text; } } catch (error) { logError(`API request error: ${getErrorMessage(error)}`); throw error; } }