UNPKG

alphe-redis-mcp-server

Version:

The most comprehensive Redis MCP Server for Alphe.AI - Optimized for sub-5 second response times with multi-layer caching

485 lines (427 loc) 16 kB
#!/usr/bin/env node import { Server } from '@modelcontextprotocol/sdk/server/index.js'; import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; import { CallToolRequestSchema, ListToolsRequestSchema, Tool, ListResourcesRequestSchema, ReadResourceRequestSchema, Resource } from '@modelcontextprotocol/sdk/types.js'; import { AlpheRedisClient } from './core/redis-client.js'; import { CognitiveOrchestrator } from './integrations/cognitive-orchestrator.js'; import { createStringTools, handleStringOperation } from './tools/string-tools.js'; import { createHashTools } from './tools/hash-tools.js'; import { createListTools } from './tools/list-tools.js'; import { createSetTools } from './tools/set-tools.js'; import { createSortedSetTools } from './tools/sorted-set-tools.js'; import { createStreamTools } from './tools/stream-tools.js'; import { createPubSubTools } from './tools/pubsub-tools.js'; import { createAdminTools } from './tools/admin-tools.js'; import dotenv from 'dotenv'; import chalk from 'chalk'; // Load environment variables dotenv.config(); // Configuration const config = { redis: { host: process.env.REDIS_HOST || 'localhost', port: parseInt(process.env.REDIS_PORT || '6379'), password: process.env.REDIS_PASSWORD, username: process.env.REDIS_USERNAME || 'default', db: parseInt(process.env.REDIS_DB || '0'), url: process.env.REDIS_URL, connectTimeout: parseInt(process.env.CONNECTION_TIMEOUT_MS || '5000'), commandTimeout: parseInt(process.env.COMMAND_TIMEOUT_MS || '10000') }, upstash: process.env.UPSTASH_REDIS_REST_URL ? { url: process.env.UPSTASH_REDIS_REST_URL, token: process.env.UPSTASH_REDIS_REST_TOKEN! } : undefined, zilliz: { clusterId: process.env.ZILLIZ_CLUSTER_ID || 'in05-2ea3b0b61c1812b', endpoint: process.env.ZILLIZ_ENDPOINT || 'https://in05-2ea3b0b61c1812b.serverless.aws-eu-central-1.cloud.zilliz.com', token: process.env.ZILLIZ_TOKEN || '7302f2675f2d62052808ab29112eaf89c82098d6e96eae7054fd231fa0938ecf826e867e999975643c118de9d5380ac76dec881e', apiKey: process.env.ZILLIZ_API_KEY || 'e9ac7daae9ec4cb7bdbcb560ddcac9ba63d6892db2d76f65785ae763448ba695ad128166c9a227a3ccdf407ff328cc0e70880465', username: process.env.ZILLIZ_USERNAME || 'db_2ea3b0b61c1812b', password: process.env.ZILLIZ_PASSWORD || 'Xx0&5f+0aWRW>;t^' }, supabase: process.env.SUPABASE_URL ? { url: process.env.SUPABASE_URL, anonKey: process.env.SUPABASE_ANON_KEY!, serviceRoleKey: process.env.SUPABASE_SERVICE_ROLE_KEY! } : undefined, performance: { cacheTtlSeconds: parseInt(process.env.CACHE_TTL_SECONDS || '3600'), maxCacheSizeMB: parseInt(process.env.MAX_CACHE_SIZE_MB || '256'), enableCompression: process.env.ENABLE_COMPRESSION !== 'false', enableBinaryQuantization: process.env.ENABLE_BINARY_QUANTIZATION !== 'false', compressionRatio: parseInt(process.env.COMPRESSION_RATIO || '32'), maxConnections: parseInt(process.env.MAX_CONNECTIONS || '100'), connectionTimeoutMs: parseInt(process.env.CONNECTION_TIMEOUT_MS || '5000'), commandTimeoutMs: parseInt(process.env.COMMAND_TIMEOUT_MS || '10000') } }; class AlpheRedisMCPServer { private server: Server; private redisClient: AlpheRedisClient; private cognitiveOrchestrator: CognitiveOrchestrator; private tools: Tool[] = []; private resources: Resource[] = []; constructor() { this.server = new Server( { name: '@alphe-ai/redis-mcp-server', version: '1.0.0' }, { capabilities: { tools: {}, resources: {} } } ); // Initialize clients this.redisClient = new AlpheRedisClient(config); this.cognitiveOrchestrator = new CognitiveOrchestrator(this.redisClient); } async initialize(): Promise<void> { console.log(chalk.blue('🚀 Initializing Alphe Redis MCP Server...')); try { // Initialize Redis client with all integrations await this.redisClient.initialize(); console.log(chalk.green('✅ Redis client initialized')); // Start cognitive orchestrator await this.cognitiveOrchestrator.startBackgroundProcessing(); console.log(chalk.green('✅ Cognitive orchestrator started')); // Initialize all tools await this.initializeTools(); console.log(chalk.green(`✅ ${this.tools.length} tools loaded`)); // Initialize resources await this.initializeResources(); console.log(chalk.green(`✅ ${this.resources.length} resources loaded`)); // Setup request handlers this.setupHandlers(); console.log(chalk.green('✅ Request handlers configured')); console.log(chalk.cyan('🎯 Alphe Redis MCP Server ready for cognitive-enhanced operations!')); } catch (error) { console.error(chalk.red('❌ Failed to initialize server:'), error); throw error; } } private async initializeTools(): Promise<void> { // String operations (with multi-layer caching) this.tools.push(...createStringTools(this.redisClient)); // Hash operations this.tools.push(...createHashTools(this.redisClient)); // List operations this.tools.push(...createListTools(this.redisClient)); // Set operations this.tools.push(...createSetTools(this.redisClient)); // Sorted Set operations this.tools.push(...createSortedSetTools(this.redisClient)); // Stream operations this.tools.push(...createStreamTools(this.redisClient)); // Pub/Sub operations this.tools.push(...createPubSubTools(this.redisClient)); // Admin operations this.tools.push(...createAdminTools(this.redisClient)); // Cognitive-enhanced operations this.tools.push({ name: 'cognitive_query', description: 'Process queries using cognitive pipeline with near-zero latency through intelligent caching and parallel agent processing', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'The query to process through cognitive pipeline' }, context: { type: 'object', description: 'Optional context for better processing', additionalProperties: true }, useCache: { type: 'boolean', description: 'Whether to use multi-layer caching', default: true }, priority: { type: 'number', description: 'Processing priority (1-10)', minimum: 1, maximum: 10, default: 5 } }, required: ['query'] } }); // Semantic search with caching this.tools.push({ name: 'semantic_search', description: 'Perform semantic search with intelligent caching across all data layers', inputSchema: { type: 'object', properties: { query: { type: 'string', description: 'Search query' }, limit: { type: 'number', description: 'Maximum results to return', default: 10 }, minSimilarity: { type: 'number', description: 'Minimum similarity threshold', default: 0.7 }, useCache: { type: 'boolean', description: 'Enable caching', default: true } }, required: ['query'] } }); // Performance monitoring this.tools.push({ name: 'get_performance_metrics', description: 'Get comprehensive performance metrics including cognitive agents status', inputSchema: { type: 'object', properties: { includeAgents: { type: 'boolean', description: 'Include cognitive agents status', default: true } } } }); } private async initializeResources(): Promise<void> { this.resources = [ { uri: 'redis://health', name: 'System Health Check', description: 'Health status of Redis, Zilliz, Supabase, and cognitive agents', mimeType: 'application/json' }, { uri: 'redis://performance', name: 'Performance Metrics', description: 'Detailed performance metrics and cache statistics', mimeType: 'application/json' }, { uri: 'redis://cognitive-status', name: 'Cognitive Agents Status', description: 'Status and performance of all cognitive agents', mimeType: 'application/json' }, { uri: 'redis://cache-stats', name: 'Multi-layer Cache Statistics', description: 'Statistics for memory, Redis, Upstash, Zilliz, and Supabase caches', mimeType: 'application/json' }, { uri: 'redis://config', name: 'Server Configuration', description: 'Current server configuration and settings', mimeType: 'application/json' } ]; } private setupHandlers(): void { // List tools handler this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: this.tools })); // List resources handler this.server.setRequestHandler(ListResourcesRequestSchema, async () => ({ resources: this.resources })); // Read resource handler this.server.setRequestHandler(ReadResourceRequestSchema, async (request) => { const { uri } = request.params; switch (uri) { case 'redis://health': return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(await this.redisClient.healthCheck(), null, 2) }] }; case 'redis://performance': return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(await this.redisClient.getPerformanceMetrics(), null, 2) }] }; case 'redis://cognitive-status': return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(await this.cognitiveOrchestrator.getSystemStatus(), null, 2) }] }; case 'redis://cache-stats': const metrics = await this.redisClient.getPerformanceMetrics(); return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(metrics.cache, null, 2) }] }; case 'redis://config': return { contents: [{ uri, mimeType: 'application/json', text: JSON.stringify(config, null, 2) }] }; default: throw new Error(`Resource not found: ${uri}`); } }); // Call tool handler this.server.setRequestHandler(CallToolRequestSchema, async (request) => { const { name, arguments: args } = request.params; try { let result; // Route to appropriate handler if (name.startsWith('redis_')) { // Regular Redis operations result = await this.handleRedisOperation(name, args); } else if (name === 'cognitive_query') { // Cognitive-enhanced query processing result = await this.cognitiveOrchestrator.processQuery( args.query, args.context ); } else if (name === 'semantic_search') { // Semantic search with caching result = await this.redisClient.semanticSearch( args.query, { limit: args.limit, minSimilarity: args.minSimilarity } ); } else if (name === 'get_performance_metrics') { // Performance metrics const redisMetrics = await this.redisClient.getPerformanceMetrics(); const cognitiveStatus = args.includeAgents ? await this.cognitiveOrchestrator.getSystemStatus() : null; result = { redis: redisMetrics, cognitive: cognitiveStatus, timestamp: new Date().toISOString() }; } else { throw new Error(`Unknown tool: ${name}`); } return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }; } catch (error) { console.error(chalk.red(`❌ Tool ${name} failed:`), error); return { content: [{ type: 'text', text: JSON.stringify({ success: false, error: error instanceof Error ? error.message : 'Unknown error', tool: name, timestamp: new Date().toISOString() }, null, 2) }], isError: true }; } }); } private async handleRedisOperation(name: string, args: any): Promise<any> { // Route to appropriate tool handler based on operation type if (name.startsWith('redis_set') || name.startsWith('redis_get') || name.startsWith('redis_mset') || name.startsWith('redis_mget') || name.startsWith('redis_incr') || name.startsWith('redis_decr') || name.startsWith('redis_append') || name.startsWith('redis_strlen')) { return await handleStringOperation(this.redisClient, name, args); } // Add other operation handlers here... throw new Error(`Unhandled Redis operation: ${name}`); } async run(): Promise<void> { const transport = new StdioServerTransport(); await this.server.connect(transport); console.log(chalk.green('🎯 Alphe Redis MCP Server running with cognitive enhancement!')); console.log(chalk.cyan('📊 Features active:')); console.log(chalk.cyan(' • Multi-layer caching (Memory → Redis → Upstash → Zilliz → Supabase)')); console.log(chalk.cyan(' • Cognitive agents (Parallel processing for near-zero latency)')); console.log(chalk.cyan(' • Semantic search with intelligent caching')); console.log(chalk.cyan(' • Performance monitoring and optimization')); console.log(chalk.cyan(' • Comprehensive Redis feature coverage')); } async shutdown(): Promise<void> { console.log(chalk.yellow('🔌 Shutting down Alphe Redis MCP Server...')); try { await this.cognitiveOrchestrator.shutdown(); await this.redisClient.disconnect(); console.log(chalk.green('👋 Server shutdown complete')); } catch (error) { console.error(chalk.red('❌ Error during shutdown:'), error); } } } // Main execution async function main(): Promise<void> { const server = new AlpheRedisMCPServer(); // Graceful shutdown handlers process.on('SIGINT', async () => { console.log('\nReceived SIGINT, shutting down gracefully...'); await server.shutdown(); process.exit(0); }); process.on('SIGTERM', async () => { console.log('Received SIGTERM, shutting down gracefully...'); await server.shutdown(); process.exit(0); }); try { await server.initialize(); await server.run(); } catch (error) { console.error(chalk.red('❌ Server failed to start:'), error); process.exit(1); } } // Handle uncaught errors process.on('uncaughtException', (error) => { console.error(chalk.red('💥 Uncaught exception:'), error); process.exit(1); }); process.on('unhandledRejection', (reason, promise) => { console.error(chalk.red('💥 Unhandled rejection at:'), promise, 'reason:', reason); process.exit(1); }); // Run the server if (import.meta.url === `file://${process.argv[1]}`) { main().catch(console.error); }