Servers Affected
ai/mcp/server/memory-core/
ai/mcp/server/knowledge-base/
Changes Implemented
1. ChromaManager.mjs (both servers)
2. DatabaseLifecycleService.mjs (both servers)
3. SessionService.mjs (memory-core only)
4. mcp-stdio.mjs (both servers)
5. config.mjs
knowledge-base:
- Fixed ChromaDB data path:
path: path.resolve(process.cwd(), 'dist/ai-knowledge-base.jsonl'),
path: path.resolve(process.cwd(), 'chroma'),
dataPath: path.resolve(process.cwd(), 'dist/ai-knowledge-base.jsonl'),
- Set
debug: true (temporary, will be reverted)
memory-core:
- Cleaned up path:
'./chroma-memory' → 'chroma-memory' (removed unnecessary ./)
- Set
debug: true (temporary, will be reverted)
6. logger.mjs (all 3 servers)
7. DatabaseService.mjs (knowledge-base only)
8. DatabaseLifecycleService.mjs (memory-core only)
9. mcp-stdio.mjs (memory-core only)
Benefits Achieved
- ✅ ChromaDB automatically starts on server initialization
- ✅ Respects external/existing ChromaDB instances (no duplicates)
- ✅ Services properly wait for dependencies via
.ready() pattern
- ✅ Single source of truth for ChromaDB access (ChromaManager)
- ✅ Graceful degradation preserved (server starts even if auto-start fails)
- ✅ Fixed config bug in knowledge-base (wrong path type)
Verification
Both servers now start successfully without manual ChromaDB startup:
- memory-core: Port 8001, 205 memories, 16 summaries, auto-summarization works
- knowledge-base: Port 8000, 0 documents (empty but healthy)
Servers Affected
ai/mcp/server/memory-core/ai/mcp/server/knowledge-base/Changes Implemented
1. ChromaManager.mjs (both servers)
connect()to return boolean instead of throwingasync connect() { try { await this.client.heartbeat(); this.connected = true; return true; } catch (e) { this.connected = false; logger.debug('[ChromaManager] ChromaDB not accessible:', e.message); return false; // Don't throw - graceful degradation } }2. DatabaseLifecycleService.mjs (both servers)
initAsync()method for auto-startasync initAsync() { await super.initAsync(); await ChromaManager.ready(); // Initialize ChromaManager await this.startDatabase(); // Auto-start ChromaDB if needed }startDatabase()- already handles all scenarios3. SessionService.mjs (memory-core only)
ChromaManagersingletondbClientproperty fromconstruct()initAsync():async initAsync() { await super.initAsync(); await DatabaseLifecycleService.ready(); // Ensure ChromaDB available // Use ChromaManager instead of direct client this.memoryCollection = await ChromaManager.getMemoryCollection(); this.sessionsCollection = await ChromaManager.getSummaryCollection(); }4. mcp-stdio.mjs (both servers)
// Before await ChromaManager.ready(); // After await DatabaseLifecycleService.ready(); // Auto-starts ChromaDB5. config.mjs
knowledge-base:
// Before path: path.resolve(process.cwd(), 'dist/ai-knowledge-base.jsonl'), // ❌ Wrong - JSONL file // After path: path.resolve(process.cwd(), 'chroma'), // ✅ ChromaDB data directory dataPath: path.resolve(process.cwd(), 'dist/ai-knowledge-base.jsonl'), // ✅ JSONL path renameddebug: true(temporary, will be reverted)memory-core:
'./chroma-memory'→'chroma-memory'(removed unnecessary./)debug: true(temporary, will be reverted)6. logger.mjs (all 3 servers)
logger.logmethod to github-workflow, knowledge-base, and memory-core:logger.log = createLogMethod('log');7. DatabaseService.mjs (knowledge-base only)
// In createKnowledgeBase() and embedKnowledgeBase() const outputPath = aiConfig.dataPath; // Was: aiConfig.path8. DatabaseLifecycleService.mjs (memory-core only)
logger.error('Starting ChromaDB (Memory Core) process...');9. mcp-stdio.mjs (memory-core only)
import Observable from '../../../../src/core/Observable.mjs';This ensures the Observable mixin is loaded globally, so services usingstatic observable = truedon't need to import it individuallyBenefits Achieved
.ready()patternVerification
Both servers now start successfully without manual ChromaDB startup: