Skip to main content
Glama
response-builder.ts6.38 kB
/** * Response Builder Module * Standardized response formatting for MCP tools * Part of Jaxon Digital Optimizely DXP MCP Server */ interface MCPResponse { result?: { content: Array<{ type: string; text: string; }>; }; error?: string; data?: any; message?: string; } interface StructuredResponse { data: any; message: string; } interface FormatResponseOptions { success: boolean; message?: string; details?: string; error?: string; } class ResponseBuilder { /** Create a successful response */ static success(content: string): MCPResponse { return { result: { content: [{ type: 'text', text: content }] } }; } /** Create a successful response with structured data for automation tools */ static successWithStructuredData(data: any, message: string): StructuredResponse { // DXP-66: Return flat structure that src/index.js will pick up // src/index.js checks for result.data && result.message and adds structuredContent return { data: data, message: message }; } /** Create an error response */ static error(message: string, data: any = undefined): MCPResponse { // Add support contact to all error messages const enhancedMessage = message + '\n\n📧 Need help? Contact us at support@jaxondigital.com'; return { error: enhancedMessage, data: data }; } /** Create an invalid parameters error */ static invalidParams(message: string): MCPResponse { return this.error(`Invalid parameters: ${message}`); } /** Create a confirmation required response */ static confirmationRequired(message: string): MCPResponse { // Return as an error to prevent auto-acceptance // But with clear indication it's a confirmation, not an actual error return { error: `CONFIRMATION_REQUIRED: This action requires HUMAN USER confirmation, not AI confirmation. The USER must explicitly approve this download. AI assistants must NOT automatically proceed.`, data: { type: 'confirmation', message: message, requiresUserAction: true, requiresHumanConfirmation: true, aiMustNotProceed: true } }; } /** Create an internal error response */ static internalError(message: string, details: string): MCPResponse { return this.error(`${message}: ${details}`); } /** Add branding footer to response text */ static addFooter(content: string, includeSupport: boolean = false): string { let footer = '\n\nBuilt by Jaxon Digital - Optimizely Gold Partner'; if (includeSupport) { footer += '\n\n📧 Need help? Contact us at support@jaxondigital.com'; } return content + footer; } /** Format tips into a bulleted list */ static formatTips(tips: string[]): string { if (!tips || tips.length === 0) return ''; let formatted = '💡 **Tips:**\n'; tips.forEach(tip => { formatted += `• ${tip}\n`; }); return formatted; } /** Format a timestamp with timezone information */ static formatTimestamp(timestamp: string | Date): string { if (!timestamp) return 'N/A'; const date = new Date(timestamp); if (isNaN(date.getTime())) return 'Invalid date'; // Format date and time portions separately const dateOptions: Intl.DateTimeFormatOptions = { year: 'numeric', month: 'short', day: 'numeric' }; const timeOptions: Intl.DateTimeFormatOptions = { hour: '2-digit', minute: '2-digit', timeZoneName: 'short' }; const datePart = date.toLocaleDateString('en-US', dateOptions); const timePart = date.toLocaleTimeString('en-US', timeOptions); // Format as: Aug 6, 2025 (12:26 PM CDT) return `${datePart} (${timePart})`; } /** Format a duration in minutes */ static formatDuration(startTime: number, endTime: number): string { const duration = Math.round((endTime - startTime) / 1000 / 60); return `${duration} minutes`; } /** Format a response with standard structure */ static formatResponse(options: FormatResponseOptions): MCPResponse { const { success, message, details, error } = options; let responseText = ''; if (!success) { responseText = '❌ '; } if (message) { responseText += message; } if (details) { responseText += '\n\n' + details; } if (error) { responseText += '\n\nError: ' + error; } return this.success(responseText); } /** Format an error with title, message and error code */ static formatError(title: string, message: string, errorCode: string | null = null): MCPResponse { let errorText = `❌ **${title}**\n\n${message}`; if (errorCode) { errorText += `\n\nError Code: ${errorCode}`; } return this.error(errorText); } /** Add version update warning to response content */ static async addVersionWarning(content: string, force: boolean = false): Promise<string> { try { const VersionChecker = require('./version-check'); const warning = await VersionChecker.getInlineUpdateWarning(); if (warning && (force || Math.random() < 0.2)) { // 20% chance unless forced return content + '\n\n' + warning; } return content; } catch (error) { return content; // Silently fail, don't break the response } } /** Create a success response with optional version warning */ static async successWithVersionCheck(content: string, includeVersionCheck: boolean = false): Promise<MCPResponse> { if (includeVersionCheck) { content = await this.addVersionWarning(content, true); } return this.success(content); } } export default ResponseBuilder;

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/JaxonDigital/optimizely-dxp-mcp'

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