Skip to main content
Glama

hypertool-mcp

validator.tsโ€ข5.07 kB
/** * Simplified toolset configuration validator */ import { ToolsetConfig, ValidationResult, DynamicToolReference, } from "./types.js"; /** * Validate a toolset configuration */ export function validateToolsetConfig(config: ToolsetConfig): ValidationResult { const errors: string[] = []; const warnings: string[] = []; const suggestions: string[] = []; // Basic structure validation if (!config.name || typeof config.name !== "string") { errors.push("Configuration must have a valid name"); } else if (config.name.trim().length === 0) { errors.push("Configuration name cannot be empty"); } else if (config.name.length < 2 || config.name.length > 50) { errors.push("Configuration name must be between 2 and 50 characters"); } else if (!/^[a-z0-9-]+$/.test(config.name)) { errors.push( "Configuration name must contain only lowercase letters, numbers, and hyphens" ); } // Tools validation if (!config.tools || !Array.isArray(config.tools)) { errors.push("Configuration must have a tools array"); } else if (config.tools.length === 0) { errors.push("Configuration must specify at least one tool"); } else { // Validate each tool reference config.tools.forEach((toolRef, index) => { const toolErrors = validateToolReference(toolRef, index); errors.push(...toolErrors); }); // Check for duplicate tool references const allRefs: string[] = []; config.tools.forEach((ref) => { if (ref.namespacedName) allRefs.push(ref.namespacedName); if (ref.refId) allRefs.push(ref.refId); }); const seenRefs = new Set<string>(); const duplicates = new Set<string>(); allRefs.forEach((ref) => { if (seenRefs.has(ref)) { duplicates.add(ref); } else { seenRefs.add(ref); } }); if (duplicates.size > 0) { warnings.push( `Duplicate tool references found: ${Array.from(duplicates).join(", ")}` ); } } // Optional fields validation if (config.description && typeof config.description !== "string") { errors.push("Description must be a string if provided"); } else if (config.description && config.description.length > 500) { warnings.push("Description is quite long, consider shortening it"); } if (config.version && typeof config.version !== "string") { errors.push("Version must be a string if provided"); } if (config.createdAt) { if (!(config.createdAt instanceof Date)) { if (typeof config.createdAt === "string") { const parsedDate = new Date(config.createdAt); if (isNaN(parsedDate.getTime())) { errors.push( "createdAt must be a valid Date object or ISO string if provided" ); } } else { errors.push( "createdAt must be a Date object or ISO string if provided" ); } } } // Provide suggestions for improvement if (config.tools && config.tools.length > 50) { suggestions.push( "Consider breaking large toolsets into smaller, focused ones for better maintainability" ); } if (config.tools && config.tools.every((ref) => !ref.refId)) { suggestions.push( "Consider adding refId values to tool references for better validation and security" ); } return { valid: errors.length === 0, errors, warnings, suggestions, }; } /** * Validate a single tool reference */ function validateToolReference( ref: DynamicToolReference, index: number ): string[] { const errors: string[] = []; // Check if at least one valid identifier is provided const hasValidNamespacedName = ref.namespacedName && typeof ref.namespacedName === "string" && ref.namespacedName.trim().length > 0; const hasValidRefId = ref.refId && typeof ref.refId === "string" && ref.refId.trim().length > 0; if (!hasValidNamespacedName && !hasValidRefId) { errors.push( `Tool reference at index ${index} must have either namespacedName or refId` ); } if (ref.namespacedName !== undefined) { if (typeof ref.namespacedName !== "string") { errors.push( `Tool reference at index ${index}: namespacedName must be a string` ); } else if (ref.namespacedName.trim().length === 0) { errors.push( `Tool reference at index ${index}: namespacedName cannot be empty` ); } else if (!ref.namespacedName.includes(".")) { errors.push( `Tool reference at index ${index}: namespacedName should include server namespace (e.g., "server.tool")` ); } } if (ref.refId !== undefined) { if (typeof ref.refId !== "string") { errors.push(`Tool reference at index ${index}: refId must be a string`); } else if (ref.refId.trim().length === 0) { errors.push(`Tool reference at index ${index}: refId cannot be empty`); } else if (ref.refId.length < 10) { errors.push( `Tool reference at index ${index}: refId appears too short to be a valid hash` ); } } return errors; }

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/toolprint/hypertool-mcp'

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