@@ -246,38 +246,47 @@ app.get('/health', (_req, res) => res.json({ status: 'healthy', mcp: 'sse', time
246246// In-memory session store: sessionId -> { transport, server, res, heartbeat }
247247const sessions = new Map ( ) ;
248248
249- // Helper: validate and extract Bearer token
250- function getBearerToken ( req ) {
249+ // Helper: validate and extract token from multiple sources
250+ function getAuthToken ( req ) {
251251 const auth = req . headers [ 'authorization' ] || '' ;
252252 const m = auth . match ( / ^ B e a r e r \s + ( .+ ) $ / i) ;
253- return m ? m [ 1 ] : undefined ;
253+ return (
254+ ( m ? m [ 1 ] : undefined ) ||
255+ req . headers [ 'x-api-key' ] ||
256+ req . query . api_key ||
257+ process . env . AUTOMEM_API_TOKEN
258+ ) ;
254259}
255260
256261// SSE endpoint
257262app . get ( '/mcp/sse' , async ( req , res ) => {
258263 try {
259264 const endpoint = process . env . AUTOMEM_ENDPOINT || 'http://127.0.0.1:8001' ;
260- const token = getBearerToken ( req ) ;
265+ const token = getAuthToken ( req ) ;
261266 if ( ! endpoint ) return res . status ( 500 ) . json ( { error : 'AUTOMEM_ENDPOINT not configured' } ) ;
262- if ( ! token ) return res . status ( 401 ) . json ( { error : 'Missing Authorization Bearer token ' } ) ;
267+ if ( ! token ) return res . status ( 401 ) . json ( { error : 'Missing API token (use Authorization: Bearer, X-API-Key, or ?api_key=) ' } ) ;
263268
264269 const client = new AutoMemClient ( { endpoint, apiKey : token } ) ;
265270 const server = buildMcpServer ( client ) ;
271+ // Help with proxy buffering before SSE headers are written
272+ res . set ( 'X-Accel-Buffering' , 'no' ) ;
273+ res . set ( 'Cache-Control' , 'no-cache, no-transform' ) ;
266274 const transport = new SSEServerTransport ( '/mcp/messages' , res ) ;
267275 await server . connect ( transport ) ;
268- await transport . start ( ) ;
269276
270- // Heartbeat to keep proxies from closing idle streams
277+ // Prepare session and lifecycle BEFORE sending the endpoint event to avoid race
271278 const heartbeat = setInterval ( ( ) => {
272279 try { res . write ( ': ping\n\n' ) ; } catch ( _ ) { /* ignore */ }
273280 } , 20000 ) ;
274-
275281 res . on ( 'close' , ( ) => {
276282 clearInterval ( heartbeat ) ;
277283 sessions . delete ( transport . sessionId ) ;
278284 } ) ;
279-
280285 sessions . set ( transport . sessionId , { transport, server, res, heartbeat } ) ;
286+ console . log ( `[MCP] New SSE session established: ${ transport . sessionId } ` ) ;
287+
288+ // Now start SSE (writes event: endpoint)
289+ await transport . start ( ) ;
281290 } catch ( e ) {
282291 try { res . status ( 500 ) . json ( { error : String ( e ) } ) ; } catch ( _ ) { /* ignore */ }
283292 }
@@ -288,10 +297,14 @@ app.post('/mcp/messages', async (req, res) => {
288297 const sessionId = req . query . sessionId ;
289298 if ( ! sessionId || typeof sessionId !== 'string' ) return res . status ( 400 ) . send ( 'Missing sessionId' ) ;
290299 const s = sessions . get ( sessionId ) ;
291- if ( ! s ) return res . status ( 404 ) . send ( 'Session not found' ) ;
300+ if ( ! s ) {
301+ console . warn ( `[MCP] POST for unknown session: ${ sessionId } ` ) ;
302+ return res . status ( 404 ) . send ( 'Session not found' ) ;
303+ }
292304 try {
293305 await s . transport . handlePostMessage ( req , res , req . body ) ;
294306 } catch ( e ) {
307+ console . error ( `[MCP] Error handling message for session ${ sessionId } :` , e ) ;
295308 try { res . status ( 400 ) . send ( String ( e ) ) ; } catch ( _ ) { /* ignore */ }
296309 }
297310} ) ;
@@ -300,4 +313,3 @@ const port = process.env.PORT || 8080;
300313app . listen ( port , ( ) => {
301314 console . log ( `AutoMem MCP SSE server listening on :${ port } ` ) ;
302315} ) ;
303-
0 commit comments