Skip to main content
Glama

Chicken Business Management MCP Server

by PSYGER02
unifiedAI.ts9.04 kB
/** * Unified AI Service * Primary AI interface that routes through MCP server with fallback to direct APIs * Replaces existing geminiAPIManager for better reliability and consistency */ import { mcpClient, MCPToolResponse } from './mcpClient'; import { GeminiAPIManager } from './geminiAPIManager'; export interface AIServiceResponse { success: boolean; data?: any; error?: string; source: 'mcp' | 'direct' | 'offline'; } class UnifiedAIService { private geminiManager: GeminiAPIManager; private mcpAvailable: boolean = true; private lastHealthCheck: number = 0; private healthCheckInterval: number = 60000; // 1 minute constructor() { this.geminiManager = new GeminiAPIManager(); this.checkMCPHealth(); } /** * Check MCP server health periodically */ private async checkMCPHealth(): Promise<void> { const now = Date.now(); if (now - this.lastHealthCheck < this.healthCheckInterval) { return; } try { this.mcpAvailable = await mcpClient.testConnection(); this.lastHealthCheck = now; if (this.mcpAvailable) { console.log('✅ MCP server is available'); } else { console.warn('⚠️ MCP server unavailable, falling back to direct API'); } } catch (error) { console.warn('⚠️ MCP health check failed:', error); this.mcpAvailable = false; } } /** * Parse chicken business note with intelligent routing */ async parseChickenNote( content: string, userRole: 'owner' | 'worker' = 'worker', branchId?: string ): Promise<AIServiceResponse> { await this.checkMCPHealth(); // Try MCP first if (this.mcpAvailable) { try { const mcpResponse = await mcpClient.parseChickenNote(content, userRole, branchId); if (mcpResponse.success) { return { success: true, data: mcpResponse.result, source: 'mcp' }; } } catch (error) { console.warn('MCP parse failed, falling back to direct API:', error); this.mcpAvailable = false; } } // Fallback to direct Gemini API try { const directResult = await this.geminiManager.parseChickenNote(content); return { success: true, data: directResult, source: 'direct' }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), source: 'direct' }; } } /** * Get business advice with intelligent routing */ async getBusinessAdvice( question: string, userRole: 'owner' | 'worker' = 'owner', businessContext?: string ): Promise<AIServiceResponse> { await this.checkMCPHealth(); // Try MCP first if (this.mcpAvailable) { try { const mcpResponse = await mcpClient.getBusinessAdvice(question, userRole, businessContext); if (mcpResponse.success) { return { success: true, data: mcpResponse.result, source: 'mcp' }; } } catch (error) { console.warn('MCP business advice failed, falling back:', error); this.mcpAvailable = false; } } // Fallback to direct API (implement basic business advice) try { const prompt = `As a chicken business expert, provide advice for this question: ${question} User Role: ${userRole} Business Context: ${businessContext || 'General chicken business operations'} Provide practical, actionable advice in a structured format.`; const directResult = await this.geminiManager.callGemini( { type: 'text', complexity: 'medium', priority: 'normal' }, prompt ); return { success: true, data: directResult, source: 'direct' }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), source: 'direct' }; } } /** * Generate embeddings with intelligent routing */ async generateEmbeddings(texts: string[]): Promise<AIServiceResponse> { await this.checkMCPHealth(); // Try MCP first if (this.mcpAvailable) { try { const mcpResponse = await mcpClient.generateEmbeddings(texts); if (mcpResponse.success) { return { success: true, data: mcpResponse.result, source: 'mcp' }; } } catch (error) { console.warn('MCP embeddings failed, falling back:', error); this.mcpAvailable = false; } } // Fallback to direct API try { const embeddings = await this.geminiManager.generateEmbeddings(texts); return { success: true, data: embeddings, source: 'direct' }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), source: 'direct' }; } } /** * Get AI insights with intelligent routing */ async getAIInsights( salesData: any[], expenseData: any[] ): Promise<AIServiceResponse> { await this.checkMCPHealth(); // Try MCP first if (this.mcpAvailable) { try { const mcpResponse = await mcpClient.getAIInsights(salesData, expenseData); if (mcpResponse.success) { return { success: true, data: mcpResponse.result, source: 'mcp' }; } } catch (error) { console.warn('MCP insights failed, falling back:', error); this.mcpAvailable = false; } } // Fallback to direct API try { const insights = await this.geminiManager.generateInsights(salesData, expenseData); return { success: true, data: insights, source: 'direct' }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), source: 'direct' }; } } /** * Get sales forecast with intelligent routing */ async getSalesForecast( historicalData: any[], period: string = '7_days' ): Promise<AIServiceResponse> { await this.checkMCPHealth(); // Try MCP first if (this.mcpAvailable) { try { const mcpResponse = await mcpClient.getSalesForecast(historicalData, period); if (mcpResponse.success) { return { success: true, data: mcpResponse.result, source: 'mcp' }; } } catch (error) { console.warn('MCP forecast failed, falling back:', error); this.mcpAvailable = false; } } // Fallback to basic forecasting logic try { // Simple forecasting logic as fallback const forecast = this.generateBasicForecast(historicalData, period); return { success: true, data: forecast, source: 'direct' }; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), source: 'direct' }; } } /** * Basic forecast generation as fallback */ private generateBasicForecast(data: any[], period: string): any { if (!data || data.length === 0) { return { forecast: [], trends: 'Insufficient data for forecasting', confidence: 0 }; } // Simple moving average forecast const recent = data.slice(-7); // Last 7 entries const average = recent.reduce((sum, item) => sum + (item.total || 0), 0) / recent.length; const periodDays = period === '7_days' ? 7 : period === '30_days' ? 30 : 7; const forecast = Array(periodDays).fill(null).map((_, i) => ({ date: new Date(Date.now() + i * 24 * 60 * 60 * 1000).toISOString().split('T')[0], predicted_sales: Math.round(average * (0.9 + Math.random() * 0.2)), confidence: 0.6 })); return { forecast, trends: recent.length > 1 ? (recent[recent.length - 1].total > recent[0].total ? 'Increasing' : 'Decreasing') : 'Stable', confidence: 0.6, source: 'basic_algorithm' }; } /** * Get service status */ async getServiceStatus(): Promise<{ mcp: { available: boolean; url: string }; direct: { available: boolean }; }> { await this.checkMCPHealth(); return { mcp: { available: this.mcpAvailable, url: mcpClient['baseUrl'] }, direct: { available: true // Direct API is always available if configured } }; } /** * Force refresh MCP connection */ async refreshMCPConnection(): Promise<boolean> { this.lastHealthCheck = 0; await this.checkMCPHealth(); return this.mcpAvailable; } } // Create singleton instance export const unifiedAI = new UnifiedAIService(); // Export for direct use export default unifiedAI;

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/PSYGER02/mcpserver'

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