Skip to content

Commit e88fe06

Browse files
committed
Feat: Add startup summarization status to healthcheck #7638
1 parent 0b1bc90 commit e88fe06

3 files changed

Lines changed: 80 additions & 18 deletions

File tree

ai/mcp/server/memory-core/mcp-stdio.mjs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -120,53 +120,60 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
120120
/**
121121
* Proactively summarizes unsummarized sessions on startup.
122122
* Runs asynchronously to avoid blocking server startup.
123-
*
123+
* Records the result in HealthService so agents can see what happened.
124+
*
124125
* @returns {Promise<void>}
125126
*/
126127
async function summarizeSessionsOnStartup() {
127128
logger.info('[Startup] Checking for unsummarized sessions...');
128-
129+
129130
try {
130131
const result = await SessionService.summarizeSessions({});
131-
132+
132133
if (result.processed > 0) {
133134
logger.info(`✅ [Startup] Summarized ${result.processed} session(s):`);
134135
result.sessions.forEach(session => {
135136
logger.info(` - ${session.title} (${session.memoryCount} memories)`);
136137
});
138+
HealthService.recordStartupSummarization('completed', {
139+
processed: result.processed,
140+
sessions : result.sessions.map(s => ({ title: s.title, memoryCount: s.memoryCount }))
141+
});
137142
} else {
138143
logger.info('[Startup] No unsummarized sessions found');
144+
HealthService.recordStartupSummarization('completed', { processed: 0 });
139145
}
140146
} catch (error) {
141147
logger.warn('⚠️ [Startup] Session summarization failed:', error.message);
142148
logger.warn(' You can manually trigger summarization using the summarize_sessions tool');
149+
HealthService.recordStartupSummarization('failed', { error: error.message });
143150
}
144151
}
145152

