Skip to main content
Glama

CodeAnalysis MCP Server

by 0xjcf
responses.ts11.4 kB
/** * Utility functions for creating standardized tool responses * * These functions help ensure all tools use a consistent response format * and provide runtime validation of responses. Standardized responses make * it easier for AI agents to understand and process the results of tool * executions. * * The standard format includes: * - A data field containing the actual response content * - Metadata about the tool execution (timing, version, etc.) * - Status information (success/error, codes, messages) * - Optional context for chaining operations */ import { z } from "zod"; import { ToolResponse, ToolResponseSchema, CodeAnalysisResult, DependencyAnalysisResult, CodeMetricsResult, } from "../types/responses.js"; /** * Creates a standardized successful tool response * * This function wraps any data object in a standardized response format * that includes metadata, status information, and optional context. The * response is validated against the ToolResponseSchema to ensure it * meets the expected structure. * * @param data - The response data object (any valid JSON-serializable value) * @param tool - The name of the tool generating the response * @param options - Additional options for customizing the response * @param options.version - Tool version (defaults to '1.0.0') * @param options.sessionId - Session identifier for chaining operations * @param options.relatedResults - Array of related result IDs * @param options.executionTime - Execution time in milliseconds (calculated if not provided) * @returns A standardized tool response object * * @example * ```typescript * // Simple success response * const response = createSuccessResponse( * { files: 42, lines: 1024 }, * 'count-code-metrics' * ); * * // Success response with additional options * const advancedResponse = createSuccessResponse( * { dependencies: ['react', 'lodash'] }, * 'analyze-dependencies', * { * version: '1.2.0', * sessionId: 'abc123', * executionTime: 350 * } * ); * ``` */ export function createSuccessResponse<T>( data: T, tool: string, options?: { version?: string; sessionId?: string; relatedResults?: string[]; executionTime?: number; } ): ToolResponse<T> { const startTime = options?.executionTime !== undefined ? Date.now() - options.executionTime : undefined; const response: ToolResponse<T> = { data, metadata: { tool, version: options?.version || "1.0.0", executionTime: options?.executionTime || 0, timestamp: new Date().toISOString(), }, status: { success: true, code: 200, }, }; // Add context if we have session information if (options?.sessionId || options?.relatedResults) { response.context = { sessionId: options?.sessionId, relatedResults: options?.relatedResults, }; } // If we need to calculate execution time if (startTime) { response.metadata.executionTime = Date.now() - startTime; } // Validate the response structure try { ToolResponseSchema.parse(response); } catch (error) { console.error("Invalid response structure:", error); // Still return the response even if validation fails } return response; } /** * Creates a standardized error response * * This function creates an error response in the standardized format, * allowing tools to report errors in a consistent way. The response * includes an error message, status code, and optional error data. * * @param message - Error message describing what went wrong * @param tool - The name of the tool generating the error * @param options - Additional options for customizing the error response * @param options.code - HTTP-like status code (defaults to 400) * @param options.data - Optional data to include with the error * @param options.version - Tool version (defaults to '1.0.0') * @param options.sessionId - Session identifier for chaining operations * @param options.executionTime - Execution time in milliseconds (calculated if not provided) * @returns A standardized error response object * * @example * ```typescript * // Simple error response * const error = createErrorResponse( * 'Repository not found', * 'analyze-repository' * ); * * // Error with additional details * const detailedError = createErrorResponse( * 'Invalid parameter format', * 'calculate-metrics', * { * code: 422, * data: { invalidParams: ['depth'] }, * sessionId: 'abc123' * } * ); * ``` */ export function createErrorResponse<T = null>( message: string, tool: string, options?: { code?: number; data?: T; version?: string; sessionId?: string; executionTime?: number; } ): ToolResponse<T | null> { const startTime = options?.executionTime !== undefined ? Date.now() - options.executionTime : undefined; const response: ToolResponse<T | null> = { data: options?.data || null, metadata: { tool, version: options?.version || "1.0.0", executionTime: options?.executionTime || 0, timestamp: new Date().toISOString(), }, status: { success: false, code: options?.code || 400, message, }, }; // Add context if we have session information if (options?.sessionId) { response.context = { sessionId: options?.sessionId, }; } // If we need to calculate execution time if (startTime) { response.metadata.executionTime = Date.now() - startTime; } // Validate the response structure try { ToolResponseSchema.parse(response); } catch (error) { console.error("Invalid error response structure:", error); // Still return the response even if validation fails } return response; } /** * Helper to time the execution of a function and include it in the response * * This utility wraps an asynchronous function execution, times how long it * takes to complete, and includes that timing information in the response. * It also handles errors by converting them to standardized error responses. * * @param tool - Name of the tool being executed * @param fn - The async function to execute and time * @param options - Additional options for the response * @param options.version - Tool version (defaults to '1.0.0') * @param options.sessionId - Session identifier for chaining operations * @param options.relatedResults - Array of related result IDs * @returns A promise that resolves to a standardized tool response * * @example * ```typescript * // Basic usage * const response = await executeWithTiming( * 'analyze-code', * async () => { * // Perform analysis... * return { complexity: 15, functions: 5 }; * } * ); * * // With additional options * const response = await executeWithTiming( * 'analyze-repository', * async () => { * const result = await expensiveAnalysis(); * return result; * }, * { * sessionId: 'user-session-123', * version: '2.1.0' * } * ); * ``` */ export async function executeWithTiming<T>( tool: string, fn: () => Promise<T>, options?: { version?: string; sessionId?: string; relatedResults?: string[]; } ): Promise<ToolResponse<T>> { const startTime = Date.now(); try { const data = await fn(); return createSuccessResponse(data, tool, { ...options, executionTime: Date.now() - startTime, }); } catch (error) { return createErrorResponse( error instanceof Error ? error.message : String(error), tool, { ...options, executionTime: Date.now() - startTime, code: 500, } ); } } /** * Validate that a response conforms to the standard format * * This function checks if a response object matches the expected * ToolResponseSchema structure. It throws an error if the response * is invalid, which can be useful for debugging. * * @param response - The response object to validate * @returns true if valid, throws an error if invalid * * @example * ```typescript * try { * validateResponse(myResponse); * console.log('Response is valid'); * } catch (error) { * console.error('Invalid response:', error); * } * ``` */ export function validateResponse<T>(response: ToolResponse<T>): boolean { ToolResponseSchema.parse(response); return true; } /** * Extract just the data portion from a tool response * * This utility extracts the data field from a standard tool response, * which can be useful when you want to work with just the payload. * * @param response - The full tool response * @returns Just the data portion * * @example * ```typescript * const response = createSuccessResponse({ count: 42 }, 'count-things'); * const data = extractResponseData(response); * console.log(data.count); // Outputs: 42 * ``` */ export function extractResponseData<T>(response: ToolResponse<T>): T { return response.data; } /** * Combine multiple related tool responses into a single response * * This utility takes an array of tool responses and combines them into * a single response. It merges metadata like execution time and related * results, and can optionally transform the combined data with a custom * function. * * @param responses - Array of tool responses to combine * @param tool - Name of the composite tool * @param options - Additional options for the combined response * @param options.version - Tool version (defaults to '1.0.0') * @param options.sessionId - Session identifier for chaining operations * @param options.transform - Optional function to transform the combined data * @returns A combined tool response * * @example * ```typescript * // Combine responses with default array output * const combinedResponse = combineResponses( * [codeResponse, dependencyResponse, metricsResponse], * 'full-analysis' * ); * * // Combine with custom transformation * const customResponse = combineResponses( * [codeResponse, dependencyResponse], * 'composite-analysis', * { * transform: (data) => ({ * summary: { * files: data[0].fileCount, * dependencies: data[1].dependencyCount, * score: calculateScore(data[0], data[1]) * } * }) * } * ); * ``` */ export function combineResponses<T>( responses: ToolResponse<any>[], tool: string, options?: { version?: string; sessionId?: string; transform?: (data: any[]) => T; } ): ToolResponse<T> { // Extract the individual data pieces const dataItems = responses.map((r) => r.data); // Apply transform function if provided, otherwise use array as is const combinedData = options?.transform ? options.transform(dataItems) : (dataItems as unknown as T); // Collect all the related results const relatedResults: string[] = []; responses.forEach((r) => { if (r.context?.relatedResults) { relatedResults.push(...r.context.relatedResults); } }); // Calculate total execution time const totalExecutionTime = responses.reduce( (sum, r) => sum + r.metadata.executionTime, 0 ); return createSuccessResponse(combinedData, tool, { version: options?.version || "1.0.0", sessionId: options?.sessionId || responses[0]?.context?.sessionId, relatedResults: relatedResults.length > 0 ? relatedResults : undefined, executionTime: totalExecutionTime, }); }

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/0xjcf/MCP_CodeAnalysis'

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