UNPKG

mcpdog

Version:

MCPDog - Universal MCP Server Manager with Web Interface

156 lines 5.31 kB
/** * Server Name Validator * Provides unified validation and naming conventions for MCP server names */ export class ServerNameValidator { // Server name regex pattern - only letters, numbers, hyphens, and underscores static SERVER_NAME_PATTERN = /^[a-zA-Z0-9\-_]+$/; // Maximum length for server names static MAX_NAME_LENGTH = 50; // Minimum length for server names static MIN_NAME_LENGTH = 1; /** * Validate server name according to best practices */ static validateServerName(name) { // Check if name is empty if (!name || name.trim() === '') { return { valid: false, error: 'Server name cannot be empty' }; } // Check minimum length if (name.length < this.MIN_NAME_LENGTH) { return { valid: false, error: `Server name must be at least ${this.MIN_NAME_LENGTH} character long` }; } // Check maximum length if (name.length > this.MAX_NAME_LENGTH) { return { valid: false, error: `Server name too long (max ${this.MAX_NAME_LENGTH} characters)` }; } // Check pattern (only letters, numbers, hyphens, and underscores) if (!this.SERVER_NAME_PATTERN.test(name)) { return { valid: false, error: 'Server name can only contain letters, numbers, hyphens, and underscores', suggestions: this.generateSuggestions(name) }; } // Check for reserved names if (this.isReservedName(name)) { return { valid: false, error: `"${name}" is a reserved name and cannot be used` }; } return { valid: true }; } /** * Generate suggestions for invalid server names */ static generateSuggestions(invalidName) { const suggestions = []; // Remove special characters and replace with hyphens let cleaned = invalidName .replace(/[^a-zA-Z0-9\-_]/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, ''); if (cleaned && this.SERVER_NAME_PATTERN.test(cleaned)) { suggestions.push(cleaned); } // Convert to lowercase and replace spaces with hyphens let lowerCase = invalidName .toLowerCase() .replace(/\s+/g, '-') .replace(/[^a-z0-9\-_]/g, ''); if (lowerCase && this.SERVER_NAME_PATTERN.test(lowerCase)) { suggestions.push(lowerCase); } // Add common patterns if (invalidName.includes(' ')) { const words = invalidName.split(/\s+/).filter(word => word.length > 0); if (words.length > 0) { const joined = words.join('-').toLowerCase().replace(/[^a-z0-9\-_]/g, ''); if (joined && this.SERVER_NAME_PATTERN.test(joined)) { suggestions.push(joined); } } } return suggestions.slice(0, 3); // Limit to 3 suggestions } /** * Check if a name is reserved */ static isReservedName(name) { const reservedNames = [ 'config', 'settings', 'system', 'admin', 'root', 'default', 'test', 'temp', 'tmp', 'backup', 'old', 'new', 'server', 'client', 'api', 'web', 'app', 'service' ]; return reservedNames.includes(name.toLowerCase()); } /** * Generate a unique server name based on base name and existing names */ static generateUniqueName(baseName, existingNames) { if (!existingNames.includes(baseName)) { return baseName; } let counter = 1; let newName = `${baseName}-${counter}`; while (existingNames.includes(newName)) { counter++; newName = `${baseName}-${counter}`; } return newName; } /** * Normalize server name (convert to valid format) */ static normalizeServerName(name) { return name .toLowerCase() .replace(/[^a-z0-9\-_]/g, '-') .replace(/-+/g, '-') .replace(/^-|-$/g, '') .substring(0, this.MAX_NAME_LENGTH); } /** * Check if server name conflicts with existing names */ static checkNameConflict(name, existingNames) { return existingNames.includes(name); } /** * Get all validation errors for multiple server names */ static validateMultipleNames(names) { const errors = []; const conflicts = []; const seenNames = new Set(); for (const name of names) { const validation = this.validateServerName(name); if (!validation.valid) { errors.push(`"${name}": ${validation.error}`); } if (seenNames.has(name)) { conflicts.push(name); } else { seenNames.add(name); } } return { valid: errors.length === 0 && conflicts.length === 0, errors, conflicts }; } } //# sourceMappingURL=server-name-validator.js.map