Skip to main content
Glama

COA Goldfish MCP

by anortham
config.tsโ€ข10.1 kB
/** * Configuration manager for Goldfish MCP * Supports environment variables and runtime configuration */ export interface GoldfishConfig { // Storage configuration basePath?: string; workspaceDetection: boolean; // Memory configuration defaultTtlHours: number; maxMemoriesPerWorkspace: number; autoCleanupEnabled: boolean; cleanupThresholdDays: number; // Tool quotas and limits maxTodoItemsPerList: number; maxPlanItemsPerPlan: number; maxCheckpointsPerSession: number; maxStandupDays: number; // Feature flags vsCodeBridgeEnabled: boolean; relationshipTrackingEnabled: boolean; indexingEnabled: boolean; // Output configuration defaultOutputMode: 'plain' | 'emoji' | 'json' | 'dual'; enableVerboseLogging: boolean; // Search configuration fuzzySearchThreshold: number; searchResultLimit: number; // Integration settings gitIntegrationEnabled: boolean; autoDetectWorkspace: boolean; // Performance settings concurrentIndexUpdates: boolean; batchSizeForBulkOperations: number; } export class ConfigManager { private static instance: ConfigManager | null = null; private config: GoldfishConfig; private constructor() { this.config = this.loadConfigFromEnvironment(); } /** * Get singleton instance */ static getInstance(): ConfigManager { if (!ConfigManager.instance) { ConfigManager.instance = new ConfigManager(); } return ConfigManager.instance; } /** * Load configuration from environment variables with defaults */ private loadConfigFromEnvironment(): GoldfishConfig { return { // Storage configuration basePath: process.env.COA_GOLDFISH_BASE_PATH, workspaceDetection: this.getBooleanEnv('COA_GOLDFISH_WORKSPACE_DETECTION', true), // Memory configuration defaultTtlHours: this.getNumberEnv('COA_GOLDFISH_DEFAULT_TTL_HOURS', 72), maxMemoriesPerWorkspace: this.getNumberEnv('COA_GOLDFISH_MAX_MEMORIES_PER_WORKSPACE', 50), autoCleanupEnabled: this.getBooleanEnv('COA_GOLDFISH_AUTO_CLEANUP', true), cleanupThresholdDays: this.getNumberEnv('COA_GOLDFISH_CLEANUP_THRESHOLD_DAYS', 7), // Tool quotas and limits maxTodoItemsPerList: this.getNumberEnv('COA_GOLDFISH_MAX_TODO_ITEMS', 100), maxPlanItemsPerPlan: this.getNumberEnv('COA_GOLDFISH_MAX_PLAN_ITEMS', 50), maxCheckpointsPerSession: this.getNumberEnv('COA_GOLDFISH_MAX_CHECKPOINTS_PER_SESSION', 20), maxStandupDays: this.getNumberEnv('COA_GOLDFISH_MAX_STANDUP_DAYS', 30), // Feature flags vsCodeBridgeEnabled: this.getBooleanEnv('COA_GOLDFISH_VSCODE_BRIDGE', true), relationshipTrackingEnabled: this.getBooleanEnv('COA_GOLDFISH_RELATIONSHIP_TRACKING', true), indexingEnabled: this.getBooleanEnv('COA_GOLDFISH_INDEXING_ENABLED', true), // Output configuration defaultOutputMode: this.getEnumEnv( 'COA_GOLDFISH_OUTPUT_MODE', ['plain', 'emoji', 'json', 'dual'], 'dual' ) as 'plain' | 'emoji' | 'json' | 'dual', enableVerboseLogging: this.getBooleanEnv('COA_GOLDFISH_VERBOSE_LOGGING', false), // Search configuration fuzzySearchThreshold: this.getNumberEnv('COA_GOLDFISH_FUZZY_SEARCH_THRESHOLD', 0.3), searchResultLimit: this.getNumberEnv('COA_GOLDFISH_SEARCH_RESULT_LIMIT', 100), // Integration settings gitIntegrationEnabled: this.getBooleanEnv('COA_GOLDFISH_GIT_INTEGRATION', true), autoDetectWorkspace: this.getBooleanEnv('COA_GOLDFISH_AUTO_DETECT_WORKSPACE', true), // Performance settings concurrentIndexUpdates: this.getBooleanEnv('COA_GOLDFISH_CONCURRENT_INDEX_UPDATES', false), batchSizeForBulkOperations: this.getNumberEnv('COA_GOLDFISH_BATCH_SIZE', 10) }; } /** * Get current configuration */ getConfig(): GoldfishConfig { return { ...this.config }; } /** * Update configuration at runtime */ updateConfig(updates: Partial<GoldfishConfig>): void { this.config = { ...this.config, ...updates }; } /** * Get a specific configuration value */ get<K extends keyof GoldfishConfig>(key: K): GoldfishConfig[K] { return this.config[key]; } /** * Set a specific configuration value */ set<K extends keyof GoldfishConfig>(key: K, value: GoldfishConfig[K]): void { this.config[key] = value; } /** * Reset configuration to environment defaults */ reset(): void { this.config = this.loadConfigFromEnvironment(); } /** * Get configuration as JSON string for debugging */ toJSON(): string { return JSON.stringify(this.config, null, 2); } /** * Validate configuration values */ validate(): { valid: boolean; errors: string[] } { const errors: string[] = []; // Validate numeric ranges if (this.config.defaultTtlHours < 0 || this.config.defaultTtlHours > 8760) { // 0 to 1 year errors.push('defaultTtlHours must be between 0 and 8760'); } if (this.config.maxMemoriesPerWorkspace < 1 || this.config.maxMemoriesPerWorkspace > 10000) { errors.push('maxMemoriesPerWorkspace must be between 1 and 10000'); } if (this.config.cleanupThresholdDays < 1 || this.config.cleanupThresholdDays > 365) { errors.push('cleanupThresholdDays must be between 1 and 365'); } if (this.config.fuzzySearchThreshold < 0 || this.config.fuzzySearchThreshold > 1) { errors.push('fuzzySearchThreshold must be between 0 and 1'); } if (this.config.searchResultLimit < 1 || this.config.searchResultLimit > 10000) { errors.push('searchResultLimit must be between 1 and 10000'); } if (this.config.batchSizeForBulkOperations < 1 || this.config.batchSizeForBulkOperations > 1000) { errors.push('batchSizeForBulkOperations must be between 1 and 1000'); } return { valid: errors.length === 0, errors }; } /** * Helper: Parse boolean environment variable */ private getBooleanEnv(key: string, defaultValue: boolean): boolean { const value = process.env[key]; if (value === undefined) return defaultValue; return value.toLowerCase() === 'true' || value === '1'; } /** * Helper: Parse number environment variable */ private getNumberEnv(key: string, defaultValue: number): number { const value = process.env[key]; if (value === undefined) return defaultValue; const parsed = parseFloat(value); return isNaN(parsed) ? defaultValue : parsed; } /** * Helper: Parse enum environment variable */ private getEnumEnv<T extends string>(key: string, allowedValues: T[], defaultValue: T): T { const value = process.env[key] as T; if (value === undefined) return defaultValue; return allowedValues.includes(value) ? value : defaultValue; } /** * Get environment variable summary for debugging */ getEnvironmentSummary(): Record<string, string | undefined> { return { COA_GOLDFISH_BASE_PATH: process.env.COA_GOLDFISH_BASE_PATH, COA_GOLDFISH_WORKSPACE_DETECTION: process.env.COA_GOLDFISH_WORKSPACE_DETECTION, COA_GOLDFISH_DEFAULT_TTL_HOURS: process.env.COA_GOLDFISH_DEFAULT_TTL_HOURS, COA_GOLDFISH_MAX_MEMORIES_PER_WORKSPACE: process.env.COA_GOLDFISH_MAX_MEMORIES_PER_WORKSPACE, COA_GOLDFISH_AUTO_CLEANUP: process.env.COA_GOLDFISH_AUTO_CLEANUP, COA_GOLDFISH_CLEANUP_THRESHOLD_DAYS: process.env.COA_GOLDFISH_CLEANUP_THRESHOLD_DAYS, COA_GOLDFISH_MAX_TODO_ITEMS: process.env.COA_GOLDFISH_MAX_TODO_ITEMS, COA_GOLDFISH_MAX_PLAN_ITEMS: process.env.COA_GOLDFISH_MAX_PLAN_ITEMS, COA_GOLDFISH_MAX_CHECKPOINTS_PER_SESSION: process.env.COA_GOLDFISH_MAX_CHECKPOINTS_PER_SESSION, COA_GOLDFISH_MAX_STANDUP_DAYS: process.env.COA_GOLDFISH_MAX_STANDUP_DAYS, COA_GOLDFISH_VSCODE_BRIDGE: process.env.COA_GOLDFISH_VSCODE_BRIDGE, COA_GOLDFISH_RELATIONSHIP_TRACKING: process.env.COA_GOLDFISH_RELATIONSHIP_TRACKING, COA_GOLDFISH_INDEXING_ENABLED: process.env.COA_GOLDFISH_INDEXING_ENABLED, COA_GOLDFISH_OUTPUT_MODE: process.env.COA_GOLDFISH_OUTPUT_MODE, COA_GOLDFISH_VERBOSE_LOGGING: process.env.COA_GOLDFISH_VERBOSE_LOGGING, COA_GOLDFISH_FUZZY_SEARCH_THRESHOLD: process.env.COA_GOLDFISH_FUZZY_SEARCH_THRESHOLD, COA_GOLDFISH_SEARCH_RESULT_LIMIT: process.env.COA_GOLDFISH_SEARCH_RESULT_LIMIT, COA_GOLDFISH_GIT_INTEGRATION: process.env.COA_GOLDFISH_GIT_INTEGRATION, COA_GOLDFISH_AUTO_DETECT_WORKSPACE: process.env.COA_GOLDFISH_AUTO_DETECT_WORKSPACE, COA_GOLDFISH_CONCURRENT_INDEX_UPDATES: process.env.COA_GOLDFISH_CONCURRENT_INDEX_UPDATES, COA_GOLDFISH_BATCH_SIZE: process.env.COA_GOLDFISH_BATCH_SIZE }; } /** * Check if a feature is enabled */ isFeatureEnabled(feature: 'vsCodeBridge' | 'relationshipTracking' | 'indexing' | 'gitIntegration' | 'autoCleanup'): boolean { switch (feature) { case 'vsCodeBridge': return this.config.vsCodeBridgeEnabled; case 'relationshipTracking': return this.config.relationshipTrackingEnabled; case 'indexing': return this.config.indexingEnabled; case 'gitIntegration': return this.config.gitIntegrationEnabled; case 'autoCleanup': return this.config.autoCleanupEnabled; default: return false; } } /** * Get quota for a specific tool/operation */ getQuota(operation: 'todoItems' | 'planItems' | 'checkpoints' | 'standupDays' | 'searchResults' | 'memories'): number { switch (operation) { case 'todoItems': return this.config.maxTodoItemsPerList; case 'planItems': return this.config.maxPlanItemsPerPlan; case 'checkpoints': return this.config.maxCheckpointsPerSession; case 'standupDays': return this.config.maxStandupDays; case 'searchResults': return this.config.searchResultLimit; case 'memories': return this.config.maxMemoriesPerWorkspace; default: return 100; // Default fallback } } }

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/anortham/coa-goldfish-mcp'

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