Skip to main content
Glama
config-manager.js•7.1 kB
// DYNAMIC CONFIGURATION MANAGER // All paths and settings in ONE place - no hardcoded paths anywhere! // Agents read from this file, making moves/changes safe import { promises as fs } from 'fs'; import path from 'path'; export class ConfigManager { constructor() { this.configPath = null; this.config = null; this.initialized = false; } // Initialize - finds config file dynamically async initialize() { if (this.initialized) return this.config; // Try common locations const possiblePaths = [ 'C:/MCP/config.json', process.cwd() + '/config.json', process.env.MCP_CONFIG_PATH ]; for (const testPath of possiblePaths) { if (testPath && await this.fileExists(testPath)) { this.configPath = testPath; break; } } // If no config found, create default if (!this.configPath) { this.configPath = 'C:/MCP/config.json'; await this.createDefaultConfig(); } // Load config this.config = await this.loadConfig(); this.initialized = true; return this.config; } // Create default configuration async createDefaultConfig() { const defaultConfig = { version: '1.0.0', environment: 'development', // PATHS - All dynamic, change here to move everything paths: { root: 'C:/MCP', agents: { core: 'C:/MCP/src/agents/core', specialized: 'C:/MCP/src/agents/specialized' }, tools: 'C:/MCP/src/tools', integrations: 'C:/MCP/src/integrations', logs: { actions: 'C:/MCP/logs/agent-actions', system: 'C:/MCP/logs/system', rollback: 'C:/MCP/logs/rollback' }, backups: { daily: 'C:/MCP/backups/daily', manual: 'C:/MCP/backups/manual' }, inventory: 'C:/MCP/inventory', workflows: 'C:/MCP/workflows', aiProjects: 'C:/AI Projects', agentSystem: 'C:/AgentSystem', tools: 'C:/tools' }, // API KEY ROTATION - Spread load across services apiKeys: { rotationEnabled: true, currentProvider: 'claude', providers: { claude: { enabled: true, tokensUsed: 0, dailyLimit: 150000, priority: 1 }, gpt4: { enabled: false, tokensUsed: 0, dailyLimit: 100000, priority: 2, apiKey: 'CONFIGURE_ME' }, perplexity: { enabled: false, tokensUsed: 0, dailyLimit: 50000, priority: 3, apiKey: 'CONFIGURE_ME' } } }, // AGENT SETTINGS agents: { autoStart: true, delegationMode: 'automatic', active: { docControl: true, docOrganizer: true, qualityAgent: true, orchestrator: true } }, // CODE INTEGRITY CHECKS integrity: { enabled: true, checkBeforeMove: true, validateImports: true, backupBeforeChange: true }, // QNAP/NAS SETTINGS qnap: { enabled: false, host: 'CONFIGURE_ME', containers: { n8n: { name: 'n8n', port: 5678, dataPath: '/share/Container/n8n' } } }, // LOGGING SETTINGS logging: { level: 'info', rollbackEnabled: true, sessionTracking: true, maxRollbackDays: 7 } }; await fs.writeFile( this.configPath, JSON.stringify(defaultConfig, null, 2) ); console.log(`📝 Created default config: ${this.configPath}`); } // Load configuration async loadConfig() { const data = await fs.readFile(this.configPath, 'utf-8'); return JSON.parse(data); } // Save configuration async saveConfig() { await fs.writeFile( this.configPath, JSON.stringify(this.config, null, 2) ); } // Get any config value get(path) { const keys = path.split('.'); let value = this.config; for (const key of keys) { if (value && typeof value === 'object') { value = value[key]; } else { return null; } } return value; } // Set any config value async set(path, value) { const keys = path.split('.'); let current = this.config; for (let i = 0; i < keys.length - 1; i++) { if (!current[keys[i]]) { current[keys[i]] = {}; } current = current[keys[i]]; } current[keys[keys.length - 1]] = value; await this.saveConfig(); } // API Key rotation methods getNextAvailableProvider() { const providers = Object.entries(this.config.apiKeys.providers) .filter(([_, config]) => config.enabled) .sort((a, b) => a[1].priority - b[1].priority); for (const [name, config] of providers) { if (config.tokensUsed < config.dailyLimit) { return name; } } return null; // All providers maxed out } async trackTokenUsage(provider, tokens) { const path = `apiKeys.providers.${provider}.tokensUsed`; const current = this.get(path) || 0; await this.set(path, current + tokens); } async resetDailyTokens() { for (const provider in this.config.apiKeys.providers) { await this.set(`apiKeys.providers.${provider}.tokensUsed`, 0); } } // Helper: Check if file exists async fileExists(filePath) { try { await fs.access(filePath); return true; } catch { return false; } } } // Export singleton export const configManager = new ConfigManager();

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/bermingham85/mcp-puppet-pipeline'

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