Skip to main content
Glama
utils.ts5.61 kB
/** * Common utility functions for XHS MCP Server */ /** * Sleep utility function * @param ms - Milliseconds to sleep * @returns Promise that resolves after the specified time */ export function sleep(ms: number): Promise<void> { return new Promise((resolve) => setTimeout(resolve, ms)); } /** * Safe error handler that logs errors without throwing * @param error - Error to handle * @param context - Additional context for the error * @param logger - Logger instance to use */ export function safeErrorHandler( error: unknown, context: string, logger: { error: (message: string, ...args: unknown[]) => void } ): void { const errorMessage = error instanceof Error ? error.message : String(error); logger.error(`${context}: ${errorMessage}`); } /** * Validate required parameters * @param params - Object containing parameters to validate * @param requiredKeys - Array of required parameter keys * @throws Error if any required parameter is missing */ export function validateRequiredParams( params: Record<string, unknown>, requiredKeys: string[] ): void { const missingKeys = requiredKeys.filter( (key) => params[key] === undefined || params[key] === null || params[key] === '' ); if (missingKeys.length > 0) { throw new Error(`Missing required parameters: ${missingKeys.join(', ')}`); } } /** * Type guard to check if a value is a string */ export function isString(value: unknown): value is string { return typeof value === 'string'; } /** * Type guard to check if a value is a number */ export function isNumber(value: unknown): value is number { return typeof value === 'number' && !Number.isNaN(value); } /** * Type guard to check if a value is an array */ export function isArray<T>(value: unknown): value is T[] { return Array.isArray(value); } /** * Safely parse JSON string * @param jsonString - JSON string to parse * @param fallback - Fallback value if parsing fails * @returns Parsed object or fallback value */ export function safeJsonParse<T>(jsonString: string, fallback: T): T { try { return JSON.parse(jsonString) as T; } catch { return fallback; } } /** * Validate publish note parameters with length constraints * @param title - Note title * @param note - Note content * @param imagePaths - Array of image paths * @throws Error if any parameter violates constraints */ export function validatePublishNoteParams(title: string, note: string, imagePaths: string[]): void { // Validate title length (max 20 characters) if (title && title.length > 20) { throw new Error(`Title length cannot exceed 20 characters. Current length: ${title.length}`); } // Validate note content length (max 1000 characters) if (note && note.length > 1000) { throw new Error( `Note content length cannot exceed 1000 characters. Current length: ${note.length}` ); } // Validate image count (max 18 images) if (imagePaths && imagePaths.length > 18) { throw new Error(`Maximum 18 images allowed. Current count: ${imagePaths.length}`); } } /** * Create a standardized response object * @param success - Whether the operation was successful * @param data - Optional data to include * @param message - Optional message * @param error - Optional error information * @returns Standardized response object */ export function createApiResponse<T = unknown>( success: boolean, data?: T, message?: string, error?: string ): { success: boolean; data?: T; message?: string; error?: string } { const response: { success: boolean; data?: T; message?: string; error?: string } = { success }; if (data !== undefined) response.data = data; if (message !== undefined) response.message = message; if (error !== undefined) response.error = error; return response; } /** * Retry a function with exponential backoff * @param fn - Function to retry * @param maxRetries - Maximum number of retries * @param baseDelay - Base delay in milliseconds * @returns Promise that resolves with the function result */ export async function retryWithBackoff<T>( fn: () => Promise<T>, maxRetries: number = 3, baseDelay: number = 1000 ): Promise<T> { let lastError: Error; for (let attempt = 0; attempt <= maxRetries; attempt++) { try { return await fn(); } catch (error) { lastError = error as Error; if (attempt === maxRetries) { throw lastError; } const delay = baseDelay * Math.pow(2, attempt); await sleep(delay); } } throw lastError!; } /** * Create a standardized MCP tool response * @param data - Data to include in the response * @returns Standardized MCP response format */ export function createMcpToolResponse<T = unknown>( data: T ): { content: Array<{ type: string; text: string }> } { return { content: [ { type: 'text', text: JSON.stringify(data, null, 2), }, ], }; } /** * Create a standardized MCP error response * @param error - Error to format * @returns Standardized MCP error response format */ export function createMcpErrorResponse(error: unknown): { content: Array<{ type: string; text: string }>; } { const errorData = error instanceof Error ? { success: false, error: 'UnknownError', message: error.message, stack: error.stack, } : { success: false, error: 'UnknownError', message: String(error), }; return { content: [ { type: 'text', text: JSON.stringify(errorData, null, 2), }, ], }; }

Latest Blog Posts

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/Algovate/xhs-mcp'

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