UNPKG

@etm-professional-control/winccoa-mcp-server

Version:

MCP Server for WinCC OA with field-specific configurations

140 lines 4.34 kB
/** * Utility helper functions for MCP tool responses and datapoint operations */ /** * Create content array for MCP responses, filtering internal types if needed * @param arr - Array of type names * @param withInternals - Whether to include internal types (starting with _) * @returns Content array for MCP response */ export function mkTypesContent(arr, withInternals) { const ret = []; for (let i = 0; i < arr.length; i++) { const item = arr[i]; if (item !== undefined) { if (!item.startsWith('_')) { ret.push({ type: "text", text: item }); } else if (withInternals) { ret.push({ type: "text", text: item }); } } } return ret; } /** * Recursively add description and unit information to datapoint children * @param children - Array of child datapoint elements * @param parentPath - Parent datapoint path * @param winccoa - WinCC OA manager instance */ export function addDescriptionAndUnitsToChildren(children, parentPath, winccoa) { children.forEach(child => { const currentPath = `${parentPath}.${child.name}`; if (Array.isArray(child.children) && child.children.length > 0) { addDescriptionAndUnitsToChildren(child.children, currentPath, winccoa); } else { // Only get unit and description for leaf elements (no children) try { child.unit = winccoa.dpGetUnit(currentPath); child.description = winccoa.dpGetDescription(currentPath); } catch (error) { // Silently ignore errors for individual elements } } }); } /** * Create standardized error response for MCP tools * @param message - Error message * @param codeOrDetails - Error code (string) or details object (optional) * @returns MCP error response */ export function createErrorResponse(message, codeOrDetails) { const response = { error: true, message }; if (typeof codeOrDetails === 'string') { response.code = codeOrDetails; } else if (typeof codeOrDetails === 'object' && codeOrDetails !== null) { Object.assign(response, codeOrDetails); } return { content: [{ type: "text", text: JSON.stringify(response) }] }; } /** * Create standardized success response for MCP tools * @param result - Result data * @param message - Optional success message * @returns MCP success response */ export function createSuccessResponse(result, message) { const response = { success: true, data: result }; if (message) { response.message = message; } return { content: [{ type: "text", text: JSON.stringify(response) }] }; } /** * Validate datapoint name format * @param dpName - Datapoint name to validate * @returns True if valid */ export function isValidDatapointName(dpName) { if (!dpName || typeof dpName !== 'string') { return false; } // Basic validation: should not be empty, no special chars that break WinCC OA return dpName.length > 0 && !dpName.includes('..') && !dpName.startsWith('.'); } /** * Validate datapoint element for dpGet operations * Rejects asterisk (*) wildcard to prevent large responses * @param dpe - Datapoint element name to validate * @returns True if valid for dpGet */ export function isValidDatapointElementForGet(dpe) { if (!dpe || typeof dpe !== 'string') { return false; } // Reject asterisk wildcard (causes response too large) if (dpe.includes('*')) { return false; } // Basic validation return dpe.length > 0 && !dpe.includes('..') && !dpe.startsWith('.'); } /** * Validate array of datapoint elements for dpGet operations * @param dpes - Array of datapoint element names * @returns Validation result with invalid entries if any */ export function validateDatapointElementsForGet(dpes) { const invalid = []; for (const dpe of dpes) { if (!isValidDatapointElementForGet(dpe)) { invalid.push(dpe); } } return { valid: invalid.length === 0, invalid }; } //# sourceMappingURL=helpers.js.map