Skip to main content
Glama

MCP Content Analyzer

by DuncanDam
config-wizard.js9.89 kB
#!/usr/bin/env node import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync } from 'fs'; import { join, dirname, resolve } from 'path'; import { fileURLToPath } from 'url'; import { createInterface } from 'readline'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); const rootDir = join(__dirname, '..'); // Create readline interface for user input const rl = createInterface({ input: process.stdin, output: process.stdout }); // Helper function to ask questions function askQuestion(question) { return new Promise((resolve) => { rl.question(question, (answer) => { resolve(answer.trim()); }); }); } // Helper function to ask yes/no questions async function askYesNo(question, defaultValue = true) { const defaultText = defaultValue ? 'Y/n' : 'y/N'; const answer = await askQuestion(`${question} [${defaultText}]: `); if (answer === '') return defaultValue; return answer.toLowerCase().startsWith('y'); } // Helper function to validate file path function validatePath(path, isDirectory = false) { if (!path) return false; const resolvedPath = resolve(rootDir, path); if (isDirectory) { return existsSync(resolvedPath) && statSync(resolvedPath).isDirectory(); } else { // For files, check if directory exists and file can be created const dir = dirname(resolvedPath); return existsSync(dir) || mkdirSync(dir, { recursive: true }); } } // Helper function to create directory if it doesn't exist function ensureDirectory(path) { const resolvedPath = resolve(rootDir, path); const dir = dirname(resolvedPath); if (!existsSync(dir)) { mkdirSync(dir, { recursive: true }); } } async function loadExistingConfig() { const envPath = join(rootDir, '.env'); const config = {}; if (existsSync(envPath)) { const envContent = readFileSync(envPath, 'utf8'); const lines = envContent.split('\n'); for (const line of lines) { const trimmedLine = line.trim(); if (trimmedLine && !trimmedLine.startsWith('#')) { const [key, ...valueParts] = trimmedLine.split('='); if (key && valueParts.length > 0) { config[key.trim()] = valueParts.join('=').trim(); } } } } return config; } async function saveConfig(config) { const envPath = join(rootDir, '.env'); // Read template to get all possible variables const templatePath = join(rootDir, 'env.template'); let templateContent = ''; if (existsSync(templatePath)) { templateContent = readFileSync(templatePath, 'utf8'); } // Create .env content let envContent = '# MCP Content Analyzer Configuration\n'; envContent += '# Generated by config wizard\n\n'; // Add core paths section envContent += '# =============================================================================\n'; envContent += '# CORE PATHS - REQUIRED\n'; envContent += '# =============================================================================\n\n'; envContent += `EXCEL_DATABASE_PATH=${config.EXCEL_DATABASE_PATH || './data/content-database.xlsx'}\n`; envContent += `CONTENT_CATALOG_PATH=${config.CONTENT_CATALOG_PATH || './data/content-catalog-guidelines.md'}\n\n`; // Add other configuration sections const sections = [ { name: 'EXCEL CONFIGURATION', vars: ['EXCEL_BACKUP_ENABLED', 'EXCEL_AUTO_SAVE', 'EXCEL_TEMPLATE_PATH', 'EXCEL_SCHEMA_VERSION'] }, { name: 'CONTENT CATALOG CONFIGURATION', vars: ['SUPPORT_DOCUMENT_VALIDATION', 'AUTO_REJECT_UNSUITABLE', 'DEFAULT_CATALOG_ENABLED'] }, { name: 'ANALYSIS CONFIGURATION', vars: ['AI_ANALYSIS_ENABLED', 'QUOTE_EXTRACTION_ENABLED', 'CASE_STUDY_DETECTION_ENABLED', 'CULTURAL_CONTEXT_ANALYSIS', 'AUTO_CATEGORIZATION', 'ENHANCED_SEARCH_ENABLED'] }, { name: 'QUALITY CONTROL', vars: ['MIN_SOURCE_CREDIBILITY', 'REQUIRE_PUBLICATION_DATE', 'REQUIRE_AUTHOR_INFO', 'MIN_WORD_COUNT', 'MAX_CONTENT_AGE', 'CULTURAL_RELEVANCE_THRESHOLD'] }, { name: 'SCRAPER CONFIGURATION', vars: ['SCRAPER_USER_AGENT', 'SCRAPER_TIMEOUT', 'SCRAPER_RATE_LIMIT'] }, { name: 'OCR CONFIGURATION', vars: ['OCR_FALLBACK_ENABLED'] }, { name: 'SERVER CONFIGURATION', vars: ['MCP_SERVER_PORT', 'LOG_LEVEL', 'MAX_CONTENT_LENGTH'] }, { name: 'TEAM CONFIGURATION', vars: ['TEAM_NAME', 'SERVER_NAME'] } ]; for (const section of sections) { envContent += `# =============================================================================\n`; envContent += `# ${section.name}\n`; envContent += `# =============================================================================\n\n`; for (const varName of section.vars) { const value = config[varName] || getDefaultValue(varName); envContent += `${varName}=${value}\n`; } envContent += '\n'; } writeFileSync(envPath, envContent); console.log(`✅ Configuration saved to ${envPath}`); } function getDefaultValue(varName) { const defaults = { 'EXCEL_BACKUP_ENABLED': 'true', 'EXCEL_AUTO_SAVE': 'true', 'EXCEL_TEMPLATE_PATH': './config/excel-template.xlsx', 'EXCEL_SCHEMA_VERSION': '2.0', 'SUPPORT_DOCUMENT_VALIDATION': 'true', 'AUTO_REJECT_UNSUITABLE': 'false', 'DEFAULT_CATALOG_ENABLED': 'true', 'AI_ANALYSIS_ENABLED': 'true', 'QUOTE_EXTRACTION_ENABLED': 'true', 'CASE_STUDY_DETECTION_ENABLED': 'true', 'CULTURAL_CONTEXT_ANALYSIS': 'true', 'AUTO_CATEGORIZATION': 'false', 'ENHANCED_SEARCH_ENABLED': 'true', 'MIN_SOURCE_CREDIBILITY': 'Medium', 'REQUIRE_PUBLICATION_DATE': 'false', 'REQUIRE_AUTHOR_INFO': 'false', 'MIN_WORD_COUNT': '100', 'MAX_CONTENT_AGE': '365', 'CULTURAL_RELEVANCE_THRESHOLD': '0.3', 'SCRAPER_USER_AGENT': 'MCP Content Analyzer 1.0', 'SCRAPER_TIMEOUT': '30000', 'SCRAPER_RATE_LIMIT': '5', 'OCR_FALLBACK_ENABLED': 'true', 'MCP_SERVER_PORT': '3000', 'LOG_LEVEL': 'info', 'MAX_CONTENT_LENGTH': '50000', 'TEAM_NAME': 'default_team', 'SERVER_NAME': 'my-mcp' }; return defaults[varName] || ''; } async function main() { console.log('🔧 MCP Content Analyzer Configuration Wizard\n'); try { // Load existing configuration const existingConfig = await loadExistingConfig(); console.log('This wizard will help you configure the MCP Content Analyzer.'); console.log('Press Enter to use default values or existing configuration.\n'); // Core paths configuration console.log('📁 CORE PATHS CONFIGURATION'); console.log('These are the most important paths for the system to function.\n'); // Excel Database Path let excelPath = existingConfig.EXCEL_DATABASE_PATH || './data/content-database.xlsx'; console.log(`Current Excel database path: ${excelPath}`); const newExcelPath = await askQuestion('Enter Excel database path (or press Enter to keep current): '); if (newExcelPath) { excelPath = newExcelPath; } // Ensure directory exists ensureDirectory(excelPath); // Content Catalog Path let catalogPath = existingConfig.CONTENT_CATALOG_PATH || './data/content-catalog-guidelines.md'; console.log(`\nCurrent content catalog path: ${catalogPath}`); const newCatalogPath = await askQuestion('Enter content catalog guidelines path (or press Enter to keep current): '); if (newCatalogPath) { catalogPath = newCatalogPath; } // Ensure directory exists ensureDirectory(catalogPath); // Ask about advanced configuration console.log('\n⚙️ ADVANCED CONFIGURATION'); const configureAdvanced = await askYesNo('Would you like to configure advanced options?', false); const config = { EXCEL_DATABASE_PATH: excelPath, CONTENT_CATALOG_PATH: catalogPath, ...existingConfig }; if (configureAdvanced) { console.log('\n📊 EXCEL CONFIGURATION'); config.EXCEL_BACKUP_ENABLED = (await askYesNo('Enable automatic Excel backup?', existingConfig.EXCEL_BACKUP_ENABLED !== 'false')).toString(); config.EXCEL_AUTO_SAVE = (await askYesNo('Enable automatic Excel saving?', existingConfig.EXCEL_AUTO_SAVE !== 'false')).toString(); console.log('\n🔍 ANALYSIS CONFIGURATION'); config.AI_ANALYSIS_ENABLED = (await askYesNo('Enable AI-powered analysis?', existingConfig.AI_ANALYSIS_ENABLED !== 'false')).toString(); config.AUTO_CATEGORIZATION = (await askYesNo('Enable automatic categorization?', existingConfig.AUTO_CATEGORIZATION === 'true')).toString(); console.log('\n🌐 SCRAPER CONFIGURATION'); const timeout = await askQuestion(`Scraper timeout in milliseconds [${existingConfig.SCRAPER_TIMEOUT || '30000'}]: `); if (timeout) config.SCRAPER_TIMEOUT = timeout; const rateLimit = await askQuestion(`Rate limit (requests per minute) [${existingConfig.SCRAPER_RATE_LIMIT || '5'}]: `); if (rateLimit) config.SCRAPER_RATE_LIMIT = rateLimit; console.log('\n🏢 TEAM CONFIGURATION'); const teamName = await askQuestion(`Team name [${existingConfig.TEAM_NAME || 'default_team'}]: `); if (teamName) config.TEAM_NAME = teamName; const serverName = await askQuestion(`Server name [${existingConfig.SERVER_NAME || 'my-mcp'}]: `); if (serverName) config.SERVER_NAME = serverName; } // Save configuration await saveConfig(config); console.log('\n✅ Configuration completed successfully!'); console.log('\n📋 Next steps:'); console.log('1. Restart Claude Desktop to load the new configuration'); console.log('2. Test the connection with: my-mcp test'); console.log('3. Start the server with: my-mcp start'); } catch (error) { console.error('\n❌ Configuration failed:', error.message); process.exit(1); } finally { rl.close(); } } main();

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/DuncanDam/my-mcp'

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