@@ -9,7 +9,6 @@ import { PublishEventRequestEventTypeEnum } from "mcpcat-api";
99import { publishEvent } from "./eventQueue.js" ;
1010import { getMCPCompatibleErrorMessage } from "./compatibility.js" ;
1111import { writeToLog } from "./logging.js" ;
12- import { INACTIVITY_TIMEOUT_IN_MINUTES } from "./constants.js" ;
1312
1413/**
1514 * Simple LRU cache for session identities.
@@ -66,66 +65,6 @@ class IdentityCache {
6665// This prevents duplicate identify events when server objects are recreated
6766const _globalIdentityCache = new IdentityCache ( 1000 ) ;
6867
69- /**
70- * Maps userId to recent session IDs for reconnection support.
71- * When a user reconnects (new initialize without MCP sessionId),
72- * we can reuse their previous session if it's recent enough.
73- */
74- class UserSessionCache {
75- private cache : Map < string , { sessionId : string ; lastSeen : number } > ;
76- private maxSize : number ;
77-
78- constructor ( maxSize : number = 1000 ) {
79- this . cache = new Map ( ) ;
80- this . maxSize = maxSize ;
81- }
82-
83- getRecentSession ( userId : string , timeoutMs : number ) : string | undefined {
84- const entry = this . cache . get ( userId ) ;
85- if ( ! entry ) return undefined ;
86-
87- // Check if session has expired
88- if ( Date . now ( ) - entry . lastSeen > timeoutMs ) {
89- this . cache . delete ( userId ) ;
90- return undefined ;
91- }
92-
93- return entry . sessionId ;
94- }
95-
96- set ( userId : string , sessionId : string ) : void {
97- // Remove if already exists (to re-add at end for LRU)
98- this . cache . delete ( userId ) ;
99-
100- // Evict oldest if at capacity
101- if ( this . cache . size >= this . maxSize ) {
102- const oldestKey = this . cache . keys ( ) . next ( ) . value ;
103- if ( oldestKey !== undefined ) {
104- this . cache . delete ( oldestKey ) ;
105- }
106- }
107-
108- this . cache . set ( userId , { sessionId, lastSeen : Date . now ( ) } ) ;
109- }
110- }
111-
112- // Global user session cache for reconnection support
113- const _globalUserSessionCache = new UserSessionCache ( 1000 ) ;
114-
115- /**
116- * FOR TESTING ONLY: Manually set a user session cache entry with custom lastSeen timestamp
117- */
118- export function _testSetUserSession (
119- userId : string ,
120- sessionId : string ,
121- lastSeenMs : number ,
122- ) : void {
123- ( _globalUserSessionCache as any ) . cache . set ( userId , {
124- sessionId,
125- lastSeen : lastSeenMs ,
126- } ) ;
127- }
128-
12968// Internal tracking storage
13069const _serverTracking = new WeakMap < MCPServerLike , MCPCatData > ( ) ;
13170
@@ -224,64 +163,6 @@ export async function handleIdentify(
224163 try {
225164 const identityResult = await data . options . identify ( request , extra ) ;
226165 if ( identityResult ) {
227- // Check for session reconnection (if no MCP sessionId provided in extra)
228- // If this user had a recent session, switch to it instead of creating new one
229- if ( ! extra ?. sessionId && identityResult . userId ) {
230- const timeoutMs = INACTIVITY_TIMEOUT_IN_MINUTES * 60 * 1000 ;
231- const previousSessionId = _globalUserSessionCache . getRecentSession (
232- identityResult . userId ,
233- timeoutMs ,
234- ) ;
235-
236- if ( previousSessionId && previousSessionId !== data . sessionId ) {
237- // User has a previous session - reconnect to it
238- const currentSessionIdentity = _globalIdentityCache . get (
239- data . sessionId ,
240- ) ;
241-
242- if ( ! currentSessionIdentity ) {
243- // Current session is brand new (no identity) - reconnect to previous session
244- data . sessionId = previousSessionId ;
245- data . lastActivity = new Date ( ) ;
246- setServerTrackingData ( server , data ) ;
247-
248- writeToLog (
249- `Reconnected user ${ identityResult . userId } to previous session ${ previousSessionId } (current session was new)` ,
250- ) ;
251- } else if ( currentSessionIdentity . userId !== identityResult . userId ) {
252- // Current session belongs to different user - reconnect to user's previous session
253- data . sessionId = previousSessionId ;
254- data . lastActivity = new Date ( ) ;
255- setServerTrackingData ( server , data ) ;
256-
257- writeToLog (
258- `Reconnected user ${ identityResult . userId } to previous session ${ previousSessionId } ` ,
259- ) ;
260- }
261- // If current session already belongs to this user, no need to do anything
262- } else if ( ! previousSessionId ) {
263- // User has NO previous session - check if current session belongs to someone else
264- const currentSessionIdentity = _globalIdentityCache . get (
265- data . sessionId ,
266- ) ;
267- if (
268- currentSessionIdentity &&
269- currentSessionIdentity . userId !== identityResult . userId
270- ) {
271- // Current session belongs to different user - create new session
272- const { newSessionId } = await import ( "./session.js" ) ;
273- data . sessionId = newSessionId ( ) ;
274- data . sessionSource = "mcpcat" ;
275- data . lastActivity = new Date ( ) ;
276- setServerTrackingData ( server , data ) ;
277-
278- writeToLog (
279- `Created new session ${ data . sessionId } for user ${ identityResult . userId } (previous session belonged to ${ currentSessionIdentity . userId } )` ,
280- ) ;
281- }
282- }
283- }
284-
285166 // Now use the (possibly updated) sessionId for all subsequent operations
286167 const currentSessionId = data . sessionId ;
287168
@@ -302,9 +183,6 @@ export async function handleIdentify(
302183 // Per-server cache: used by getSessionInfo() for fast local access
303184 data . identifiedSessions . set ( data . sessionId , mergedIdentity ) ;
304185
305- // Track userId → sessionId mapping for reconnection support
306- _globalUserSessionCache . set ( mergedIdentity . userId , currentSessionId ) ;
307-
308186 if ( hasChanged ) {
309187 writeToLog (
310188 `Identified session ${ currentSessionId } with identity: ${ JSON . stringify ( mergedIdentity ) } ` ,
0 commit comments