146153
/**
147154
* Main startup sequence for the Memory Core MCP server.
148-
*
155+
*
149156
* Performs the following steps:
150-
* 1. Health check - verifies ChromaDB connectivity
151-
* 2. Status reporting - logs detailed diagnostics
152-
* 3. Auto-summarization - processes unsummarized sessions (if healthy)
153-
* 4. Server startup - connects stdio transport
154-
*
157+
* 1. Wait for async services - ensures ChromaManager is initialized
158+
* 2. Health check - verifies ChromaDB connectivity
159+
* 3. Status reporting - logs detailed diagnostics
160+
* 4. Auto-summarization - processes unsummarized sessions (if healthy)
161+
* 5. Server startup - connects stdio transport
162+
*
155163
* The server starts even if ChromaDB is unavailable, but tools will fail
156164
* gracefully with helpful error messages until dependencies are resolved.
157165
*/
158166
async function main() {
159-
// Wait for async services to initialize
167+
// Wait for async services to initialize (fixes race condition)
160168
await ChromaManager.ready();
161-
162169
// Perform initial health check (non-blocking)
163170
const health = await HealthService.healthcheck();
164171

165172
// Report status based on health check results
166173
if (health.status === 'unhealthy') {
167174
logger.warn('⚠️ [Startup] Memory Core is unhealthy. Server will start but tools will fail until resolved.');
168175
health.details.forEach(detail => logger.warn(` ${detail}`));
169-
176+
170177
// Provide helpful guidance based on process status
171178
if (!health.database.process.running) {
172179
logger.warn(' 💡 Tip: Use the start_database tool after server starts, or run:');
@@ -176,7 +183,7 @@ async function main() {
176183
} else if (health.status === 'degraded') {
177184
logger.warn('⚠️ [Startup] Memory Core is degraded. Some features may be unavailable.');
178185
health.details.forEach(detail => logger.warn(` ${detail}`));
179-
186+
180187
// Still proceed with summarization if ChromaDB is accessible, even without API key
181188
// This allows the user to see what would be summarized
182189
logger.info('✅ [Startup] ChromaDB connectivity confirmed');
@@ -191,7 +198,7 @@ async function main() {
191198
logger.info(` - Memories: ${health.database.connection.collections.memories.count}`);
192199
logger.info(` - Summaries: ${health.database.connection.collections.summaries.count}`);
193200
}
194-
201+
195202
// Only auto-summarize if we're fully healthy
196203
if (health.features.summarization) {
197204
// Run summarization asynchronously (non-blocking)
@@ -201,6 +208,7 @@ async function main() {
201208
} else {
202209
logger.warn('⚠️ [Startup] GEMINI_API_KEY not set - skipping automatic session summarization');
203210
logger.warn(' Set GEMINI_API_KEY environment variable to enable summarization features');
211+
HealthService.recordStartupSummarization('skipped', { reason: 'GEMINI_API_KEY not set' });
204212
}
205213
}
206214

ai/mcp/server/memory-core/openapi.yaml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,26 @@ components:
555555
type: boolean
556556
description: "Indicates if the summarization feature is available (requires GEMINI_API_KEY)."
557557
example: true
558+
startup:
559+
type: object
560+
description: "Provides status on asynchronous tasks performed at server startup."
561+
properties:
562+
summarizationStatus:
563+
type: string
564+
enum: [not_attempted, skipped, completed, failed]
565+
description: "The status of the automatic session summarization attempt at startup."
566+
example: "completed"
567+
summarizationDetails:
568+
type: object
569+
nullable: true
570+
description: "Details about the summarization result, present if status is 'completed' or 'failed'."
571+
example:
572+
processed: 2
573+
sessions:
574+
- title: "Implement MCP Server Configuration"
575+
memoryCount: 15
576+
- title: "Debugged UI Rendering Issue"
577+
memoryCount: 25
558578
details:
559579
type: array
560580
items:

ai/mcp/server/memory-core/services/HealthService.mjs

Lines changed: 38 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@ class HealthService extends Base {
7171
*/
7272
#previousStatus = null;
7373

74+
/**
75+
* Tracks whether startup summarization has been attempted.
76+
* This helps agents understand if they need to manually trigger summarization.
77+
* Values: 'pending', 'completed', 'failed', 'skipped', null (if not yet attempted)
78+
* @member {string|null} #startupSummarizationStatus
79+
* @private
80+
*/
81+
#startupSummarizationStatus = null;
82+
83+
/**
84+
* Details about the startup summarization attempt
85+
* @member {Object|null} #startupSummarizationDetails
86+
* @private
87+
*/
88+
#startupSummarizationDetails = null;
89+
7490
/**
7591
* Checks if ChromaDB is running and accessible.
7692
*
@@ -188,21 +204,25 @@ class HealthService extends Base {
188204
*/
189205
async #performHealthCheck() {
190206
const payload = {
191-
status: 'healthy',
207+
status : 'healthy',
192208
timestamp: new Date().toISOString(),
193-
database: {
209+
database : {
194210
process: DatabaseLifecycleService.getDatabaseStatus(),
195211
connection: {
196-
connected: false,
212+
connected : false,
197213
collections: null
198214
}
199215
},
200216
features: {
201217
summarization: false
202218
},
219+
startup: {
220+
summarizationStatus : this.#startupSummarizationStatus || 'not_attempted',
221+
summarizationDetails: this.#startupSummarizationDetails
222+
},
203223
details: [],
204224
version: '1.0.0',
205-
uptime: process.uptime()
225+
uptime : process.uptime()
206226
};
207227

208228
// Step 1: Check ChromaDB connectivity
@@ -348,6 +368,20 @@ class HealthService extends Base {
348368
}
349369
}
350370

371+
/**
372+
* Records the result of startup summarization attempt.
373+
* Called by the startup sequence in mcp-stdio.mjs
374+
* @param {string} status - One of: 'completed', 'failed', 'skipped'
375+
* @param {Object} details - Additional information about the summarization
376+
*/
377+
recordStartupSummarization(status, details = null) {
378+
this.#startupSummarizationStatus = status;
379+
this.#startupSummarizationDetails = details;
380+
381+
// Clear the cache to ensure next healthcheck returns updated info
382+
this.clearCache();
383+
}
384+
351385
/**
352386
* Clears the health check cache, forcing the next call to perform a fresh check.
353387
*

0 commit comments

Comments
 (0)