@@ -4,6 +4,8 @@ import {CallToolRequestSchema, ListToolsRequestSchema} from '@modelcontextprotoc
44import Neo from '../../../../src/Neo.mjs' ;
55import * as core from '../../../../src/core/_export.mjs' ;
66import InstanceManager from '../../../../src/manager/Instance.mjs' ;
7+ import HealthService from './services/HealthService.mjs' ;
8+ import SessionService from './services/SessionService.mjs' ;
79import logger from './logger.mjs' ;
810import { listTools , callTool } from './services/toolService.mjs' ;
911
@@ -51,7 +53,26 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
5153 const { name, arguments : args } = request . params ;
5254
5355 try {
54- logger . error ( `[MCP] Calling tool: ${ name } with args:` , JSON . stringify ( args ) ) ;
56+ logger . debug ( `[MCP] Calling tool: ${ name } with args:` , JSON . stringify ( args ) ) ;
57+
58+ const exemptFromHealthCheck = [ 'healthcheck' , 'start_database' , 'stop_database' ] ;
59+
60+ // Perform health check before tool execution (with caching)
61+ // Skip for lifecycle and healthcheck tools to avoid circular dependencies
62+ if ( ! exemptFromHealthCheck . includes ( name ) ) {
63+ try {
64+ await HealthService . ensureHealthy ( ) ;
65+ } catch ( healthError ) {
66+ logger . error ( `[MCP] Health check failed for tool ${ name } :` , healthError . message ) ;
67+ return {
68+ content : [ {
69+ type : 'text' ,
70+ text : `Cannot execute ${ name } : ${ healthError . message } `
71+ } ] ,
72+ isError : true
73+ } ;
74+ }
75+ }
5576
5677 const result = await callTool ( name , args ) ;
5778
@@ -95,12 +116,94 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
95116 }
96117} ) ;
97118
98- // Start the stdio transport
119+ /**
120+ * Proactively summarizes unsummarized sessions on startup.
121+ * Runs asynchronously to avoid blocking server startup.
122+ *
123+ * @returns {Promise<void> }
124+ */
125+ async function summarizeSessionsOnStartup ( ) {
126+ logger . info ( '[Startup] Checking for unsummarized sessions...' ) ;
127+
128+ try {
129+ const result = await SessionService . summarizeSessions ( { } ) ;
130+
131+ if ( result . processed > 0 ) {
132+ logger . info ( `✅ [Startup] Summarized ${ result . processed } session(s):` ) ;
133+ result . sessions . forEach ( session => {
134+ logger . info ( ` - ${ session . title } (${ session . memoryCount } memories)` ) ;
135+ } ) ;
136+ } else {
137+ logger . info ( '[Startup] No unsummarized sessions found' ) ;
138+ }
139+ } catch ( error ) {
140+ logger . warn ( '⚠️ [Startup] Session summarization failed:' , error . message ) ;
141+ logger . warn ( ' You can manually trigger summarization using the summarize_sessions tool' ) ;
142+ }
143+ }
144+
145+ /**
146+ * Main startup sequence for the Memory Core MCP server.
147+ *
148+ * Performs the following steps:
149+ * 1. Health check - verifies ChromaDB connectivity
150+ * 2. Status reporting - logs detailed diagnostics
151+ * 3. Auto-summarization - processes unsummarized sessions (if healthy)
152+ * 4. Server startup - connects stdio transport
153+ *
154+ * The server starts even if ChromaDB is unavailable, but tools will fail
155+ * gracefully with helpful error messages until dependencies are resolved.
156+ */
99157async function main ( ) {
158+ // Perform initial health check (non-blocking)
159+ const health = await HealthService . healthcheck ( ) ;
160+
161+ // Report status based on health check results
162+ if ( health . status === 'unhealthy' ) {
163+ logger . warn ( '⚠️ [Startup] Memory Core is unhealthy. Server will start but tools will fail until resolved.' ) ;
164+ health . details . forEach ( detail => logger . warn ( ` ${ detail } ` ) ) ;
165+
166+ // Provide helpful guidance based on process status
167+ if ( ! health . database . process . running ) {
168+ logger . warn ( ' 💡 Tip: Use the start_database tool after server starts, or run:' ) ;
169+ logger . warn ( ` chroma run --path ${ process . env . CHROMA_DATA_PATH || './data/chroma' } --port ${ process . env . CHROMA_PORT || '8000' } ` ) ;
170+ }
171+ logger . warn ( ' The server will periodically retry and recover automatically once dependencies are met.' ) ;
172+ } else if ( health . status === 'degraded' ) {
173+ logger . warn ( '⚠️ [Startup] Memory Core is degraded. Some features may be unavailable.' ) ;
174+ health . details . forEach ( detail => logger . warn ( ` ${ detail } ` ) ) ;
175+
176+ // Still proceed with summarization if ChromaDB is accessible, even without API key
177+ // This allows the user to see what would be summarized
178+ logger . info ( '✅ [Startup] ChromaDB connectivity confirmed' ) ;
179+ if ( health . database . connection . collections ) {
180+ logger . info ( ` - Memories: ${ health . database . connection . collections . memories . count } ` ) ;
181+ logger . info ( ` - Summaries: ${ health . database . connection . collections . summaries . count } ` ) ;
182+ }
183+ } else {
184+ // Fully healthy - log success and collection stats
185+ logger . info ( '✅ [Startup] Memory Core health check passed' ) ;
186+ if ( health . database . connection . collections ) {
187+ logger . info ( ` - Memories: ${ health . database . connection . collections . memories . count } ` ) ;
188+ logger . info ( ` - Summaries: ${ health . database . connection . collections . summaries . count } ` ) ;
189+ }
190+
191+ // Only auto-summarize if we're fully healthy
192+ if ( health . features . summarization ) {
193+ // Run summarization asynchronously (non-blocking)
194+ summarizeSessionsOnStartup ( ) . catch ( err => {
195+ // Error already logged in summarizeSessionsOnStartup
196+ } ) ;
197+ } else {
198+ logger . warn ( '⚠️ [Startup] GEMINI_API_KEY not set - skipping automatic session summarization' ) ;
199+ logger . warn ( ' Set GEMINI_API_KEY environment variable to enable summarization features' ) ;
200+ }
201+ }
202+
203+ // Start the stdio transport
100204 const transport = new StdioServerTransport ( ) ;
101205 await server . connect ( transport ) ;
102206
103- // Log to stderr (stdout is reserved for MCP protocol)
104207 logger . info ( '[neo-memory-core MCP] Server started on stdio transport' ) ;
105208 logger . info ( '[neo-memory-core MCP] Available tools loaded from OpenAPI spec' ) ;
106209}
0 commit comments