Skip to content

Commit 2446be3

Browse files
committed
fix: revert actor corellation changes for sessions identification
1 parent 5e36d5f commit 2446be3

File tree

5 files changed

+9
-1048
lines changed

5 files changed

+9
-1048
lines changed

src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ function track(
179179
identify: options.identify,
180180
redactSensitiveInformation: options.redactSensitiveInformation,
181181
},
182-
sessionSource: "mcpcat", // Initially MCPCat-generated, will change to "mcp" if MCP sessionId is provided
182+
sessionSource: "mcpcat", // Initially MCPCat-generated, will change to "mcp" if MCP sessionId is provided in requests
183183
};
184184

185185
setServerTrackingData(lowLevelServer, mcpcatData);

src/modules/internal.ts

Lines changed: 0 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import { PublishEventRequestEventTypeEnum } from "mcpcat-api";
99
import { publishEvent } from "./eventQueue.js";
1010
import { getMCPCompatibleErrorMessage } from "./compatibility.js";
1111
import { 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
6766
const _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
13069
const _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)}`,

src/modules/session.ts

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -69,17 +69,14 @@ export function getServerSessionId(
6969

7070
// If MCP sessionId is provided
7171
if (mcpSessionId) {
72-
// Check if it's a new or changed MCP sessionId
73-
if (mcpSessionId !== data.lastMcpSessionId) {
74-
// Derive deterministic KSUID from MCP sessionId
75-
data.sessionId = deriveSessionIdFromMCPSession(
76-
mcpSessionId,
77-
data.projectId || undefined,
78-
);
79-
data.lastMcpSessionId = mcpSessionId;
80-
data.sessionSource = "mcp";
81-
setServerTrackingData(server, data);
82-
}
72+
// Derive deterministic KSUID from MCP sessionId
73+
data.sessionId = deriveSessionIdFromMCPSession(
74+
mcpSessionId,
75+
data.projectId || undefined,
76+
);
77+
data.lastMcpSessionId = mcpSessionId;
78+
data.sessionSource = "mcp";
79+
setServerTrackingData(server, data);
8380
// If MCP sessionId hasn't changed, continue using the existing derived KSUID
8481
setLastActivity(server);
8582
return data.sessionId;

0 commit comments

Comments
 (0)