Skip to main content
Glama

Orchestrator MCP

helpers.ts•3.63 kB
/** * Helper utilities * Common utility functions used across the orchestrator */ /** * Delay execution for specified milliseconds */ export function delay(ms: number): Promise<void> { return new Promise(resolve => setTimeout(resolve, ms)); } /** * Retry a function with exponential backoff */ export async function retry<T>( fn: () => Promise<T>, options: { maxAttempts?: number; baseDelay?: number; maxDelay?: number; backoffFactor?: number; } = {} ): Promise<T> { const { maxAttempts = 3, baseDelay = 1000, maxDelay = 10000, backoffFactor = 2, } = options; let lastError: Error; for (let attempt = 1; attempt <= maxAttempts; attempt++) { try { return await fn(); } catch (error) { lastError = error instanceof Error ? error : new Error(String(error)); if (attempt === maxAttempts) { throw lastError; } const delayMs = Math.min( baseDelay * Math.pow(backoffFactor, attempt - 1), maxDelay ); await delay(delayMs); } } throw lastError!; } /** * Safely parse JSON with fallback */ export function safeJsonParse<T>( json: string, fallback: T ): T { try { return JSON.parse(json); } catch { return fallback; } } /** * Deep merge objects */ export function deepMerge<T extends Record<string, any>>( target: T, ...sources: Partial<T>[] ): T { if (!sources.length) return target; const source = sources.shift(); if (isObject(target) && isObject(source)) { for (const key in source) { if (isObject(source[key])) { if (!target[key]) Object.assign(target, { [key]: {} }); deepMerge(target[key] as Record<string, any>, source[key] as Record<string, any>); } else { Object.assign(target, { [key]: source[key] }); } } } return deepMerge(target, ...sources); } /** * Check if value is an object */ function isObject(item: any): item is Record<string, any> { return item && typeof item === 'object' && !Array.isArray(item); } /** * Truncate string to specified length */ export function truncate(str: string, length: number, suffix = '...'): string { if (str.length <= length) return str; return str.substring(0, length - suffix.length) + suffix; } /** * Generate a random ID */ export function generateId(prefix = '', length = 8): string { const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; let result = prefix; for (let i = 0; i < length; i++) { result += chars.charAt(Math.floor(Math.random() * chars.length)); } return result; } /** * Format duration in milliseconds to human readable string */ export function formatDuration(ms: number): string { if (ms < 1000) return `${ms}ms`; if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`; if (ms < 3600000) return `${(ms / 60000).toFixed(1)}m`; return `${(ms / 3600000).toFixed(1)}h`; } /** * Debounce function calls */ export function debounce<T extends (...args: any[]) => any>( func: T, wait: number ): (...args: Parameters<T>) => void { let timeout: NodeJS.Timeout; return (...args: Parameters<T>) => { clearTimeout(timeout); timeout = setTimeout(() => func(...args), wait); }; } /** * Throttle function calls */ export function throttle<T extends (...args: any[]) => any>( func: T, limit: number ): (...args: Parameters<T>) => void { let inThrottle: boolean; return (...args: Parameters<T>) => { if (!inThrottle) { func(...args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; }

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/Phoenixrr2113/Orchestrator-MCP'

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