UNPKG

vector-embedding-mcp-server

Version:
108 lines (93 loc) 4.09 kB
#!/usr/bin/env node /** * Main entry point for vector-embedding-mcp-server * This script determines which command to run based on arguments */ const { spawn } = require('child_process'); const path = require('path'); const fs = require('fs').promises; const args = process.argv.slice(2); // Logging function for consistency with mcp-server.js // All logs go to stderr to avoid breaking MCP JSON-RPC protocol const logFile = path.join(__dirname, 'mcp-server.log'); const logToFile = async (message) => { const timestamp = new Date().toISOString(); const logMessage = `[${timestamp}] [Index] ${message}\n`; await fs.appendFile(logFile, logMessage).catch(err => console.error(`❌ [Index] Failed to write log: ${err.message}`)); // Use stderr to avoid breaking MCP protocol console.error(`[Index] ${message}`); }; // Validate environment variables const validateEnv = () => { const requiredEnv = ['DATABASE_URL', 'INDEX_DOCS_FILE_PATH', 'DOCS_FILE_PATH']; const missingEnv = requiredEnv.filter(env => !process.env[env]); if (missingEnv.length > 0) { throw new Error(`Missing required environment variables: ${missingEnv.join(', ')}`); } logToFile(`🗄️ DATABASE_URL: ${process.env.DATABASE_URL.replace(/\/\/.*@/, '//***@')}`); logToFile(`📄 INDEX_DOCS_FILE_PATH: ${process.env.INDEX_DOCS_FILE_PATH}`); logToFile(`📁 DOCS_FILE_PATH: ${process.env.DOCS_FILE_PATH}`); }; // Spawn process with error handling const spawnProcess = (script, scriptArgs, commandName) => { return new Promise((resolve, reject) => { logToFile(`🚀 Starting ${commandName} with script: ${script} and args: ${scriptArgs.join(' ')}`); const child = spawn('node', [script, ...scriptArgs], { stdio: ['inherit', 'inherit', 'inherit'], // Inherit stdin, stdout, stderr env: { ...process.env, NODE_ENV: process.env.NODE_ENV || 'development' } }); child.on('error', (error) => { logToFile(`❌ [${commandName}] Spawn error: ${error.message}`); reject(error); }); child.on('close', (code) => { logToFile(`🏁 [${commandName}] Completed with exit code: ${code}`); if (code === 0) { resolve(); } else { reject(new Error(`[${commandName}] Failed with exit code ${code}`)); } }); }); }; // Main execution async function main() { try { const command = args[0] || 'mcp'; // Map commands to scripts const commandMap = { 'migrate': { script: 'scripts/migrate.js', args: args.slice(1), name: 'Migration' }, 'migrate:setup': { script: 'scripts/migrate.js', args: ['setup'], name: 'Migration Setup' }, 'migrate:full': { script: 'scripts/migrate.js', args: ['full', ...args.slice(1)], name: 'Full Migration' }, 'migrate:stats': { script: 'scripts/migrate.js', args: ['stats'], name: 'Migration Stats' }, 'ingest-all': { script: 'scripts/ingest-all.js', args: args.slice(1), name: 'Ingest All Rules' }, 'mcp': { script: 'mcp-server.js', args: args.slice(1), name: 'MCP Server' } }; // For MCP server, skip validation and logging to avoid stdout pollution // MCP servers must only output JSON-RPC messages to stdout if (command === 'mcp' || !commandMap[command]) { // Directly require MCP server without any logging to stdout require('./src/mcp/mcp-server'); return; } // Validate environment variables (only for non-MCP commands) validateEnv(); const commandConfig = commandMap[command]; if (commandConfig) { const scriptPath = path.join(__dirname, commandConfig.script); // Verify script exists await fs.access(scriptPath).catch(() => { throw new Error(`Script not found: ${scriptPath}`); }); await spawnProcess(scriptPath, commandConfig.args, commandConfig.name); } } catch (error) { await logToFile(`❌ Error: ${error.message}`); console.error(`❌ [Index] Error: ${error.message}`); process.exit(1); } } main().catch(error => { console.error(`❌ [Index] Fatal error: ${error.message}`); process.exit(1); });