Skip to main content
Glama

My Credentials MCP Server

by preangelleo
credential-generator.ts•26.9 kB
/** * Comprehensive Credential Generation System for MCP Server * * This module provides a complete suite of credential generation functions * for software development, including UUIDs, random strings, passwords, * tokens, and cryptographic elements. * * All functions use cryptographically secure random number generation * and follow OWASP security best practices. */ import { z } from "zod"; // ============================================================================ // Types and Interfaces // ============================================================================ export interface BaseOptions { length?: number; format?: string; prefix?: string; suffix?: string; case?: 'upper' | 'lower' | 'mixed'; } export interface StringOptions extends BaseOptions { include_uppercase?: boolean; include_lowercase?: boolean; include_numbers?: boolean; include_special_chars?: boolean; exclude_chars?: string; custom_charset?: string; special_char_set?: string; min_length?: number; max_length?: number; } export interface PasswordOptions extends BaseOptions { include_uppercase?: boolean; include_lowercase?: boolean; include_numbers?: boolean; include_special_chars?: boolean; exclude_ambiguous?: boolean; min_uppercase?: number; min_lowercase?: number; min_numbers?: number; min_special?: number; special_char_set?: string; strength?: 'low' | 'medium' | 'high' | 'maximum'; } export interface CryptoOptions extends BaseOptions { algorithm?: string; key_size?: number; encoding?: 'hex' | 'base64' | 'binary'; secure_random?: boolean; } export interface GenerationResult { value: string; name: string; description: string; metadata: { type: string; length: number; algorithm?: string; entropy_bits?: number; charset?: string; generated_at: string; [key: string]: any; }; } // ============================================================================ // Core Utility Functions // ============================================================================ /** * Generate cryptographically secure random bytes */ function getSecureRandomBytes(length: number): Uint8Array { return crypto.getRandomValues(new Uint8Array(length)); } /** * Convert bytes to hex string */ function bytesToHex(bytes: Uint8Array): string { return Array.from(bytes, byte => byte.toString(16).padStart(2, '0')).join(''); } /** * Convert bytes to base64 string */ function bytesToBase64(bytes: Uint8Array): string { return btoa(String.fromCharCode(...bytes)); } /** * Convert bytes to base64url (URL-safe) string */ function bytesToBase64Url(bytes: Uint8Array): string { return bytesToBase64(bytes) .replace(/\+/g, '-') .replace(/\//g, '_') .replace(/=/g, ''); } /** * Apply case transformation */ function applyCase(str: string, caseOption: 'upper' | 'lower' | 'mixed' = 'mixed'): string { switch (caseOption) { case 'upper': return str.toUpperCase(); case 'lower': return str.toLowerCase(); default: return str; } } /** * Add prefix and suffix to a value */ function addAffixes(value: string, prefix?: string, suffix?: string): string { return (prefix || '') + value + (suffix || ''); } /** * Calculate entropy bits for a charset and length */ function calculateEntropy(charsetSize: number, length: number): number { return Math.floor(Math.log2(Math.pow(charsetSize, length))); } // ============================================================================ // Character Sets // ============================================================================ const CHARSETS = { uppercase: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', lowercase: 'abcdefghijklmnopqrstuvwxyz', numbers: '0123456789', special: '!@#$%^&*()_+-=[]{}|;:,.<>?', special_safe: '!@#$%^&*_+-=', hex: '0123456789ABCDEF', hex_lower: '0123456789abcdef', alphanumeric: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789', url_safe: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_', ambiguous: 'il1Lo0O', base58: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz' }; // ============================================================================ // UUID Generation Functions // ============================================================================ /** * Generate UUID v4 (Random) */ export function generateUuid4(): GenerationResult { const bytes = getSecureRandomBytes(16); // Set version (4) and variant bits bytes[6] = (bytes[6] & 0x0f) | 0x40; // Version 4 bytes[8] = (bytes[8] & 0x3f) | 0x80; // Variant 10 const hex = bytesToHex(bytes); const uuid = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`; return { value: uuid, name: 'uuid4', description: 'Generated UUID4 for unique identification', metadata: { type: 'uuid4', length: 36, algorithm: 'secure_random', entropy_bits: 122, charset: 'hex-with-dashes', generated_at: new Date().toISOString() } }; } /** * Generate ULID (Universally Unique Lexicographically Sortable Identifier) */ export function generateUlid(): GenerationResult { const timestamp = Date.now(); const timestampChars = 10; const randomChars = 16; // Crockford's Base32 encoding const base32 = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Encode timestamp (48 bits) let ulid = ''; let temp = timestamp; for (let i = timestampChars - 1; i >= 0; i--) { ulid = base32[temp % 32] + ulid; temp = Math.floor(temp / 32); } // Add random part (80 bits) const randomBytes = getSecureRandomBytes(10); for (let i = 0; i < randomChars; i++) { ulid += base32[randomBytes[Math.floor(i * 10 / 16)] % 32]; } return { value: ulid, name: 'ulid', description: 'Generated ULID for time-sortable unique identification', metadata: { type: 'ulid', length: 26, algorithm: 'timestamp+secure_random', entropy_bits: 80, charset: 'crockford_base32', generated_at: new Date().toISOString() } }; } /** * Generate Nano ID */ export function generateNanoId(length: number = 21): GenerationResult { const alphabet = CHARSETS.url_safe; const bytes = getSecureRandomBytes(length); let result = ''; for (let i = 0; i < length; i++) { result += alphabet[bytes[i] % alphabet.length]; } return { value: result, name: 'nano_id', description: 'Generated Nano ID for URL-safe unique identification', metadata: { type: 'nano_id', length, algorithm: 'secure_random', entropy_bits: calculateEntropy(alphabet.length, length), charset: 'url_safe', generated_at: new Date().toISOString() } }; } // ============================================================================ // Random String Generation Functions // ============================================================================ /** * Generate random string with custom options */ export function generateRandomString(length: number = 32, options: StringOptions = {}): GenerationResult { let charset = ''; if (options.custom_charset) { charset = options.custom_charset; } else { if (options.include_uppercase !== false) charset += CHARSETS.uppercase; if (options.include_lowercase !== false) charset += CHARSETS.lowercase; if (options.include_numbers !== false) charset += CHARSETS.numbers; if (options.include_special_chars) charset += options.special_char_set || CHARSETS.special_safe; } if (!charset) { charset = CHARSETS.alphanumeric; // Default } // Remove excluded characters if (options.exclude_chars) { for (const char of options.exclude_chars) { charset = charset.replace(new RegExp(char.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'), 'g'), ''); } } const bytes = getSecureRandomBytes(length); let result = ''; for (let i = 0; i < length; i++) { result += charset[bytes[i] % charset.length]; } result = applyCase(result, options.case); result = addAffixes(result, options.prefix, options.suffix); return { value: result, name: 'random_string', description: 'Generated random string with custom character set', metadata: { type: 'random_string', length: result.length, algorithm: 'secure_random', entropy_bits: calculateEntropy(charset.length, length), charset: charset.slice(0, 20) + (charset.length > 20 ? '...' : ''), charset_size: charset.length, generated_at: new Date().toISOString() } }; } /** * Generate hexadecimal string */ export function generateHexString(length: number = 32): GenerationResult { const bytes = getSecureRandomBytes(Math.ceil(length / 2)); const hex = bytesToHex(bytes).slice(0, length); return { value: hex, name: 'hex_string', description: 'Generated hexadecimal string', metadata: { type: 'hex_string', length, algorithm: 'secure_random', entropy_bits: length * 4, charset: 'hexadecimal', generated_at: new Date().toISOString() } }; } /** * Generate alphanumeric string */ export function generateAlphanumeric(length: number = 16): GenerationResult { return generateRandomString(length, { include_uppercase: true, include_lowercase: true, include_numbers: true, include_special_chars: false }); } /** * Generate numeric string */ export function generateNumericString(length: number = 10): GenerationResult { return generateRandomString(length, { custom_charset: CHARSETS.numbers }); } /** * Generate base64 string */ export function generateBase64String(length: number = 32): GenerationResult { const byteLength = Math.ceil(length * 3 / 4); const bytes = getSecureRandomBytes(byteLength); const base64 = bytesToBase64(bytes).slice(0, length); return { value: base64, name: 'base64_string', description: 'Generated Base64 encoded string', metadata: { type: 'base64_string', length, algorithm: 'secure_random', entropy_bits: calculateEntropy(64, length), charset: 'base64', generated_at: new Date().toISOString() } }; } // ============================================================================ // Password Generation Functions // ============================================================================ /** * Generate strong password with customizable requirements */ export function generatePassword(length: number = 16, options: PasswordOptions = {}): GenerationResult { const { include_uppercase = true, include_lowercase = true, include_numbers = true, include_special_chars = true, exclude_ambiguous = false, min_uppercase = 1, min_lowercase = 1, min_numbers = 1, min_special = 1, special_char_set = CHARSETS.special_safe, strength = 'high' } = options; // Build character sets let charset = ''; const sets: { chars: string; min: number }[] = []; if (include_uppercase) { let upper = CHARSETS.uppercase; if (exclude_ambiguous) upper = upper.replace(/[IL]/g, ''); sets.push({ chars: upper, min: min_uppercase }); charset += upper; } if (include_lowercase) { let lower = CHARSETS.lowercase; if (exclude_ambiguous) lower = lower.replace(/[il]/g, ''); sets.push({ chars: lower, min: min_lowercase }); charset += lower; } if (include_numbers) { let nums = CHARSETS.numbers; if (exclude_ambiguous) nums = nums.replace(/[01]/g, ''); sets.push({ chars: nums, min: min_numbers }); charset += nums; } if (include_special_chars) { sets.push({ chars: special_char_set, min: min_special }); charset += special_char_set; } // Generate password ensuring minimum requirements const password: string[] = []; // First, meet minimum requirements for (const set of sets) { for (let i = 0; i < set.min; i++) { const bytes = getSecureRandomBytes(1); password.push(set.chars[bytes[0] % set.chars.length]); } } // Fill remaining length with random characters const remaining = length - password.length; for (let i = 0; i < remaining; i++) { const bytes = getSecureRandomBytes(1); password.push(charset[bytes[0] % charset.length]); } // Shuffle the password array for (let i = password.length - 1; i > 0; i--) { const bytes = getSecureRandomBytes(1); const j = bytes[0] % (i + 1); [password[i], password[j]] = [password[j], password[i]]; } const result = password.join(''); return { value: result, name: 'secure_password', description: 'Generated secure password with customizable requirements', metadata: { type: 'secure_password', length, algorithm: 'secure_random_with_requirements', entropy_bits: calculateEntropy(charset.length, length), charset_size: charset.length, strength, requirements: { uppercase: include_uppercase ? min_uppercase : 0, lowercase: include_lowercase ? min_lowercase : 0, numbers: include_numbers ? min_numbers : 0, special: include_special_chars ? min_special : 0, exclude_ambiguous }, generated_at: new Date().toISOString() } }; } /** * Generate passphrase from dictionary words */ export function generatePassphrase(words: number = 4, separator: string = '-'): GenerationResult { // Common word list for passphrases const wordList = [ 'correct', 'horse', 'battery', 'staple', 'apple', 'banana', 'cherry', 'dragon', 'elephant', 'forest', 'guitar', 'hammer', 'island', 'jungle', 'knight', 'lemon', 'mountain', 'network', 'ocean', 'piano', 'queen', 'rainbow', 'sunset', 'thunder', 'umbrella', 'valley', 'winter', 'x-ray', 'yellow', 'zebra', 'bridge', 'castle', 'diamond', 'eagle', 'flower', 'golden', 'harbor', 'iceberg', 'jacket', 'kitten' ]; const selectedWords: string[] = []; for (let i = 0; i < words; i++) { const bytes = getSecureRandomBytes(1); selectedWords.push(wordList[bytes[0] % wordList.length]); } const result = selectedWords.join(separator); return { value: result, name: 'passphrase', description: 'Generated passphrase using dictionary words', metadata: { type: 'passphrase', length: result.length, word_count: words, separator, algorithm: 'dictionary_words', entropy_bits: Math.floor(Math.log2(Math.pow(wordList.length, words))), generated_at: new Date().toISOString() } }; } /** * Generate PIN code */ export function generatePin(length: number = 6): GenerationResult { return generateRandomString(length, { custom_charset: CHARSETS.numbers }); } // ============================================================================ // Token and API Key Generation Functions // ============================================================================ /** * Generate API key in various formats */ export function generateApiKey(format: 'hex' | 'base64' | 'base64url' = 'hex', length: number = 64): GenerationResult { const bytes = getSecureRandomBytes(Math.ceil(length * 3 / 4)); let result: string; switch (format) { case 'base64': result = bytesToBase64(bytes).slice(0, length); break; case 'base64url': result = bytesToBase64Url(bytes).slice(0, length); break; default: result = bytesToHex(bytes).slice(0, length); } return { value: result, name: `api_key_${format}${length}`, description: `Generated API key in ${format} format`, metadata: { type: 'api_key', format, length, algorithm: 'secure_random', entropy_bits: calculateEntropy(format === 'hex' ? 16 : 64, length), generated_at: new Date().toISOString() } }; } /** * Generate bearer token */ export function generateBearerToken(length: number = 128): GenerationResult { const result = generateApiKey('base64url', length); return { ...result, name: 'bearer_token', description: 'Generated bearer token for API authentication' }; } /** * Generate JWT secret */ export function generateJwtSecret(length: number = 64): GenerationResult { const bytes = getSecureRandomBytes(length); const result = bytesToBase64Url(bytes); return { value: result, name: 'jwt_secret', description: 'Generated JWT signing secret', metadata: { type: 'jwt_secret', length: result.length, algorithm: 'secure_random', entropy_bits: length * 8, use_case: 'jwt_signing', generated_at: new Date().toISOString() } }; } /** * Generate session token */ export function generateSessionToken(length: number = 32): GenerationResult { const result = generateApiKey('base64url', length); return { ...result, name: 'session_token', description: 'Generated session token for web session management' }; } /** * Generate CSRF token */ export function generateCsrfToken(length: number = 32): GenerationResult { const result = generateApiKey('base64url', length); return { ...result, name: 'csrf_token', description: 'Generated CSRF token for cross-site request forgery protection' }; } // ============================================================================ // Cryptographic Element Generation Functions // ============================================================================ /** * Generate salt for password hashing */ export function generateSalt(length: number = 32): GenerationResult { const bytes = getSecureRandomBytes(length); const result = bytesToBase64(bytes); return { value: result, name: 'password_salt', description: 'Generated salt for secure password hashing', metadata: { type: 'password_salt', length: result.length, algorithm: 'secure_random', entropy_bits: length * 8, use_case: 'password_hashing', generated_at: new Date().toISOString() } }; } /** * Generate initialization vector (IV) */ export function generateIv(algorithm: string = 'aes256'): GenerationResult { // Common IV sizes for different algorithms const ivSizes: Record<string, number> = { 'aes128': 16, 'aes192': 16, 'aes256': 16, 'des': 8, 'blowfish': 8, 'chacha20': 12 }; const size = ivSizes[algorithm.toLowerCase()] || 16; const bytes = getSecureRandomBytes(size); const result = bytesToHex(bytes); return { value: result, name: 'initialization_vector', description: `Generated initialization vector for ${algorithm} encryption`, metadata: { type: 'initialization_vector', length: result.length, algorithm, byte_size: size, entropy_bits: size * 8, use_case: 'encryption', generated_at: new Date().toISOString() } }; } /** * Generate HMAC key */ export function generateHmacKey(length: number = 64): GenerationResult { const bytes = getSecureRandomBytes(length); const result = bytesToBase64(bytes); return { value: result, name: 'hmac_key', description: 'Generated HMAC key for message authentication', metadata: { type: 'hmac_key', length: result.length, algorithm: 'secure_random', entropy_bits: length * 8, use_case: 'message_authentication', generated_at: new Date().toISOString() } }; } /** * Generate encryption key */ export function generateEncryptionKey(algorithm: string = 'aes256'): GenerationResult { // Common key sizes for different algorithms const keySizes: Record<string, number> = { 'aes128': 16, 'aes192': 24, 'aes256': 32, 'des': 8, 'blowfish': 16, 'chacha20': 32 }; const size = keySizes[algorithm.toLowerCase()] || 32; const bytes = getSecureRandomBytes(size); const result = bytesToBase64(bytes); return { value: result, name: 'encryption_key', description: `Generated encryption key for ${algorithm}`, metadata: { type: 'encryption_key', length: result.length, algorithm, byte_size: size, entropy_bits: size * 8, use_case: 'encryption', generated_at: new Date().toISOString() } }; } /** * Generate nonce (number used once) */ export function generateNonce(length: number = 32): GenerationResult { const bytes = getSecureRandomBytes(length); const result = bytesToBase64Url(bytes); return { value: result, name: 'nonce', description: 'Generated nonce for cryptographic operations', metadata: { type: 'nonce', length: result.length, algorithm: 'secure_random', entropy_bits: length * 8, use_case: 'cryptographic_operations', generated_at: new Date().toISOString() } }; } // ============================================================================ // Service-Specific Generation Functions // ============================================================================ /** * Generate AWS-style credentials */ export function generateAwsCredentials(): GenerationResult { const accessKey = 'AKIA' + generateAlphanumeric(16).value; const secretKey = generateApiKey('base64', 40).value; const result = { access_key: accessKey, secret_key: secretKey }; return { value: JSON.stringify(result, null, 2), name: 'aws_credentials', description: 'Generated AWS-style access credentials', metadata: { type: 'aws_credentials', length: JSON.stringify(result).length, algorithm: 'aws_format', components: ['access_key', 'secret_key'], access_key_format: 'AKIA + 16 alphanumeric', secret_key_format: 'base64 40 chars', generated_at: new Date().toISOString() } }; } /** * Generate GitHub token format */ export function generateGithubToken(): GenerationResult { const prefix = 'ghp_'; const token = generateAlphanumeric(36).value; const result = prefix + token; return { value: result, name: 'github_token', description: 'Generated GitHub personal access token format', metadata: { type: 'github_token', length: result.length, algorithm: 'github_format', prefix: 'ghp_', token_length: 36, generated_at: new Date().toISOString() } }; } /** * Generate database password */ export function generateDatabasePassword(length: number = 20): GenerationResult { return generatePassword(length, { include_uppercase: true, include_lowercase: true, include_numbers: true, include_special_chars: true, exclude_ambiguous: true, special_char_set: '@#$%^&*_+-=', strength: 'maximum' }); } // ============================================================================ // Batch Generation Function // ============================================================================ export interface BatchRequest { type: string; count: number; options?: any; } /** * Generate multiple credentials in batch */ export function generateBatch(requests: BatchRequest[]): GenerationResult { const results: Record<string, GenerationResult[]> = {}; for (const request of requests) { const { type, count, options = {} } = request; results[type] = []; for (let i = 0; i < count; i++) { let result: GenerationResult; switch (type) { // UUID and ID types case 'uuid4': result = generateUuid4(); break; case 'ulid': result = generateUlid(); break; case 'nano_id': result = generateNanoId(options.length); break; // String types case 'random_string': result = generateRandomString(options.length || 32, options); break; case 'hex_string': result = generateHexString(options.length || 32); break; case 'base64_string': result = generateBase64String(options.length || 32); break; // Password types case 'password': case 'secure_password': result = generatePassword(options.length || 16, options); break; case 'passphrase': result = generatePassphrase(options.words || 4, options.separator || '-'); break; case 'pin': result = generatePin(options.length || 6); break; // API and Token types case 'api_key': result = generateApiKey(options.format, options.length); break; case 'bearer_token': result = generateBearerToken(options.length || 128); break; case 'jwt_secret': result = generateJwtSecret(options.length || 256); break; case 'session_token': result = generateSessionToken(options.length || 128); break; case 'csrf_token': result = generateCsrfToken(options.length || 32); break; // Cryptographic types case 'password_salt': case 'salt': result = generateSalt(options.length || 32); break; case 'initialization_vector': case 'iv': result = generateIv(options.algorithm || 'aes256'); break; case 'hmac_key': result = generateHmacKey(options.length || 64); break; case 'encryption_key': result = generateEncryptionKey(options.algorithm || 'aes256'); break; case 'nonce': result = generateNonce(options.length || 16); break; // Service-specific types case 'aws_credentials': result = generateAwsCredentials(); break; case 'github_token': result = generateGithubToken(); break; case 'database_password': result = generateDatabasePassword(options.length || 20); break; default: throw new Error(`Unknown credential type: ${type}. Supported types: uuid4, ulid, nano_id, random_string, hex_string, base64_string, password, secure_password, passphrase, pin, api_key, bearer_token, jwt_secret, session_token, csrf_token, salt, password_salt, iv, initialization_vector, hmac_key, encryption_key, nonce, aws_credentials, github_token, database_password`); } results[type].push(result); } } return { value: JSON.stringify(results, null, 2), name: 'batch_generation', description: 'Generated multiple credentials in batch', metadata: { type: 'batch_generation', length: JSON.stringify(results).length, algorithm: 'batch_secure_random', total_items: requests.reduce((sum, req) => sum + req.count, 0), types_generated: Object.keys(results), generated_at: new Date().toISOString() } }; }

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/preangelleo/my-credentials-mcp'

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