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
text/typescript
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);
}