Skip to main content
Glama
config.js5.66 kB
/** * Configuration system for MongTap * Manages all configuration without third-party dependencies */ import { readFileSync, existsSync } from 'fs'; import { join, dirname } from 'path'; import { fileURLToPath } from 'url'; import logger from './logger.js'; const __dirname = dirname(fileURLToPath(import.meta.url)); const log = logger.child('Config'); class Config { constructor() { this.config = this.loadDefaults(); this.loadFromFile(); this.loadFromEnv(); log.debug('Configuration loaded', { config: this.config }); } loadDefaults() { return { mcp: { name: 'mongtap', version: '0.1.0', description: 'AI-powered MongoDB server with DataFlood models', port: 3000, host: '0.0.0.0', }, dataflood: { modelPath: './models', tempPath: './temp', testDataPath: './test-data', generationOptions: { stringModelDepth: 3, histogramBins: 20, patternDetection: true, defaultSeed: null, // null for random, number for deterministic }, }, welldb: { dataPath: './welldb-data', portRange: [27018, 27099], defaultPort: 27017, cacheSize: 100, // MB workerThreads: 4, maxConnections: 1000, }, limits: { maxServers: 10, maxModels: 100, maxSampleSize: 10000, serverTimeout: 3600000, // 1 hour in ms generationTimeout: 30000, // 30 seconds }, logging: { level: 'INFO', file: null, colors: true, timestamps: true, }, testing: { enabled: false, fixturesPath: './test/fixtures', }, }; } loadFromFile() { const configPaths = [ join(process.cwd(), 'mongtap.config.json'), join(process.cwd(), '.mongtaprc.json'), join(__dirname, '../../mongtap.config.json'), ]; for (const configPath of configPaths) { if (existsSync(configPath)) { try { const fileContent = readFileSync(configPath, 'utf8'); const fileConfig = JSON.parse(fileContent); this.config = this.deepMerge(this.config, fileConfig); log.info(`Configuration loaded from ${configPath}`); break; } catch (error) { log.error(`Failed to load config from ${configPath}`, { error: error.message }); } } } } loadFromEnv() { // MCP configuration if (process.env.MCP_PORT) { this.config.mcp.port = parseInt(process.env.MCP_PORT, 10); } if (process.env.MCP_HOST) { this.config.mcp.host = process.env.MCP_HOST; } // DataFlood configuration if (process.env.DATAFLOOD_MODEL_PATH) { this.config.dataflood.modelPath = process.env.DATAFLOOD_MODEL_PATH; } if (process.env.DATAFLOOD_SEED) { this.config.dataflood.generationOptions.defaultSeed = parseInt(process.env.DATAFLOOD_SEED, 10); } // WellDB configuration if (process.env.WELLDB_PORT) { this.config.welldb.defaultPort = parseInt(process.env.WELLDB_PORT, 10); } if (process.env.WELLDB_CACHE_SIZE) { this.config.welldb.cacheSize = parseInt(process.env.WELLDB_CACHE_SIZE, 10); } // Logging configuration if (process.env.LOG_LEVEL) { this.config.logging.level = process.env.LOG_LEVEL; } if (process.env.LOG_FILE) { this.config.logging.file = process.env.LOG_FILE; } // Testing mode if (process.env.NODE_ENV === 'test') { this.config.testing.enabled = true; } } deepMerge(target, source) { const output = { ...target }; for (const key in source) { if (source[key] && typeof source[key] === 'object' && !Array.isArray(source[key])) { if (target[key] && typeof target[key] === 'object' && !Array.isArray(target[key])) { output[key] = this.deepMerge(target[key], source[key]); } else { output[key] = source[key]; } } else { output[key] = source[key]; } } return output; } get(path) { const keys = path.split('.'); let value = this.config; for (const key of keys) { if (value && typeof value === 'object' && key in value) { value = value[key]; } else { return undefined; } } return value; } set(path, value) { const keys = path.split('.'); let target = this.config; for (let i = 0; i < keys.length - 1; i++) { const key = keys[i]; if (!target[key] || typeof target[key] !== 'object') { target[key] = {}; } target = target[key]; } target[keys[keys.length - 1]] = value; log.debug(`Configuration updated: ${path} = ${value}`); } getAll() { return { ...this.config }; } // Validate configuration validate() { const errors = []; // Validate ports if (this.config.mcp.port < 1 || this.config.mcp.port > 65535) { errors.push('MCP port must be between 1 and 65535'); } if (this.config.welldb.defaultPort < 1 || this.config.welldb.defaultPort > 65535) { errors.push('WellDB port must be between 1 and 65535'); } // Validate paths exist or can be created // TODO: Add path validation when needed // Validate limits if (this.config.limits.maxSampleSize < 1) { errors.push('Max sample size must be positive'); } if (errors.length > 0) { throw new Error(`Configuration validation failed:\n${errors.join('\n')}`); } return true; } } // Create singleton instance const config = new Config(); export default config;

Latest Blog Posts

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/smallmindsco/MongTap'

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