UNPKG

mcp-cve-intelligence-server-lite-test

Version:

Lite Model Context Protocol server for comprehensive CVE intelligence gathering with multi-source exploit discovery, designed for security professionals and cybersecurity researchers - Alpha Release

169 lines 5.03 kB
import { createContextLogger } from '../utils/logger.js'; const logger = createContextLogger('TransportSessionManager'); export class TransportSessionManager { sessions = new Map(); sessionTimeout; constructor(sessionTimeoutMs = 30 * 60 * 1000) { this.sessionTimeout = sessionTimeoutMs; this.startCleanupInterval(); } /** * Create a new session */ createSession(sessionId, transportType, metadata) { const sessionInfo = { sessionId, transportType, createdAt: new Date(), lastActivity: new Date(), metadata, }; this.sessions.set(sessionId, sessionInfo); logger.info('Session created', { sessionId, transportType, totalSessions: this.sessions.size, }); } /** * Update session activity */ updateSessionActivity(sessionId) { const session = this.sessions.get(sessionId); if (session) { session.lastActivity = new Date(); } } /** * Remove a session */ removeSession(sessionId) { const removed = this.sessions.delete(sessionId); if (removed) { logger.info('Session removed', { sessionId, totalSessions: this.sessions.size, }); } return removed; } /** * Get session information */ getSession(sessionId) { return this.sessions.get(sessionId); } /** * Get all active sessions */ getAllSessions() { return Array.from(this.sessions.values()); } /** * Get sessions by transport type */ getSessionsByType(transportType) { return Array.from(this.sessions.values()).filter(s => s.transportType === transportType); } /** * Get session count */ getSessionCount() { return this.sessions.size; } /** * Get session count by transport type */ getSessionCountByType(transportType) { return this.getSessionsByType(transportType).length; } /** * Check if a session exists */ hasSession(sessionId) { return this.sessions.has(sessionId); } /** * Clean up expired sessions */ cleanupExpiredSessions() { const now = new Date(); const expiredSessions = []; for (const [sessionId, session] of this.sessions) { const timeSinceActivity = now.getTime() - session.lastActivity.getTime(); if (timeSinceActivity > this.sessionTimeout) { expiredSessions.push(sessionId); } } for (const sessionId of expiredSessions) { this.removeSession(sessionId); } if (expiredSessions.length > 0) { logger.info('Cleaned up expired sessions', { expiredCount: expiredSessions.length, remainingSessions: this.sessions.size, }); } return expiredSessions.length; } /** * Get session statistics */ getSessionStats() { const sessions = this.getAllSessions(); const now = new Date(); if (sessions.length === 0) { return { total: 0, byType: { stdio: 0, http: 0 }, averageAge: 0, }; } const byType = sessions.reduce((acc, session) => { acc[session.transportType] = (acc[session.transportType] || 0) + 1; return acc; }, {}); const ages = sessions.map(s => now.getTime() - s.createdAt.getTime()); const averageAge = ages.reduce((sum, age) => sum + age, 0) / ages.length; const sortedByCreation = sessions.sort((a, b) => a.createdAt.getTime() - b.createdAt.getTime()); return { total: sessions.length, byType, oldestSession: sortedByCreation[0]?.createdAt, newestSession: sortedByCreation[sortedByCreation.length - 1]?.createdAt, averageAge, }; } /** * Start the cleanup interval */ startCleanupInterval() { // Run cleanup every 10 minutes setInterval(() => { this.cleanupExpiredSessions(); }, 10 * 60 * 1000); logger.info('Session cleanup interval started', { intervalMs: 10 * 60 * 1000, timeoutMs: this.sessionTimeout, }); } /** * Set session metadata */ setSessionMetadata(sessionId, metadata) { const session = this.sessions.get(sessionId); if (session) { session.metadata = { ...session.metadata, ...metadata }; this.updateSessionActivity(sessionId); return true; } return false; } /** * Get session metadata */ getSessionMetadata(sessionId) { return this.sessions.get(sessionId)?.metadata; } } //# sourceMappingURL=transport-session-manager.js.map