Skip to main content
Glama

1MCP Server

http-sessions.test.ts13.1 kB
import { ConfigBuilder, ProtocolValidator, TestProcessManager } from '@test/e2e/utils/index.js'; import { join } from 'path'; import { afterEach, beforeEach, describe, expect, it } from 'vitest'; describe('HTTP Session Management Infrastructure E2E', () => { let processManager: TestProcessManager; let configBuilder: ConfigBuilder; let configPath: string; beforeEach(async () => { processManager = new TestProcessManager(); configBuilder = new ConfigBuilder(); const fixturesPath = join(__dirname, '../fixtures'); configPath = configBuilder .enableHttpTransport(3000) .enableAuth('test-client-id', 'test-client-secret') .addStdioServer('echo-server', 'node', [join(fixturesPath, 'echo-server.js')], ['test', 'echo']) .writeToFile(); }); afterEach(async () => { await processManager.cleanup(); configBuilder.cleanup(); }); it('should create valid session management configuration', async () => { // Test that session configuration builds correctly expect(configPath).toBeDefined(); expect(configPath.endsWith('.json')).toBe(true); const config = configBuilder.build(); // Just validate that configuration is created without specific structure requirements expect(config).toBeDefined(); expect(config.servers).toBeDefined(); expect(Array.isArray(config.servers)).toBe(true); expect(config.auth).toBeDefined(); }); it('should validate session data structures', async () => { // Test session object structure const sessionData = { session_id: 'sess_abc123', user_id: 'user_123', client_id: 'test-client-id', scopes: ['mcp:read', 'mcp:write'], created_at: Date.now(), expires_at: Date.now() + 3600000, // 1 hour metadata: { user_agent: 'test-client/1.0', ip_address: '127.0.0.1', device_type: 'desktop', }, }; expect(sessionData.session_id).toMatch(/^sess_[a-zA-Z0-9]+$/); expect(sessionData.user_id).toMatch(/^user_\d+$/); expect(Array.isArray(sessionData.scopes)).toBe(true); expect(sessionData.expires_at).toBeGreaterThan(sessionData.created_at); expect(sessionData.metadata).toBeDefined(); }); it('should validate OAuth 2.1 session creation request', async () => { // Test OAuth session creation request structure const sessionRequest = { client_id: 'test-client-id', user_id: 'test-user-123', scopes: ['mcp:read', 'mcp:write'], expires_in: 3600, metadata: { device_id: 'device-123', user_agent: 'test-app/1.0', }, }; expect(sessionRequest.client_id).toBe('test-client-id'); expect(sessionRequest.user_id).toBe('test-user-123'); expect(sessionRequest.scopes).toContain('mcp:read'); expect(typeof sessionRequest.expires_in).toBe('number'); expect(sessionRequest.metadata.device_id).toBeDefined(); }); it('should validate session expiration handling', async () => { // Test session expiration logic const currentTime = Date.now(); const sessions = [ { session_id: 'sess1', expires_at: currentTime + 1000 }, // Valid { session_id: 'sess2', expires_at: currentTime - 1000 }, // Expired { session_id: 'sess3', expires_at: currentTime + 3600000 }, // Valid ]; const validSessions = sessions.filter((s) => s.expires_at > currentTime); const expiredSessions = sessions.filter((s) => s.expires_at <= currentTime); expect(validSessions).toHaveLength(2); expect(expiredSessions).toHaveLength(1); expect(expiredSessions[0].session_id).toBe('sess2'); }); it('should handle session-based authentication patterns', async () => { // Test session authentication request structure const authenticatedRequest = { headers: { 'X-Session-ID': 'sess_abc123', 'Content-Type': 'application/json', }, method: 'POST', body: { jsonrpc: '2.0', id: 1, method: 'tools/list', }, }; expect(authenticatedRequest.headers['X-Session-ID']).toMatch(/^sess_[a-zA-Z0-9]+$/); const validation = ProtocolValidator.validateRequest(authenticatedRequest.body); expect(validation.valid).toBe(true); }); it('should validate concurrent session management', async () => { // Test multiple sessions for the same user const user = 'test-user-123'; const sessions = [ { session_id: 'sess_device1', user_id: user, device_id: 'device-1', scopes: ['mcp:read'], }, { session_id: 'sess_device2', user_id: user, device_id: 'device-2', scopes: ['mcp:read', 'mcp:write'], }, { session_id: 'sess_device3', user_id: user, device_id: 'device-3', scopes: ['mcp:read'], }, ]; const userSessions = sessions.filter((s) => s.user_id === user); const uniqueDevices = new Set(sessions.map((s) => s.device_id)); expect(userSessions).toHaveLength(3); expect(uniqueDevices.size).toBe(3); // Each session should have unique ID const sessionIds = sessions.map((s) => s.session_id); const uniqueSessionIds = new Set(sessionIds); expect(uniqueSessionIds.size).toBe(3); }); it('should handle session revocation patterns', async () => { // Test session revocation request const revocationRequest = { session_id: 'sess_abc123', reason: 'user_logout', revoked_by: 'user', revoked_at: Date.now(), }; expect(revocationRequest.session_id).toMatch(/^sess_[a-zA-Z0-9]+$/); expect(['user_logout', 'admin_revoke', 'security_breach', 'timeout']).toContain(revocationRequest.reason); expect(['user', 'admin', 'system']).toContain(revocationRequest.revoked_by); expect(typeof revocationRequest.revoked_at).toBe('number'); }); it('should validate session scope authorization', async () => { // Test scope validation logic const session = { scopes: ['mcp:read', 'mcp:admin'], }; const operations = [ { operation: 'tools/list', required_scope: 'mcp:read', allowed: true }, { operation: 'tools/call', required_scope: 'mcp:write', allowed: false }, { operation: 'servers/restart', required_scope: 'mcp:admin', allowed: true }, { operation: 'config/reload', required_scope: 'mcp:admin', allowed: true }, ]; operations.forEach((op) => { const hasScope = session.scopes.includes(op.required_scope); expect(hasScope).toBe(op.allowed); }); }); it('should handle session refresh mechanisms', async () => { // Test session refresh structure const refreshRequest = { session_id: 'sess_abc123', extend_by: 3600, // Extend by 1 hour preserve_metadata: true, }; const refreshResponse = { session_id: 'sess_abc123', new_expires_at: Date.now() + 3600000, extended_by: 3600000, success: true, }; expect(refreshRequest.session_id).toMatch(/^sess_[a-zA-Z0-9]+$/); expect(typeof refreshRequest.extend_by).toBe('number'); expect(refreshResponse.new_expires_at).toBeGreaterThan(Date.now()); expect(refreshResponse.success).toBe(true); }); it('should validate session metadata management', async () => { // Test session metadata structure const metadata = { user_agent: 'Mozilla/5.0 (compatible; TestClient/1.0)', ip_address: '192.168.1.100', device_type: 'mobile', device_os: 'iOS 15.0', app_version: '2.1.0', login_method: 'oauth', security_level: 'standard', last_activity: Date.now(), }; expect(metadata.user_agent).toContain('TestClient'); expect(metadata.ip_address).toMatch(/^\d+\.\d+\.\d+\.\d+$/); expect(['desktop', 'mobile', 'tablet', 'server']).toContain(metadata.device_type); expect(['oauth', 'password', 'sso', 'api_key']).toContain(metadata.login_method); expect(['basic', 'standard', 'high', 'critical']).toContain(metadata.security_level); }); it('should handle session listing and filtering', async () => { // Test session listing request structure const listRequest = { user_id: 'test-user-123', active_only: true, device_type: 'mobile', limit: 10, offset: 0, }; const listResponse = { sessions: [ { session_id: 'sess_1', user_id: 'test-user-123', device_type: 'mobile', active: true, created_at: Date.now() - 3600000, }, ], total_count: 1, has_more: false, }; expect(listRequest.user_id).toBe('test-user-123'); expect(typeof listRequest.active_only).toBe('boolean'); expect(Array.isArray(listResponse.sessions)).toBe(true); expect(typeof listResponse.total_count).toBe('number'); expect(typeof listResponse.has_more).toBe('boolean'); }); it('should validate session security patterns', async () => { // Test security-related session data const securityContext = { session_id: 'sess_abc123', security_checks: { ip_validation: true, device_fingerprint: true, rate_limiting: true, suspicious_activity: false, }, risk_score: 0.2, // Low risk blocked_actions: [], security_events: [ { event_type: 'login_success', timestamp: Date.now(), details: 'Normal login from recognized device', }, ], }; expect(securityContext.risk_score).toBeGreaterThanOrEqual(0); expect(securityContext.risk_score).toBeLessThanOrEqual(1); expect(Array.isArray(securityContext.blocked_actions)).toBe(true); expect(Array.isArray(securityContext.security_events)).toBe(true); expect(securityContext.security_checks.ip_validation).toBe(true); }); it('should handle session cleanup and garbage collection', async () => { // Test session cleanup configuration const cleanupConfig = { enabled: true, cleanup_interval: 300000, // 5 minutes expired_session_retention: 86400000, // 24 hours max_sessions_per_user: 10, inactive_threshold: 1800000, // 30 minutes }; const cleanupResult = { expired_sessions_removed: 15, inactive_sessions_removed: 3, total_sessions_before: 150, total_sessions_after: 132, cleanup_duration: 1250, }; expect(cleanupConfig.cleanup_interval).toBeGreaterThan(0); expect(cleanupResult.total_sessions_after).toBeLessThan(cleanupResult.total_sessions_before); expect(cleanupResult.expired_sessions_removed).toBeGreaterThanOrEqual(0); expect(typeof cleanupResult.cleanup_duration).toBe('number'); }); it('should validate session error handling', async () => { // Test session error responses const sessionErrors = [ { error_code: 'SESSION_NOT_FOUND', message: 'Session with ID sess_invalid does not exist', status_code: 404, }, { error_code: 'SESSION_EXPIRED', message: 'Session has expired', status_code: 401, }, { error_code: 'INSUFFICIENT_SCOPE', message: 'Session does not have required scope: mcp:admin', status_code: 403, }, { error_code: 'SESSION_SUSPENDED', message: 'Session has been suspended due to security concerns', status_code: 403, }, ]; sessionErrors.forEach((error) => { expect(error.error_code).toMatch(/^[A-Z_]+$/); expect(error.message).toBeDefined(); expect([400, 401, 403, 404, 500]).toContain(error.status_code); }); }); it('should handle session analytics and monitoring', async () => { // Test session analytics data structure const analytics = { active_sessions: 42, total_sessions_today: 156, average_session_duration: 2400000, // 40 minutes sessions_by_device_type: { desktop: 25, mobile: 15, tablet: 2, }, sessions_by_scope: { 'mcp:read': 40, 'mcp:write': 30, 'mcp:admin': 5, }, peak_concurrent_sessions: 67, session_creation_rate: 0.5, // per minute }; expect(analytics.active_sessions).toBeGreaterThan(0); expect(analytics.total_sessions_today).toBeGreaterThanOrEqual(analytics.active_sessions); expect(analytics.average_session_duration).toBeGreaterThan(0); expect(analytics.sessions_by_device_type.desktop).toBeGreaterThan(0); expect(analytics.peak_concurrent_sessions).toBeGreaterThanOrEqual(analytics.active_sessions); }); it('should validate process management for session handling', async () => { // Test session-related process management const processInfo = await processManager.startProcess('test-session-process', { command: 'sleep', args: ['1'], }); expect(processInfo.pid).toBeGreaterThan(0); expect(processManager.isProcessRunning('test-session-process')).toBe(true); await processManager.stopProcess('test-session-process'); expect(processManager.isProcessRunning('test-session-process')).toBe(false); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/1mcp-app/agent'

If you have feedback or need assistance with the MCP directory API, please join our Discord server