@mcp-ts/sdk 1.3.4 → 1.3.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +404 -400
- package/dist/adapters/agui-adapter.d.mts +1 -1
- package/dist/adapters/agui-adapter.d.ts +1 -1
- package/dist/adapters/agui-middleware.d.mts +1 -1
- package/dist/adapters/agui-middleware.d.ts +1 -1
- package/dist/adapters/ai-adapter.d.mts +1 -1
- package/dist/adapters/ai-adapter.d.ts +1 -1
- package/dist/adapters/langchain-adapter.d.mts +1 -1
- package/dist/adapters/langchain-adapter.d.ts +1 -1
- package/dist/adapters/mastra-adapter.d.mts +1 -1
- package/dist/adapters/mastra-adapter.d.ts +1 -1
- package/dist/client/index.d.mts +1 -0
- package/dist/client/index.d.ts +1 -0
- package/dist/client/index.js +14 -5
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +14 -5
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/react.js +15 -6
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +15 -6
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.js +15 -6
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +15 -6
- package/dist/client/vue.mjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +201 -158
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +201 -158
- package/dist/index.mjs.map +1 -1
- package/dist/{multi-session-client-FAFpUzZ4.d.ts → multi-session-client-BYLarghq.d.ts} +29 -19
- package/dist/{multi-session-client-DzjmT7FX.d.mts → multi-session-client-CzhMkE0k.d.mts} +29 -19
- package/dist/server/index.d.mts +1 -1
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.js +193 -151
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +193 -151
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +2 -2
- package/dist/shared/index.d.ts +2 -2
- package/dist/shared/index.js +2 -2
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs +2 -2
- package/dist/shared/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/client/core/sse-client.ts +371 -354
- package/src/client/react/use-mcp.ts +31 -31
- package/src/client/vue/use-mcp.ts +77 -77
- package/src/server/handlers/nextjs-handler.ts +194 -197
- package/src/server/handlers/sse-handler.ts +62 -111
- package/src/server/mcp/oauth-client.ts +67 -79
- package/src/server/mcp/storage-oauth-provider.ts +71 -38
- package/src/server/storage/index.ts +15 -13
- package/src/server/storage/redis-backend.ts +93 -23
- package/src/server/storage/types.ts +12 -12
- package/src/shared/constants.ts +2 -2
- package/src/shared/event-routing.ts +28 -0
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server/storage/redis.ts","../src/shared/constants.ts","../src/server/storage/redis-backend.ts","../src/server/storage/memory-backend.ts","../src/server/storage/file-backend.ts","../src/server/storage/sqlite-backend.ts","../src/server/storage/index.ts","../src/server/mcp/storage-oauth-provider.ts","../src/shared/utils.ts","../src/shared/events.ts","../src/shared/errors.ts","../src/server/mcp/oauth-client.ts","../src/server/mcp/multi-session-client.ts","../src/server/handlers/sse-handler.ts","../src/server/handlers/nextjs-handler.ts","../src/client/core/sse-client.ts","../src/client/core/app-host.ts","../src/shared/types.ts","../src/shared/tool-utils.ts"],"names":["customAlphabet","redis","firstChar","rest","path","fs","path2","fs2","getRedis","nanoid","SSEClientTransport","StreamableHTTPClientTransport","Client","SDKUnauthorizedError","ListToolsResultSchema","CallToolResultSchema","ListPromptsResultSchema","GetPromptResultSchema","ListResourcesResultSchema","ReadResourceResultSchema","discoverOAuthProtectedResourceMetadata","discoverAuthorizationServerMetadata","refreshAuthorization","manager","data","AppBridge","PostMessageTransport"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Redis connection management with dependency injection support\r\n * Allows configuration and testing without environment variables\r\n */\r\nimport type { Redis } from 'ioredis';\r\n\r\nexport interface RedisConfig {\r\n /**\r\n * Redis connection URL (defaults to REDIS_URL env var)\r\n */\r\n url?: string;\r\n\r\n /**\r\n * Enable lazy connection (default: true)\r\n */\r\n lazyConnect?: boolean;\r\n\r\n /**\r\n * Maximum retries per request (default: 1)\r\n */\r\n maxRetriesPerRequest?: number;\r\n\r\n /**\r\n * Enable verbose logging (default: false)\r\n */\r\n verbose?: boolean;\r\n /**\r\n * @internal For testing only - bypass ioredis import\r\n */\r\n RedisConstructor?: any;\r\n}\r\n\r\ndeclare global {\r\n // eslint-disable-next-line no-var\r\n var __redis: Redis | undefined;\r\n var __redisConfig: RedisConfig | undefined;\r\n}\r\n\r\nlet redisInstance: Redis | null = null;\r\n\r\n/**\r\n * Initialize Redis with custom configuration\r\n * Call this before any Redis operations if you need custom config\r\n * @param config - Redis configuration options\r\n */\r\nexport async function initRedis(config: RedisConfig): Promise<Redis> {\r\n if (redisInstance) {\r\n // Already initialized, return existing instance\r\n return redisInstance;\r\n }\r\n\r\n const url = config.url ?? process.env.REDIS_URL;\r\n\r\n if (!url) {\r\n throw new Error(\r\n 'Redis URL is required. Set REDIS_URL environment variable or pass url in config.'\r\n );\r\n }\r\n\r\n let Redis: typeof import('ioredis').Redis;\r\n if (config.RedisConstructor) {\r\n Redis = config.RedisConstructor;\r\n } else {\r\n try {\r\n const ioredis = await import('ioredis');\r\n Redis = ioredis.Redis;\r\n } catch (error) {\r\n throw new Error(\r\n 'ioredis is not installed. Install it with:\\n' +\r\n ' npm install ioredis\\n\\n' +\r\n 'Or use a different storage backend:\\n' +\r\n ' MCP_TS_STORAGE_TYPE=memory (for development)\\n' +\r\n ' MCP_TS_STORAGE_TYPE=file (for local persistence)'\r\n );\r\n }\r\n }\r\n\r\n redisInstance = new Redis(url, {\r\n lazyConnect: config.lazyConnect ?? true,\r\n maxRetriesPerRequest: config.maxRetriesPerRequest ?? 1,\r\n });\r\n\r\n if (config.verbose !== false) {\r\n redisInstance.on('ready', () => {\r\n console.log('✅ Redis connected');\r\n });\r\n\r\n redisInstance.on('error', (err) => {\r\n console.error('❌ Redis error:', err.message);\r\n });\r\n\r\n redisInstance.on('reconnecting', () => {\r\n console.log('🔄 Redis reconnecting...');\r\n });\r\n }\r\n\r\n // Store globally for hot reloading scenarios\r\n global.__redis = redisInstance;\r\n global.__redisConfig = config;\r\n\r\n return redisInstance;\r\n}\r\n\r\n/**\r\n * Get the Redis instance\r\n * Automatically initializes with default config if not already initialized\r\n */\r\nexport async function getRedis(): Promise<Redis> {\r\n if (redisInstance) {\r\n return redisInstance;\r\n }\r\n\r\n // Check for existing global instance (hot reload scenario)\r\n if (global.__redis) {\r\n redisInstance = global.__redis;\r\n return redisInstance;\r\n }\r\n\r\n // Initialize with default config\r\n return await initRedis({});\r\n}\r\n\r\n/**\r\n * Set a custom Redis instance (useful for testing with mocks)\r\n * @param instance - Redis instance or mock\r\n */\r\nexport function setRedisInstance(instance: Redis): void {\r\n redisInstance = instance;\r\n global.__redis = instance;\r\n}\r\n\r\n/**\r\n * Close Redis connection and clear instance\r\n */\r\nexport async function closeRedis(): Promise<void> {\r\n if (redisInstance) {\r\n await redisInstance.quit();\r\n redisInstance = null;\r\n global.__redis = undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Default Redis export for backward compatibility\r\n * Will auto-initialize on first access\r\n * Note: This is a lazy proxy that initializes Redis on first method call\r\n */\r\nexport const redis = new Proxy({} as Redis, {\r\n get(_target, prop) {\r\n // Return a function that handles async initialization\r\n return async (...args: any[]) => {\r\n const instance = await getRedis();\r\n const value = (instance as any)[prop];\r\n if (typeof value === 'function') {\r\n return value.apply(instance, args);\r\n }\r\n return value;\r\n };\r\n },\r\n});\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.png';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.0.0-beta.5';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","\r\nimport type { Redis } from 'ioredis';\r\nimport { customAlphabet } from 'nanoid';\r\nimport { StorageBackend, SessionData, SetClientOptions } from './types';\r\nimport { SESSION_TTL_SECONDS } from '../../shared/constants.js';\r\n\r\n/** first char: letters only (required by OpenAI) */\r\nconst firstChar = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\r\n 1\r\n);\r\n\r\n/** remaining chars: alphanumeric */\r\nconst rest = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\r\n 11\r\n);\r\n\r\n/**\r\n * Redis implementation of StorageBackend\r\n */\r\nexport class RedisStorageBackend implements StorageBackend {\r\n private readonly DEFAULT_TTL = SESSION_TTL_SECONDS;\r\n private readonly KEY_PREFIX = 'mcp:session:';\r\n\r\n constructor(private redis: Redis) { }\r\n\r\n /**\r\n * Generates Redis key for a specific session\r\n * @private\r\n */\r\n private getSessionKey(identity: string, sessionId: string): string {\r\n return `${this.KEY_PREFIX}${identity}:${sessionId}`;\r\n }\r\n\r\n /**\r\n * Generates Redis key for tracking all sessions for an identity\r\n * @private\r\n */\r\n private getIdentityKey(identity: string): string {\r\n return `mcp:identity:${identity}:sessions`;\r\n }\r\n\r\n generateSessionId(): string {\r\n return firstChar() + rest();\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n const { sessionId, identity } = session;\r\n if (!sessionId || !identity) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const identityKey = this.getIdentityKey(identity);\r\n const effectiveTtl = ttl ?? this.DEFAULT_TTL;\r\n\r\n /** ioredis syntax: set(key, val, 'EX', ttl, 'NX') */\r\n const result = await this.redis.set(\r\n sessionKey,\r\n JSON.stringify(session),\r\n 'EX',\r\n effectiveTtl,\r\n 'NX'\r\n );\r\n\r\n if (result !== 'OK') {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n\r\n await this.redis.sadd(identityKey, sessionId);\r\n }\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const effectiveTtl = ttl ?? this.DEFAULT_TTL;\r\n\r\n /** Lua script for atomic parsing, merging, and saving */\r\n const script = `\r\n local currentStr = redis.call(\"GET\", KEYS[1])\r\n if not currentStr then\r\n return 0\r\n end\r\n\r\n local current = cjson.decode(currentStr)\r\n local updates = cjson.decode(ARGV[1])\r\n\r\n for k,v in pairs(updates) do\r\n current[k] = v\r\n end\r\n\r\n redis.call(\"SET\", KEYS[1], cjson.encode(current), \"EX\", ARGV[2])\r\n return 1\r\n `;\r\n\r\n const result = await this.redis.eval(\r\n script,\r\n 1,\r\n sessionKey,\r\n JSON.stringify(data),\r\n effectiveTtl\r\n );\r\n\r\n if (result === 0) {\r\n throw new Error(`Session ${sessionId} not found for identity ${identity}`);\r\n }\r\n }\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n try {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const sessionDataStr = await this.redis.get(sessionKey);\r\n\r\n if (!sessionDataStr) {\r\n return null;\r\n }\r\n\r\n const sessionData: SessionData = JSON.parse(sessionDataStr);\r\n return sessionData;\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to get session:', error);\r\n return null;\r\n }\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n const identityKey = this.getIdentityKey(identity);\r\n try {\r\n return await this.redis.smembers(identityKey);\r\n } catch (error) {\r\n console.error(`[RedisStorage] Failed to get sessions for ${identity}:`, error);\r\n return [];\r\n }\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n try {\r\n const sessionIds = await this.redis.smembers(this.getIdentityKey(identity));\r\n if (sessionIds.length === 0) return [];\r\n\r\n const results = await Promise.all(\r\n sessionIds.map(async (sessionId) => {\r\n const data = await this.redis.get(this.getSessionKey(identity, sessionId));\r\n return data ? (JSON.parse(data) as SessionData) : null;\r\n })\r\n );\r\n\r\n return results.filter((session): session is SessionData => session !== null);\r\n } catch (error) {\r\n console.error(`[RedisStorage] Failed to get session data for ${identity}:`, error);\r\n return [];\r\n }\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n try {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const identityKey = this.getIdentityKey(identity);\r\n\r\n await this.redis.srem(identityKey, sessionId);\r\n await this.redis.del(sessionKey);\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to remove session:', error);\r\n }\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n try {\r\n const pattern = `${this.KEY_PREFIX}*`;\r\n const keys = await this.redis.keys(pattern);\r\n return keys.map((key) => key.replace(this.KEY_PREFIX, ''));\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to get all sessions:', error);\r\n return [];\r\n }\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n try {\r\n const pattern = `${this.KEY_PREFIX}*`;\r\n const keys = await this.redis.keys(pattern);\r\n if (keys.length > 0) {\r\n await this.redis.del(...keys);\r\n }\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to clear sessions:', error);\r\n }\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n try {\r\n const pattern = `${this.KEY_PREFIX}*`;\r\n const keys = await this.redis.keys(pattern);\r\n\r\n for (const key of keys) {\r\n const ttl = await this.redis.ttl(key);\r\n if (ttl <= 0) {\r\n await this.redis.del(key);\r\n }\r\n }\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to cleanup expired sessions:', error);\r\n }\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n try {\r\n await this.redis.quit();\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to disconnect:', error);\r\n }\r\n }\r\n}\r\n","\r\nimport { customAlphabet } from 'nanoid';\r\nimport { StorageBackend, SessionData, SetClientOptions } from './types';\r\n\r\n// first char: letters only (required by OpenAI)\r\nconst firstChar = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\r\n 1\r\n);\r\n\r\n// remaining chars: alphanumeric\r\nconst rest = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\r\n 11\r\n);\r\n\r\n/**\r\n * In-memory implementation of StorageBackend\r\n * Useful for local development or testing\r\n */\r\nexport class MemoryStorageBackend implements StorageBackend {\r\n // Map<identity:sessionId, SessionData>\r\n private sessions = new Map<string, SessionData>();\r\n\r\n // Map<identity, Set<sessionId>>\r\n private identitySessions = new Map<string, Set<string>>();\r\n\r\n constructor() { }\r\n\r\n private getSessionKey(identity: string, sessionId: string): string {\r\n return `${identity}:${sessionId}`;\r\n }\r\n\r\n generateSessionId(): string {\r\n return firstChar() + rest();\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n const { sessionId, identity } = session;\r\n if (!sessionId || !identity) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n if (this.sessions.has(sessionKey)) {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n\r\n this.sessions.set(sessionKey, session);\r\n\r\n // Update index\r\n if (!this.identitySessions.has(identity)) {\r\n this.identitySessions.set(identity, new Set());\r\n }\r\n this.identitySessions.get(identity)!.add(sessionId);\r\n // Note: TTL is ignored in memory backend - sessions don't auto-expire\r\n }\r\n\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n if (!identity || !sessionId) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const current = this.sessions.get(sessionKey);\r\n\r\n if (!current) {\r\n throw new Error(`Session ${sessionId} not found`);\r\n }\r\n\r\n const updated = {\r\n ...current,\r\n ...data\r\n };\r\n\r\n this.sessions.set(sessionKey, updated);\r\n // Note: TTL is ignored in memory backend - sessions don't auto-expire\r\n }\r\n\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n return this.sessions.get(sessionKey) || null;\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n const set = this.identitySessions.get(identity);\r\n return set ? Array.from(set) : [];\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n const set = this.identitySessions.get(identity);\r\n if (!set) return [];\r\n\r\n const results: SessionData[] = [];\r\n for (const sessionId of set) {\r\n const session = this.sessions.get(this.getSessionKey(identity, sessionId));\r\n if (session) {\r\n results.push(session);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n this.sessions.delete(sessionKey);\r\n\r\n const set = this.identitySessions.get(identity);\r\n if (set) {\r\n set.delete(sessionId);\r\n if (set.size === 0) {\r\n this.identitySessions.delete(identity);\r\n }\r\n }\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n return Array.from(this.sessions.values()).map(s => s.sessionId);\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n this.sessions.clear();\r\n this.identitySessions.clear();\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n // In-memory doesn't implement TTL automatically, \r\n // but we could check createdAt + TTL here if needed.\r\n // For now, no-op.\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n // No-op for memory\r\n }\r\n}\r\n","\r\nimport { promises as fs } from 'fs';\r\nimport * as path from 'path';\r\nimport { customAlphabet } from 'nanoid';\r\nimport { StorageBackend, SessionData, SetClientOptions } from './types';\r\n\r\n// first char: letters only (required by OpenAI)\r\nconst firstChar = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\r\n 1\r\n);\r\n\r\n// remaining chars: alphanumeric\r\nconst rest = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\r\n 11\r\n);\r\n\r\n/**\r\n * File system implementation of StorageBackend\r\n * Persists sessions to a JSON file\r\n */\r\nexport class FileStorageBackend implements StorageBackend {\r\n private filePath: string;\r\n private memoryCache: Map<string, SessionData> | null = null;\r\n private initialized = false;\r\n\r\n /**\r\n * @param options.path Path to the JSON file storage (default: ./sessions.json)\r\n */\r\n constructor(options: { path?: string } = {}) {\r\n this.filePath = options.path || './sessions.json';\r\n }\r\n\r\n /**\r\n * Initialize storage: ensure file exists and load into memory cache\r\n */\r\n async init(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n // Ensure directory exists\r\n const dir = path.dirname(this.filePath);\r\n await fs.mkdir(dir, { recursive: true });\r\n\r\n // Try to read file\r\n const data = await fs.readFile(this.filePath, 'utf-8');\r\n const json = JSON.parse(data);\r\n\r\n this.memoryCache = new Map();\r\n if (Array.isArray(json)) {\r\n json.forEach((s: SessionData) => {\r\n this.memoryCache!.set(this.getSessionKey(s.identity || 'unknown', s.sessionId), s);\r\n });\r\n }\r\n } catch (error: any) {\r\n if (error.code === 'ENOENT') {\r\n // File does not exist, initialize empty\r\n this.memoryCache = new Map();\r\n await this.flush();\r\n } else {\r\n console.error('[FileStorage] Failed to load sessions:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n this.initialized = true;\r\n }\r\n\r\n private async ensureInitialized() {\r\n if (!this.initialized) await this.init();\r\n }\r\n\r\n private async flush(): Promise<void> {\r\n if (!this.memoryCache) return;\r\n const sessions = Array.from(this.memoryCache.values());\r\n await fs.writeFile(this.filePath, JSON.stringify(sessions, null, 2), 'utf-8');\r\n }\r\n\r\n private getSessionKey(identity: string, sessionId: string): string {\r\n return `${identity}:${sessionId}`;\r\n }\r\n\r\n generateSessionId(): string {\r\n return firstChar() + rest();\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n await this.ensureInitialized();\r\n const { sessionId, identity } = session;\r\n if (!sessionId || !identity) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n if (this.memoryCache!.has(sessionKey)) {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n\r\n this.memoryCache!.set(sessionKey, session);\r\n await this.flush();\r\n // Note: TTL is ignored in file backend - sessions don't auto-expire\r\n }\r\n\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n await this.ensureInitialized();\r\n if (!identity || !sessionId) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const current = this.memoryCache!.get(sessionKey);\r\n\r\n if (!current) {\r\n throw new Error(`Session ${sessionId} not found`);\r\n }\r\n\r\n const updated = {\r\n ...current,\r\n ...data\r\n };\r\n\r\n this.memoryCache!.set(sessionKey, updated);\r\n await this.flush();\r\n // Note: TTL is ignored in file backend - sessions don't auto-expire\r\n }\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n await this.ensureInitialized();\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n return this.memoryCache!.get(sessionKey) || null;\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n await this.ensureInitialized();\r\n return Array.from(this.memoryCache!.values()).filter(s => s.identity === identity);\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n await this.ensureInitialized();\r\n return Array.from(this.memoryCache!.values())\r\n .filter(s => s.identity === identity)\r\n .map(s => s.sessionId);\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n await this.ensureInitialized();\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n if (this.memoryCache!.delete(sessionKey)) {\r\n await this.flush();\r\n }\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n await this.ensureInitialized();\r\n return Array.from(this.memoryCache!.values()).map(s => s.sessionId);\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n await this.ensureInitialized();\r\n this.memoryCache!.clear();\r\n await this.flush();\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n // Could implement TTL check here using createdAt\r\n await this.ensureInitialized();\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n // No explicit disconnect needed for file\r\n }\r\n}\r\n","import type { Database } from 'better-sqlite3';\r\nimport { StorageBackend, SessionData } from './types.js'; // Ensure .js extension\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\n\r\nexport interface SqliteStorageOptions {\r\n path?: string;\r\n table?: string;\r\n}\r\n\r\nexport class SqliteStorage implements StorageBackend {\r\n private db: Database | null = null;\r\n private table: string;\r\n private initialized = false;\r\n private dbPath: string;\r\n\r\n constructor(options: SqliteStorageOptions = {}) {\r\n this.dbPath = options.path || './sessions.db';\r\n this.table = options.table || 'mcp_sessions';\r\n }\r\n\r\n async init(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n // Dynamic import for peer dependency\r\n const DatabaseConstructor = (await import('better-sqlite3')).default;\r\n\r\n // Ensure directory exists\r\n const dir = path.dirname(this.dbPath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n this.db = new DatabaseConstructor(this.dbPath);\r\n this.db.exec(`\r\n CREATE TABLE IF NOT EXISTS ${this.table} (\r\n sessionId TEXT PRIMARY KEY,\r\n identity TEXT NOT NULL,\r\n data TEXT NOT NULL,\r\n expiresAt INTEGER\r\n );\r\n CREATE INDEX IF NOT EXISTS idx_${this.table}_identity ON ${this.table}(identity);\r\n `);\r\n\r\n this.initialized = true;\r\n } catch (error: any) {\r\n if (error.code === 'MODULE_NOT_FOUND' || error.message?.includes('better-sqlite3')) {\r\n throw new Error(\r\n 'better-sqlite3 is not installed. Please install it with: npm install better-sqlite3'\r\n );\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n private ensureInitialized() {\r\n if (!this.initialized) {\r\n throw new Error('SqliteStorage not initialized. Call init() first.');\r\n }\r\n }\r\n\r\n generateSessionId(): string {\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r\n let result = '';\r\n for (let i = 0; i < 32; i++) {\r\n result += chars.charAt(Math.floor(Math.random() * chars.length));\r\n }\r\n return result;\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n this.ensureInitialized();\r\n const { sessionId, identity } = session;\r\n\r\n if (!sessionId || !identity) {\r\n throw new Error('identity and sessionId required');\r\n }\r\n\r\n const expiresAt = ttl ? Date.now() + ttl * 1000 : null;\r\n\r\n try {\r\n const stmt = this.db!.prepare(\r\n `INSERT INTO ${this.table} (sessionId, identity, data, expiresAt) VALUES (?, ?, ?, ?)`\r\n );\r\n stmt.run(sessionId, identity, JSON.stringify(session), expiresAt);\r\n } catch (error: any) {\r\n if (error.code === 'SQLITE_CONSTRAINT_PRIMARYKEY') {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n this.ensureInitialized();\r\n if (!sessionId || !identity) {\r\n throw new Error('identity and sessionId required');\r\n }\r\n\r\n const currentSession = await this.getSession(identity, sessionId);\r\n if (!currentSession) {\r\n throw new Error(`Session ${sessionId} not found for identity ${identity}`);\r\n }\r\n\r\n const updatedSession = { ...currentSession, ...data };\r\n const expiresAt = ttl ? Date.now() + ttl * 1000 : null;\r\n\r\n const stmt = this.db!.prepare(\r\n `UPDATE ${this.table} SET data = ?, expiresAt = ? WHERE sessionId = ? AND identity = ?`\r\n );\r\n\r\n stmt.run(JSON.stringify(updatedSession), expiresAt, sessionId, identity);\r\n }\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n this.ensureInitialized();\r\n\r\n const stmt = this.db!.prepare(\r\n `SELECT data FROM ${this.table} WHERE sessionId = ? AND identity = ?`\r\n );\r\n const row = stmt.get(sessionId, identity) as { data: string } | undefined;\r\n\r\n if (!row) return null;\r\n return JSON.parse(row.data) as SessionData;\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n this.ensureInitialized();\r\n\r\n const stmt = this.db!.prepare(\r\n `SELECT data FROM ${this.table} WHERE identity = ?`\r\n );\r\n const rows = stmt.all(identity) as { data: string }[];\r\n\r\n return rows.map(row => JSON.parse(row.data) as SessionData);\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n this.ensureInitialized();\r\n\r\n const stmt = this.db!.prepare(\r\n `SELECT sessionId FROM ${this.table} WHERE identity = ?`\r\n );\r\n const rows = stmt.all(identity) as { sessionId: string }[];\r\n\r\n return rows.map(row => row.sessionId);\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n this.ensureInitialized();\r\n const stmt = this.db!.prepare(\r\n `DELETE FROM ${this.table} WHERE sessionId = ? AND identity = ?`\r\n );\r\n stmt.run(sessionId, identity);\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n this.ensureInitialized();\r\n const stmt = this.db!.prepare(`SELECT sessionId FROM ${this.table}`);\r\n const rows = stmt.all() as { sessionId: string }[];\r\n return rows.map(row => row.sessionId);\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n this.ensureInitialized();\r\n const stmt = this.db!.prepare(`DELETE FROM ${this.table}`);\r\n stmt.run();\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n this.ensureInitialized();\r\n const now = Date.now();\r\n const stmt = this.db!.prepare(\r\n `DELETE FROM ${this.table} WHERE expiresAt IS NOT NULL AND expiresAt < ?`\r\n );\r\n stmt.run(now);\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n if (this.db) {\r\n this.db.close();\r\n }\r\n }\r\n}\r\n","\r\nimport { RedisStorageBackend } from './redis-backend';\r\nimport { MemoryStorageBackend } from './memory-backend';\r\nimport { FileStorageBackend } from './file-backend';\r\nimport { SqliteStorage } from './sqlite-backend';\r\nimport type { StorageBackend } from './types';\r\n\r\n// Re-export types\r\nexport * from './types';\r\nexport { RedisStorageBackend, MemoryStorageBackend, FileStorageBackend, SqliteStorage };\r\n\r\nlet storageInstance: StorageBackend | null = null;\r\nlet storagePromise: Promise<StorageBackend> | null = null;\r\n\r\nasync function createStorage(): Promise<StorageBackend> {\r\n const type = process.env.MCP_TS_STORAGE_TYPE?.toLowerCase();\r\n\r\n // Explicit selection\r\n if (type === 'redis') {\r\n if (!process.env.REDIS_URL) {\r\n console.warn('[Storage] MCP_TS_STORAGE_TYPE is \"redis\" but REDIS_URL is missing');\r\n }\r\n try {\r\n const { getRedis } = await import('./redis.js');\r\n const redis = await getRedis();\r\n console.log('[Storage] Using Redis storage (Explicit)');\r\n return new RedisStorageBackend(redis);\r\n } catch (error: any) {\r\n console.error('[Storage] Failed to initialize Redis:', error.message);\r\n console.log('[Storage] Falling back to In-Memory storage');\r\n return new MemoryStorageBackend();\r\n }\r\n }\r\n\r\n if (type === 'file') {\r\n const filePath = process.env.MCP_TS_STORAGE_FILE;\r\n if (!filePath) {\r\n console.warn('[Storage] MCP_TS_STORAGE_TYPE is \"file\" but MCP_TS_STORAGE_FILE is missing');\r\n }\r\n console.log(`[Storage] Using File storage (${filePath}) (Explicit)`);\r\n const store = new FileStorageBackend({ path: filePath });\r\n store.init().catch(err => console.error('[Storage] Failed to initialize file storage:', err));\r\n return store;\r\n }\r\n\r\n if (type === 'sqlite') {\r\n const dbPath = process.env.MCP_TS_STORAGE_SQLITE_PATH;\r\n console.log(`[Storage] Using SQLite storage (${dbPath || 'default'}) (Explicit)`);\r\n const store = new SqliteStorage({ path: dbPath });\r\n store.init().catch(err => console.error('[Storage] Failed to initialize SQLite storage:', err));\r\n return store;\r\n }\r\n\r\n if (type === 'memory') {\r\n console.log('[Storage] Using In-Memory storage (Explicit)');\r\n return new MemoryStorageBackend();\r\n }\r\n\r\n // Automatic inference (Fallback)\r\n if (process.env.REDIS_URL) {\r\n try {\r\n const { getRedis } = await import('./redis.js');\r\n const redis = await getRedis();\r\n console.log('[Storage] Auto-detected REDIS_URL. Using Redis storage.');\r\n return new RedisStorageBackend(redis);\r\n } catch (error: any) {\r\n console.error('[Storage] Redis auto-detection failed:', error.message);\r\n console.log('[Storage] Falling back to In-Memory storage');\r\n return new MemoryStorageBackend();\r\n }\r\n }\r\n\r\n if (process.env.MCP_TS_STORAGE_FILE) {\r\n console.log(`[Storage] Auto-detected MCP_TS_STORAGE_FILE. Using File storage (${process.env.MCP_TS_STORAGE_FILE}).`);\r\n const store = new FileStorageBackend({ path: process.env.MCP_TS_STORAGE_FILE });\r\n store.init().catch(err => console.error('[Storage] Failed to initialize file storage:', err));\r\n return store;\r\n }\r\n\r\n if (process.env.MCP_TS_STORAGE_SQLITE_PATH) {\r\n console.log(`[Storage] Auto-detected MCP_TS_STORAGE_SQLITE_PATH. Using SQLite storage (${process.env.MCP_TS_STORAGE_SQLITE_PATH}).`);\r\n const store = new SqliteStorage({ path: process.env.MCP_TS_STORAGE_SQLITE_PATH });\r\n store.init().catch(err => console.error('[Storage] Failed to initialize SQLite storage:', err));\r\n return store;\r\n }\r\n\r\n console.log('[Storage] No storage configured. Using In-Memory storage (Default).');\r\n return new MemoryStorageBackend();\r\n}\r\n\r\nasync function getStorage(): Promise<StorageBackend> {\r\n if (storageInstance) {\r\n return storageInstance;\r\n }\r\n\r\n if (!storagePromise) {\r\n storagePromise = createStorage();\r\n }\r\n\r\n storageInstance = await storagePromise;\r\n return storageInstance;\r\n}\r\n\r\n/**\r\n * Set the storage instance (for testing)\r\n * @internal\r\n * @param instance - StorageBackend instance or null to reset\r\n */\r\nexport function _setStorageInstanceForTesting(instance: StorageBackend | null): void {\r\n storageInstance = instance;\r\n if (!instance) {\r\n storagePromise = null;\r\n }\r\n}\r\n\r\n/**\r\n * Global session store instance\r\n * Uses lazy initialization with a Proxy to handle async setup transparently\r\n */\r\nexport const storage: StorageBackend = new Proxy({} as StorageBackend, {\r\n get(_target, prop) {\r\n return async (...args: any[]) => {\r\n const instance = await getStorage();\r\n const value = (instance as any)[prop];\r\n if (typeof value === 'function') {\r\n return value.apply(instance, args);\r\n }\r\n return value;\r\n };\r\n },\r\n});\r\n","\r\nimport type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\r\nimport type {\r\n OAuthClientInformation,\r\n OAuthClientInformationFull,\r\n OAuthClientMetadata,\r\n OAuthTokens\r\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\r\nimport { storage, SessionData } from \"../storage/index.js\";\r\nimport { TOKEN_EXPIRY_BUFFER_MS } from '../../shared/constants.js';\r\n\r\n/**\r\n * Extension of OAuthClientProvider interface with additional methods\r\n * Enables server-specific tracking and state management\r\n */\r\nexport interface AgentsOAuthProvider extends OAuthClientProvider {\r\n authUrl: string | undefined;\r\n clientId: string | undefined;\r\n serverId: string | undefined;\r\n checkState(\r\n state: string\r\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\r\n consumeState(state: string): Promise<void>;\r\n deleteCodeVerifier(): Promise<void>;\r\n isTokenExpired(): boolean;\r\n setTokenExpiresAt(expiresAt: number): void;\r\n}\r\n\r\n/**\r\n * Storage-backed OAuth provider implementation for MCP\r\n * Stores OAuth tokens, client information, and PKCE verifiers using the configured StorageBackend\r\n */\r\nexport class StorageOAuthClientProvider implements AgentsOAuthProvider {\r\n private _authUrl: string | undefined;\r\n private _clientId: string | undefined;\r\n private onRedirectCallback?: (url: string) => void;\r\n private tokenExpiresAt?: number;\r\n\r\n /**\r\n * Creates a new Storage-backed OAuth provider\r\n * @param identity - User/Client identifier\r\n * @param serverId - Server identifier (for tracking which server this OAuth session belongs to)\r\n * @param sessionId - Session identifier (used as OAuth state)\r\n * @param clientName - OAuth client name\r\n * @param baseRedirectUrl - OAuth callback URL\r\n * @param onRedirect - Optional callback when redirect to authorization is needed\r\n */\r\n constructor(\r\n public identity: string,\r\n public serverId: string,\r\n public sessionId: string,\r\n public clientName: string,\r\n public baseRedirectUrl: string,\r\n onRedirect?: (url: string) => void\r\n ) {\r\n this.onRedirectCallback = onRedirect;\r\n }\r\n\r\n get clientMetadata(): OAuthClientMetadata {\r\n return {\r\n client_name: this.clientName,\r\n client_uri: this.clientUri,\r\n grant_types: [\"authorization_code\", \"refresh_token\"],\r\n redirect_uris: [this.redirectUrl],\r\n response_types: [\"code\"],\r\n token_endpoint_auth_method: \"none\",\r\n ...(this._clientId ? { client_id: this._clientId } : {})\r\n };\r\n }\r\n\r\n get clientUri() {\r\n return new URL(this.redirectUrl).origin;\r\n }\r\n\r\n get redirectUrl() {\r\n return this.baseRedirectUrl;\r\n }\r\n\r\n get clientId() {\r\n return this._clientId;\r\n }\r\n\r\n set clientId(clientId_: string | undefined) {\r\n this._clientId = clientId_;\r\n }\r\n\r\n /**\r\n * Loads OAuth data from storage session\r\n * @private\r\n */\r\n private async getSessionData(): Promise<SessionData> {\r\n const data = await storage.getSession(this.identity, this.sessionId);\r\n if (!data) {\r\n // Return empty/partial object if not found\r\n return {} as SessionData;\r\n }\r\n return data;\r\n }\r\n\r\n /**\r\n * Saves OAuth data to storage\r\n * @param data - Partial OAuth data to save\r\n * @private\r\n * @throws Error if session doesn't exist (session must be created by controller layer)\r\n */\r\n private async saveSessionData(data: Partial<SessionData>): Promise<void> {\r\n await storage.updateSession(this.identity, this.sessionId, data);\r\n }\r\n\r\n /**\r\n * Retrieves stored OAuth client information\r\n */\r\n async clientInformation(): Promise<OAuthClientInformation | undefined> {\r\n const data = await this.getSessionData();\r\n\r\n if (data.clientId && !this._clientId) {\r\n this._clientId = data.clientId;\r\n }\r\n\r\n return data.clientInformation;\r\n }\r\n\r\n /**\r\n * Stores OAuth client information\r\n */\r\n async saveClientInformation(clientInformation: OAuthClientInformationFull): Promise<void> {\r\n await this.saveSessionData({\r\n clientInformation,\r\n clientId: clientInformation.client_id\r\n });\r\n this.clientId = clientInformation.client_id;\r\n }\r\n\r\n /**\r\n * Stores OAuth tokens\r\n */\r\n async saveTokens(tokens: OAuthTokens): Promise<void> {\r\n const data: Partial<SessionData> = { tokens };\r\n\r\n if (tokens.expires_in) {\r\n this.tokenExpiresAt = Date.now() + (tokens.expires_in * 1000) - TOKEN_EXPIRY_BUFFER_MS;\r\n }\r\n\r\n await this.saveSessionData(data);\r\n }\r\n\r\n get authUrl() {\r\n return this._authUrl;\r\n }\r\n\r\n async state(): Promise<string> {\r\n return this.sessionId;\r\n }\r\n\r\n async checkState(state: string): Promise<{ valid: boolean; serverId?: string; error?: string }> {\r\n const data = await storage.getSession(this.identity, this.sessionId);\r\n\r\n if (!data) {\r\n return { valid: false, error: \"Session not found\" };\r\n }\r\n\r\n return { valid: true, serverId: this.serverId };\r\n }\r\n\r\n async consumeState(state: string): Promise<void> {\r\n // No-op\r\n }\r\n\r\n async redirectToAuthorization(authUrl: URL): Promise<void> {\r\n this._authUrl = authUrl.toString();\r\n if (this.onRedirectCallback) {\r\n this.onRedirectCallback(authUrl.toString());\r\n }\r\n }\r\n\r\n async invalidateCredentials(\r\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\"\r\n ): Promise<void> {\r\n if (scope === \"all\") {\r\n await storage.removeSession(this.identity, this.sessionId);\r\n } else {\r\n const data = await this.getSessionData();\r\n // Create a copy to modify\r\n const updates: Partial<SessionData> = {};\r\n\r\n if (scope === \"client\") {\r\n updates.clientInformation = undefined;\r\n updates.clientId = undefined;\r\n } else if (scope === \"tokens\") {\r\n updates.tokens = undefined;\r\n } else if (scope === \"verifier\") {\r\n updates.codeVerifier = undefined;\r\n }\r\n await this.saveSessionData(updates);\r\n }\r\n }\r\n\r\n async saveCodeVerifier(verifier: string): Promise<void> {\r\n await this.saveSessionData({ codeVerifier: verifier });\r\n }\r\n\r\n async codeVerifier(): Promise<string> {\r\n const data = await this.getSessionData();\r\n\r\n if (data.clientId && !this._clientId) {\r\n this._clientId = data.clientId;\r\n }\r\n\r\n if (!data.codeVerifier) {\r\n throw new Error(\"No code verifier found\");\r\n }\r\n return data.codeVerifier;\r\n }\r\n\r\n async deleteCodeVerifier(): Promise<void> {\r\n await this.saveSessionData({ codeVerifier: undefined });\r\n }\r\n\r\n async tokens(): Promise<OAuthTokens | undefined> {\r\n const data = await this.getSessionData();\r\n\r\n if (data.clientId && !this._clientId) {\r\n this._clientId = data.clientId;\r\n }\r\n\r\n return data.tokens;\r\n }\r\n\r\n isTokenExpired(): boolean {\r\n if (!this.tokenExpiresAt) {\r\n return false;\r\n }\r\n return Date.now() >= this.tokenExpiresAt;\r\n }\r\n\r\n setTokenExpiresAt(expiresAt: number): void {\r\n this.tokenExpiresAt = expiresAt;\r\n }\r\n}\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\n","/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n serverUrl: string;\r\n createdAt?: number;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Event fired when a tool execution returns a UI resource URI\r\n */\r\nexport interface McpAppsUIEvent {\r\n type: 'mcp-apps-ui';\r\n sessionId: string;\r\n resourceUri: string;\r\n toolName: string;\r\n result: unknown;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\r\nimport { nanoid } from 'nanoid';\r\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\r\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\r\nimport {\r\n UnauthorizedError as SDKUnauthorizedError,\r\n refreshAuthorization,\r\n discoverOAuthProtectedResourceMetadata,\r\n discoverAuthorizationServerMetadata,\r\n} from '@modelcontextprotocol/sdk/client/auth.js';\r\nimport {\r\n ListToolsRequest,\r\n ListToolsResult,\r\n ListToolsResultSchema,\r\n CallToolRequest,\r\n CallToolResult,\r\n CallToolResultSchema,\r\n ListPromptsRequest,\r\n ListPromptsResult,\r\n ListPromptsResultSchema,\r\n GetPromptRequest,\r\n GetPromptResult,\r\n GetPromptResultSchema,\r\n ListResourcesRequest,\r\n ListResourcesResult,\r\n ListResourcesResultSchema,\r\n ReadResourceRequest,\r\n ReadResourceResult,\r\n ReadResourceResultSchema,\r\n} from '@modelcontextprotocol/sdk/types.js';\r\nimport type { OAuthClientMetadata, OAuthTokens, OAuthClientInformationFull } from '@modelcontextprotocol/sdk/shared/auth.js';\r\nimport { StorageOAuthClientProvider, type AgentsOAuthProvider } from './storage-oauth-provider.js';\r\nimport { sanitizeServerLabel } from '../../shared/utils.js';\r\nimport { Emitter, type McpConnectionEvent, type McpObservabilityEvent, type McpConnectionState } from '../../shared/events.js';\r\nimport { UnauthorizedError } from '../../shared/errors.js';\r\nimport { storage } from '../storage/index.js';\r\nimport { SESSION_TTL_SECONDS, STATE_EXPIRATION_MS } from '../../shared/constants.js';\r\n\r\n\r\n\r\n/**\r\n * Supported MCP transport types\r\n */\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n/**\r\n * Extended capabilities including MCP App support\r\n */\r\nimport type { ClientCapabilities } from '@modelcontextprotocol/sdk/types.js';\r\n\r\ninterface McpAppClientCapabilities extends ClientCapabilities {\r\n extensions?: {\r\n 'io.modelcontextprotocol/ui'?: {\r\n mimeTypes: string[];\r\n };\r\n [key: string]: unknown;\r\n };\r\n}\r\n\r\nexport interface MCPOAuthClientOptions {\r\n serverUrl?: string;\r\n serverName?: string;\r\n callbackUrl?: string;\r\n onRedirect?: (url: string) => void;\r\n identity: string;\r\n serverId?: string; /** Optional - loaded from session if not provided */\r\n sessionId: string; /** Required - primary key for session lookup */\r\n transportType?: TransportType;\r\n clientId?: string;\r\n clientSecret?: string;\r\n headers?: Record<string, string>;\r\n /** OAuth Client Metadata (optional - user application info) */\r\n clientName?: string;\r\n clientUri?: string;\r\n logoUri?: string;\r\n policyUri?: string;\r\n}\r\n\r\n/**\r\n * MCP Client with OAuth 2.1 authentication support\r\n * Manages connections to MCP servers with automatic token refresh and session restoration\r\n * Emits connection lifecycle events for observability\r\n */\r\nexport class MCPClient {\r\n private client: Client | null = null;\r\n public oauthProvider: AgentsOAuthProvider | null = null;\r\n private transport: StreamableHTTPClientTransport | SSEClientTransport | null = null;\r\n private identity: string;\r\n private serverId?: string;\r\n private sessionId: string;\r\n private serverName?: string;\r\n private transportType: TransportType | undefined;\r\n private serverUrl: string | undefined;\r\n private callbackUrl: string | undefined;\r\n private onRedirect: ((url: string) => void) | undefined;\r\n private clientId?: string;\r\n private clientSecret?: string;\r\n private headers?: Record<string, string>;\r\n /** OAuth Client Metadata */\r\n private clientName?: string;\r\n private clientUri?: string;\r\n private logoUri?: string;\r\n private policyUri?: string;\r\n private createdAt?: number;\r\n\r\n\r\n /** Event emitters for connection lifecycle */\r\n private readonly _onConnectionEvent = new Emitter<McpConnectionEvent>();\r\n public readonly onConnectionEvent = this._onConnectionEvent.event;\r\n\r\n private readonly _onObservabilityEvent = new Emitter<McpObservabilityEvent>();\r\n public readonly onObservabilityEvent = this._onObservabilityEvent.event;\r\n\r\n private currentState: McpConnectionState = 'DISCONNECTED';\r\n\r\n /**\r\n * Creates a new MCP client instance\r\n * Can be initialized with minimal options (identity + sessionId) for session restoration\r\n * @param options - Client configuration options\r\n */\r\n constructor(options: MCPOAuthClientOptions) {\r\n this.serverUrl = options.serverUrl;\r\n this.serverName = options.serverName;\r\n this.callbackUrl = options.callbackUrl;\r\n this.onRedirect = options.onRedirect;\r\n this.identity = options.identity;\r\n this.serverId = options.serverId;\r\n this.sessionId = options.sessionId;\r\n this.transportType = options.transportType;\r\n this.clientId = options.clientId;\r\n this.clientSecret = options.clientSecret;\r\n this.headers = options.headers;\r\n this.clientName = options.clientName;\r\n this.clientUri = options.clientUri;\r\n this.logoUri = options.logoUri;\r\n this.policyUri = options.policyUri;\r\n }\r\n\r\n /**\r\n * Emit a connection state change event\r\n * @private\r\n */\r\n private emitStateChange(newState: McpConnectionState): void {\r\n const previousState = this.currentState;\r\n this.currentState = newState;\r\n\r\n if (!this.serverId) return;\r\n\r\n this._onConnectionEvent.fire({\r\n type: 'state_changed',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n serverName: this.serverName || this.serverId,\r\n serverUrl: this.serverUrl || '',\r\n createdAt: this.createdAt,\r\n state: newState,\r\n previousState,\r\n timestamp: Date.now(),\r\n });\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:state_change',\r\n level: 'info',\r\n message: `Connection state: ${previousState} → ${newState}`,\r\n displayMessage: `State changed to ${newState}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: { previousState, newState },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n }\r\n\r\n /**\r\n * Emit an error event\r\n * @private\r\n */\r\n private emitError(error: string, errorType: 'connection' | 'auth' | 'validation' | 'unknown' = 'unknown'): void {\r\n if (!this.serverId) return;\r\n\r\n this._onConnectionEvent.fire({\r\n type: 'error',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n error,\r\n errorType,\r\n timestamp: Date.now(),\r\n });\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:error',\r\n level: 'error',\r\n message: error,\r\n displayMessage: error,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: { errorType, error },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n }\r\n\r\n /**\r\n * Emit a progress event\r\n * @private\r\n */\r\n private emitProgress(message: string): void {\r\n if (!this.serverId) return;\r\n\r\n this._onConnectionEvent.fire({\r\n type: 'progress',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n message,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n /**\r\n * Get current connection state\r\n */\r\n getConnectionState(): McpConnectionState {\r\n return this.currentState;\r\n }\r\n\r\n /**\r\n * Helper to create a transport instance\r\n * @param type - The transport type to create\r\n * @returns Configured transport instance\r\n * @private\r\n */\r\n private getTransport(type: TransportType): StreamableHTTPClientTransport | SSEClientTransport {\r\n if (!this.serverUrl) {\r\n throw new Error('Server URL is required to create transport');\r\n }\r\n\r\n const baseUrl = new URL(this.serverUrl);\r\n const transportOptions = {\r\n authProvider: this.oauthProvider!,\r\n ...(this.headers && { headers: this.headers }),\r\n /**\r\n * Custom fetch implementation to handle connection timeouts.\r\n * Observation: SDK 1.24.0+ connections may hang indefinitely in some environments.\r\n * This wrapper enforces a timeout and properly uses AbortController to unblock the request.\r\n */\r\n fetch: (url: RequestInfo | URL, init?: RequestInit) => {\r\n const timeout = 30000;\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n const signal = init?.signal ?\r\n // @ts-ignore: AbortSignal.any is available in Node 20+\r\n (AbortSignal.any ? AbortSignal.any([init.signal, controller.signal]) : controller.signal) :\r\n controller.signal;\r\n\r\n return fetch(url, { ...init, signal }).finally(() => clearTimeout(timeoutId));\r\n }\r\n };\r\n\r\n if (type === 'sse') {\r\n return new SSEClientTransport(baseUrl, transportOptions);\r\n } else {\r\n return new StreamableHTTPClientTransport(baseUrl, transportOptions);\r\n }\r\n }\r\n\r\n /**\r\n * Initializes client components (client, transport, OAuth provider)\r\n * Loads missing configuration from Redis session store if needed\r\n * This method is idempotent and safe to call multiple times\r\n * @private\r\n */\r\n private async initialize(): Promise<void> {\r\n if (this.client && this.oauthProvider) {\r\n return;\r\n }\r\n\r\n this.emitStateChange('INITIALIZING');\r\n this.emitProgress('Loading session configuration...');\r\n\r\n if (!this.serverUrl || !this.callbackUrl || !this.serverId) {\r\n const sessionData = await storage.getSession(this.identity, this.sessionId);\r\n if (!sessionData) {\r\n throw new Error(`Session not found: ${this.sessionId}`);\r\n }\r\n\r\n this.serverUrl = this.serverUrl || sessionData.serverUrl;\r\n this.callbackUrl = this.callbackUrl || sessionData.callbackUrl;\r\n /**\r\n * Do NOT load transportType from session if not explicitly provided.\r\n * We want to re-negotiate (try streamable -> sse) on new connections if in \"Auto\" mode.\r\n * this.transportType = this.transportType || sessionData.transportType; \r\n */\r\n this.serverName = this.serverName || sessionData.serverName;\r\n this.serverId = this.serverId || sessionData.serverId || 'unknown';\r\n this.headers = this.headers || sessionData.headers;\r\n this.createdAt = sessionData.createdAt;\r\n }\r\n\r\n if (!this.serverUrl || !this.callbackUrl || !this.serverId) {\r\n throw new Error('Missing required connection metadata');\r\n }\r\n\r\n const clientMetadata: OAuthClientMetadata = {\r\n client_name: this.clientName || 'MCP Assistant',\r\n redirect_uris: [this.callbackUrl],\r\n grant_types: ['authorization_code', 'refresh_token'],\r\n response_types: ['code'],\r\n token_endpoint_auth_method: this.clientSecret ? 'client_secret_basic' : 'none',\r\n client_uri: this.clientUri || 'https://mcp-assistant.in',\r\n logo_uri: this.logoUri || 'https://mcp-assistant.in/logo.png',\r\n policy_uri: this.policyUri || 'https://mcp-assistant.in/privacy',\r\n software_id: '@mcp-ts',\r\n software_version: '1.0.0-beta.4',\r\n ...(this.clientId ? { client_id: this.clientId } : {}),\r\n ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),\r\n };\r\n\r\n if (!this.oauthProvider) {\r\n if (!this.serverId) {\r\n throw new Error('serverId required for OAuth provider initialization');\r\n }\r\n\r\n this.oauthProvider = new StorageOAuthClientProvider(\r\n this.identity,\r\n this.serverId,\r\n this.sessionId,\r\n clientMetadata.client_name ?? 'MCP Assistant',\r\n this.callbackUrl,\r\n (redirectUrl: string) => {\r\n if (this.onRedirect) {\r\n this.onRedirect(redirectUrl);\r\n }\r\n }\r\n );\r\n\r\n if (this.clientId && this.oauthProvider) {\r\n this.oauthProvider.clientId = this.clientId;\r\n }\r\n }\r\n\r\n if (!this.client) {\r\n this.client = new Client(\r\n {\r\n name: 'mcp-ts-oauth-client',\r\n version: '2.0',\r\n },\r\n {\r\n capabilities: {\r\n extensions: {\r\n 'io.modelcontextprotocol/ui': {\r\n mimeTypes: ['text/html+mcp'],\r\n },\r\n },\r\n } as McpAppClientCapabilities\r\n }\r\n );\r\n }\r\n\r\n // Create session in storage if it doesn't exist yet\r\n // This is needed BEFORE OAuth flow starts because the OAuth provider\r\n // will call saveCodeVerifier() which requires the session to exist\r\n const existingSession = await storage.getSession(this.identity, this.sessionId);\r\n if (!existingSession && this.serverId && this.serverUrl && this.callbackUrl) {\r\n this.createdAt = Date.now();\r\n console.log(`[MCPClient] Creating initial session ${this.sessionId} for OAuth flow`);\r\n await storage.createSession({\n sessionId: this.sessionId,\n identity: this.identity,\n serverId: this.serverId,\n serverName: this.serverName,\n serverUrl: this.serverUrl,\n callbackUrl: this.callbackUrl,\n transportType: this.transportType || 'streamable_http',\n createdAt: this.createdAt,\n active: false,\n }, Math.floor(STATE_EXPIRATION_MS / 1000)); // Short TTL until connection succeeds\n }\n }\n\r\n /**\r\n * Saves current session state to storage\r\n * Creates new session if it doesn't exist, updates if it does\r\n * @param ttl - Time-to-live in seconds (defaults to 12hr for connected sessions)\n * @param active - Session status marker used to avoid unnecessary TTL rewrites\n * @private\n */\n private async saveSession(\n ttl: number = SESSION_TTL_SECONDS,\n active: boolean = true\n ): Promise<void> {\n if (!this.sessionId || !this.serverId || !this.serverUrl || !this.callbackUrl) {\n return;\n }\n\r\n const sessionData = {\r\n sessionId: this.sessionId,\r\n identity: this.identity,\r\n serverId: this.serverId,\r\n serverName: this.serverName,\r\n serverUrl: this.serverUrl,\r\n callbackUrl: this.callbackUrl,\n transportType: (this.transportType || 'streamable_http') as TransportType,\n createdAt: this.createdAt || Date.now(),\n active,\n };\n\r\n // Try to update first, create if doesn't exist\r\n const existingSession = await storage.getSession(this.identity, this.sessionId);\r\n if (existingSession) {\r\n await storage.updateSession(this.identity, this.sessionId, sessionData, ttl);\r\n } else {\r\n await storage.createSession(sessionData, ttl);\r\n }\r\n }\r\n\r\n /**\r\n * Try to connect using available transports\r\n * @returns The corrected transport type object if successful\r\n * @private\r\n */\r\n private async tryConnect(): Promise<{ transportType: TransportType }> {\r\n /**\r\n * If exact transport type is known, only try that.\r\n * Otherwise (auto mode), try streamable_http first, then sse.\r\n */\r\n const transportsToTry: TransportType[] = this.transportType\r\n ? [this.transportType]\r\n : ['streamable_http', 'sse'];\r\n\r\n let lastError: unknown;\r\n\r\n for (const currentType of transportsToTry) {\r\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\r\n\r\n try {\r\n const transport = this.getTransport(currentType);\r\n\r\n /** Update local state with the transport we are about to try */\r\n this.transport = transport;\r\n\r\n /** Race connection against timeout */\r\n await this.client!.connect(transport);\r\n\r\n /** Success! Return the type that worked */\r\n return { transportType: currentType };\r\n\r\n } catch (error: any) {\r\n lastError = error;\r\n\r\n /** Check for Auth Errors - these should fail immediately, no fallback */\r\n const isAuthError = error instanceof SDKUnauthorizedError ||\r\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\r\n\r\n if (isAuthError) {\r\n throw error;\r\n }\r\n\r\n /** If this was the last transport to try, throw the error */\r\n if (isLastAttempt) {\r\n throw error;\r\n }\r\n\r\n /** Otherwise, log and continue to next transport */\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.emitProgress(`Connection attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\r\n this._onObservabilityEvent.fire({\r\n level: 'warn',\r\n message: `Transport ${currentType} failed, falling back`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n metadata: {\r\n failedTransport: currentType,\r\n error: errorMessage\r\n },\r\n timestamp: Date.now(),\r\n });\r\n }\r\n }\r\n\r\n throw lastError || new Error('No transports available');\r\n }\r\n\r\n /**\r\n * Connects to the MCP server\r\n * Automatically validates and refreshes OAuth tokens if needed\r\n * Saves session to Redis on first successful connection\r\n * @throws {UnauthorizedError} When OAuth authorization is required\r\n * @throws {Error} When connection fails for other reasons\r\n */\r\n async connect(): Promise<void> {\r\n await this.initialize();\r\n\r\n if (!this.client || !this.oauthProvider) {\r\n const error = 'Client or OAuth provider not initialized';\r\n this.emitError(error, 'connection');\r\n this.emitStateChange('FAILED');\r\n throw new Error(error);\r\n }\r\n\r\n try {\r\n this.emitProgress('Validating OAuth tokens...');\r\n await this.getValidTokens();\r\n\r\n this.emitStateChange('CONNECTING');\r\n\r\n /** Use the tryConnect loop to handle transport fallbacks */\r\n const { transportType } = await this.tryConnect();\r\n\r\n /** Update transport type to the one that actually worked */\r\n this.transportType = transportType;\r\n\r\n this.emitStateChange('CONNECTED');\r\n this.emitProgress('Connected successfully');\r\n\r\n // Promote short-lived OAuth-pending session TTL to long-lived active TTL once.\n // Also persist when transport negotiation changed the effective transport.\n const existingSession = await storage.getSession(this.identity, this.sessionId);\n const needsTransportUpdate = !existingSession || existingSession.transportType !== this.transportType;\n const needsTtlPromotion = !existingSession || existingSession.active !== true;\n\n if (needsTransportUpdate || needsTtlPromotion) {\n console.log(`[MCPClient] Saving session ${this.sessionId} with 12hr TTL (connect success)`);\n await this.saveSession(SESSION_TTL_SECONDS, true);\n }\n } catch (error) {\r\n /** Handle Authentication Errors */\r\n if (\r\n error instanceof SDKUnauthorizedError ||\r\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'))\r\n ) {\r\n this.emitStateChange('AUTHENTICATING');\r\n // Save session with 10min TTL for OAuth pending state\r\n console.log(`[MCPClient] Saving session ${this.sessionId} with 10min TTL (OAuth pending)`);\r\n await this.saveSession(Math.floor(STATE_EXPIRATION_MS / 1000), false);\n\r\n /** Get OAuth authorization URL if available */\r\n let authUrl = '';\r\n if (this.oauthProvider) {\r\n authUrl = this.oauthProvider.authUrl || '';\r\n }\r\n\r\n if (this.serverId) {\r\n this._onConnectionEvent.fire({\r\n type: 'auth_required',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n authUrl,\r\n timestamp: Date.now(),\r\n });\r\n\r\n if (authUrl && this.onRedirect) {\r\n this.onRedirect(authUrl);\r\n }\r\n }\r\n\r\n throw new UnauthorizedError('OAuth authorization required');\r\n }\r\n\r\n /** Handle Generic Errors */\r\n const errorMessage = error instanceof Error ? error.message : 'Connection failed';\r\n this.emitError(errorMessage, 'connection');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Completes OAuth authorization flow by exchanging authorization code for tokens\r\n * Creates new authenticated client and transport, then establishes connection\r\n * Saves active session to Redis after successful authentication\r\n * @param authCode - Authorization code received from OAuth callback\r\n */\r\n\r\n // TODO: needs to be optimized\r\n async finishAuth(authCode: string): Promise<void> {\r\n this.emitStateChange('AUTHENTICATING');\r\n this.emitProgress('Exchanging authorization code for tokens...');\r\n\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n const error = 'OAuth provider not initialized';\r\n this.emitError(error, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw new Error(error);\r\n }\r\n\r\n /**\r\n * Determine which transports to try for finishing auth\r\n * If transportType is set, use only that. Otherwise try streamable_http then sse.\r\n */\r\n const transportsToTry: TransportType[] = this.transportType\r\n ? [this.transportType]\r\n : ['streamable_http', 'sse'];\r\n\r\n let lastError: unknown;\r\n let tokensExchanged = false;\r\n\r\n for (const currentType of transportsToTry) {\r\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\r\n\r\n try {\r\n const transport = this.getTransport(currentType);\r\n\r\n /** Update local state with the transport we are about to try */\r\n this.transport = transport;\r\n\r\n if (!tokensExchanged) {\r\n await transport.finishAuth(authCode);\r\n tokensExchanged = true;\r\n } else {\r\n this.emitProgress(`Tokens already exchanged, skipping auth step for ${currentType}...`);\r\n }\r\n\r\n /** Success! Update transport type */\r\n this.transportType = currentType;\r\n\r\n this.emitStateChange('AUTHENTICATED');\r\n this.emitProgress('Creating authenticated client...');\r\n\r\n this.client = new Client(\r\n {\r\n name: 'mcp-ts-oauth-client',\r\n version: '2.0',\r\n },\r\n {\r\n capabilities: {\r\n extensions: {\r\n 'io.modelcontextprotocol/ui': {\r\n mimeTypes: ['text/html+mcp'],\r\n },\r\n },\r\n } as McpAppClientCapabilities\r\n }\r\n );\r\n\r\n this.emitStateChange('CONNECTING');\r\n\r\n /** We explicitly try to connect with the transport we just auth'd with first */\r\n await this.client.connect(this.transport);\r\n\r\n this.emitStateChange('CONNECTED');\r\n // Update session with 12hr TTL after successful OAuth\r\n console.log(`[MCPClient] Updating session ${this.sessionId} to 12hr TTL (OAuth complete)`);\r\n await this.saveSession(SESSION_TTL_SECONDS, true);\n\r\n return; // Success, exit function\r\n\r\n } catch (error) {\r\n lastError = error;\r\n\r\n const isAuthError = error instanceof SDKUnauthorizedError ||\r\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\r\n\r\n if (isAuthError) {\r\n throw error;\r\n }\r\n\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n\r\n // Don't retry if the authorization code was rejected (it's one-time use)\r\n if (!tokensExchanged && errorMessage.toLowerCase().includes('invalid authorization code')) {\r\n const msg = error instanceof Error ? error.message : 'Authentication failed';\r\n this.emitError(msg, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n\r\n if (isLastAttempt) {\r\n const msg = error instanceof Error ? error.message : 'Authentication failed';\r\n this.emitError(msg, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n\r\n // Log and retry\r\n this.emitProgress(`Auth attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\r\n }\r\n }\r\n\r\n if (lastError) {\r\n const errorMessage = lastError instanceof Error ? lastError.message : 'Authentication failed';\r\n this.emitError(errorMessage, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw lastError;\r\n }\r\n }\r\n\r\n /**\r\n * Lists all available tools from the connected MCP server\r\n * @returns List of tools with their schemas and descriptions\r\n * @throws {Error} When client is not connected\r\n */\r\n async listTools(): Promise<ListToolsResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n this.emitStateChange('DISCOVERING');\r\n\r\n try {\r\n const request: ListToolsRequest = {\r\n method: 'tools/list',\r\n params: {},\r\n };\r\n\r\n const result = await this.client.request(request, ListToolsResultSchema);\r\n\r\n if (this.serverId) {\r\n this._onConnectionEvent.fire({\r\n type: 'tools_discovered',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n toolCount: result.tools.length,\r\n tools: result.tools,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n this.emitStateChange('READY');\r\n this.emitProgress(`Discovered ${result.tools.length} tools`);\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Failed to list tools';\r\n this.emitError(errorMessage, 'validation');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Executes a tool on the connected MCP server\r\n * @param toolName - Name of the tool to execute\r\n * @param toolArgs - Arguments to pass to the tool\r\n * @returns Tool execution result\r\n * @throws {Error} When client is not connected\r\n */\r\n async callTool(toolName: string, toolArgs: Record<string, unknown>): Promise<CallToolResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n const request: CallToolRequest = {\r\n method: 'tools/call',\r\n params: {\r\n name: toolName,\r\n arguments: toolArgs,\r\n },\r\n };\r\n\r\n try {\r\n const result = await this.client.request(request, CallToolResultSchema);\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:tool_call',\r\n level: 'info',\r\n message: `Tool ${toolName} called successfully`,\r\n displayMessage: `Called tool ${toolName}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: {\r\n toolName,\r\n args: toolArgs,\r\n },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : `Failed to call tool ${toolName}`;\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:error',\r\n level: 'error',\r\n message: errorMessage,\r\n displayMessage: `Failed to call tool ${toolName}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: {\r\n errorType: 'tool_execution',\r\n error: errorMessage,\r\n toolName,\r\n args: toolArgs,\r\n },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Lists all available prompts from the connected MCP server\r\n * @returns List of available prompts\r\n * @throws {Error} When client is not connected\r\n */\r\n async listPrompts(): Promise<ListPromptsResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n this.emitStateChange('DISCOVERING');\r\n\r\n try {\r\n const request: ListPromptsRequest = {\r\n method: 'prompts/list',\r\n params: {},\r\n };\r\n\r\n const result = await this.client.request(request, ListPromptsResultSchema);\r\n\r\n this.emitStateChange('READY');\r\n this.emitProgress(`Discovered ${result.prompts.length} prompts`);\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Failed to list prompts';\r\n this.emitError(errorMessage, 'validation');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Gets a specific prompt with arguments\r\n * @param name - Name of the prompt\r\n * @param args - Arguments for the prompt\r\n * @returns Prompt content\r\n * @throws {Error} When client is not connected\r\n */\r\n async getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n const request: GetPromptRequest = {\r\n method: 'prompts/get',\r\n params: {\r\n name,\r\n arguments: args,\r\n },\r\n };\r\n\r\n return await this.client.request(request, GetPromptResultSchema);\r\n }\r\n\r\n /**\r\n * Lists all available resources from the connected MCP server\r\n * @returns List of available resources\r\n * @throws {Error} When client is not connected\r\n */\r\n async listResources(): Promise<ListResourcesResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n this.emitStateChange('DISCOVERING');\r\n\r\n try {\r\n const request: ListResourcesRequest = {\r\n method: 'resources/list',\r\n params: {},\r\n };\r\n\r\n const result = await this.client.request(request, ListResourcesResultSchema);\r\n\r\n this.emitStateChange('READY');\r\n this.emitProgress(`Discovered ${result.resources.length} resources`);\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Failed to list resources';\r\n this.emitError(errorMessage, 'validation');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Reads a specific resource\r\n * @param uri - URI of the resource to read\r\n * @returns Resource content\r\n * @throws {Error} When client is not connected\r\n */\r\n async readResource(uri: string): Promise<ReadResourceResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n const request: ReadResourceRequest = {\r\n method: 'resources/read',\r\n params: {\r\n uri,\r\n },\r\n };\r\n\r\n return await this.client.request(request, ReadResourceResultSchema);\r\n }\r\n\r\n /**\r\n * Refreshes the OAuth access token using the refresh token\r\n * Discovers OAuth metadata from server and exchanges refresh token for new access token\r\n * @returns True if refresh was successful, false otherwise\r\n */\r\n async refreshToken(): Promise<boolean> {\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n return false;\r\n }\r\n\r\n const tokens = await this.oauthProvider.tokens();\r\n if (!tokens || !tokens.refresh_token) {\r\n return false;\r\n }\r\n\r\n const clientInformation = await this.oauthProvider.clientInformation();\r\n if (!clientInformation) {\r\n return false;\r\n }\r\n\r\n try {\r\n const resourceMetadata = await discoverOAuthProtectedResourceMetadata(this.serverUrl!);\r\n const authServerUrl = resourceMetadata?.authorization_servers?.[0] || this.serverUrl!;\r\n const authMetadata = await discoverAuthorizationServerMetadata(authServerUrl);\r\n\r\n const newTokens = await refreshAuthorization(authServerUrl, {\r\n metadata: authMetadata,\r\n clientInformation,\r\n refreshToken: tokens.refresh_token,\r\n });\r\n\r\n await this.oauthProvider.saveTokens(newTokens);\r\n return true;\r\n } catch (error) {\r\n console.error('[OAuth] Token refresh failed:', error);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Ensures OAuth tokens are valid, refreshing them if expired\r\n * Called automatically by connect() - rarely needs to be called manually\r\n * @returns True if valid tokens are available, false otherwise\r\n */\r\n async getValidTokens(): Promise<boolean> {\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n return false;\r\n }\r\n\r\n const tokens = await this.oauthProvider.tokens();\r\n if (!tokens) {\r\n return false;\r\n }\r\n\r\n if (this.oauthProvider.isTokenExpired()) {\r\n return await this.refreshToken();\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Reconnects to MCP server using existing OAuth provider from Redis\r\n * Used for session restoration in serverless environments\r\n * Creates new client and transport without re-initializing OAuth provider\r\n * @throws {Error} When OAuth provider is not initialized\r\n */\r\n async reconnect(): Promise<void> {\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n throw new Error('OAuth provider not initialized');\r\n }\r\n\r\n this.client = new Client(\r\n {\r\n name: 'mcp-ts-oauth-client',\r\n version: '2.0',\r\n },\r\n { capabilities: {} }\r\n );\r\n\r\n // Use default logic to get transport, defaulting to what's stored or auto\r\n const tt = this.transportType || 'streamable_http';\r\n this.transport = this.getTransport(tt);\r\n\r\n await this.client.connect(this.transport);\r\n }\r\n\r\n /**\r\n * Completely removes the session from Redis including all OAuth data\r\n * Invalidates credentials and disconnects the client\r\n */\r\n async clearSession(): Promise<void> {\r\n try {\r\n await this.initialize();\r\n } catch (error) {\r\n console.warn('[MCPClient] Initialization failed during clearSession:', error);\r\n }\r\n\r\n if (this.oauthProvider) {\r\n await (this.oauthProvider as any).invalidateCredentials('all');\r\n }\r\n\r\n await storage.removeSession(this.identity, this.sessionId);\r\n this.disconnect();\r\n }\r\n\r\n /**\r\n * Checks if the client is currently connected to an MCP server\r\n * @returns True if connected, false otherwise\r\n */\r\n isConnected(): boolean {\r\n return this.client !== null;\r\n }\r\n\r\n /**\r\n * Disconnects from the MCP server and cleans up resources\r\n * Does not remove session from Redis - use clearSession() for that\r\n */\r\n disconnect(reason?: string): void {\r\n if (this.client) {\r\n this.client.close();\r\n }\r\n this.client = null;\r\n this.oauthProvider = null;\r\n this.transport = null;\r\n\r\n // Emit disconnected event\r\n if (this.serverId) {\r\n this._onConnectionEvent.fire({\r\n type: 'disconnected',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n reason,\r\n timestamp: Date.now(),\r\n });\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:disconnect',\r\n level: 'info',\r\n message: `Disconnected from ${this.serverId}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: {\r\n reason: reason || 'unknown',\r\n },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n }\r\n\r\n this.emitStateChange('DISCONNECTED');\r\n }\r\n\r\n /**\r\n * Dispose of all event emitters\r\n * Call this when the client is no longer needed\r\n */\r\n dispose(): void {\r\n this._onConnectionEvent.dispose();\r\n this._onObservabilityEvent.dispose();\r\n }\r\n\r\n /**\r\n * Gets the server URL\r\n * @returns Server URL or empty string if not set\r\n */\r\n getServerUrl(): string {\r\n return this.serverUrl || '';\r\n }\r\n\r\n /**\r\n * Gets the OAuth callback URL\r\n * @returns Callback URL or empty string if not set\r\n */\r\n getCallbackUrl(): string {\r\n return this.callbackUrl || '';\r\n }\r\n\r\n /**\r\n * Gets the transport type being used\r\n * @returns Transport type (defaults to 'streamable_http')\r\n */\r\n getTransportType(): TransportType {\r\n return this.transportType || 'streamable_http';\r\n }\r\n\r\n /**\r\n * Gets the human-readable server name\r\n * @returns Server name or undefined\r\n */\r\n getServerName(): string | undefined {\r\n return this.serverName;\r\n }\r\n\r\n /**\r\n * Gets the server ID\r\n * @returns Server ID or undefined\r\n */\r\n getServerId(): string | undefined {\r\n return this.serverId;\r\n }\r\n\r\n /**\r\n * Gets the session ID\r\n * @returns Session ID\r\n */\r\n getSessionId(): string {\r\n return this.sessionId;\r\n }\r\n\r\n /**\r\n * Gets MCP server configuration for all active user sessions\r\n * Loads sessions from Redis, validates OAuth tokens, refreshes if expired\r\n * Returns ready-to-use configuration with valid auth headers\r\n * @param identity - User ID to fetch sessions for\r\n * @returns Object keyed by sanitized server labels containing transport, url, headers, etc.\r\n * @static\r\n */\r\n static async getMcpServerConfig(identity: string): Promise<Record<string, any>> {\r\n const mcpConfig: Record<string, any> = {};\r\n const sessions = await storage.getIdentitySessionsData(identity);\r\n\r\n await Promise.all(\r\n sessions.map(async (sessionData) => {\r\n const { sessionId } = sessionData;\r\n\r\n try {\r\n // Validate session - remove if missing required fields\r\n if (\r\n !sessionData.serverId ||\r\n !sessionData.transportType ||\r\n !sessionData.serverUrl ||\r\n !sessionData.callbackUrl\r\n ) {\r\n await storage.removeSession(identity, sessionId);\r\n return;\r\n }\r\n\r\n // Get OAuth headers if session requires authentication\r\n let headers: Record<string, string> | undefined;\r\n try {\r\n // Inject existing session data to avoid redundant storage reads in initialize()\r\n const client = new MCPClient({\r\n identity,\r\n sessionId,\r\n serverId: sessionData.serverId,\r\n serverUrl: sessionData.serverUrl,\r\n callbackUrl: sessionData.callbackUrl,\r\n serverName: sessionData.serverName,\r\n transportType: sessionData.transportType,\r\n headers: sessionData.headers,\r\n });\r\n\r\n await client.initialize();\r\n\r\n const hasValidTokens = await client.getValidTokens();\r\n if (hasValidTokens && client.oauthProvider) {\r\n const tokens = await client.oauthProvider.tokens();\r\n if (tokens?.access_token) {\r\n headers = { Authorization: `Bearer ${tokens.access_token}` };\r\n }\r\n }\r\n } catch (error) {\r\n console.warn(`[MCP] Failed to get OAuth tokens for ${sessionId}:`, error);\r\n }\r\n\r\n // Build server config\r\n const label = sanitizeServerLabel(\r\n sessionData.serverName || sessionData.serverId || 'server'\r\n );\r\n\r\n mcpConfig[label] = {\r\n transport: sessionData.transportType,\r\n url: sessionData.serverUrl,\r\n ...(sessionData.serverName && {\r\n serverName: sessionData.serverName,\r\n serverLabel: label,\r\n }),\r\n ...(headers && { headers }),\r\n };\r\n } catch (error) {\r\n await storage.removeSession(identity, sessionId);\r\n console.warn(`[MCP] Failed to process session ${sessionId}:`, error);\r\n }\r\n })\r\n );\r\n\r\n return mcpConfig;\r\n }\r\n\r\n}\r\n\r\n","\r\n\r\nimport { MCPClient } from './oauth-client.js';\r\nimport { storage, type SessionData } from '../storage/index.js';\r\n\r\n/**\r\n * Manages multiple MCP connections for a single user identity.\r\n * Allows aggregating tools from all connected servers.\r\n */\r\nexport interface MultiSessionOptions {\r\n /**\r\n * Connection timeout in milliseconds\r\n * @default 15000\r\n */\r\n timeout?: number;\r\n /**\r\n * Maximum number of retry attempts\r\n * @default 2\r\n */\r\n maxRetries?: number;\r\n /**\r\n * Delay between retries in milliseconds\r\n * @default 1000\r\n */\r\n retryDelay?: number;\r\n}\r\n\r\n/**\r\n * Manages multiple MCP connections for a single user identity.\r\n * Allows aggregating tools from all connected servers.\r\n */\r\nexport class MultiSessionClient {\r\n private clients: MCPClient[] = [];\r\n private identity: string;\r\n private options: MultiSessionOptions;\r\n\r\n constructor(identity: string, options: MultiSessionOptions = {}) {\r\n this.identity = identity;\r\n this.options = {\r\n timeout: 15000,\r\n maxRetries: 2,\r\n retryDelay: 1000,\r\n ...options\r\n };\r\n }\r\n\r\n private async getActiveSessions(): Promise<SessionData[]> {\r\n const sessions = await storage.getIdentitySessionsData(this.identity);\r\n console.log(`[MultiSessionClient] All sessions for ${this.identity}:`,\r\n sessions.map(s => ({ sessionId: s.sessionId, serverId: s.serverId }))\r\n );\r\n const valid = sessions.filter(s => s.serverId && s.serverUrl && s.callbackUrl);\r\n console.log(`[MultiSessionClient] Filtered valid sessions:`, valid.length);\r\n return valid;\r\n }\r\n\r\n private async connectInBatches(sessions: SessionData[]): Promise<void> {\r\n const BATCH_SIZE = 5;\r\n for (let i = 0; i < sessions.length; i += BATCH_SIZE) {\r\n const batch = sessions.slice(i, i + BATCH_SIZE);\r\n await Promise.all(batch.map(session => this.connectSession(session)));\r\n }\r\n }\r\n\r\n private async connectSession(session: SessionData): Promise<void> {\r\n const existingClient = this.clients.find(c => c.getSessionId() === session.sessionId);\r\n if (existingClient?.isConnected()) {\r\n return;\r\n }\r\n\r\n const maxRetries = this.options.maxRetries ?? 2;\r\n const retryDelay = this.options.retryDelay ?? 1000;\r\n let lastError: unknown;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n try {\r\n const client = await this.createAndConnectClient(session);\r\n this.clients.push(client);\r\n return;\r\n } catch (error) {\r\n lastError = error;\r\n if (attempt < maxRetries) {\r\n await new Promise(resolve => setTimeout(resolve, retryDelay));\r\n }\r\n }\r\n }\r\n\r\n console.error(`[MultiSessionClient] Failed to connect to session ${session.sessionId} after ${maxRetries + 1} attempts:`, lastError);\r\n }\r\n\r\n private async createAndConnectClient(session: SessionData): Promise<MCPClient> {\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId: session.sessionId,\r\n serverId: session.serverId,\r\n serverUrl: session.serverUrl,\r\n callbackUrl: session.callbackUrl,\r\n serverName: session.serverName,\r\n transportType: session.transportType,\r\n headers: session.headers,\r\n });\r\n\r\n const timeoutMs = this.options.timeout ?? 15000;\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n setTimeout(() => reject(new Error(`Connection timed out after ${timeoutMs}ms`)), timeoutMs);\r\n });\r\n\r\n await Promise.race([client.connect(), timeoutPromise]);\r\n return client;\r\n }\r\n\r\n async connect(): Promise<void> {\r\n const sessions = await this.getActiveSessions();\r\n await this.connectInBatches(sessions);\r\n }\r\n\r\n /**\r\n * Returns the array of currently connected clients.\r\n */\r\n getClients(): MCPClient[] {\r\n return this.clients;\r\n }\r\n\r\n /**\r\n * Disconnects all clients.\r\n */\r\n disconnect(): void {\r\n this.clients.forEach((client) => client.disconnect());\r\n this.clients = [];\r\n }\r\n}\r\n\r\n","/**\r\n * SSE (Server-Sent Events) Handler for MCP Connections\r\n *\r\n * Manages real-time bidirectional communication with MCP clients:\r\n * - SSE stream for server → client events (connection state, tools, logs)\r\n * - HTTP POST for client → server RPC requests\r\n *\r\n * Key features:\r\n * - Direct HTTP response for RPC calls (bypasses SSE latency)\r\n * - Automatic session restoration and validation\r\n * - OAuth 2.1 authentication flow support\r\n * - Heartbeat to keep connections alive\r\n */\r\n\r\nimport type { McpConnectionEvent, McpObservabilityEvent } from '../../shared/events.js';\r\nimport type {\r\n McpRpcRequest,\r\n McpRpcResponse,\r\n ConnectParams,\r\n DisconnectParams,\r\n SessionParams,\r\n CallToolParams,\r\n GetPromptParams,\r\n ReadResourceParams,\r\n FinishAuthParams,\r\n SessionListResult,\r\n ConnectResult,\r\n DisconnectResult,\r\n RestoreSessionResult,\r\n FinishAuthResult,\r\n ListToolsRpcResult,\r\n ListPromptsResult,\r\n ListResourcesResult,\r\n CallToolResult,\r\n} from '../../shared/types.js';\r\nimport { RpcErrorCodes } from '../../shared/errors.js';\r\nimport { MCPClient } from '../mcp/oauth-client.js';\r\nimport { storage } from '../storage/index.js';\r\n\r\n// ============================================\r\n// Types & Interfaces\r\n// ============================================\r\n\r\nexport interface ClientMetadata {\r\n clientName?: string;\r\n clientUri?: string;\r\n logoUri?: string;\r\n policyUri?: string;\r\n}\r\n\r\nexport interface SSEHandlerOptions {\r\n /** User/Client identifier */\r\n identity: string;\r\n\r\n /** Optional callback for authentication/authorization */\r\n onAuth?: (identity: string) => Promise<boolean>;\r\n\r\n /** Heartbeat interval in milliseconds @default 30000 */\r\n heartbeatInterval?: number;\r\n\r\n /** Static OAuth client metadata defaults (for all connections) */\r\n clientDefaults?: ClientMetadata;\r\n\r\n /** Dynamic OAuth client metadata getter (per-request, useful for multi-tenant) */\r\n getClientMetadata?: (request?: unknown) => ClientMetadata | Promise<ClientMetadata>;\r\n}\r\n\r\n// ============================================\r\n// Constants\r\n// ============================================\r\n\r\nconst DEFAULT_HEARTBEAT_INTERVAL = 30000;\r\n\r\n// ============================================\r\n// SSEConnectionManager Class\r\n// ============================================\r\n\r\n/**\r\n * Manages a single SSE connection and handles MCP operations.\r\n * Each instance corresponds to one connected browser client.\r\n */\r\nexport class SSEConnectionManager {\r\n private readonly identity: string;\r\n private readonly clients = new Map<string, MCPClient>();\r\n private heartbeatTimer?: NodeJS.Timeout;\r\n private isActive = true;\r\n\r\n constructor(\r\n private readonly options: SSEHandlerOptions,\r\n private readonly sendEvent: (event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse) => void\r\n ) {\r\n this.identity = options.identity;\r\n this.startHeartbeat();\r\n }\r\n\r\n /**\r\n * Get resolved client metadata (dynamic > static > defaults)\r\n */\r\n private async getResolvedClientMetadata(request?: any): Promise<ClientMetadata> {\r\n // Priority: getClientMetadata() > clientDefaults > empty object\r\n let metadata: ClientMetadata = {};\r\n\r\n // Start with static defaults\r\n if (this.options.clientDefaults) {\r\n metadata = { ...this.options.clientDefaults };\r\n }\r\n\r\n // Override with dynamic metadata if provided\r\n if (this.options.getClientMetadata) {\r\n const dynamicMetadata = await this.options.getClientMetadata(request);\r\n metadata = { ...metadata, ...dynamicMetadata };\r\n }\r\n\r\n return metadata;\r\n }\r\n\r\n /**\r\n * Start heartbeat to keep connection alive\r\n */\r\n private startHeartbeat(): void {\r\n const interval = this.options.heartbeatInterval ?? DEFAULT_HEARTBEAT_INTERVAL;\r\n this.heartbeatTimer = setInterval(() => {\r\n if (this.isActive) {\r\n this.sendEvent({\r\n level: 'debug',\r\n message: 'heartbeat',\r\n timestamp: Date.now(),\r\n } as McpObservabilityEvent);\r\n }\r\n }, interval);\r\n }\r\n\r\n /**\r\n * Handle incoming RPC requests\r\n * Returns the RPC response directly for immediate HTTP response (bypassing SSE latency)\r\n */\r\n async handleRequest(request: McpRpcRequest): Promise<McpRpcResponse> {\r\n try {\r\n let result: SessionListResult | ConnectResult | DisconnectResult | RestoreSessionResult | FinishAuthResult | ListToolsRpcResult | ListPromptsResult | ListResourcesResult | unknown;\r\n\r\n switch (request.method) {\r\n case 'getSessions':\r\n result = await this.getSessions();\r\n break;\r\n\r\n case 'connect':\r\n result = await this.connect(request.params as ConnectParams);\r\n break;\r\n\r\n case 'disconnect':\r\n result = await this.disconnect(request.params as DisconnectParams);\r\n break;\r\n\r\n case 'listTools':\r\n result = await this.listTools(request.params as SessionParams);\r\n break;\r\n\r\n case 'callTool':\r\n result = await this.callTool(request.params as CallToolParams);\r\n break;\r\n\r\n case 'restoreSession':\r\n result = await this.restoreSession(request.params as SessionParams);\r\n break;\r\n\r\n case 'finishAuth':\r\n result = await this.finishAuth(request.params as FinishAuthParams);\r\n break;\r\n\r\n case 'listPrompts':\r\n result = await this.listPrompts(request.params as SessionParams);\r\n break;\r\n\r\n case 'getPrompt':\r\n result = await this.getPrompt(request.params as GetPromptParams);\r\n break;\r\n\r\n case 'listResources':\r\n result = await this.listResources(request.params as SessionParams);\r\n break;\r\n\r\n case 'readResource':\r\n result = await this.readResource(request.params as ReadResourceParams);\r\n break;\r\n\r\n default:\r\n throw new Error(`Unknown method: ${request.method}`);\r\n }\r\n\r\n const response: McpRpcResponse = {\r\n id: request.id,\r\n result,\r\n };\r\n\r\n // Also send via SSE for backwards compatibility\r\n this.sendEvent(response);\r\n\r\n return response;\r\n } catch (error) {\r\n const errorResponse: McpRpcResponse = {\r\n id: request.id,\r\n error: {\r\n code: RpcErrorCodes.EXECUTION_ERROR,\r\n message: error instanceof Error ? error.message : 'Unknown error',\r\n },\r\n };\r\n\r\n // Also send via SSE for backwards compatibility\r\n this.sendEvent(errorResponse);\r\n\r\n return errorResponse;\r\n }\r\n }\r\n\r\n /**\r\n * Get all sessions for the current identity\r\n */\r\n private async getSessions(): Promise<SessionListResult> {\r\n const sessions = await storage.getIdentitySessionsData(this.identity);\r\n\r\n return {\r\n sessions: sessions.map((s) => ({\r\n sessionId: s.sessionId,\r\n serverId: s.serverId,\r\n serverName: s.serverName,\r\n serverUrl: s.serverUrl,\r\n transport: s.transportType,\r\n createdAt: s.createdAt,\r\n active: s.active !== false,\r\n })),\r\n };\r\n }\r\n\r\n /**\r\n * Connect to an MCP server\r\n */\r\n private async connect(params: ConnectParams): Promise<ConnectResult> {\r\n const { serverName, serverUrl, callbackUrl, transportType } = params;\r\n\r\n // Normalize serverId to max 12 chars to keep tool names under 64 chars (DeepSeek/OpenAI limits)\r\n // Tool name format: tool_<serverId>_<toolName> - with 12 char serverId leaves 46 chars for tool name\r\n const serverId = params.serverId && params.serverId.length <= 12\r\n ? params.serverId\r\n : await storage.generateSessionId();\r\n\r\n // Check for existing connections\r\n const existingSessions = await storage.getIdentitySessionsData(this.identity);\r\n const duplicate = existingSessions.find(s =>\r\n s.serverId === serverId || s.serverUrl === serverUrl\r\n );\r\n\r\n if (duplicate) {\r\n // If the existing session is still pending OAuth, treat connect as \"resume auth\"\r\n // instead of failing with duplicate connection error.\r\n if (duplicate.active === false) {\r\n await this.restoreSession({ sessionId: duplicate.sessionId });\r\n return {\r\n sessionId: duplicate.sessionId,\r\n success: true,\r\n };\r\n }\r\n throw new Error(`Connection already exists for server: ${duplicate.serverUrl || duplicate.serverId} (${duplicate.serverName})`);\r\n }\r\n\r\n // Generate session ID\r\n const sessionId = await storage.generateSessionId();\r\n\r\n // Emit connecting state\r\n this.emitConnectionEvent({\r\n type: 'state_changed',\r\n sessionId,\r\n serverId,\r\n serverName,\r\n serverUrl,\r\n state: 'CONNECTING',\r\n previousState: 'DISCONNECTED',\r\n timestamp: Date.now(),\r\n });\r\n\r\n try {\r\n // Get resolved client metadata\r\n const clientMetadata = await this.getResolvedClientMetadata();\r\n\r\n // Create MCP client\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId,\r\n serverId,\r\n serverName,\r\n serverUrl,\r\n callbackUrl,\r\n transportType,\r\n ...clientMetadata, // Spread client metadata (clientName, clientUri, logoUri, policyUri)\r\n onRedirect: (authUrl) => {\r\n // Emit auth required event\r\n this.emitConnectionEvent({\r\n type: 'auth_required',\r\n sessionId,\r\n serverId,\r\n authUrl,\r\n timestamp: Date.now(),\r\n });\r\n },\r\n });\r\n\r\n // Note: Session will be created by MCPClient after successful connection\r\n // This ensures sessions only exist for successful or OAuth-pending connections\r\n\r\n // Store client\r\n this.clients.set(sessionId, client);\r\n\r\n // Subscribe to client events\r\n client.onConnectionEvent((event) => {\r\n this.emitConnectionEvent(event);\r\n });\r\n\r\n client.onObservabilityEvent((event) => {\r\n this.sendEvent(event);\r\n });\r\n\r\n // Attempt connection\r\n await client.connect();\r\n\r\n // Fetch tools\r\n const tools = await client.listTools();\r\n\r\n this.emitConnectionEvent({\r\n type: 'tools_discovered',\r\n sessionId,\r\n serverId,\r\n toolCount: tools.tools.length,\r\n tools: tools.tools,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return {\r\n sessionId,\r\n success: true,\r\n };\r\n } catch (error) {\r\n this.emitConnectionEvent({\r\n type: 'error',\r\n sessionId,\r\n serverId,\r\n error: error instanceof Error ? error.message : 'Connection failed',\r\n errorType: 'connection',\r\n timestamp: Date.now(),\r\n });\r\n\r\n // Clean up client\r\n this.clients.delete(sessionId);\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect from an MCP server\r\n */\r\n private async disconnect(params: DisconnectParams): Promise<DisconnectResult> {\r\n const { sessionId } = params;\r\n const client = this.clients.get(sessionId);\r\n\r\n if (client) {\r\n await client.clearSession();\r\n client.disconnect();\r\n this.clients.delete(sessionId);\r\n } else {\r\n // Handle orphaned sessions (e.g., OAuth flow failed before client was stored)\r\n // Directly remove from storage since there's no active client\r\n await storage.removeSession(this.identity, sessionId);\r\n }\r\n\r\n return { success: true };\r\n }\r\n\r\n /**\r\n * Get an existing client or create and connect a new one for the session.\r\n */\r\n private async getOrCreateClient(sessionId: string): Promise<MCPClient> {\r\n const existing = this.clients.get(sessionId);\r\n if (existing) {\r\n return existing;\r\n }\r\n\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId,\r\n });\r\n\r\n // Subscribe to events before connecting\r\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\r\n client.onObservabilityEvent((event) => this.sendEvent(event));\r\n\r\n await client.connect();\r\n this.clients.set(sessionId, client);\r\n\r\n return client;\r\n }\r\n\r\n /**\r\n * List tools from a session\r\n */\r\n private async listTools(params: SessionParams): Promise<ListToolsRpcResult> {\r\n const { sessionId } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.listTools();\r\n return { tools: result.tools };\r\n }\r\n\r\n /**\r\n * Call a tool on the MCP server\r\n */\r\n private async callTool(params: CallToolParams): Promise<CallToolResult> {\r\n const { sessionId, toolName, toolArgs } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.callTool(toolName, toolArgs);\r\n\r\n // Inject sessionId into meta so client knows who handled it\r\n // This allows AppHost to auto-launch without scanning all sessions\r\n const meta = result._meta || {};\r\n\r\n return {\r\n ...result,\r\n _meta: {\r\n ...meta,\r\n sessionId,\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Restore and validate an existing session\r\n */\r\n private async restoreSession(params: SessionParams): Promise<RestoreSessionResult> {\r\n const { sessionId } = params;\r\n\r\n const session = await storage.getSession(this.identity, sessionId);\r\n if (!session) {\r\n throw new Error('Session not found');\r\n }\r\n\r\n this.emitConnectionEvent({\r\n type: 'state_changed',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n serverName: session.serverName ?? 'Unknown',\r\n serverUrl: session.serverUrl,\r\n state: 'VALIDATING',\r\n previousState: 'DISCONNECTED',\r\n timestamp: Date.now(),\r\n });\r\n\r\n try {\r\n const clientMetadata = await this.getResolvedClientMetadata();\r\n\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId,\r\n ...clientMetadata,\r\n });\r\n\r\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\r\n client.onObservabilityEvent((event) => this.sendEvent(event));\r\n\r\n await client.connect();\r\n this.clients.set(sessionId, client);\r\n\r\n const tools = await client.listTools();\r\n\r\n this.emitConnectionEvent({\r\n type: 'tools_discovered',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n toolCount: tools.tools.length,\r\n tools: tools.tools,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return { success: true, toolCount: tools.tools.length };\r\n } catch (error) {\r\n this.emitConnectionEvent({\r\n type: 'error',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n error: error instanceof Error ? error.message : 'Validation failed',\r\n errorType: 'validation',\r\n timestamp: Date.now(),\r\n });\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Complete OAuth authorization flow\r\n */\r\n private async finishAuth(params: FinishAuthParams): Promise<FinishAuthResult> {\r\n const { sessionId, code } = params;\r\n\r\n const session = await storage.getSession(this.identity, sessionId);\r\n if (!session) {\r\n throw new Error('Session not found');\r\n }\r\n\r\n this.emitConnectionEvent({\r\n type: 'state_changed',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n serverName: session.serverName ?? 'Unknown',\r\n serverUrl: session.serverUrl,\r\n state: 'AUTHENTICATING',\r\n previousState: 'DISCONNECTED',\r\n timestamp: Date.now(),\r\n });\r\n\r\n try {\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId,\r\n });\r\n\r\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\r\n\r\n await client.finishAuth(code);\r\n this.clients.set(sessionId, client);\r\n\r\n const tools = await client.listTools();\r\n\r\n this.emitConnectionEvent({\r\n type: 'tools_discovered',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n toolCount: tools.tools.length,\r\n tools: tools.tools,\r\n timestamp: Date.now(),\r\n });\r\n\r\n return { success: true, toolCount: tools.tools.length };\r\n } catch (error) {\r\n this.emitConnectionEvent({\r\n type: 'error',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n error: error instanceof Error ? error.message : 'OAuth completion failed',\r\n errorType: 'auth',\r\n timestamp: Date.now(),\r\n });\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * List prompts from a session\r\n */\r\n private async listPrompts(params: SessionParams): Promise<ListPromptsResult> {\r\n const { sessionId } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.listPrompts();\r\n return { prompts: result.prompts };\r\n }\r\n\r\n /**\r\n * Get a specific prompt\r\n */\r\n private async getPrompt(params: GetPromptParams): Promise<unknown> {\r\n const { sessionId, name, args } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n return await client.getPrompt(name, args);\r\n }\r\n\r\n /**\r\n * List resources from a session\r\n */\r\n private async listResources(params: SessionParams): Promise<ListResourcesResult> {\r\n const { sessionId } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.listResources();\r\n return { resources: result.resources };\r\n }\r\n\r\n /**\r\n * Read a specific resource\r\n */\r\n private async readResource(params: ReadResourceParams): Promise<unknown> {\r\n const { sessionId, uri } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n return client.readResource(uri);\r\n }\r\n\r\n /**\r\n * Emit connection event\r\n */\r\n private emitConnectionEvent(event: McpConnectionEvent): void {\r\n this.sendEvent(event);\r\n }\r\n\r\n /**\r\n * Cleanup and close all connections\r\n */\r\n dispose(): void {\r\n this.isActive = false;\r\n\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n }\r\n\r\n for (const client of this.clients.values()) {\r\n client.disconnect();\r\n }\r\n\r\n this.clients.clear();\r\n }\r\n}\r\n\r\n// ============================================\r\n// SSE Handler Factory\r\n// ============================================\r\n\r\n/**\r\n * Create an SSE endpoint handler compatible with Node.js HTTP frameworks.\r\n * Handles both SSE streaming (GET) and RPC requests (POST).\r\n */\r\nexport function createSSEHandler(options: SSEHandlerOptions) {\r\n return async (req: { method?: string; on: Function }, res: { writeHead: Function; write: Function }) => {\r\n // Set SSE headers\r\n res.writeHead(200, {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive',\r\n 'Access-Control-Allow-Origin': '*',\r\n });\r\n\r\n // Send initial connection acknowledgment\r\n writeSSEEvent(res, 'connected', { timestamp: Date.now() });\r\n\r\n // Create connection manager with event routing\r\n const manager = new SSEConnectionManager(options, (event) => {\r\n if ('id' in event) {\r\n writeSSEEvent(res, 'rpc-response', event);\r\n } else if ('type' in event && 'sessionId' in event) {\r\n writeSSEEvent(res, 'connection', event);\r\n } else {\r\n writeSSEEvent(res, 'observability', event);\r\n }\r\n });\r\n\r\n // Cleanup on client disconnect\r\n req.on('close', () => manager.dispose());\r\n\r\n // Handle RPC requests via POST\r\n if (req.method === 'POST') {\r\n let body = '';\r\n req.on('data', (chunk: Buffer) => {\r\n body += chunk.toString();\r\n });\r\n req.on('end', async () => {\r\n try {\r\n const request: McpRpcRequest = JSON.parse(body);\r\n await manager.handleRequest(request);\r\n } catch {\r\n // Request parsing/handling errors are sent via SSE error events\r\n }\r\n });\r\n }\r\n };\r\n}\r\n\r\n// ============================================\r\n// Utilities\r\n// ============================================\r\n\r\n/**\r\n * Write an SSE event to the response stream\r\n */\r\nfunction writeSSEEvent(res: { write: Function }, event: string, data: unknown): void {\r\n res.write(`event: ${event}\\n`);\r\n res.write(`data: ${JSON.stringify(data)}\\n\\n`);\r\n}\r\n","/**\n * Next.js App Router Handler for MCP\n * Stateless transport for serverless environments:\n * - POST + `Accept: text/event-stream` streams progress + rpc-response\n * - POST + JSON accepts direct RPC result response\n */\n\nimport { SSEConnectionManager, type ClientMetadata } from './sse-handler.js';\nimport type { McpConnectionEvent, McpObservabilityEvent } from '../../shared/events.js';\nimport type { McpRpcResponse } from '../../shared/types.js';\n\nfunction isRpcResponseEvent(event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse): event is McpRpcResponse {\n return 'id' in event && ('result' in event || 'error' in event);\n}\n\nexport interface NextMcpHandlerOptions {\n /**\n * Extract identity from request (default: from 'identity' query param)\n */\n getIdentity?: (request: Request) => string | null;\n\n /**\n * Extract auth token from request (default: from 'token' query param or Authorization header)\n */\n getAuthToken?: (request: Request) => string | null;\n\n /**\n * Authenticate user and verify access (optional)\n * Return true if user is authenticated, false otherwise\n */\n authenticate?: (identity: string, token: string | null) => Promise<boolean> | boolean;\n\n /**\n * Heartbeat interval in milliseconds (default: 30000)\n */\n heartbeatInterval?: number;\n\n /**\n * Static OAuth client metadata defaults (for all connections)\n */\n clientDefaults?: ClientMetadata;\n\n /**\n * Dynamic OAuth client metadata getter (per-request)\n */\n getClientMetadata?: (request: Request) => ClientMetadata | Promise<ClientMetadata>;\n}\n\nexport function createNextMcpHandler(options: NextMcpHandlerOptions = {}) {\n const {\n getIdentity = (request: Request) => new URL(request.url).searchParams.get('identity'),\n getAuthToken = (request: Request) => {\n const url = new URL(request.url);\n return url.searchParams.get('token') || request.headers.get('authorization');\n },\n authenticate = () => true,\n heartbeatInterval = 30000,\n clientDefaults,\n getClientMetadata,\n } = options;\n\n const toManagerOptions = (identity: string, resolvedClientMetadata?: ClientMetadata) => ({\n identity,\n heartbeatInterval,\n clientDefaults: resolvedClientMetadata,\n });\n\n async function resolveClientMetadata(request: Request): Promise<ClientMetadata | undefined> {\n return getClientMetadata ? await getClientMetadata(request) : clientDefaults;\n }\n\n async function GET(): Promise<Response> {\n return Response.json(\n {\n error: {\n code: 'METHOD_NOT_ALLOWED',\n message: 'Use POST /api/mcp. For streaming use Accept: text/event-stream.',\n },\n },\n { status: 405 }\n );\n }\n\n async function POST(request: Request): Promise<Response> {\n const identity = getIdentity(request);\n const authToken = getAuthToken(request);\n const acceptsEventStream = (request.headers.get('accept') || '').toLowerCase().includes('text/event-stream');\n\n if (!identity) {\n return Response.json({ error: { code: 'MISSING_IDENTITY', message: 'Missing identity' } }, { status: 400 });\n }\n\n const isAuthorized = await authenticate(identity, authToken);\n if (!isAuthorized) {\n return Response.json({ error: { code: 'UNAUTHORIZED', message: 'Unauthorized' } }, { status: 401 });\n }\n\n let rawBody = '';\n try {\n rawBody = await request.text();\n const body = rawBody ? JSON.parse(rawBody) : null;\n\n if (!body || typeof body !== 'object') {\n return Response.json(\n {\n error: {\n code: 'INVALID_REQUEST',\n message: 'Invalid JSON-RPC request body',\n },\n },\n { status: 400 }\n );\n }\n\n const resolvedClientMetadata = await resolveClientMetadata(request);\n\n if (!acceptsEventStream) {\n const manager = new SSEConnectionManager(\n toManagerOptions(identity, resolvedClientMetadata),\n () => { }\n );\n try {\n const response = await manager.handleRequest(body as any);\n return Response.json(response);\n } finally {\n manager.dispose();\n }\n }\n\n const stream = new TransformStream();\n const writer = stream.writable.getWriter();\n const encoder = new TextEncoder();\n let streamWritable = true;\n\n const sendSSE = (event: string, data: unknown) => {\n if (!streamWritable) return;\n const message = `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\n writer.write(encoder.encode(message)).catch(() => {\n streamWritable = false;\n });\n };\n\n const manager = new SSEConnectionManager(\n toManagerOptions(identity, resolvedClientMetadata),\n (event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse) => {\n if (isRpcResponseEvent(event)) {\n sendSSE('rpc-response', event);\n } else if ('type' in event && 'sessionId' in event) {\n sendSSE('connection', event);\n } else {\n sendSSE('observability', event);\n }\n }\n );\n\n sendSSE('connected', { timestamp: Date.now() });\n\n void (async () => {\n try {\n await manager.handleRequest(body as any);\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Unknown error');\n sendSSE('rpc-response', {\n id: (body as any).id || 'unknown',\n error: {\n code: 'EXECUTION_ERROR',\n message: err.message,\n },\n } satisfies McpRpcResponse);\n } finally {\n streamWritable = false;\n manager.dispose();\n writer.close().catch(() => { });\n }\n })();\n\n return new Response(stream.readable, {\n status: 200,\n headers: {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache, no-transform',\n 'Connection': 'keep-alive',\n 'X-Accel-Buffering': 'no',\n },\n });\n } catch (error) {\n const err = error instanceof Error ? error : new Error('Unknown error');\n console.error('[MCP Next Handler] Failed to handle RPC', {\n identity,\n message: err.message,\n stack: err.stack,\n rawBody: rawBody.slice(0, 500),\n });\n return Response.json(\n {\n error: {\n code: 'EXECUTION_ERROR',\n message: err.message,\n },\n },\n { status: 500 }\n );\n }\n }\n\n return { GET, POST };\n}\n","/**\n * Stateless RPC-over-stream client for MCP connections.\n *\n * Uses single POST requests with `Accept: text/event-stream` for every RPC call.\n * Progress events and the final rpc-response are delivered in the same response.\n */\n\nimport { nanoid } from 'nanoid';\nimport type {\n McpConnectionEvent,\n McpObservabilityEvent,\n McpAppsUIEvent\n} from '../../shared/events.js';\nimport type {\n McpRpcRequest,\n McpRpcResponse,\n McpRpcMethod,\n McpRpcParams,\n ConnectParams,\n SessionListResult,\n ConnectResult,\n DisconnectResult,\n RestoreSessionResult,\n FinishAuthResult,\n ListToolsRpcResult,\n ListPromptsResult,\n ListResourcesResult,\n} from '../../shared/types.js';\n\nexport interface SSEClientOptions {\n /** MCP endpoint URL */\n url: string;\n\n /** User/Client identifier */\n identity: string;\n\n /** Optional auth token for authenticated requests */\n authToken?: string;\n\n /** Callback for MCP connection state changes */\n onConnectionEvent?: (event: McpConnectionEvent) => void;\n\n /** Callback for observability/logging events */\n onObservabilityEvent?: (event: McpObservabilityEvent) => void;\n\n /** Callback for connection status changes */\n onStatusChange?: (status: ConnectionStatus) => void;\n\n /** Callback for MCP App UI events */\n onEvent?: (event: McpAppsUIEvent) => void;\n\n /** Enable debug logging @default false */\n debug?: boolean;\n}\n\nexport type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\n\ninterface ToolUiMetadata {\n resourceUri?: string;\n uri?: string;\n visibility?: string[];\n}\n\nexport class SSEClient {\n private resourceCache = new Map<string, Promise<unknown>>();\n private connected = false;\n\n constructor(private readonly options: SSEClientOptions) {}\n\n connect(): void {\n if (this.connected) {\n return;\n }\n this.connected = true;\n this.options.onStatusChange?.('connected');\n this.log('RPC mode: post_stream');\n }\n\n disconnect(): void {\n this.connected = false;\n this.options.onStatusChange?.('disconnected');\n }\n\n isConnected(): boolean {\n return this.connected;\n }\n\n async getSessions(): Promise<SessionListResult> {\n return this.sendRequest<SessionListResult>('getSessions');\n }\n\n async connectToServer(params: ConnectParams): Promise<ConnectResult> {\n return this.sendRequest<ConnectResult>('connect', params);\n }\n\n async disconnectFromServer(sessionId: string): Promise<DisconnectResult> {\n return this.sendRequest<DisconnectResult>('disconnect', { sessionId });\n }\n\n async listTools(sessionId: string): Promise<ListToolsRpcResult> {\n return this.sendRequest<ListToolsRpcResult>('listTools', { sessionId });\n }\n\n async callTool(\n sessionId: string,\n toolName: string,\n toolArgs: Record<string, unknown>\n ): Promise<unknown> {\n const result = await this.sendRequest('callTool', { sessionId, toolName, toolArgs });\n this.emitUiEventIfPresent(result, sessionId, toolName);\n return result;\n }\n\n async restoreSession(sessionId: string): Promise<RestoreSessionResult> {\n return this.sendRequest<RestoreSessionResult>('restoreSession', { sessionId });\n }\n\n async finishAuth(sessionId: string, code: string): Promise<FinishAuthResult> {\n return this.sendRequest<FinishAuthResult>('finishAuth', { sessionId, code });\n }\n\n async listPrompts(sessionId: string): Promise<ListPromptsResult> {\n return this.sendRequest<ListPromptsResult>('listPrompts', { sessionId });\n }\n\n async getPrompt(sessionId: string, name: string, args?: Record<string, string>): Promise<unknown> {\n return this.sendRequest('getPrompt', { sessionId, name, args });\n }\n\n async listResources(sessionId: string): Promise<ListResourcesResult> {\n return this.sendRequest<ListResourcesResult>('listResources', { sessionId });\n }\n\n async readResource(sessionId: string, uri: string): Promise<unknown> {\n return this.sendRequest('readResource', { sessionId, uri });\n }\n\n preloadToolUiResources(sessionId: string, tools: Array<{ name: string; _meta?: unknown }>): void {\n for (const tool of tools) {\n const uri = this.extractUiResourceUri(tool);\n if (!uri || this.resourceCache.has(uri)) continue;\n const promise = this.sendRequest('readResource', { sessionId, uri }).catch((err) => {\n this.log(`Failed to preload resource ${uri}: ${err.message}`, 'warn');\n this.resourceCache.delete(uri);\n return null;\n });\n this.resourceCache.set(uri, promise);\n }\n }\n\n getOrFetchResource(sessionId: string, uri: string): Promise<unknown> {\n const cached = this.resourceCache.get(uri);\n if (cached) return cached;\n const promise = this.sendRequest('readResource', { sessionId, uri });\n this.resourceCache.set(uri, promise);\n return promise;\n }\n\n hasPreloadedResource(uri: string): boolean {\n return this.resourceCache.has(uri);\n }\n\n clearResourceCache(): void {\n this.resourceCache.clear();\n }\n\n private async sendRequest<T = unknown>(method: McpRpcMethod, params?: McpRpcParams): Promise<T> {\n if (!this.connected) {\n this.connect();\n }\n\n this.log(`RPC request via post_stream: ${method}`);\n\n const request: McpRpcRequest = {\n id: `rpc_${nanoid(10)}`,\n method,\n params,\n };\n\n const response = await fetch(this.buildUrl(), {\n method: 'POST',\n headers: this.buildHeaders(),\n body: JSON.stringify(request),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\n if (!contentType.includes('text/event-stream')) {\n const data = await response.json() as McpRpcResponse;\n return this.parseRpcResponse<T>(data);\n }\n\n const data = await this.readRpcResponseFromStream(response);\n return this.parseRpcResponse<T>(data);\n }\n\n private async readRpcResponseFromStream(response: Response): Promise<McpRpcResponse> {\n if (!response.body) {\n throw new Error('Streaming response body is missing');\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n let buffer = '';\n let rpcResponse: McpRpcResponse | null = null;\n\n const dispatchBlock = (block: string) => {\n const lines = block.split('\\n');\n let eventName = 'message';\n const dataLines: string[] = [];\n\n for (const rawLine of lines) {\n const line = rawLine.replace(/\\r$/, '');\n if (!line || line.startsWith(':')) continue;\n if (line.startsWith('event:')) {\n eventName = line.slice('event:'.length).trim();\n continue;\n }\n if (line.startsWith('data:')) {\n dataLines.push(line.slice('data:'.length).trimStart());\n }\n }\n\n if (!dataLines.length) return;\n const payloadText = dataLines.join('\\n');\n let payload: unknown = payloadText;\n try {\n payload = JSON.parse(payloadText);\n } catch {\n // Keep raw text\n }\n\n switch (eventName) {\n case 'connected':\n this.options.onStatusChange?.('connected');\n break;\n case 'connection':\n this.options.onConnectionEvent?.(payload as McpConnectionEvent);\n break;\n case 'observability':\n this.options.onObservabilityEvent?.(payload as McpObservabilityEvent);\n break;\n case 'rpc-response':\n rpcResponse = payload as McpRpcResponse;\n break;\n default:\n break;\n }\n };\n\n while (true) {\n const { value, done } = await reader.read();\n if (done) break;\n buffer += decoder.decode(value, { stream: true });\n\n let separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\n while (separatorMatch && separatorMatch.index !== undefined) {\n const separatorIndex = separatorMatch.index;\n const separatorLength = separatorMatch[0].length;\n const block = buffer.slice(0, separatorIndex);\n buffer = buffer.slice(separatorIndex + separatorLength);\n dispatchBlock(block);\n separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\n }\n }\n\n if (buffer.trim()) {\n dispatchBlock(buffer);\n }\n\n if (!rpcResponse) {\n throw new Error('Missing rpc-response event in streamed RPC result');\n }\n\n return rpcResponse;\n }\n\n private parseRpcResponse<T>(data: McpRpcResponse): T {\n if ('result' in data) {\n return data.result as T;\n }\n if ('error' in data && data.error) {\n throw new Error(data.error.message || 'Unknown RPC error');\n }\n // JSON omits `result` when it is `undefined` (response becomes `{ id: ... }`).\n // Treat that shape as a successful void result.\n if (data && typeof data === 'object' && 'id' in data) {\n return undefined as T;\n }\n throw new Error('Invalid RPC response format');\n }\n\n private buildUrl(): string {\n const url = new URL(this.options.url, globalThis.location?.origin);\n url.searchParams.set('identity', this.options.identity);\n if (this.options.authToken) {\n url.searchParams.set('token', this.options.authToken);\n }\n return url.toString();\n }\n\n private buildHeaders(): HeadersInit {\n const headers: HeadersInit = {\n 'Content-Type': 'application/json',\n 'Accept': 'text/event-stream',\n };\n if (this.options.authToken) {\n headers['Authorization'] = `Bearer ${this.options.authToken}`;\n }\n return headers;\n }\n\n private extractUiResourceUri(tool: { name: string; _meta?: unknown }): string | undefined {\n const meta = (tool._meta as { ui?: ToolUiMetadata })?.ui;\n if (!meta || typeof meta !== 'object') return undefined;\n if (meta.visibility && !meta.visibility.includes('app')) return undefined;\n return meta.resourceUri ?? meta.uri;\n }\n\n private emitUiEventIfPresent(result: unknown, sessionId: string, toolName: string): void {\n const meta = (result as { _meta?: { ui?: ToolUiMetadata } })?._meta;\n const resourceUri = meta?.ui?.resourceUri ?? (meta as any)?.['ui/resourceUri'];\n\n if (resourceUri) {\n this.options.onEvent?.({\n type: 'mcp-apps-ui',\n sessionId,\n resourceUri,\n toolName,\n result,\n timestamp: Date.now(),\n });\n }\n }\n\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\n if (!this.options.debug && level === 'info') return;\n\n const prefix = '[SSEClient]';\n switch (level) {\n case 'warn':\n console.warn(prefix, message);\n break;\n case 'error':\n console.error(prefix, message);\n break;\n default:\n console.log(prefix, message);\n }\n }\n}\n","/**\r\n * MCP App Host\r\n *\r\n * Bridges the gap between an iframe (MCP App) and the SSEClient (MCP Server).\r\n * Handles secure iframe sandboxing, resource loading, and bi-directional\r\n * communication via the AppBridge protocol.\r\n *\r\n * Key features:\r\n * - Secure iframe sandboxing with minimal permissions\r\n * - Resource preloading for instant MCP App UI loading\r\n * - Cache-aware resource fetching (SSEClient cache → local cache → direct fetch)\r\n * - Support for ui:// and mcp-app:// resource URIs\r\n */\r\n\r\nimport { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';\r\nimport type { AppHostClient } from './types';\r\n\r\n// ============================================\r\n// Types & Interfaces\r\n// ============================================\r\n\r\nexport interface AppHostOptions {\r\n /** Enable debug logging @default false */\r\n debug?: boolean;\r\n}\r\n\r\nexport interface AppMessageParams {\r\n role: string;\r\n content: unknown;\r\n}\r\n\r\ninterface ToolCallParams {\r\n name: string;\r\n arguments?: Record<string, unknown>;\r\n}\r\n\r\ninterface ResourceContent {\r\n blob?: string;\r\n text?: string;\r\n}\r\n\r\ninterface ResourceResponse {\r\n contents: ResourceContent[];\r\n}\r\n\r\n// ============================================\r\n// Constants\r\n// ============================================\r\n\r\nconst HOST_INFO = { name: 'mcp-ts-host', version: '1.0.0' };\r\n\r\n/** Sandbox permissions - minimal set required for MCP Apps to function */\r\nconst SANDBOX_PERMISSIONS = [\r\n 'allow-scripts', // Required for app JavaScript execution\r\n 'allow-forms', // Required for form submissions\r\n 'allow-same-origin', // Required for Blob URL correctness\r\n 'allow-modals', // Required for dialogs/alerts\r\n 'allow-popups', // Required for opening links\r\n 'allow-downloads' // Required for file downloads\r\n].join(' ');\r\n\r\n/** Supported MCP App URI schemes */\r\nconst MCP_URI_SCHEMES = ['ui://', 'mcp-app://'] as const;\r\n\r\n// ============================================\r\n// AppHost Class\r\n// ============================================\r\n\r\n/**\r\n * Host for MCP Apps embedded in iframes.\r\n * Manages secure communication between the app and the MCP server.\r\n */\r\nexport class AppHost {\r\n private bridge: AppBridge;\r\n private sessionId?: string;\r\n private resourceCache = new Map<string, Promise<ResourceResponse | null>>();\r\n private debug: boolean;\r\n\r\n /** Callback for app messages (e.g., chat messages from the app) */\r\n public onAppMessage?: (params: AppMessageParams) => void;\r\n\r\n constructor(\r\n private readonly client: AppHostClient,\r\n private readonly iframe: HTMLIFrameElement,\r\n options?: AppHostOptions\r\n ) {\r\n this.debug = options?.debug ?? false;\r\n this.configureSandbox();\r\n this.bridge = this.initializeBridge();\r\n }\r\n\r\n // ============================================\r\n // Public API\r\n // ============================================\r\n\r\n /**\r\n * Start the host. This prepares the bridge handlers but doesn't connect yet.\r\n * The actual connection happens in launch() after HTML is loaded.\r\n * @returns Promise that resolves immediately (bridge connects during launch)\r\n */\r\n async start(): Promise<void> {\r\n // Bridge handlers are already registered in constructor.\r\n // Connection happens in launch() after HTML is loaded.\r\n this.log('Host started, ready to launch');\r\n }\r\n\r\n /**\r\n * Preload UI resources to enable instant app loading.\r\n * Call this when tools are discovered to cache their UI resources.\r\n */\r\n preload(tools: Array<{ _meta?: unknown }>): void {\r\n for (const tool of tools) {\r\n const uri = this.extractUiResourceUri(tool);\r\n if (!uri || this.resourceCache.has(uri)) continue;\r\n\r\n const promise = this.preloadResource(uri);\r\n this.resourceCache.set(uri, promise);\r\n }\r\n }\r\n\r\n /**\r\n * Launch an MCP App from a URL or MCP resource URI.\r\n * Loads the HTML first, then establishes bridge connection.\r\n */\r\n async launch(url: string, sessionId?: string): Promise<void> {\r\n if (sessionId) this.sessionId = sessionId;\r\n\r\n // Set up initialization promise BEFORE connecting\r\n const initializedPromise = this.onAppReady();\r\n\r\n // Load HTML into iframe first\r\n if (this.isMcpUri(url)) {\r\n await this.launchMcpApp(url);\r\n } else {\r\n this.iframe.src = url;\r\n }\r\n\r\n // Wait for iframe to load before connecting bridge\r\n await this.onIframeReady();\r\n\r\n // Connect the bridge (HTML is loaded, contentWindow is ready)\r\n await this.connectBridge();\r\n\r\n // Wait for app to signal it's initialized (with timeout)\r\n this.log('Waiting for app initialization');\r\n await Promise.race([\r\n initializedPromise,\r\n new Promise<void>((resolve) => setTimeout(() => {\r\n this.log('Initialization timeout - continuing anyway', 'warn');\r\n resolve();\r\n }, 3000))\r\n ]);\r\n this.log('App launched and ready');\r\n }\r\n\r\n /**\r\n * Wait for app to signal initialization complete\r\n */\r\n private onAppReady(): Promise<void> {\r\n return new Promise<void>((resolve) => {\r\n const originalHandler = this.bridge.oninitialized;\r\n this.bridge.oninitialized = (...args) => {\r\n this.log('App initialized');\r\n resolve();\r\n this.bridge.oninitialized = originalHandler;\r\n originalHandler?.(...args);\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Wait for iframe to finish loading\r\n */\r\n private onIframeReady(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (this.iframe.contentDocument?.readyState === 'complete') {\r\n resolve();\r\n return;\r\n }\r\n this.iframe.addEventListener('load', () => resolve(), { once: true });\r\n });\r\n }\r\n\r\n /**\r\n * Send tool input arguments to the MCP App.\r\n * Call this after launch() when tool input is available.\r\n */\r\n sendToolInput(args: Record<string, unknown>): void {\r\n this.log('Sending tool input to app');\r\n this.bridge.sendToolInput({ arguments: args });\r\n }\r\n\r\n /**\r\n * Send tool result to the MCP App.\r\n * Call this when the tool call completes.\r\n */\r\n sendToolResult(result: unknown): void {\r\n this.log('Sending tool result to app');\r\n this.bridge.sendToolResult(result as any);\r\n }\r\n\r\n /**\r\n * Send tool cancellation to the MCP App.\r\n * Call this when the tool call is cancelled or fails.\r\n */\r\n sendToolCancelled(reason: string): void {\r\n this.log('Sending tool cancellation to app');\r\n this.bridge.sendToolCancelled({ reason });\r\n }\r\n\r\n // ============================================\r\n // Private: Initialization\r\n // ============================================\r\n\r\n private configureSandbox(): void {\r\n if (this.iframe.sandbox.value !== SANDBOX_PERMISSIONS) {\r\n this.iframe.sandbox.value = SANDBOX_PERMISSIONS;\r\n }\r\n }\r\n\r\n private initializeBridge(): AppBridge {\r\n const bridge = new AppBridge(\r\n null,\r\n HOST_INFO,\r\n {\r\n openLinks: {},\r\n serverTools: {},\r\n logging: {},\r\n // Declare support for model context updates\r\n updateModelContext: { text: {} },\r\n },\r\n {\r\n // Initial host context\r\n hostContext: {\r\n theme: 'dark',\r\n platform: 'web',\r\n containerDimensions: { maxHeight: 6000 },\r\n displayMode: 'inline',\r\n availableDisplayModes: ['inline', 'fullscreen'],\r\n },\r\n }\r\n );\r\n\r\n // Register handlers - must be done BEFORE connect()\r\n bridge.oncalltool = (params) => this.handleToolCall(params);\r\n bridge.onopenlink = this.handleOpenLink.bind(this);\r\n bridge.onmessage = this.handleMessage.bind(this);\r\n bridge.onloggingmessage = (params) => this.log(`App log [${params.level}]: ${params.data}`);\r\n bridge.onupdatemodelcontext = async () => ({});\r\n bridge.onsizechange = async ({ width, height }) => {\r\n if (height !== undefined) this.iframe.style.height = `${height}px`;\r\n if (width !== undefined) this.iframe.style.minWidth = `min(${width}px, 100%)`;\r\n return {};\r\n };\r\n bridge.onrequestdisplaymode = async (params) => ({\r\n mode: params.mode === 'fullscreen' ? 'fullscreen' : 'inline'\r\n });\r\n\r\n return bridge;\r\n }\r\n\r\n private async connectBridge(): Promise<void> {\r\n this.log('Connecting bridge to iframe');\r\n\r\n const transport = new PostMessageTransport(\r\n this.iframe.contentWindow!,\r\n this.iframe.contentWindow!\r\n );\r\n\r\n try {\r\n await this.bridge.connect(transport);\r\n this.log('Bridge connected successfully');\r\n } catch (error) {\r\n this.log('Bridge connection failed', 'error');\r\n throw error;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Bridge Event Handlers\r\n // ============================================\r\n\r\n private async handleToolCall(params: ToolCallParams) {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client disconnected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n const result = await this.client.callTool(\r\n sessionId,\r\n params.name,\r\n params.arguments ?? {}\r\n );\r\n return result as any;\r\n }\r\n\r\n private async handleOpenLink(params: { url: string }): Promise<Record<string, never>> {\r\n window.open(params.url, '_blank', 'noopener,noreferrer');\r\n return {};\r\n }\r\n\r\n private async handleMessage(params: AppMessageParams): Promise<Record<string, never>> {\r\n this.onAppMessage?.(params);\r\n return {};\r\n }\r\n\r\n // ============================================\r\n // Private: Resource Loading\r\n // ============================================\r\n\r\n private async launchMcpApp(uri: string): Promise<void> {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client must be connected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n // Fetch resource using cache hierarchy: SSEClient cache → local cache → direct fetch\r\n const response = await this.fetchResourceWithCache(sessionId, uri);\r\n if (!response?.contents?.length) {\r\n throw new Error(`Empty resource: ${uri}`);\r\n }\r\n\r\n const content = response.contents[0];\r\n const html = this.decodeContent(content);\r\n if (!html) {\r\n throw new Error(`Invalid content in resource: ${uri}`);\r\n }\r\n\r\n // Render via Blob URL for clean isolation\r\n const blob = new Blob([html], { type: 'text/html' });\r\n this.iframe.src = URL.createObjectURL(blob);\r\n }\r\n\r\n private async fetchResourceWithCache(sessionId: string, uri: string): Promise<ResourceResponse> {\r\n // Priority 1: SSEClient's built-in cache (best performance)\r\n if (this.hasClientCache()) {\r\n return (this.client as any).getOrFetchResource(sessionId, uri);\r\n }\r\n\r\n // Priority 2: Local preload cache\r\n const cached = this.resourceCache.get(uri);\r\n if (cached) {\r\n const result = await cached;\r\n if (result) return result;\r\n }\r\n\r\n // Priority 3: Direct fetch\r\n return this.client.readResource(sessionId, uri) as Promise<ResourceResponse>;\r\n }\r\n\r\n private async preloadResource(uri: string): Promise<ResourceResponse | null> {\r\n try {\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) return null;\r\n return await this.client.readResource(sessionId, uri) as ResourceResponse;\r\n } catch (error) {\r\n this.log(`Preload failed for ${uri}`, 'warn');\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Utilities\r\n // ============================================\r\n\r\n private async getSessionId(): Promise<string | undefined> {\r\n if (this.sessionId) return this.sessionId;\r\n const result = await this.client.getSessions();\r\n return result.sessions?.[0]?.sessionId;\r\n }\r\n\r\n private isMcpUri(url: string): boolean {\r\n return MCP_URI_SCHEMES.some(scheme => url.startsWith(scheme));\r\n }\r\n\r\n private hasClientCache(): boolean {\r\n return 'getOrFetchResource' in this.client &&\r\n typeof (this.client as any).getOrFetchResource === 'function';\r\n }\r\n\r\n private extractUiResourceUri(tool: { _meta?: unknown }): string | undefined {\r\n const meta = tool._meta as { ui?: { resourceUri?: string; uri?: string } } | undefined;\r\n if (!meta?.ui) return undefined;\r\n return meta.ui.resourceUri ?? meta.ui.uri;\r\n }\r\n\r\n private decodeContent(content: ResourceContent): string | undefined {\r\n if (content.blob) {\r\n return atob(content.blob);\r\n }\r\n return content.text;\r\n }\r\n\r\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\r\n if (!this.debug && level === 'info') return;\r\n\r\n const prefix = '[AppHost]';\r\n switch (level) {\r\n case 'warn':\r\n console.warn(prefix, message);\r\n break;\r\n case 'error':\r\n console.error(prefix, message);\r\n break;\r\n default:\r\n console.log(prefix, message);\r\n }\r\n }\r\n}\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId?: string; // Optional - generated server-side if not provided\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n createdAt: number;\r\n /**\r\n * Session readiness for auto-restore.\r\n * false means auth is pending and should be resumed explicitly by user action.\r\n */\r\n active?: boolean;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\nexport type { CallToolResult };\r\n","/**\r\n * Utility functions for working with MCP tool metadata\r\n */\r\n\r\nimport type { ToolInfo } from './types.js';\r\n\r\nexport interface ToolUiConfig {\r\n resourceUri: string;\r\n sessionId: string;\r\n}\r\n\r\n/**\r\n * Extract UI resource URI from tool metadata\r\n *\r\n * @param tool - The tool to extract UI config from\r\n * @returns The resource URI if available, undefined otherwise\r\n *\r\n * @example\r\n * const uri = getToolUiResourceUri(tool);\r\n * if (uri) {\r\n * // Tool has UI configuration\r\n * }\r\n */\r\nexport function getToolUiResourceUri(tool: ToolInfo): string | undefined {\r\n const meta = (tool as any)._meta;\r\n if (!meta?.ui) return undefined;\r\n\r\n const ui = meta.ui;\r\n if (typeof ui !== \"object\" || !ui) return undefined;\r\n\r\n // Check visibility filter - skip if explicitly hidden from app\r\n if (ui.visibility && !ui.visibility.includes(\"app\")) return undefined;\r\n\r\n // Support both 'uri' and 'resourceUri' field names for flexibility\r\n return typeof ui.resourceUri === \"string\"\r\n ? ui.resourceUri\r\n : typeof ui.uri === \"string\"\r\n ? ui.uri\r\n : undefined;\r\n}\r\n\r\n/**\r\n * Find a tool by name within connections\r\n *\r\n * @param connections - Array of MCP connections\r\n * @param toolName - Name of the tool to find\r\n * @returns The tool if found, undefined otherwise\r\n *\r\n * @example\r\n * const tool = findToolByName(connections, \"get_weather\");\r\n */\r\nexport function findToolByName(\r\n connections: Array<{ tools: ToolInfo[] }>,\r\n toolName: string\r\n): ToolInfo | undefined {\r\n for (const conn of connections) {\r\n const tool = conn.tools.find((t) => t.name === toolName);\r\n if (tool) return tool;\r\n }\r\n return undefined;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/server/storage/redis.ts","../src/shared/constants.ts","../src/server/storage/redis-backend.ts","../src/server/storage/memory-backend.ts","../src/server/storage/file-backend.ts","../src/server/storage/sqlite-backend.ts","../src/server/storage/index.ts","../src/server/mcp/storage-oauth-provider.ts","../src/shared/utils.ts","../src/shared/events.ts","../src/shared/errors.ts","../src/server/mcp/oauth-client.ts","../src/server/mcp/multi-session-client.ts","../src/shared/event-routing.ts","../src/server/handlers/sse-handler.ts","../src/server/handlers/nextjs-handler.ts","../src/client/core/sse-client.ts","../src/client/core/app-host.ts","../src/shared/types.ts","../src/shared/tool-utils.ts"],"names":["customAlphabet","redis","firstChar","rest","path","fs","path2","fs2","getRedis","nanoid","SSEClientTransport","StreamableHTTPClientTransport","Client","SDKUnauthorizedError","ListToolsResultSchema","CallToolResultSchema","ListPromptsResultSchema","GetPromptResultSchema","ListResourcesResultSchema","ReadResourceResultSchema","discoverOAuthProtectedResourceMetadata","discoverAuthorizationServerMetadata","refreshAuthorization","manager","data","AppBridge","PostMessageTransport"],"mappings":"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","file":"index.js","sourcesContent":["/**\r\n * Redis connection management with dependency injection support\r\n * Allows configuration and testing without environment variables\r\n */\r\nimport type { Redis } from 'ioredis';\r\n\r\nexport interface RedisConfig {\r\n /**\r\n * Redis connection URL (defaults to REDIS_URL env var)\r\n */\r\n url?: string;\r\n\r\n /**\r\n * Enable lazy connection (default: true)\r\n */\r\n lazyConnect?: boolean;\r\n\r\n /**\r\n * Maximum retries per request (default: 1)\r\n */\r\n maxRetriesPerRequest?: number;\r\n\r\n /**\r\n * Enable verbose logging (default: false)\r\n */\r\n verbose?: boolean;\r\n /**\r\n * @internal For testing only - bypass ioredis import\r\n */\r\n RedisConstructor?: any;\r\n}\r\n\r\ndeclare global {\r\n // eslint-disable-next-line no-var\r\n var __redis: Redis | undefined;\r\n var __redisConfig: RedisConfig | undefined;\r\n}\r\n\r\nlet redisInstance: Redis | null = null;\r\n\r\n/**\r\n * Initialize Redis with custom configuration\r\n * Call this before any Redis operations if you need custom config\r\n * @param config - Redis configuration options\r\n */\r\nexport async function initRedis(config: RedisConfig): Promise<Redis> {\r\n if (redisInstance) {\r\n // Already initialized, return existing instance\r\n return redisInstance;\r\n }\r\n\r\n const url = config.url ?? process.env.REDIS_URL;\r\n\r\n if (!url) {\r\n throw new Error(\r\n 'Redis URL is required. Set REDIS_URL environment variable or pass url in config.'\r\n );\r\n }\r\n\r\n let Redis: typeof import('ioredis').Redis;\r\n if (config.RedisConstructor) {\r\n Redis = config.RedisConstructor;\r\n } else {\r\n try {\r\n const ioredis = await import('ioredis');\r\n Redis = ioredis.Redis;\r\n } catch (error) {\r\n throw new Error(\r\n 'ioredis is not installed. Install it with:\\n' +\r\n ' npm install ioredis\\n\\n' +\r\n 'Or use a different storage backend:\\n' +\r\n ' MCP_TS_STORAGE_TYPE=memory (for development)\\n' +\r\n ' MCP_TS_STORAGE_TYPE=file (for local persistence)'\r\n );\r\n }\r\n }\r\n\r\n redisInstance = new Redis(url, {\r\n lazyConnect: config.lazyConnect ?? true,\r\n maxRetriesPerRequest: config.maxRetriesPerRequest ?? 1,\r\n });\r\n\r\n if (config.verbose !== false) {\r\n redisInstance.on('ready', () => {\r\n console.log('✅ Redis connected');\r\n });\r\n\r\n redisInstance.on('error', (err) => {\r\n console.error('❌ Redis error:', err.message);\r\n });\r\n\r\n redisInstance.on('reconnecting', () => {\r\n console.log('🔄 Redis reconnecting...');\r\n });\r\n }\r\n\r\n // Store globally for hot reloading scenarios\r\n global.__redis = redisInstance;\r\n global.__redisConfig = config;\r\n\r\n return redisInstance;\r\n}\r\n\r\n/**\r\n * Get the Redis instance\r\n * Automatically initializes with default config if not already initialized\r\n */\r\nexport async function getRedis(): Promise<Redis> {\r\n if (redisInstance) {\r\n return redisInstance;\r\n }\r\n\r\n // Check for existing global instance (hot reload scenario)\r\n if (global.__redis) {\r\n redisInstance = global.__redis;\r\n return redisInstance;\r\n }\r\n\r\n // Initialize with default config\r\n return await initRedis({});\r\n}\r\n\r\n/**\r\n * Set a custom Redis instance (useful for testing with mocks)\r\n * @param instance - Redis instance or mock\r\n */\r\nexport function setRedisInstance(instance: Redis): void {\r\n redisInstance = instance;\r\n global.__redis = instance;\r\n}\r\n\r\n/**\r\n * Close Redis connection and clear instance\r\n */\r\nexport async function closeRedis(): Promise<void> {\r\n if (redisInstance) {\r\n await redisInstance.quit();\r\n redisInstance = null;\r\n global.__redis = undefined;\r\n }\r\n}\r\n\r\n/**\r\n * Default Redis export for backward compatibility\r\n * Will auto-initialize on first access\r\n * Note: This is a lazy proxy that initializes Redis on first method call\r\n */\r\nexport const redis = new Proxy({} as Redis, {\r\n get(_target, prop) {\r\n // Return a function that handles async initialization\r\n return async (...args: any[]) => {\r\n const instance = await getRedis();\r\n const value = (instance as any)[prop];\r\n if (typeof value === 'function') {\r\n return value.apply(instance, args);\r\n }\r\n return value;\r\n };\r\n },\r\n});\r\n","/**\r\n * Centralized constants for MCP Redis library\r\n * Eliminates magic numbers and enables consistent configuration\r\n */\r\n\r\n// Redis TTL and Session Management\r\nexport const SESSION_TTL_SECONDS = 43200; // 12 hours\r\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\r\n\r\n// Heartbeat and Connection\r\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\r\n\r\n// Redis Key Prefixes\r\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\r\n\r\n// Token Management\r\nexport const TOKEN_EXPIRY_BUFFER_MS = 5 * 60 * 1000; // 5 minute buffer before expiry\r\n\r\n// Client Information\r\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\r\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\r\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.svg';\r\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\r\nexport const SOFTWARE_ID = '@mcp-ts';\r\nexport const SOFTWARE_VERSION = '1.3.4';\r\n\r\n// MCP Client Configuration\r\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\r\nexport const MCP_CLIENT_VERSION = '2.0';\r\n","\r\nimport type { Redis } from 'ioredis';\r\nimport { customAlphabet } from 'nanoid';\r\nimport { StorageBackend, SessionData } from './types';\r\nimport { SESSION_TTL_SECONDS } from '../../shared/constants.js';\r\n\r\n/** first char: letters only (required by OpenAI) */\r\nconst firstChar = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\r\n 1\r\n);\r\n\r\n/** remaining chars: alphanumeric */\r\nconst rest = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\r\n 11\r\n);\r\n\r\n/**\r\n * Redis implementation of StorageBackend\r\n */\r\nexport class RedisStorageBackend implements StorageBackend {\r\n private readonly DEFAULT_TTL = SESSION_TTL_SECONDS;\r\n private readonly KEY_PREFIX = 'mcp:session:';\r\n private readonly IDENTITY_KEY_PREFIX = 'mcp:identity:';\r\n private readonly IDENTITY_KEY_SUFFIX = ':sessions';\r\n\r\n constructor(private redis: Redis) { }\r\n\r\n /**\r\n * Generates Redis key for a specific session\r\n * @private\r\n */\r\n private getSessionKey(identity: string, sessionId: string): string {\r\n return `${this.KEY_PREFIX}${identity}:${sessionId}`;\r\n }\r\n\r\n /**\r\n * Generates Redis key for tracking all sessions for an identity\r\n * @private\r\n */\r\n private getIdentityKey(identity: string): string {\r\n return `${this.IDENTITY_KEY_PREFIX}${identity}${this.IDENTITY_KEY_SUFFIX}`;\r\n }\r\n\r\n private parseIdentityFromKey(identityKey: string): string {\r\n return identityKey.slice(\r\n this.IDENTITY_KEY_PREFIX.length,\r\n identityKey.length - this.IDENTITY_KEY_SUFFIX.length\r\n );\r\n }\r\n\r\n private async scanKeys(pattern: string): Promise<string[]> {\r\n const redis = this.redis as Redis & {\r\n scan?: (cursor: string, ...args: Array<string | number>) => Promise<[string, string[]]>;\r\n };\r\n\r\n if (typeof redis.scan !== 'function') {\r\n return await this.redis.keys(pattern);\r\n }\r\n\r\n const keys = new Set<string>();\r\n let cursor = '0';\r\n\r\n try {\r\n do {\r\n const [nextCursor, batch] = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);\r\n cursor = nextCursor;\r\n for (const key of batch) {\r\n keys.add(key);\r\n }\r\n } while (cursor !== '0');\r\n } catch (error) {\r\n console.warn('[RedisStorage] SCAN failed, falling back to KEYS:', error);\r\n return await this.redis.keys(pattern);\r\n }\r\n\r\n return Array.from(keys);\r\n }\r\n\r\n generateSessionId(): string {\r\n return firstChar() + rest();\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n const { sessionId, identity } = session;\r\n if (!sessionId || !identity) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const identityKey = this.getIdentityKey(identity);\r\n const effectiveTtl = ttl ?? this.DEFAULT_TTL;\r\n\r\n /** ioredis syntax: set(key, val, 'EX', ttl, 'NX') */\r\n const result = await this.redis.set(\r\n sessionKey,\r\n JSON.stringify(session),\r\n 'EX',\r\n effectiveTtl,\r\n 'NX'\r\n );\r\n\r\n if (result !== 'OK') {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n\r\n await this.redis.sadd(identityKey, sessionId);\r\n }\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const effectiveTtl = ttl ?? this.DEFAULT_TTL;\r\n\r\n /** Lua script for atomic parsing, merging, and saving */\r\n const script = `\r\n local currentStr = redis.call(\"GET\", KEYS[1])\r\n if not currentStr then\r\n return 0\r\n end\r\n\r\n local current = cjson.decode(currentStr)\r\n local updates = cjson.decode(ARGV[1])\r\n\r\n for k,v in pairs(updates) do\r\n current[k] = v\r\n end\r\n\r\n redis.call(\"SET\", KEYS[1], cjson.encode(current), \"EX\", ARGV[2])\r\n return 1\r\n `;\r\n\r\n const result = await this.redis.eval(\r\n script,\r\n 1,\r\n sessionKey,\r\n JSON.stringify(data),\r\n effectiveTtl\r\n );\r\n\r\n if (result === 0) {\r\n throw new Error(`Session ${sessionId} not found for identity ${identity}`);\r\n }\r\n }\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n try {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const sessionDataStr = await this.redis.get(sessionKey);\r\n\r\n if (!sessionDataStr) {\r\n return null;\r\n }\r\n\r\n const sessionData: SessionData = JSON.parse(sessionDataStr);\r\n return sessionData;\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to get session:', error);\r\n return null;\r\n }\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n const sessions = await this.getIdentitySessionsData(identity);\r\n return sessions.map((session) => session.sessionId);\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n try {\r\n const identityKey = this.getIdentityKey(identity);\r\n const sessionIds = await this.redis.smembers(identityKey);\r\n if (sessionIds.length === 0) return [];\r\n\r\n const results = await Promise.all(\r\n sessionIds.map(async (sessionId) => {\r\n const data = await this.redis.get(this.getSessionKey(identity, sessionId));\r\n return data ? (JSON.parse(data) as SessionData) : null;\r\n })\r\n );\r\n\r\n const staleSessionIds = sessionIds.filter((_, index) => results[index] === null);\r\n if (staleSessionIds.length > 0) {\r\n await this.redis.srem(identityKey, ...staleSessionIds);\r\n }\r\n\r\n return results.filter((session): session is SessionData => session !== null);\r\n } catch (error) {\r\n console.error(`[RedisStorage] Failed to get session data for ${identity}:`, error);\r\n return [];\r\n }\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n try {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const identityKey = this.getIdentityKey(identity);\r\n\r\n await this.redis.srem(identityKey, sessionId);\r\n await this.redis.del(sessionKey);\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to remove session:', error);\r\n }\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n try {\r\n const keys = await this.scanKeys(`${this.KEY_PREFIX}*`);\r\n const sessions = await Promise.all(\r\n keys.map(async (key) => {\r\n const data = await this.redis.get(key);\r\n if (!data) {\r\n return null;\r\n }\r\n\r\n try {\r\n return (JSON.parse(data) as SessionData).sessionId;\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to parse session while listing all session IDs:', error);\r\n return null;\r\n }\r\n })\r\n );\r\n\r\n return sessions.filter((sessionId): sessionId is string => sessionId !== null);\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to get all sessions:', error);\r\n return [];\r\n }\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n try {\r\n const keys = await this.scanKeys(`${this.KEY_PREFIX}*`);\r\n const identityKeys = await this.scanKeys(`${this.IDENTITY_KEY_PREFIX}*${this.IDENTITY_KEY_SUFFIX}`);\r\n const allKeys = [...keys, ...identityKeys];\r\n if (allKeys.length > 0) {\r\n await this.redis.del(...allKeys);\r\n }\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to clear sessions:', error);\r\n }\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n try {\r\n const identityKeys = await this.scanKeys(`${this.IDENTITY_KEY_PREFIX}*${this.IDENTITY_KEY_SUFFIX}`);\r\n\r\n for (const identityKey of identityKeys) {\r\n const identity = this.parseIdentityFromKey(identityKey);\r\n const sessionIds = await this.redis.smembers(identityKey);\r\n\r\n if (sessionIds.length === 0) {\r\n await this.redis.del(identityKey);\r\n continue;\r\n }\r\n\r\n const existenceChecks = await Promise.all(\r\n sessionIds.map((sessionId) => this.redis.exists(this.getSessionKey(identity, sessionId)))\r\n );\r\n\r\n const staleSessionIds = sessionIds.filter((_, index) => existenceChecks[index] === 0);\r\n if (staleSessionIds.length > 0) {\r\n await this.redis.srem(identityKey, ...staleSessionIds);\r\n }\r\n\r\n const remainingCount = await this.redis.scard(identityKey);\r\n if (remainingCount === 0) {\r\n await this.redis.del(identityKey);\r\n }\r\n }\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to cleanup expired sessions:', error);\r\n }\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n try {\r\n await this.redis.quit();\r\n } catch (error) {\r\n console.error('[RedisStorage] Failed to disconnect:', error);\r\n }\r\n }\r\n}\r\n","\r\nimport { customAlphabet } from 'nanoid';\r\nimport { StorageBackend, SessionData, SetClientOptions } from './types';\r\n\r\n// first char: letters only (required by OpenAI)\r\nconst firstChar = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\r\n 1\r\n);\r\n\r\n// remaining chars: alphanumeric\r\nconst rest = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\r\n 11\r\n);\r\n\r\n/**\r\n * In-memory implementation of StorageBackend\r\n * Useful for local development or testing\r\n */\r\nexport class MemoryStorageBackend implements StorageBackend {\r\n // Map<identity:sessionId, SessionData>\r\n private sessions = new Map<string, SessionData>();\r\n\r\n // Map<identity, Set<sessionId>>\r\n private identitySessions = new Map<string, Set<string>>();\r\n\r\n constructor() { }\r\n\r\n private getSessionKey(identity: string, sessionId: string): string {\r\n return `${identity}:${sessionId}`;\r\n }\r\n\r\n generateSessionId(): string {\r\n return firstChar() + rest();\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n const { sessionId, identity } = session;\r\n if (!sessionId || !identity) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n if (this.sessions.has(sessionKey)) {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n\r\n this.sessions.set(sessionKey, session);\r\n\r\n // Update index\r\n if (!this.identitySessions.has(identity)) {\r\n this.identitySessions.set(identity, new Set());\r\n }\r\n this.identitySessions.get(identity)!.add(sessionId);\r\n // Note: TTL is ignored in memory backend - sessions don't auto-expire\r\n }\r\n\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n if (!identity || !sessionId) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const current = this.sessions.get(sessionKey);\r\n\r\n if (!current) {\r\n throw new Error(`Session ${sessionId} not found`);\r\n }\r\n\r\n const updated = {\r\n ...current,\r\n ...data\r\n };\r\n\r\n this.sessions.set(sessionKey, updated);\r\n // Note: TTL is ignored in memory backend - sessions don't auto-expire\r\n }\r\n\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n return this.sessions.get(sessionKey) || null;\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n const set = this.identitySessions.get(identity);\r\n return set ? Array.from(set) : [];\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n const set = this.identitySessions.get(identity);\r\n if (!set) return [];\r\n\r\n const results: SessionData[] = [];\r\n for (const sessionId of set) {\r\n const session = this.sessions.get(this.getSessionKey(identity, sessionId));\r\n if (session) {\r\n results.push(session);\r\n }\r\n }\r\n return results;\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n this.sessions.delete(sessionKey);\r\n\r\n const set = this.identitySessions.get(identity);\r\n if (set) {\r\n set.delete(sessionId);\r\n if (set.size === 0) {\r\n this.identitySessions.delete(identity);\r\n }\r\n }\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n return Array.from(this.sessions.values()).map(s => s.sessionId);\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n this.sessions.clear();\r\n this.identitySessions.clear();\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n // In-memory doesn't implement TTL automatically, \r\n // but we could check createdAt + TTL here if needed.\r\n // For now, no-op.\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n // No-op for memory\r\n }\r\n}\r\n","\r\nimport { promises as fs } from 'fs';\r\nimport * as path from 'path';\r\nimport { customAlphabet } from 'nanoid';\r\nimport { StorageBackend, SessionData, SetClientOptions } from './types';\r\n\r\n// first char: letters only (required by OpenAI)\r\nconst firstChar = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz',\r\n 1\r\n);\r\n\r\n// remaining chars: alphanumeric\r\nconst rest = customAlphabet(\r\n 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',\r\n 11\r\n);\r\n\r\n/**\r\n * File system implementation of StorageBackend\r\n * Persists sessions to a JSON file\r\n */\r\nexport class FileStorageBackend implements StorageBackend {\r\n private filePath: string;\r\n private memoryCache: Map<string, SessionData> | null = null;\r\n private initialized = false;\r\n\r\n /**\r\n * @param options.path Path to the JSON file storage (default: ./sessions.json)\r\n */\r\n constructor(options: { path?: string } = {}) {\r\n this.filePath = options.path || './sessions.json';\r\n }\r\n\r\n /**\r\n * Initialize storage: ensure file exists and load into memory cache\r\n */\r\n async init(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n // Ensure directory exists\r\n const dir = path.dirname(this.filePath);\r\n await fs.mkdir(dir, { recursive: true });\r\n\r\n // Try to read file\r\n const data = await fs.readFile(this.filePath, 'utf-8');\r\n const json = JSON.parse(data);\r\n\r\n this.memoryCache = new Map();\r\n if (Array.isArray(json)) {\r\n json.forEach((s: SessionData) => {\r\n this.memoryCache!.set(this.getSessionKey(s.identity || 'unknown', s.sessionId), s);\r\n });\r\n }\r\n } catch (error: any) {\r\n if (error.code === 'ENOENT') {\r\n // File does not exist, initialize empty\r\n this.memoryCache = new Map();\r\n await this.flush();\r\n } else {\r\n console.error('[FileStorage] Failed to load sessions:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n this.initialized = true;\r\n }\r\n\r\n private async ensureInitialized() {\r\n if (!this.initialized) await this.init();\r\n }\r\n\r\n private async flush(): Promise<void> {\r\n if (!this.memoryCache) return;\r\n const sessions = Array.from(this.memoryCache.values());\r\n await fs.writeFile(this.filePath, JSON.stringify(sessions, null, 2), 'utf-8');\r\n }\r\n\r\n private getSessionKey(identity: string, sessionId: string): string {\r\n return `${identity}:${sessionId}`;\r\n }\r\n\r\n generateSessionId(): string {\r\n return firstChar() + rest();\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n await this.ensureInitialized();\r\n const { sessionId, identity } = session;\r\n if (!sessionId || !identity) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n if (this.memoryCache!.has(sessionKey)) {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n\r\n this.memoryCache!.set(sessionKey, session);\r\n await this.flush();\r\n // Note: TTL is ignored in file backend - sessions don't auto-expire\r\n }\r\n\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n await this.ensureInitialized();\r\n if (!identity || !sessionId) throw new Error('identity and sessionId required');\r\n\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n const current = this.memoryCache!.get(sessionKey);\r\n\r\n if (!current) {\r\n throw new Error(`Session ${sessionId} not found`);\r\n }\r\n\r\n const updated = {\r\n ...current,\r\n ...data\r\n };\r\n\r\n this.memoryCache!.set(sessionKey, updated);\r\n await this.flush();\r\n // Note: TTL is ignored in file backend - sessions don't auto-expire\r\n }\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n await this.ensureInitialized();\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n return this.memoryCache!.get(sessionKey) || null;\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n await this.ensureInitialized();\r\n return Array.from(this.memoryCache!.values()).filter(s => s.identity === identity);\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n await this.ensureInitialized();\r\n return Array.from(this.memoryCache!.values())\r\n .filter(s => s.identity === identity)\r\n .map(s => s.sessionId);\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n await this.ensureInitialized();\r\n const sessionKey = this.getSessionKey(identity, sessionId);\r\n if (this.memoryCache!.delete(sessionKey)) {\r\n await this.flush();\r\n }\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n await this.ensureInitialized();\r\n return Array.from(this.memoryCache!.values()).map(s => s.sessionId);\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n await this.ensureInitialized();\r\n this.memoryCache!.clear();\r\n await this.flush();\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n // Could implement TTL check here using createdAt\r\n await this.ensureInitialized();\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n // No explicit disconnect needed for file\r\n }\r\n}\r\n","import type { Database } from 'better-sqlite3';\r\nimport { StorageBackend, SessionData } from './types.js'; // Ensure .js extension\r\nimport * as fs from 'fs';\r\nimport * as path from 'path';\r\n\r\nexport interface SqliteStorageOptions {\r\n path?: string;\r\n table?: string;\r\n}\r\n\r\nexport class SqliteStorage implements StorageBackend {\r\n private db: Database | null = null;\r\n private table: string;\r\n private initialized = false;\r\n private dbPath: string;\r\n\r\n constructor(options: SqliteStorageOptions = {}) {\r\n this.dbPath = options.path || './sessions.db';\r\n this.table = options.table || 'mcp_sessions';\r\n }\r\n\r\n async init(): Promise<void> {\r\n if (this.initialized) return;\r\n\r\n try {\r\n // Dynamic import for peer dependency\r\n const DatabaseConstructor = (await import('better-sqlite3')).default;\r\n\r\n // Ensure directory exists\r\n const dir = path.dirname(this.dbPath);\r\n if (!fs.existsSync(dir)) {\r\n fs.mkdirSync(dir, { recursive: true });\r\n }\r\n\r\n this.db = new DatabaseConstructor(this.dbPath);\r\n this.db.exec(`\r\n CREATE TABLE IF NOT EXISTS ${this.table} (\r\n sessionId TEXT PRIMARY KEY,\r\n identity TEXT NOT NULL,\r\n data TEXT NOT NULL,\r\n expiresAt INTEGER\r\n );\r\n CREATE INDEX IF NOT EXISTS idx_${this.table}_identity ON ${this.table}(identity);\r\n `);\r\n\r\n this.initialized = true;\r\n } catch (error: any) {\r\n if (error.code === 'MODULE_NOT_FOUND' || error.message?.includes('better-sqlite3')) {\r\n throw new Error(\r\n 'better-sqlite3 is not installed. Please install it with: npm install better-sqlite3'\r\n );\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n private ensureInitialized() {\r\n if (!this.initialized) {\r\n throw new Error('SqliteStorage not initialized. Call init() first.');\r\n }\r\n }\r\n\r\n generateSessionId(): string {\r\n const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\r\n let result = '';\r\n for (let i = 0; i < 32; i++) {\r\n result += chars.charAt(Math.floor(Math.random() * chars.length));\r\n }\r\n return result;\r\n }\r\n\r\n async createSession(session: SessionData, ttl?: number): Promise<void> {\r\n this.ensureInitialized();\r\n const { sessionId, identity } = session;\r\n\r\n if (!sessionId || !identity) {\r\n throw new Error('identity and sessionId required');\r\n }\r\n\r\n const expiresAt = ttl ? Date.now() + ttl * 1000 : null;\r\n\r\n try {\r\n const stmt = this.db!.prepare(\r\n `INSERT INTO ${this.table} (sessionId, identity, data, expiresAt) VALUES (?, ?, ?, ?)`\r\n );\r\n stmt.run(sessionId, identity, JSON.stringify(session), expiresAt);\r\n } catch (error: any) {\r\n if (error.code === 'SQLITE_CONSTRAINT_PRIMARYKEY') {\r\n throw new Error(`Session ${sessionId} already exists`);\r\n }\r\n throw error;\r\n }\r\n }\r\n\r\n async updateSession(identity: string, sessionId: string, data: Partial<SessionData>, ttl?: number): Promise<void> {\r\n this.ensureInitialized();\r\n if (!sessionId || !identity) {\r\n throw new Error('identity and sessionId required');\r\n }\r\n\r\n const currentSession = await this.getSession(identity, sessionId);\r\n if (!currentSession) {\r\n throw new Error(`Session ${sessionId} not found for identity ${identity}`);\r\n }\r\n\r\n const updatedSession = { ...currentSession, ...data };\r\n const expiresAt = ttl ? Date.now() + ttl * 1000 : null;\r\n\r\n const stmt = this.db!.prepare(\r\n `UPDATE ${this.table} SET data = ?, expiresAt = ? WHERE sessionId = ? AND identity = ?`\r\n );\r\n\r\n stmt.run(JSON.stringify(updatedSession), expiresAt, sessionId, identity);\r\n }\r\n\r\n async getSession(identity: string, sessionId: string): Promise<SessionData | null> {\r\n this.ensureInitialized();\r\n\r\n const stmt = this.db!.prepare(\r\n `SELECT data FROM ${this.table} WHERE sessionId = ? AND identity = ?`\r\n );\r\n const row = stmt.get(sessionId, identity) as { data: string } | undefined;\r\n\r\n if (!row) return null;\r\n return JSON.parse(row.data) as SessionData;\r\n }\r\n\r\n async getIdentitySessionsData(identity: string): Promise<SessionData[]> {\r\n this.ensureInitialized();\r\n\r\n const stmt = this.db!.prepare(\r\n `SELECT data FROM ${this.table} WHERE identity = ?`\r\n );\r\n const rows = stmt.all(identity) as { data: string }[];\r\n\r\n return rows.map(row => JSON.parse(row.data) as SessionData);\r\n }\r\n\r\n async getIdentityMcpSessions(identity: string): Promise<string[]> {\r\n this.ensureInitialized();\r\n\r\n const stmt = this.db!.prepare(\r\n `SELECT sessionId FROM ${this.table} WHERE identity = ?`\r\n );\r\n const rows = stmt.all(identity) as { sessionId: string }[];\r\n\r\n return rows.map(row => row.sessionId);\r\n }\r\n\r\n async removeSession(identity: string, sessionId: string): Promise<void> {\r\n this.ensureInitialized();\r\n const stmt = this.db!.prepare(\r\n `DELETE FROM ${this.table} WHERE sessionId = ? AND identity = ?`\r\n );\r\n stmt.run(sessionId, identity);\r\n }\r\n\r\n async getAllSessionIds(): Promise<string[]> {\r\n this.ensureInitialized();\r\n const stmt = this.db!.prepare(`SELECT sessionId FROM ${this.table}`);\r\n const rows = stmt.all() as { sessionId: string }[];\r\n return rows.map(row => row.sessionId);\r\n }\r\n\r\n async clearAll(): Promise<void> {\r\n this.ensureInitialized();\r\n const stmt = this.db!.prepare(`DELETE FROM ${this.table}`);\r\n stmt.run();\r\n }\r\n\r\n async cleanupExpiredSessions(): Promise<void> {\r\n this.ensureInitialized();\r\n const now = Date.now();\r\n const stmt = this.db!.prepare(\r\n `DELETE FROM ${this.table} WHERE expiresAt IS NOT NULL AND expiresAt < ?`\r\n );\r\n stmt.run(now);\r\n }\r\n\r\n async disconnect(): Promise<void> {\r\n if (this.db) {\r\n this.db.close();\r\n }\r\n }\r\n}\r\n","\r\nimport { RedisStorageBackend } from './redis-backend';\r\nimport { MemoryStorageBackend } from './memory-backend';\r\nimport { FileStorageBackend } from './file-backend';\r\nimport { SqliteStorage } from './sqlite-backend';\r\nimport type { StorageBackend } from './types';\r\n\r\n// Re-export types\r\nexport * from './types';\r\nexport { RedisStorageBackend, MemoryStorageBackend, FileStorageBackend, SqliteStorage };\r\n\r\nlet storageInstance: StorageBackend | null = null;\r\nlet storagePromise: Promise<StorageBackend> | null = null;\r\n\r\nasync function initializeStorage<T extends StorageBackend>(store: T): Promise<T> {\r\n if (typeof store.init === 'function') {\r\n await store.init();\r\n }\r\n return store;\r\n}\r\n\r\nasync function createStorage(): Promise<StorageBackend> {\r\n const type = process.env.MCP_TS_STORAGE_TYPE?.toLowerCase();\r\n\r\n // Explicit selection\r\n if (type === 'redis') {\r\n if (!process.env.REDIS_URL) {\r\n console.warn('[Storage] MCP_TS_STORAGE_TYPE is \"redis\" but REDIS_URL is missing');\r\n }\r\n try {\r\n const { getRedis } = await import('./redis.js');\r\n const redis = await getRedis();\r\n console.log('[Storage] Using Redis storage (Explicit)');\r\n return new RedisStorageBackend(redis);\r\n } catch (error: any) {\r\n console.error('[Storage] Failed to initialize Redis:', error.message);\r\n console.log('[Storage] Falling back to In-Memory storage');\r\n return new MemoryStorageBackend();\r\n }\r\n }\r\n\r\n if (type === 'file') {\r\n const filePath = process.env.MCP_TS_STORAGE_FILE;\r\n if (!filePath) {\r\n console.warn('[Storage] MCP_TS_STORAGE_TYPE is \"file\" but MCP_TS_STORAGE_FILE is missing');\r\n }\r\n console.log(`[Storage] Using File storage (${filePath}) (Explicit)`);\r\n return await initializeStorage(new FileStorageBackend({ path: filePath }));\r\n }\r\n\r\n if (type === 'sqlite') {\r\n const dbPath = process.env.MCP_TS_STORAGE_SQLITE_PATH;\r\n console.log(`[Storage] Using SQLite storage (${dbPath || 'default'}) (Explicit)`);\r\n return await initializeStorage(new SqliteStorage({ path: dbPath }));\r\n }\r\n\r\n if (type === 'memory') {\r\n console.log('[Storage] Using In-Memory storage (Explicit)');\r\n return new MemoryStorageBackend();\r\n }\r\n\r\n // Automatic inference (Fallback)\r\n if (process.env.REDIS_URL) {\r\n try {\r\n const { getRedis } = await import('./redis.js');\r\n const redis = await getRedis();\r\n console.log('[Storage] Auto-detected REDIS_URL. Using Redis storage.');\r\n return new RedisStorageBackend(redis);\r\n } catch (error: any) {\r\n console.error('[Storage] Redis auto-detection failed:', error.message);\r\n console.log('[Storage] Falling back to In-Memory storage');\r\n return new MemoryStorageBackend();\r\n }\r\n }\r\n\r\n if (process.env.MCP_TS_STORAGE_FILE) {\r\n console.log(`[Storage] Auto-detected MCP_TS_STORAGE_FILE. Using File storage (${process.env.MCP_TS_STORAGE_FILE}).`);\r\n return await initializeStorage(new FileStorageBackend({ path: process.env.MCP_TS_STORAGE_FILE }));\r\n }\r\n\r\n if (process.env.MCP_TS_STORAGE_SQLITE_PATH) {\r\n console.log(`[Storage] Auto-detected MCP_TS_STORAGE_SQLITE_PATH. Using SQLite storage (${process.env.MCP_TS_STORAGE_SQLITE_PATH}).`);\r\n return await initializeStorage(new SqliteStorage({ path: process.env.MCP_TS_STORAGE_SQLITE_PATH }));\r\n }\r\n\r\n console.log('[Storage] No storage configured. Using In-Memory storage (Default).');\r\n return new MemoryStorageBackend();\r\n}\r\n\r\nasync function getStorage(): Promise<StorageBackend> {\r\n if (storageInstance) {\r\n return storageInstance;\r\n }\r\n\r\n if (!storagePromise) {\r\n storagePromise = createStorage().catch((error) => {\r\n storagePromise = null;\r\n throw error;\r\n });\r\n }\r\n\r\n storageInstance = await storagePromise;\r\n return storageInstance;\r\n}\r\n\r\n/**\r\n * Set the storage instance (for testing)\r\n * @internal\r\n * @param instance - StorageBackend instance or null to reset\r\n */\r\nexport function _setStorageInstanceForTesting(instance: StorageBackend | null): void {\r\n storageInstance = instance;\r\n if (!instance) {\r\n storagePromise = null;\r\n }\r\n}\r\n\r\n/**\r\n * Global session store instance\r\n * Uses lazy initialization with a Proxy to handle async setup transparently\r\n */\r\nexport const storage: StorageBackend = new Proxy({} as StorageBackend, {\r\n get(_target, prop) {\r\n return async (...args: any[]) => {\r\n const instance = await getStorage();\r\n const value = (instance as any)[prop];\r\n if (typeof value === 'function') {\r\n return value.apply(instance, args);\r\n }\r\n return value;\r\n };\r\n },\r\n});\r\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\r\nimport type {\r\n OAuthClientInformationFull,\r\n OAuthClientInformationMixed,\r\n OAuthClientMetadata,\r\n OAuthTokens\r\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\r\nimport { storage, SessionData } from \"../storage/index.js\";\r\nimport {\r\n DEFAULT_CLIENT_NAME,\r\n DEFAULT_CLIENT_URI,\r\n DEFAULT_LOGO_URI,\r\n DEFAULT_POLICY_URI,\r\n SOFTWARE_ID,\r\n SOFTWARE_VERSION,\r\n TOKEN_EXPIRY_BUFFER_MS,\r\n} from '../../shared/constants.js';\r\n\r\n/**\r\n * Extension of OAuthClientProvider interface with additional methods\r\n * Enables server-specific tracking and state management\r\n */\r\nexport interface AgentsOAuthProvider extends OAuthClientProvider {\r\n authUrl: string | undefined;\r\n clientId: string | undefined;\r\n serverId: string | undefined;\r\n checkState(\r\n state: string\r\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\r\n consumeState(state: string): Promise<void>;\r\n deleteCodeVerifier(): Promise<void>;\r\n isTokenExpired(): boolean;\r\n setTokenExpiresAt(expiresAt: number): void;\r\n}\r\n\r\nexport interface StorageOAuthClientProviderOptions {\r\n identity: string;\r\n serverId: string;\r\n sessionId: string;\r\n redirectUrl: string;\r\n clientName?: string;\r\n clientUri?: string;\r\n logoUri?: string;\r\n policyUri?: string;\r\n clientId?: string;\r\n clientSecret?: string;\r\n onRedirect?: (url: string) => void;\r\n}\r\n\r\n/**\r\n * Storage-backed OAuth provider implementation for MCP\r\n * Stores OAuth tokens, client information, and PKCE verifiers using the configured StorageBackend\r\n */\r\nexport class StorageOAuthClientProvider implements AgentsOAuthProvider {\r\n public readonly identity: string;\r\n public readonly serverId: string;\r\n public readonly sessionId: string;\r\n public readonly redirectUrl: string;\r\n\r\n private readonly clientName?: string;\r\n private readonly clientUri?: string;\r\n private readonly logoUri?: string;\r\n private readonly policyUri?: string;\r\n private readonly clientSecret?: string;\r\n\r\n private _authUrl: string | undefined;\r\n private _clientId: string | undefined;\r\n private onRedirectCallback?: (url: string) => void;\r\n private tokenExpiresAt?: number;\r\n\r\n /**\r\n * Creates a new storage-backed OAuth provider\r\n * @param options - Provider configuration\r\n */\r\n constructor(options: StorageOAuthClientProviderOptions) {\r\n this.identity = options.identity;\r\n this.serverId = options.serverId;\r\n this.sessionId = options.sessionId;\r\n this.redirectUrl = options.redirectUrl;\r\n this.clientName = options.clientName;\r\n this.clientUri = options.clientUri;\r\n this.logoUri = options.logoUri;\r\n this.policyUri = options.policyUri;\r\n this._clientId = options.clientId;\r\n this.clientSecret = options.clientSecret;\r\n this.onRedirectCallback = options.onRedirect;\r\n }\r\n\r\n get clientMetadata(): OAuthClientMetadata {\r\n return {\r\n client_name: this.clientName || DEFAULT_CLIENT_NAME,\r\n client_uri: this.clientUri || DEFAULT_CLIENT_URI,\r\n logo_uri: this.logoUri || DEFAULT_LOGO_URI,\r\n policy_uri: this.policyUri || DEFAULT_POLICY_URI,\r\n grant_types: [\"authorization_code\", \"refresh_token\"],\r\n redirect_uris: [this.redirectUrl],\r\n response_types: [\"code\"],\r\n token_endpoint_auth_method: this.clientSecret ? \"client_secret_basic\" : \"none\",\r\n software_id: SOFTWARE_ID,\r\n software_version: SOFTWARE_VERSION,\r\n };\r\n }\r\n\r\n get clientId() {\r\n return this._clientId;\r\n }\r\n\r\n set clientId(clientId_: string | undefined) {\r\n this._clientId = clientId_;\r\n }\r\n\r\n /**\r\n * Loads OAuth data from storage session\r\n * @private\r\n */\r\n private async getSessionData(): Promise<SessionData> {\r\n const data = await storage.getSession(this.identity, this.sessionId);\r\n if (!data) {\r\n return {} as SessionData;\r\n }\r\n return data;\r\n }\r\n\r\n /**\r\n * Saves OAuth data to storage\r\n * @param data - Partial OAuth data to save\r\n * @private\r\n * @throws Error if session doesn't exist (session must be created by controller layer)\r\n */\r\n private async saveSessionData(data: Partial<SessionData>): Promise<void> {\r\n await storage.updateSession(this.identity, this.sessionId, data);\r\n }\r\n\r\n /**\r\n * Retrieves stored OAuth client information\r\n */\r\n async clientInformation(): Promise<OAuthClientInformationMixed | undefined> {\r\n const data = await this.getSessionData();\r\n\r\n if (data.clientId && !this._clientId) {\r\n this._clientId = data.clientId;\r\n }\r\n\r\n if (data.clientInformation) {\r\n return data.clientInformation;\r\n }\r\n\r\n if (!this._clientId) {\r\n return undefined;\r\n }\r\n\r\n return {\r\n client_id: this._clientId,\r\n ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),\r\n };\r\n }\r\n\r\n /**\r\n * Stores OAuth client information\r\n */\r\n async saveClientInformation(clientInformation: OAuthClientInformationFull): Promise<void> {\r\n await this.saveSessionData({\r\n clientInformation,\r\n clientId: clientInformation.client_id\r\n });\r\n this.clientId = clientInformation.client_id;\r\n }\r\n\r\n /**\r\n * Stores OAuth tokens\r\n */\r\n async saveTokens(tokens: OAuthTokens): Promise<void> {\r\n const data: Partial<SessionData> = { tokens };\r\n\r\n if (tokens.expires_in) {\r\n this.tokenExpiresAt = Date.now() + (tokens.expires_in * 1000) - TOKEN_EXPIRY_BUFFER_MS;\r\n }\r\n\r\n await this.saveSessionData(data);\r\n }\r\n\r\n get authUrl() {\r\n return this._authUrl;\r\n }\r\n\r\n async state(): Promise<string> {\r\n return this.sessionId;\r\n }\r\n\r\n async checkState(_state: string): Promise<{ valid: boolean; serverId?: string; error?: string }> {\r\n const data = await storage.getSession(this.identity, this.sessionId);\r\n\r\n if (!data) {\r\n return { valid: false, error: \"Session not found\" };\r\n }\r\n\r\n return { valid: true, serverId: this.serverId };\r\n }\r\n\r\n async consumeState(_state: string): Promise<void> {\r\n // No-op\r\n }\r\n\r\n async redirectToAuthorization(authUrl: URL): Promise<void> {\r\n this._authUrl = authUrl.toString();\r\n if (this.onRedirectCallback) {\r\n this.onRedirectCallback(authUrl.toString());\r\n }\r\n }\r\n\r\n async invalidateCredentials(\r\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\"\r\n ): Promise<void> {\r\n if (scope === \"all\") {\r\n await storage.removeSession(this.identity, this.sessionId);\r\n } else {\r\n const updates: Partial<SessionData> = {};\r\n\r\n if (scope === \"client\") {\r\n updates.clientInformation = undefined;\r\n updates.clientId = undefined;\r\n } else if (scope === \"tokens\") {\r\n updates.tokens = undefined;\r\n } else if (scope === \"verifier\") {\r\n updates.codeVerifier = undefined;\r\n }\r\n await this.saveSessionData(updates);\r\n }\r\n }\r\n\r\n async saveCodeVerifier(verifier: string): Promise<void> {\r\n await this.saveSessionData({ codeVerifier: verifier });\r\n }\r\n\r\n async codeVerifier(): Promise<string> {\r\n const data = await this.getSessionData();\r\n\r\n if (data.clientId && !this._clientId) {\r\n this._clientId = data.clientId;\r\n }\r\n\r\n if (!data.codeVerifier) {\r\n throw new Error(\"No code verifier found\");\r\n }\r\n return data.codeVerifier;\r\n }\r\n\r\n async deleteCodeVerifier(): Promise<void> {\r\n await this.saveSessionData({ codeVerifier: undefined });\r\n }\r\n\r\n async tokens(): Promise<OAuthTokens | undefined> {\r\n const data = await this.getSessionData();\r\n\r\n if (data.clientId && !this._clientId) {\r\n this._clientId = data.clientId;\r\n }\r\n\r\n return data.tokens;\r\n }\r\n\r\n isTokenExpired(): boolean {\r\n if (!this.tokenExpiresAt) {\r\n return false;\r\n }\r\n return Date.now() >= this.tokenExpiresAt;\r\n }\r\n\r\n setTokenExpiresAt(expiresAt: number): void {\r\n this.tokenExpiresAt = expiresAt;\r\n }\r\n}\r\n","/**\r\n * Sanitize server name to create a valid server label\r\n * Must start with a letter and contain only letters, digits, '-' and '_'\r\n */\r\nexport function sanitizeServerLabel(name: string): string {\r\n let sanitized = name\r\n .replace(/[^a-zA-Z0-9-_]/g, '_')\r\n .replace(/_{2,}/g, '_')\r\n .toLowerCase();\r\n\r\n if (!/^[a-zA-Z]/.test(sanitized)) {\r\n sanitized = 's_' + sanitized;\r\n }\r\n\r\n return sanitized;\r\n}\r\n","/**\r\n * Simple event emitter pattern for MCP connection events\r\n * Inspired by Cloudflare's agents pattern but adapted for serverless\r\n */\r\n\r\nexport type Disposable = {\r\n dispose(): void;\r\n};\r\n\r\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\r\n\r\n/**\r\n * Event emitter class for type-safe event handling\r\n * Similar to Cloudflare's Emitter but simplified for our use case\r\n */\r\nexport class Emitter<T> {\r\n private listeners: Set<(event: T) => void> = new Set();\r\n\r\n /**\r\n * Subscribe to events\r\n * @param listener - Callback function to handle events\r\n * @returns Disposable to unsubscribe\r\n */\r\n get event(): Event<T> {\r\n return (listener: (event: T) => void) => {\r\n this.listeners.add(listener);\r\n return {\r\n dispose: () => {\r\n this.listeners.delete(listener);\r\n },\r\n };\r\n };\r\n }\r\n\r\n /**\r\n * Fire an event to all listeners\r\n * @param event - Event data to emit\r\n */\r\n fire(event: T): void {\r\n for (const listener of this.listeners) {\r\n try {\r\n listener(event);\r\n } catch (error) {\r\n console.error('[Emitter] Error in event listener:', error);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Clear all listeners\r\n */\r\n dispose(): void {\r\n this.listeners.clear();\r\n }\r\n\r\n /**\r\n * Get number of active listeners\r\n */\r\n get listenerCount(): number {\r\n return this.listeners.size;\r\n }\r\n}\r\n\r\n/**\r\n * Connection state types matching your existing ConnectionStatus\r\n * Extended with more granular states for better observability\r\n */\r\nexport type McpConnectionState =\r\n | 'DISCONNECTED' // Not connected\r\n | 'CONNECTING' // Establishing transport connection to MCP server\r\n | 'AUTHENTICATING' // OAuth flow in progress\r\n | 'AUTHENTICATED' // OAuth complete, pre-connect\r\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\r\n | 'CONNECTED' // Transport connection established\r\n | 'READY' // Fully connected and ready to use\r\n | 'VALIDATING' // Validating existing session\r\n | 'RECONNECTING' // Attempting to reconnect\r\n | 'INITIALIZING' // Initializing session or connection\r\n | 'FAILED'; // Connection error at some point\r\n\r\n/**\r\n * MCP Connection Event Types\r\n * Discriminated union for type-safe event handling\r\n */\r\nexport type McpConnectionEvent =\r\n | {\r\n type: 'state_changed';\r\n sessionId: string;\r\n serverId: string;\r\n serverName: string;\r\n serverUrl: string;\r\n createdAt?: number;\r\n state: McpConnectionState;\r\n previousState: McpConnectionState;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'tools_discovered';\r\n sessionId: string;\r\n serverId: string;\r\n toolCount: number;\r\n tools: any[];\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'auth_required';\r\n sessionId: string;\r\n serverId: string;\r\n authUrl: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'error';\r\n sessionId: string;\r\n serverId: string;\r\n error: string;\r\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'disconnected';\r\n sessionId: string;\r\n serverId: string;\r\n reason?: string;\r\n timestamp: number;\r\n }\r\n | {\r\n type: 'progress';\r\n sessionId: string;\r\n serverId: string;\r\n message: string;\r\n timestamp: number;\r\n };\r\n\r\n/**\r\n * Event fired when a tool execution returns a UI resource URI\r\n */\r\nexport interface McpAppsUIEvent {\r\n type: 'mcp-apps-ui';\r\n sessionId: string;\r\n resourceUri: string;\r\n toolName: string;\r\n result: unknown;\r\n timestamp: number;\r\n}\r\n\r\n/**\r\n * Observability event for debugging and monitoring\r\n */\r\nexport interface McpObservabilityEvent {\r\n type?: string;\r\n level?: 'debug' | 'info' | 'warn' | 'error';\r\n message?: string;\r\n displayMessage?: string;\r\n sessionId?: string;\r\n serverId?: string;\r\n payload?: Record<string, any>;\r\n metadata?: Record<string, any>; // Kept for backward compatibility\r\n timestamp: number;\r\n id?: string;\r\n}\r\n\r\n/**\r\n * DisposableStore for managing multiple disposables\r\n * Useful for cleanup in React hooks\r\n */\r\nexport class DisposableStore {\r\n private disposables: Set<Disposable> = new Set();\r\n\r\n add(disposable: Disposable): void {\r\n this.disposables.add(disposable);\r\n }\r\n\r\n dispose(): void {\r\n for (const disposable of this.disposables) {\r\n disposable.dispose();\r\n }\r\n this.disposables.clear();\r\n }\r\n}\r\n","/**\r\n * Standardized error classes for MCP Redis library\r\n * Provides consistent error handling across the codebase\r\n */\r\n\r\n/**\r\n * Base error class for all MCP-related errors\r\n */\r\nexport class McpError extends Error {\r\n constructor(\r\n public readonly code: string,\r\n message: string,\r\n public readonly cause?: Error\r\n ) {\r\n super(message);\r\n this.name = 'McpError';\r\n // Maintain proper prototype chain for instanceof checks\r\n Object.setPrototypeOf(this, new.target.prototype);\r\n }\r\n\r\n toJSON() {\r\n return {\r\n name: this.name,\r\n code: this.code,\r\n message: this.message,\r\n ...(this.cause ? { cause: this.cause.message } : {}),\r\n };\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth authorization is required\r\n */\r\nexport class UnauthorizedError extends McpError {\r\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\r\n super('UNAUTHORIZED', message, cause);\r\n this.name = 'UnauthorizedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when connection to MCP server fails\r\n */\r\nexport class ConnectionError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONNECTION_ERROR', message, cause);\r\n this.name = 'ConnectionError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session is not found or expired\r\n */\r\nexport class SessionNotFoundError extends McpError {\r\n constructor(sessionId: string, cause?: Error) {\r\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\r\n this.name = 'SessionNotFoundError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when session validation fails\r\n */\r\nexport class SessionValidationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('SESSION_VALIDATION_ERROR', message, cause);\r\n this.name = 'SessionValidationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when authentication fails\r\n */\r\nexport class AuthenticationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('AUTH_ERROR', message, cause);\r\n this.name = 'AuthenticationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when OAuth state validation fails\r\n */\r\nexport class InvalidStateError extends McpError {\r\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\r\n super('INVALID_STATE', message, cause);\r\n this.name = 'InvalidStateError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when client is not connected\r\n */\r\nexport class NotConnectedError extends McpError {\r\n constructor(message: string = 'Not connected to server', cause?: Error) {\r\n super('NOT_CONNECTED', message, cause);\r\n this.name = 'NotConnectedError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when required configuration is missing\r\n */\r\nexport class ConfigurationError extends McpError {\r\n constructor(message: string, cause?: Error) {\r\n super('CONFIGURATION_ERROR', message, cause);\r\n this.name = 'ConfigurationError';\r\n }\r\n}\r\n\r\n/**\r\n * Thrown when tool execution fails\r\n */\r\nexport class ToolExecutionError extends McpError {\r\n constructor(toolName: string, message: string, cause?: Error) {\r\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\r\n this.name = 'ToolExecutionError';\r\n }\r\n}\r\n\r\n/**\r\n * RPC error codes for SSE communication\r\n */\r\nexport const RpcErrorCodes = {\r\n EXECUTION_ERROR: 'EXECUTION_ERROR',\r\n MISSING_IDENTITY: 'MISSING_IDENTITY',\r\n UNAUTHORIZED: 'UNAUTHORIZED',\r\n NO_CONNECTION: 'NO_CONNECTION',\r\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\r\n INVALID_PARAMS: 'INVALID_PARAMS',\r\n} as const;\r\n\r\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\r\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\r\nimport { nanoid } from 'nanoid';\r\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\r\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\r\nimport {\r\n UnauthorizedError as SDKUnauthorizedError,\r\n refreshAuthorization,\r\n discoverOAuthProtectedResourceMetadata,\r\n discoverAuthorizationServerMetadata,\r\n} from '@modelcontextprotocol/sdk/client/auth.js';\r\nimport {\r\n ListToolsRequest,\r\n ListToolsResult,\r\n ListToolsResultSchema,\r\n CallToolRequest,\r\n CallToolResult,\r\n CallToolResultSchema,\r\n ListPromptsRequest,\r\n ListPromptsResult,\r\n ListPromptsResultSchema,\r\n GetPromptRequest,\r\n GetPromptResult,\r\n GetPromptResultSchema,\r\n ListResourcesRequest,\r\n ListResourcesResult,\r\n ListResourcesResultSchema,\r\n ReadResourceRequest,\r\n ReadResourceResult,\r\n ReadResourceResultSchema,\r\n} from '@modelcontextprotocol/sdk/types.js';\r\nimport type { OAuthTokens, OAuthClientInformationFull } from '@modelcontextprotocol/sdk/shared/auth.js';\r\nimport { StorageOAuthClientProvider, type AgentsOAuthProvider } from './storage-oauth-provider.js';\r\nimport { sanitizeServerLabel } from '../../shared/utils.js';\r\nimport { Emitter, type McpConnectionEvent, type McpObservabilityEvent, type McpConnectionState } from '../../shared/events.js';\r\nimport { UnauthorizedError } from '../../shared/errors.js';\r\nimport { storage } from '../storage/index.js';\r\nimport {\r\n MCP_CLIENT_NAME,\r\n MCP_CLIENT_VERSION,\r\n SESSION_TTL_SECONDS,\r\n STATE_EXPIRATION_MS,\r\n} from '../../shared/constants.js';\r\n\r\n/**\r\n * Supported MCP transport types\r\n */\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n/**\r\n * Extended capabilities including MCP App support\r\n */\r\nimport type { ClientCapabilities } from '@modelcontextprotocol/sdk/types.js';\r\n\r\ninterface McpAppClientCapabilities extends ClientCapabilities {\r\n extensions?: {\r\n 'io.modelcontextprotocol/ui'?: {\r\n mimeTypes: string[];\r\n };\r\n [key: string]: unknown;\r\n };\r\n}\r\n\r\nexport interface MCPOAuthClientOptions {\r\n serverUrl?: string;\r\n serverName?: string;\r\n callbackUrl?: string;\r\n onRedirect?: (url: string) => void;\r\n identity: string;\r\n serverId?: string; /** Optional - loaded from session if not provided */\r\n sessionId: string; /** Required - primary key for session lookup */\r\n transportType?: TransportType;\r\n clientId?: string;\r\n clientSecret?: string;\r\n headers?: Record<string, string>;\r\n /** OAuth Client Metadata (optional - user application info) */\r\n clientName?: string;\r\n clientUri?: string;\r\n logoUri?: string;\r\n policyUri?: string;\r\n}\r\n\r\n/**\r\n * MCP Client with OAuth 2.1 authentication support\r\n * Manages connections to MCP servers with automatic token refresh and session restoration\r\n * Emits connection lifecycle events for observability\r\n */\r\nexport class MCPClient {\r\n private client: Client | null = null;\r\n public oauthProvider: AgentsOAuthProvider | null = null;\r\n private transport: StreamableHTTPClientTransport | SSEClientTransport | null = null;\r\n private identity: string;\r\n private serverId?: string;\r\n private sessionId: string;\r\n private serverName?: string;\r\n private transportType: TransportType | undefined;\r\n private serverUrl: string | undefined;\r\n private callbackUrl: string | undefined;\r\n private onRedirect: ((url: string) => void) | undefined;\r\n private clientId?: string;\r\n private clientSecret?: string;\r\n private headers?: Record<string, string>;\r\n /** OAuth Client Metadata */\r\n private clientName?: string;\r\n private clientUri?: string;\r\n private logoUri?: string;\r\n private policyUri?: string;\r\n private createdAt?: number;\r\n\r\n\r\n /** Event emitters for connection lifecycle */\r\n private readonly _onConnectionEvent = new Emitter<McpConnectionEvent>();\r\n public readonly onConnectionEvent = this._onConnectionEvent.event;\r\n\r\n private readonly _onObservabilityEvent = new Emitter<McpObservabilityEvent>();\r\n public readonly onObservabilityEvent = this._onObservabilityEvent.event;\r\n\r\n private currentState: McpConnectionState = 'DISCONNECTED';\r\n\r\n /**\r\n * Creates a new MCP client instance\r\n * Can be initialized with minimal options (identity + sessionId) for session restoration\r\n * @param options - Client configuration options\r\n */\r\n constructor(options: MCPOAuthClientOptions) {\r\n this.serverUrl = options.serverUrl;\r\n this.serverName = options.serverName;\r\n this.callbackUrl = options.callbackUrl;\r\n this.onRedirect = options.onRedirect;\r\n this.identity = options.identity;\r\n this.serverId = options.serverId;\r\n this.sessionId = options.sessionId;\r\n this.transportType = options.transportType;\r\n this.clientId = options.clientId;\r\n this.clientSecret = options.clientSecret;\r\n this.headers = options.headers;\r\n this.clientName = options.clientName;\r\n this.clientUri = options.clientUri;\r\n this.logoUri = options.logoUri;\r\n this.policyUri = options.policyUri;\r\n }\r\n\r\n /**\r\n * Emit a connection state change event\r\n * @private\r\n */\r\n private emitStateChange(newState: McpConnectionState): void {\r\n const previousState = this.currentState;\r\n this.currentState = newState;\r\n\r\n if (!this.serverId) return;\r\n\r\n this._onConnectionEvent.fire({\r\n type: 'state_changed',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n serverName: this.serverName || this.serverId,\r\n serverUrl: this.serverUrl || '',\r\n createdAt: this.createdAt,\r\n state: newState,\r\n previousState,\r\n timestamp: Date.now(),\r\n });\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:state_change',\r\n level: 'info',\r\n message: `Connection state: ${previousState} → ${newState}`,\r\n displayMessage: `State changed to ${newState}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: { previousState, newState },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n }\r\n\r\n /**\r\n * Emit an error event\r\n * @private\r\n */\r\n private emitError(error: string, errorType: 'connection' | 'auth' | 'validation' | 'unknown' = 'unknown'): void {\r\n if (!this.serverId) return;\r\n\r\n this._onConnectionEvent.fire({\r\n type: 'error',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n error,\r\n errorType,\r\n timestamp: Date.now(),\r\n });\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:error',\r\n level: 'error',\r\n message: error,\r\n displayMessage: error,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: { errorType, error },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n }\r\n\r\n /**\r\n * Emit a progress event\r\n * @private\r\n */\r\n private emitProgress(message: string): void {\r\n if (!this.serverId) return;\r\n\r\n this._onConnectionEvent.fire({\r\n type: 'progress',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n message,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n /**\r\n * Get current connection state\r\n */\r\n getConnectionState(): McpConnectionState {\r\n return this.currentState;\r\n }\r\n\r\n /**\r\n * Helper to create a transport instance\r\n * @param type - The transport type to create\r\n * @returns Configured transport instance\r\n * @private\r\n */\r\n private getTransport(type: TransportType): StreamableHTTPClientTransport | SSEClientTransport {\r\n if (!this.serverUrl) {\r\n throw new Error('Server URL is required to create transport');\r\n }\r\n\r\n const baseUrl = new URL(this.serverUrl);\r\n const transportOptions = {\r\n authProvider: this.oauthProvider!,\r\n ...(this.headers && { headers: this.headers }),\r\n /**\r\n * Custom fetch implementation to handle connection timeouts.\r\n * Observation: SDK 1.24.0+ connections may hang indefinitely in some environments.\r\n * This wrapper enforces a timeout and properly uses AbortController to unblock the request.\r\n */\r\n fetch: (url: RequestInfo | URL, init?: RequestInit) => {\r\n const timeout = 30000;\r\n const controller = new AbortController();\r\n const timeoutId = setTimeout(() => controller.abort(), timeout);\r\n const signal = init?.signal ?\r\n // @ts-ignore: AbortSignal.any is available in Node 20+\r\n (AbortSignal.any ? AbortSignal.any([init.signal, controller.signal]) : controller.signal) :\r\n controller.signal;\r\n\r\n return fetch(url, { ...init, signal }).finally(() => clearTimeout(timeoutId));\r\n }\r\n };\r\n\r\n if (type === 'sse') {\r\n return new SSEClientTransport(baseUrl, transportOptions);\r\n } else {\r\n return new StreamableHTTPClientTransport(baseUrl, transportOptions);\r\n }\r\n }\r\n\r\n /**\r\n * Initializes client components (client, transport, OAuth provider)\r\n * Loads missing configuration from Redis session store if needed\r\n * This method is idempotent and safe to call multiple times\r\n * @private\r\n */\r\n private async initialize(): Promise<void> {\r\n if (this.client && this.oauthProvider) {\r\n return;\r\n }\r\n\r\n this.emitStateChange('INITIALIZING');\r\n this.emitProgress('Loading session configuration...');\r\n\r\n if (!this.serverUrl || !this.callbackUrl || !this.serverId) {\r\n const sessionData = await storage.getSession(this.identity, this.sessionId);\r\n if (!sessionData) {\r\n throw new Error(`Session not found: ${this.sessionId}`);\r\n }\r\n\r\n this.serverUrl = this.serverUrl || sessionData.serverUrl;\r\n this.callbackUrl = this.callbackUrl || sessionData.callbackUrl;\r\n /**\r\n * Do NOT load transportType from session if not explicitly provided.\r\n * We want to re-negotiate (try streamable -> sse) on new connections if in \"Auto\" mode.\r\n * this.transportType = this.transportType || sessionData.transportType; \r\n */\r\n this.serverName = this.serverName || sessionData.serverName;\r\n this.serverId = this.serverId || sessionData.serverId || 'unknown';\r\n this.headers = this.headers || sessionData.headers;\r\n this.createdAt = sessionData.createdAt;\r\n }\r\n\r\n if (!this.serverUrl || !this.callbackUrl || !this.serverId) {\r\n throw new Error('Missing required connection metadata');\r\n }\r\n\r\n if (!this.oauthProvider) {\r\n if (!this.serverId) {\r\n throw new Error('serverId required for OAuth provider initialization');\r\n }\r\n this.oauthProvider = new StorageOAuthClientProvider({\r\n identity: this.identity,\r\n serverId: this.serverId,\r\n sessionId: this.sessionId,\r\n redirectUrl: this.callbackUrl!,\r\n clientName: this.clientName,\r\n clientUri: this.clientUri,\r\n logoUri: this.logoUri,\r\n policyUri: this.policyUri,\r\n clientId: this.clientId,\r\n clientSecret: this.clientSecret,\r\n onRedirect: (redirectUrl: string) => {\r\n if (this.onRedirect) {\r\n this.onRedirect(redirectUrl);\r\n }\r\n }\r\n });\r\n }\r\n\r\n if (!this.client) {\r\n this.client = new Client(\r\n {\r\n name: MCP_CLIENT_NAME,\r\n version: MCP_CLIENT_VERSION,\r\n },\r\n {\r\n capabilities: {\r\n extensions: {\r\n 'io.modelcontextprotocol/ui': {\r\n mimeTypes: ['text/html+mcp'],\r\n },\r\n },\r\n } as McpAppClientCapabilities\r\n }\r\n );\r\n }\r\n\r\n // Create session in storage if it doesn't exist yet\r\n // This is needed BEFORE OAuth flow starts because the OAuth provider\r\n // will call saveCodeVerifier() which requires the session to exist\r\n const existingSession = await storage.getSession(this.identity, this.sessionId);\r\n if (!existingSession && this.serverId && this.serverUrl && this.callbackUrl) {\r\n this.createdAt = Date.now();\r\n console.log(`[MCPClient] Creating initial session ${this.sessionId} for OAuth flow`);\r\n await storage.createSession({\r\n sessionId: this.sessionId,\r\n identity: this.identity,\r\n serverId: this.serverId,\r\n serverName: this.serverName,\r\n serverUrl: this.serverUrl,\r\n callbackUrl: this.callbackUrl,\r\n transportType: this.transportType || 'streamable_http',\r\n createdAt: this.createdAt,\r\n active: false,\r\n }, Math.floor(STATE_EXPIRATION_MS / 1000)); // Short TTL until connection succeeds\r\n }\r\n }\r\n\r\n /**\r\n * Saves current session state to storage\r\n * Creates new session if it doesn't exist, updates if it does\r\n * @param ttl - Time-to-live in seconds (defaults to 12hr for connected sessions)\r\n * @param active - Session status marker used to avoid unnecessary TTL rewrites\r\n * @private\r\n */\r\n private async saveSession(\r\n ttl: number = SESSION_TTL_SECONDS,\r\n active: boolean = true\r\n ): Promise<void> {\r\n if (!this.sessionId || !this.serverId || !this.serverUrl || !this.callbackUrl) {\r\n return;\r\n }\r\n\r\n const sessionData = {\r\n sessionId: this.sessionId,\r\n identity: this.identity,\r\n serverId: this.serverId,\r\n serverName: this.serverName,\r\n serverUrl: this.serverUrl,\r\n callbackUrl: this.callbackUrl,\r\n transportType: (this.transportType || 'streamable_http') as TransportType,\r\n createdAt: this.createdAt || Date.now(),\r\n active,\r\n };\r\n\r\n // Try to update first, create if doesn't exist\r\n const existingSession = await storage.getSession(this.identity, this.sessionId);\r\n if (existingSession) {\r\n await storage.updateSession(this.identity, this.sessionId, sessionData, ttl);\r\n } else {\r\n await storage.createSession(sessionData, ttl);\r\n }\r\n }\r\n\r\n /**\r\n * Try to connect using available transports\r\n * @returns The corrected transport type object if successful\r\n * @private\r\n */\r\n private async tryConnect(): Promise<{ transportType: TransportType }> {\r\n /**\r\n * If exact transport type is known, only try that.\r\n * Otherwise (auto mode), try streamable_http first, then sse.\r\n */\r\n const transportsToTry: TransportType[] = this.transportType\r\n ? [this.transportType]\r\n : ['streamable_http', 'sse'];\r\n\r\n let lastError: unknown;\r\n\r\n for (const currentType of transportsToTry) {\r\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\r\n\r\n try {\r\n const transport = this.getTransport(currentType);\r\n\r\n /** Update local state with the transport we are about to try */\r\n this.transport = transport;\r\n\r\n /** Race connection against timeout */\r\n await this.client!.connect(transport);\r\n\r\n /** Success! Return the type that worked */\r\n return { transportType: currentType };\r\n\r\n } catch (error: any) {\r\n lastError = error;\r\n\r\n /** Check for Auth Errors - these should fail immediately, no fallback */\r\n const isAuthError = error instanceof SDKUnauthorizedError ||\r\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\r\n\r\n if (isAuthError) {\r\n throw error;\r\n }\r\n\r\n /** If this was the last transport to try, throw the error */\r\n if (isLastAttempt) {\r\n throw error;\r\n }\r\n\r\n /** Otherwise, log and continue to next transport */\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n this.emitProgress(`Connection attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\r\n this._onObservabilityEvent.fire({\r\n level: 'warn',\r\n message: `Transport ${currentType} failed, falling back`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n metadata: {\r\n failedTransport: currentType,\r\n error: errorMessage\r\n },\r\n timestamp: Date.now(),\r\n });\r\n }\r\n }\r\n\r\n throw lastError || new Error('No transports available');\r\n }\r\n\r\n /**\r\n * Connects to the MCP server\r\n * Automatically validates and refreshes OAuth tokens if needed\r\n * Saves session to Redis on first successful connection\r\n * @throws {UnauthorizedError} When OAuth authorization is required\r\n * @throws {Error} When connection fails for other reasons\r\n */\r\n async connect(): Promise<void> {\r\n await this.initialize();\r\n\r\n if (!this.client || !this.oauthProvider) {\r\n const error = 'Client or OAuth provider not initialized';\r\n this.emitError(error, 'connection');\r\n this.emitStateChange('FAILED');\r\n throw new Error(error);\r\n }\r\n\r\n try {\r\n this.emitProgress('Validating OAuth tokens...');\r\n await this.getValidTokens();\r\n\r\n this.emitStateChange('CONNECTING');\r\n\r\n /** Use the tryConnect loop to handle transport fallbacks */\r\n const { transportType } = await this.tryConnect();\r\n\r\n /** Update transport type to the one that actually worked */\r\n this.transportType = transportType;\r\n\r\n this.emitStateChange('CONNECTED');\r\n this.emitProgress('Connected successfully');\r\n\r\n // Promote short-lived OAuth-pending session TTL to long-lived active TTL once.\r\n // Also persist when transport negotiation changed the effective transport.\r\n const existingSession = await storage.getSession(this.identity, this.sessionId);\r\n const needsTransportUpdate = !existingSession || existingSession.transportType !== this.transportType;\r\n const needsTtlPromotion = !existingSession || existingSession.active !== true;\r\n\r\n if (needsTransportUpdate || needsTtlPromotion) {\r\n console.log(`[MCPClient] Saving session ${this.sessionId} with 12hr TTL (connect success)`);\r\n await this.saveSession(SESSION_TTL_SECONDS, true);\r\n }\r\n } catch (error) {\r\n /** Handle Authentication Errors */\r\n if (\r\n error instanceof SDKUnauthorizedError ||\r\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'))\r\n ) {\r\n this.emitStateChange('AUTHENTICATING');\r\n // Save session with 10min TTL for OAuth pending state\r\n console.log(`[MCPClient] Saving session ${this.sessionId} with 10min TTL (OAuth pending)`);\r\n await this.saveSession(Math.floor(STATE_EXPIRATION_MS / 1000), false);\r\n\r\n /** Get OAuth authorization URL if available */\r\n let authUrl = '';\r\n if (this.oauthProvider) {\r\n authUrl = this.oauthProvider.authUrl || '';\r\n }\r\n\r\n if (this.serverId) {\r\n this._onConnectionEvent.fire({\r\n type: 'auth_required',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n authUrl,\r\n timestamp: Date.now(),\r\n });\r\n\r\n if (authUrl && this.onRedirect) {\r\n this.onRedirect(authUrl);\r\n }\r\n }\r\n\r\n throw new UnauthorizedError('OAuth authorization required');\r\n }\r\n\r\n /** Handle Generic Errors */\r\n const errorMessage = error instanceof Error ? error.message : 'Connection failed';\r\n this.emitError(errorMessage, 'connection');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Completes OAuth authorization flow by exchanging authorization code for tokens\r\n * Creates new authenticated client and transport, then establishes connection\r\n * Saves active session to Redis after successful authentication\r\n * @param authCode - Authorization code received from OAuth callback\r\n */\r\n\r\n // TODO: needs to be optimized\r\n async finishAuth(authCode: string): Promise<void> {\r\n this.emitStateChange('AUTHENTICATING');\r\n this.emitProgress('Exchanging authorization code for tokens...');\r\n\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n const error = 'OAuth provider not initialized';\r\n this.emitError(error, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw new Error(error);\r\n }\r\n\r\n /**\r\n * Determine which transports to try for finishing auth\r\n * If transportType is set, use only that. Otherwise try streamable_http then sse.\r\n */\r\n const transportsToTry: TransportType[] = this.transportType\r\n ? [this.transportType]\r\n : ['streamable_http', 'sse'];\r\n\r\n let lastError: unknown;\r\n let tokensExchanged = false;\r\n\r\n for (const currentType of transportsToTry) {\r\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\r\n\r\n try {\r\n const transport = this.getTransport(currentType);\r\n\r\n /** Update local state with the transport we are about to try */\r\n this.transport = transport;\r\n\r\n if (!tokensExchanged) {\r\n await transport.finishAuth(authCode);\r\n tokensExchanged = true;\r\n } else {\r\n this.emitProgress(`Tokens already exchanged, skipping auth step for ${currentType}...`);\r\n }\r\n\r\n /** Success! Update transport type */\r\n this.transportType = currentType;\r\n\r\n this.emitStateChange('AUTHENTICATED');\r\n this.emitProgress('Creating authenticated client...');\r\n\r\n this.client = new Client(\r\n {\r\n name: MCP_CLIENT_NAME,\r\n version: MCP_CLIENT_VERSION,\r\n },\r\n {\r\n capabilities: {\r\n extensions: {\r\n 'io.modelcontextprotocol/ui': {\r\n mimeTypes: ['text/html+mcp'],\r\n },\r\n },\r\n } as McpAppClientCapabilities\r\n }\r\n );\r\n\r\n this.emitStateChange('CONNECTING');\r\n\r\n /** We explicitly try to connect with the transport we just auth'd with first */\r\n await this.client.connect(this.transport);\r\n\r\n this.emitStateChange('CONNECTED');\r\n // Update session with 12hr TTL after successful OAuth\r\n console.log(`[MCPClient] Updating session ${this.sessionId} to 12hr TTL (OAuth complete)`);\r\n await this.saveSession(SESSION_TTL_SECONDS, true);\r\n\r\n return; // Success, exit function\r\n\r\n } catch (error) {\r\n lastError = error;\r\n\r\n const isAuthError = error instanceof SDKUnauthorizedError ||\r\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\r\n\r\n if (isAuthError) {\r\n throw error;\r\n }\r\n\r\n const errorMessage = error instanceof Error ? error.message : String(error);\r\n\r\n // Don't retry if the authorization code was rejected (it's one-time use)\r\n if (!tokensExchanged && errorMessage.toLowerCase().includes('invalid authorization code')) {\r\n const msg = error instanceof Error ? error.message : 'Authentication failed';\r\n this.emitError(msg, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n\r\n if (isLastAttempt) {\r\n const msg = error instanceof Error ? error.message : 'Authentication failed';\r\n this.emitError(msg, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n\r\n // Log and retry\r\n this.emitProgress(`Auth attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\r\n }\r\n }\r\n\r\n if (lastError) {\r\n const errorMessage = lastError instanceof Error ? lastError.message : 'Authentication failed';\r\n this.emitError(errorMessage, 'auth');\r\n this.emitStateChange('FAILED');\r\n throw lastError;\r\n }\r\n }\r\n\r\n /**\r\n * Lists all available tools from the connected MCP server\r\n * @returns List of tools with their schemas and descriptions\r\n * @throws {Error} When client is not connected\r\n */\r\n async listTools(): Promise<ListToolsResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n this.emitStateChange('DISCOVERING');\r\n\r\n try {\r\n const request: ListToolsRequest = {\r\n method: 'tools/list',\r\n params: {},\r\n };\r\n\r\n const result = await this.client.request(request, ListToolsResultSchema);\r\n\r\n if (this.serverId) {\r\n this._onConnectionEvent.fire({\r\n type: 'tools_discovered',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n toolCount: result.tools.length,\r\n tools: result.tools,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n\r\n this.emitStateChange('READY');\r\n this.emitProgress(`Discovered ${result.tools.length} tools`);\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Failed to list tools';\r\n this.emitError(errorMessage, 'validation');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Executes a tool on the connected MCP server\r\n * @param toolName - Name of the tool to execute\r\n * @param toolArgs - Arguments to pass to the tool\r\n * @returns Tool execution result\r\n * @throws {Error} When client is not connected\r\n */\r\n async callTool(toolName: string, toolArgs: Record<string, unknown>): Promise<CallToolResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n const request: CallToolRequest = {\r\n method: 'tools/call',\r\n params: {\r\n name: toolName,\r\n arguments: toolArgs,\r\n },\r\n };\r\n\r\n try {\r\n const result = await this.client.request(request, CallToolResultSchema);\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:tool_call',\r\n level: 'info',\r\n message: `Tool ${toolName} called successfully`,\r\n displayMessage: `Called tool ${toolName}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: {\r\n toolName,\r\n args: toolArgs,\r\n },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : `Failed to call tool ${toolName}`;\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:error',\r\n level: 'error',\r\n message: errorMessage,\r\n displayMessage: `Failed to call tool ${toolName}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: {\r\n errorType: 'tool_execution',\r\n error: errorMessage,\r\n toolName,\r\n args: toolArgs,\r\n },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Lists all available prompts from the connected MCP server\r\n * @returns List of available prompts\r\n * @throws {Error} When client is not connected\r\n */\r\n async listPrompts(): Promise<ListPromptsResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n this.emitStateChange('DISCOVERING');\r\n\r\n try {\r\n const request: ListPromptsRequest = {\r\n method: 'prompts/list',\r\n params: {},\r\n };\r\n\r\n const result = await this.client.request(request, ListPromptsResultSchema);\r\n\r\n this.emitStateChange('READY');\r\n this.emitProgress(`Discovered ${result.prompts.length} prompts`);\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Failed to list prompts';\r\n this.emitError(errorMessage, 'validation');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Gets a specific prompt with arguments\r\n * @param name - Name of the prompt\r\n * @param args - Arguments for the prompt\r\n * @returns Prompt content\r\n * @throws {Error} When client is not connected\r\n */\r\n async getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n const request: GetPromptRequest = {\r\n method: 'prompts/get',\r\n params: {\r\n name,\r\n arguments: args,\r\n },\r\n };\r\n\r\n return await this.client.request(request, GetPromptResultSchema);\r\n }\r\n\r\n /**\r\n * Lists all available resources from the connected MCP server\r\n * @returns List of available resources\r\n * @throws {Error} When client is not connected\r\n */\r\n async listResources(): Promise<ListResourcesResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n this.emitStateChange('DISCOVERING');\r\n\r\n try {\r\n const request: ListResourcesRequest = {\r\n method: 'resources/list',\r\n params: {},\r\n };\r\n\r\n const result = await this.client.request(request, ListResourcesResultSchema);\r\n\r\n this.emitStateChange('READY');\r\n this.emitProgress(`Discovered ${result.resources.length} resources`);\r\n\r\n return result;\r\n } catch (error) {\r\n const errorMessage = error instanceof Error ? error.message : 'Failed to list resources';\r\n this.emitError(errorMessage, 'validation');\r\n this.emitStateChange('FAILED');\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Reads a specific resource\r\n * @param uri - URI of the resource to read\r\n * @returns Resource content\r\n * @throws {Error} When client is not connected\r\n */\r\n async readResource(uri: string): Promise<ReadResourceResult> {\r\n if (!this.client) {\r\n throw new Error('Not connected to server');\r\n }\r\n\r\n const request: ReadResourceRequest = {\r\n method: 'resources/read',\r\n params: {\r\n uri,\r\n },\r\n };\r\n\r\n return await this.client.request(request, ReadResourceResultSchema);\r\n }\r\n\r\n /**\r\n * Refreshes the OAuth access token using the refresh token\r\n * Discovers OAuth metadata from server and exchanges refresh token for new access token\r\n * @returns True if refresh was successful, false otherwise\r\n */\r\n async refreshToken(): Promise<boolean> {\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n return false;\r\n }\r\n\r\n const tokens = await this.oauthProvider.tokens();\r\n if (!tokens || !tokens.refresh_token) {\r\n return false;\r\n }\r\n\r\n const clientInformation = await this.oauthProvider.clientInformation();\r\n if (!clientInformation) {\r\n return false;\r\n }\r\n\r\n try {\r\n const resourceMetadata = await discoverOAuthProtectedResourceMetadata(this.serverUrl!);\r\n const authServerUrl = resourceMetadata?.authorization_servers?.[0] || this.serverUrl!;\r\n const authMetadata = await discoverAuthorizationServerMetadata(authServerUrl);\r\n\r\n const newTokens = await refreshAuthorization(authServerUrl, {\r\n metadata: authMetadata,\r\n clientInformation,\r\n refreshToken: tokens.refresh_token,\r\n });\r\n\r\n await this.oauthProvider.saveTokens(newTokens);\r\n return true;\r\n } catch (error) {\r\n console.error('[OAuth] Token refresh failed:', error);\r\n return false;\r\n }\r\n }\r\n\r\n /**\r\n * Ensures OAuth tokens are valid, refreshing them if expired\r\n * Called automatically by connect() - rarely needs to be called manually\r\n * @returns True if valid tokens are available, false otherwise\r\n */\r\n async getValidTokens(): Promise<boolean> {\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n return false;\r\n }\r\n\r\n const tokens = await this.oauthProvider.tokens();\r\n if (!tokens) {\r\n return false;\r\n }\r\n\r\n if (this.oauthProvider.isTokenExpired()) {\r\n return await this.refreshToken();\r\n }\r\n\r\n return true;\r\n }\r\n\r\n /**\r\n * Reconnects to MCP server using existing OAuth provider from Redis\r\n * Used for session restoration in serverless environments\r\n * Creates new client and transport without re-initializing OAuth provider\r\n * @throws {Error} When OAuth provider is not initialized\r\n */\r\n async reconnect(): Promise<void> {\r\n await this.initialize();\r\n\r\n if (!this.oauthProvider) {\r\n throw new Error('OAuth provider not initialized');\r\n }\r\n\r\n this.client = new Client(\r\n {\r\n name: MCP_CLIENT_NAME,\r\n version: MCP_CLIENT_VERSION,\r\n },\r\n { capabilities: {} }\r\n );\r\n\r\n // Use default logic to get transport, defaulting to what's stored or auto\r\n const tt = this.transportType || 'streamable_http';\r\n this.transport = this.getTransport(tt);\r\n\r\n await this.client.connect(this.transport);\r\n }\r\n\r\n /**\r\n * Completely removes the session from Redis including all OAuth data\r\n * Invalidates credentials and disconnects the client\r\n */\r\n async clearSession(): Promise<void> {\r\n try {\r\n await this.initialize();\r\n } catch (error) {\r\n console.warn('[MCPClient] Initialization failed during clearSession:', error);\r\n }\r\n\r\n if (this.oauthProvider) {\r\n await (this.oauthProvider as any).invalidateCredentials('all');\r\n }\r\n\r\n await storage.removeSession(this.identity, this.sessionId);\r\n this.disconnect();\r\n }\r\n\r\n /**\r\n * Checks if the client is currently connected to an MCP server\r\n * @returns True if connected, false otherwise\r\n */\r\n isConnected(): boolean {\r\n return this.client !== null;\r\n }\r\n\r\n /**\r\n * Disconnects from the MCP server and cleans up resources\r\n * Does not remove session from Redis - use clearSession() for that\r\n */\r\n disconnect(reason?: string): void {\r\n if (this.client) {\r\n this.client.close();\r\n }\r\n this.client = null;\r\n this.oauthProvider = null;\r\n this.transport = null;\r\n\r\n // Emit disconnected event\r\n if (this.serverId) {\r\n this._onConnectionEvent.fire({\r\n type: 'disconnected',\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n reason,\r\n timestamp: Date.now(),\r\n });\r\n\r\n this._onObservabilityEvent.fire({\r\n type: 'mcp:client:disconnect',\r\n level: 'info',\r\n message: `Disconnected from ${this.serverId}`,\r\n sessionId: this.sessionId,\r\n serverId: this.serverId,\r\n payload: {\r\n reason: reason || 'unknown',\r\n },\r\n timestamp: Date.now(),\r\n id: nanoid(),\r\n });\r\n }\r\n\r\n this.emitStateChange('DISCONNECTED');\r\n }\r\n\r\n /**\r\n * Dispose of all event emitters\r\n * Call this when the client is no longer needed\r\n */\r\n dispose(): void {\r\n this._onConnectionEvent.dispose();\r\n this._onObservabilityEvent.dispose();\r\n }\r\n\r\n /**\r\n * Gets the server URL\r\n * @returns Server URL or empty string if not set\r\n */\r\n getServerUrl(): string {\r\n return this.serverUrl || '';\r\n }\r\n\r\n /**\r\n * Gets the OAuth callback URL\r\n * @returns Callback URL or empty string if not set\r\n */\r\n getCallbackUrl(): string {\r\n return this.callbackUrl || '';\r\n }\r\n\r\n /**\r\n * Gets the transport type being used\r\n * @returns Transport type (defaults to 'streamable_http')\r\n */\r\n getTransportType(): TransportType {\r\n return this.transportType || 'streamable_http';\r\n }\r\n\r\n /**\r\n * Gets the human-readable server name\r\n * @returns Server name or undefined\r\n */\r\n getServerName(): string | undefined {\r\n return this.serverName;\r\n }\r\n\r\n /**\r\n * Gets the server ID\r\n * @returns Server ID or undefined\r\n */\r\n getServerId(): string | undefined {\r\n return this.serverId;\r\n }\r\n\r\n /**\r\n * Gets the session ID\r\n * @returns Session ID\r\n */\r\n getSessionId(): string {\r\n return this.sessionId;\r\n }\r\n\r\n /**\r\n * Gets MCP server configuration for all active user sessions\r\n * Loads sessions from Redis, validates OAuth tokens, refreshes if expired\r\n * Returns ready-to-use configuration with valid auth headers\r\n * @param identity - User ID to fetch sessions for\r\n * @returns Object keyed by sanitized server labels containing transport, url, headers, etc.\r\n * @static\r\n */\r\n static async getMcpServerConfig(identity: string): Promise<Record<string, any>> {\r\n const mcpConfig: Record<string, any> = {};\r\n const sessions = await storage.getIdentitySessionsData(identity);\r\n\r\n await Promise.all(\r\n sessions.map(async (sessionData) => {\r\n const { sessionId } = sessionData;\r\n\r\n try {\r\n // Validate session - remove if missing required fields\r\n if (\r\n !sessionData.serverId ||\r\n !sessionData.transportType ||\r\n !sessionData.serverUrl ||\r\n !sessionData.callbackUrl\r\n ) {\r\n await storage.removeSession(identity, sessionId);\r\n return;\r\n }\r\n\r\n // Get OAuth headers if session requires authentication\r\n let headers: Record<string, string> | undefined;\r\n try {\r\n // Inject existing session data to avoid redundant storage reads in initialize()\r\n const client = new MCPClient({\r\n identity,\r\n sessionId,\r\n serverId: sessionData.serverId,\r\n serverUrl: sessionData.serverUrl,\r\n callbackUrl: sessionData.callbackUrl,\r\n serverName: sessionData.serverName,\r\n transportType: sessionData.transportType,\r\n headers: sessionData.headers,\r\n });\r\n\r\n await client.initialize();\r\n\r\n const hasValidTokens = await client.getValidTokens();\r\n if (hasValidTokens && client.oauthProvider) {\r\n const tokens = await client.oauthProvider.tokens();\r\n if (tokens?.access_token) {\r\n headers = { Authorization: `Bearer ${tokens.access_token}` };\r\n }\r\n }\r\n } catch (error) {\r\n console.warn(`[MCP] Failed to get OAuth tokens for ${sessionId}:`, error);\r\n }\r\n\r\n // Build server config\r\n const label = sanitizeServerLabel(\r\n sessionData.serverName || sessionData.serverId || 'server'\r\n );\r\n\r\n mcpConfig[label] = {\r\n transport: sessionData.transportType,\r\n url: sessionData.serverUrl,\r\n ...(sessionData.serverName && {\r\n serverName: sessionData.serverName,\r\n serverLabel: label,\r\n }),\r\n ...(headers && { headers }),\r\n };\r\n } catch (error) {\r\n await storage.removeSession(identity, sessionId);\r\n console.warn(`[MCP] Failed to process session ${sessionId}:`, error);\r\n }\r\n })\r\n );\r\n\r\n return mcpConfig;\r\n }\r\n\r\n}\r\n\r\n","\r\n\r\nimport { MCPClient } from './oauth-client.js';\r\nimport { storage, type SessionData } from '../storage/index.js';\r\n\r\n/**\r\n * Manages multiple MCP connections for a single user identity.\r\n * Allows aggregating tools from all connected servers.\r\n */\r\nexport interface MultiSessionOptions {\r\n /**\r\n * Connection timeout in milliseconds\r\n * @default 15000\r\n */\r\n timeout?: number;\r\n /**\r\n * Maximum number of retry attempts\r\n * @default 2\r\n */\r\n maxRetries?: number;\r\n /**\r\n * Delay between retries in milliseconds\r\n * @default 1000\r\n */\r\n retryDelay?: number;\r\n}\r\n\r\n/**\r\n * Manages multiple MCP connections for a single user identity.\r\n * Allows aggregating tools from all connected servers.\r\n */\r\nexport class MultiSessionClient {\r\n private clients: MCPClient[] = [];\r\n private identity: string;\r\n private options: MultiSessionOptions;\r\n\r\n constructor(identity: string, options: MultiSessionOptions = {}) {\r\n this.identity = identity;\r\n this.options = {\r\n timeout: 15000,\r\n maxRetries: 2,\r\n retryDelay: 1000,\r\n ...options\r\n };\r\n }\r\n\r\n private async getActiveSessions(): Promise<SessionData[]> {\r\n const sessions = await storage.getIdentitySessionsData(this.identity);\r\n console.log(`[MultiSessionClient] All sessions for ${this.identity}:`,\r\n sessions.map(s => ({ sessionId: s.sessionId, serverId: s.serverId }))\r\n );\r\n const valid = sessions.filter(s => s.serverId && s.serverUrl && s.callbackUrl);\r\n console.log(`[MultiSessionClient] Filtered valid sessions:`, valid.length);\r\n return valid;\r\n }\r\n\r\n private async connectInBatches(sessions: SessionData[]): Promise<void> {\r\n const BATCH_SIZE = 5;\r\n for (let i = 0; i < sessions.length; i += BATCH_SIZE) {\r\n const batch = sessions.slice(i, i + BATCH_SIZE);\r\n await Promise.all(batch.map(session => this.connectSession(session)));\r\n }\r\n }\r\n\r\n private async connectSession(session: SessionData): Promise<void> {\r\n const existingClient = this.clients.find(c => c.getSessionId() === session.sessionId);\r\n if (existingClient?.isConnected()) {\r\n return;\r\n }\r\n\r\n const maxRetries = this.options.maxRetries ?? 2;\r\n const retryDelay = this.options.retryDelay ?? 1000;\r\n let lastError: unknown;\r\n\r\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\r\n try {\r\n const client = await this.createAndConnectClient(session);\r\n this.clients.push(client);\r\n return;\r\n } catch (error) {\r\n lastError = error;\r\n if (attempt < maxRetries) {\r\n await new Promise(resolve => setTimeout(resolve, retryDelay));\r\n }\r\n }\r\n }\r\n\r\n console.error(`[MultiSessionClient] Failed to connect to session ${session.sessionId} after ${maxRetries + 1} attempts:`, lastError);\r\n }\r\n\r\n private async createAndConnectClient(session: SessionData): Promise<MCPClient> {\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId: session.sessionId,\r\n serverId: session.serverId,\r\n serverUrl: session.serverUrl,\r\n callbackUrl: session.callbackUrl,\r\n serverName: session.serverName,\r\n transportType: session.transportType,\r\n headers: session.headers,\r\n });\r\n\r\n const timeoutMs = this.options.timeout ?? 15000;\r\n const timeoutPromise = new Promise<never>((_, reject) => {\r\n setTimeout(() => reject(new Error(`Connection timed out after ${timeoutMs}ms`)), timeoutMs);\r\n });\r\n\r\n await Promise.race([client.connect(), timeoutPromise]);\r\n return client;\r\n }\r\n\r\n async connect(): Promise<void> {\r\n const sessions = await this.getActiveSessions();\r\n await this.connectInBatches(sessions);\r\n }\r\n\r\n /**\r\n * Returns the array of currently connected clients.\r\n */\r\n getClients(): MCPClient[] {\r\n return this.clients;\r\n }\r\n\r\n /**\r\n * Disconnects all clients.\r\n */\r\n disconnect(): void {\r\n this.clients.forEach((client) => client.disconnect());\r\n this.clients = [];\r\n }\r\n}\r\n\r\n","import type { McpConnectionEvent, McpObservabilityEvent } from './events.js';\nimport type { McpRpcResponse } from './types.js';\n\nexport function isRpcResponseEvent(\n event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse\n): event is McpRpcResponse {\n return 'id' in event && ('result' in event || 'error' in event);\n}\n\nexport function isConnectionEvent(\n event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse\n): event is McpConnectionEvent {\n if (!('type' in event)) {\n return false;\n }\n\n switch (event.type) {\n case 'state_changed':\n case 'tools_discovered':\n case 'auth_required':\n case 'error':\n case 'disconnected':\n case 'progress':\n return true;\n default:\n return false;\n }\n}\n","/**\r\n * SSE (Server-Sent Events) Handler for MCP Connections\r\n *\r\n * Manages real-time bidirectional communication with MCP clients:\r\n * - SSE stream for server → client events (connection state, tools, logs)\r\n * - HTTP POST for client → server RPC requests\r\n *\r\n * Key features:\r\n * - Direct HTTP response for RPC calls (bypasses SSE latency)\r\n * - Automatic session restoration and validation\r\n * - OAuth 2.1 authentication flow support\r\n * - Heartbeat to keep connections alive\r\n */\r\n\r\nimport type { McpConnectionEvent, McpObservabilityEvent } from '../../shared/events.js';\r\nimport type {\n McpRpcRequest,\n McpRpcResponse,\r\n ConnectParams,\r\n DisconnectParams,\r\n SessionParams,\r\n CallToolParams,\r\n GetPromptParams,\r\n ReadResourceParams,\r\n FinishAuthParams,\r\n SessionListResult,\r\n ConnectResult,\r\n DisconnectResult,\r\n RestoreSessionResult,\r\n FinishAuthResult,\r\n ListToolsRpcResult,\r\n ListPromptsResult,\r\n ListResourcesResult,\r\n CallToolResult,\r\n} from '../../shared/types.js';\nimport { RpcErrorCodes } from '../../shared/errors.js';\nimport { UnauthorizedError } from '../../shared/errors.js';\nimport { isConnectionEvent, isRpcResponseEvent } from '../../shared/event-routing.js';\nimport { MCPClient } from '../mcp/oauth-client.js';\nimport { storage } from '../storage/index.js';\n\r\n// ============================================\r\n// Types & Interfaces\r\n// ============================================\r\n\r\nexport interface ClientMetadata {\r\n clientName?: string;\r\n clientUri?: string;\r\n logoUri?: string;\r\n policyUri?: string;\r\n}\r\n\r\nexport interface SSEHandlerOptions {\r\n /** User/Client identifier */\r\n identity: string;\r\n\r\n /** Optional callback for authentication/authorization */\r\n onAuth?: (identity: string) => Promise<boolean>;\r\n\r\n /** Heartbeat interval in milliseconds @default 30000 */\r\n heartbeatInterval?: number;\r\n\r\n /** Static OAuth client metadata defaults (for all connections) */\r\n clientDefaults?: ClientMetadata;\r\n\r\n /** Dynamic OAuth client metadata getter (per-request, useful for multi-tenant) */\r\n getClientMetadata?: (request?: unknown) => ClientMetadata | Promise<ClientMetadata>;\r\n}\r\n\r\n// ============================================\r\n// Constants\r\n// ============================================\r\n\r\nconst DEFAULT_HEARTBEAT_INTERVAL = 30000;\r\n\r\n// ============================================\r\n// SSEConnectionManager Class\r\n// ============================================\r\n\r\n/**\r\n * Manages a single SSE connection and handles MCP operations.\r\n * Each instance corresponds to one connected browser client.\r\n */\r\nexport class SSEConnectionManager {\n private readonly identity: string;\r\n private readonly clients = new Map<string, MCPClient>();\r\n private heartbeatTimer?: NodeJS.Timeout;\r\n private isActive = true;\r\n\r\n constructor(\r\n private readonly options: SSEHandlerOptions,\r\n private readonly sendEvent: (event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse) => void\r\n ) {\r\n this.identity = options.identity;\r\n this.startHeartbeat();\r\n }\r\n\r\n /**\r\n * Get resolved client metadata (dynamic > static > defaults)\r\n */\r\n private async getResolvedClientMetadata(request?: any): Promise<ClientMetadata> {\r\n // Priority: getClientMetadata() > clientDefaults > empty object\r\n let metadata: ClientMetadata = {};\r\n\r\n // Start with static defaults\r\n if (this.options.clientDefaults) {\r\n metadata = { ...this.options.clientDefaults };\r\n }\r\n\r\n // Override with dynamic metadata if provided\r\n if (this.options.getClientMetadata) {\r\n const dynamicMetadata = await this.options.getClientMetadata(request);\r\n metadata = { ...metadata, ...dynamicMetadata };\r\n }\r\n\r\n return metadata;\r\n }\r\n\r\n /**\r\n * Start heartbeat to keep connection alive\r\n */\r\n private startHeartbeat(): void {\r\n const interval = this.options.heartbeatInterval ?? DEFAULT_HEARTBEAT_INTERVAL;\r\n this.heartbeatTimer = setInterval(() => {\r\n if (this.isActive) {\r\n this.sendEvent({\r\n level: 'debug',\r\n message: 'heartbeat',\r\n timestamp: Date.now(),\r\n } as McpObservabilityEvent);\r\n }\r\n }, interval);\r\n }\r\n\r\n /**\r\n * Handle incoming RPC requests\r\n * Returns the RPC response directly for immediate HTTP response (bypassing SSE latency)\r\n */\r\n async handleRequest(request: McpRpcRequest): Promise<McpRpcResponse> {\r\n try {\r\n let result: SessionListResult | ConnectResult | DisconnectResult | RestoreSessionResult | FinishAuthResult | ListToolsRpcResult | ListPromptsResult | ListResourcesResult | unknown;\r\n\r\n switch (request.method) {\r\n case 'getSessions':\r\n result = await this.getSessions();\r\n break;\r\n\r\n case 'connect':\r\n result = await this.connect(request.params as ConnectParams);\r\n break;\r\n\r\n case 'disconnect':\r\n result = await this.disconnect(request.params as DisconnectParams);\r\n break;\r\n\r\n case 'listTools':\r\n result = await this.listTools(request.params as SessionParams);\r\n break;\r\n\r\n case 'callTool':\r\n result = await this.callTool(request.params as CallToolParams);\r\n break;\r\n\r\n case 'restoreSession':\r\n result = await this.restoreSession(request.params as SessionParams);\r\n break;\r\n\r\n case 'finishAuth':\r\n result = await this.finishAuth(request.params as FinishAuthParams);\r\n break;\r\n\r\n case 'listPrompts':\r\n result = await this.listPrompts(request.params as SessionParams);\r\n break;\r\n\r\n case 'getPrompt':\r\n result = await this.getPrompt(request.params as GetPromptParams);\r\n break;\r\n\r\n case 'listResources':\r\n result = await this.listResources(request.params as SessionParams);\r\n break;\r\n\r\n case 'readResource':\r\n result = await this.readResource(request.params as ReadResourceParams);\r\n break;\r\n\r\n default:\r\n throw new Error(`Unknown method: ${request.method}`);\r\n }\r\n\r\n const response: McpRpcResponse = {\r\n id: request.id,\r\n result,\r\n };\r\n\r\n // Also send via SSE for backwards compatibility\r\n this.sendEvent(response);\r\n\r\n return response;\r\n } catch (error) {\r\n const errorResponse: McpRpcResponse = {\r\n id: request.id,\r\n error: {\r\n code: RpcErrorCodes.EXECUTION_ERROR,\r\n message: error instanceof Error ? error.message : 'Unknown error',\r\n },\r\n };\r\n\r\n // Also send via SSE for backwards compatibility\r\n this.sendEvent(errorResponse);\r\n\r\n return errorResponse;\r\n }\r\n }\r\n\r\n /**\r\n * Get all sessions for the current identity\r\n */\r\n private async getSessions(): Promise<SessionListResult> {\r\n const sessions = await storage.getIdentitySessionsData(this.identity);\r\n\r\n return {\r\n sessions: sessions.map((s) => ({\r\n sessionId: s.sessionId,\r\n serverId: s.serverId,\r\n serverName: s.serverName,\r\n serverUrl: s.serverUrl,\r\n transport: s.transportType,\r\n createdAt: s.createdAt,\r\n active: s.active !== false,\r\n })),\r\n };\r\n }\r\n\r\n /**\r\n * Connect to an MCP server\r\n */\r\n private async connect(params: ConnectParams): Promise<ConnectResult> {\n const { serverName, serverUrl, callbackUrl, transportType } = params;\r\n\r\n // Normalize serverId to max 12 chars to keep tool names under 64 chars (DeepSeek/OpenAI limits)\r\n // Tool name format: tool_<serverId>_<toolName> - with 12 char serverId leaves 46 chars for tool name\r\n const serverId = params.serverId && params.serverId.length <= 12\r\n ? params.serverId\r\n : await storage.generateSessionId();\r\n\r\n // Check for existing connections\r\n const existingSessions = await storage.getIdentitySessionsData(this.identity);\r\n const duplicate = existingSessions.find(s =>\r\n s.serverId === serverId || s.serverUrl === serverUrl\r\n );\r\n\r\n if (duplicate) {\r\n // If the existing session is still pending OAuth, treat connect as \"resume auth\"\r\n // instead of failing with duplicate connection error.\r\n if (duplicate.active === false) {\r\n await this.restoreSession({ sessionId: duplicate.sessionId });\r\n return {\r\n sessionId: duplicate.sessionId,\r\n success: true,\r\n };\r\n }\r\n throw new Error(`Connection already exists for server: ${duplicate.serverUrl || duplicate.serverId} (${duplicate.serverName})`);\r\n }\r\n\r\n // Generate session ID\r\n const sessionId = await storage.generateSessionId();\r\n\r\n try {\n // Get resolved client metadata\r\n const clientMetadata = await this.getResolvedClientMetadata();\r\n\r\n // Create MCP client\r\n const client = new MCPClient({\n identity: this.identity,\n sessionId,\n serverId,\n serverName,\n serverUrl,\n callbackUrl,\n transportType,\n ...clientMetadata, // Spread client metadata (clientName, clientUri, logoUri, policyUri)\n });\n\r\n // Note: Session will be created by MCPClient after successful connection\r\n // This ensures sessions only exist for successful or OAuth-pending connections\r\n\r\n // Store client\r\n this.clients.set(sessionId, client);\r\n\r\n // Subscribe to client events\r\n client.onConnectionEvent((event) => {\r\n this.emitConnectionEvent(event);\r\n });\r\n\r\n client.onObservabilityEvent((event) => {\r\n this.sendEvent(event);\r\n });\r\n\r\n // Attempt connection\r\n await client.connect();\r\n\r\n // Fetch tools\r\n await client.listTools();\r\n\r\n return {\r\n sessionId,\r\n success: true,\r\n };\r\n } catch (error) {\n if (error instanceof UnauthorizedError) {\n // OAuth-required is a pending-auth state, not a failed connection.\n this.clients.delete(sessionId);\n return {\n sessionId,\n success: true,\n };\n }\n\n this.emitConnectionEvent({\n type: 'error',\n sessionId,\n serverId,\r\n error: error instanceof Error ? error.message : 'Connection failed',\r\n errorType: 'connection',\r\n timestamp: Date.now(),\r\n });\r\n\r\n // Clean up client\r\n this.clients.delete(sessionId);\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Disconnect from an MCP server\r\n */\r\n private async disconnect(params: DisconnectParams): Promise<DisconnectResult> {\r\n const { sessionId } = params;\r\n const client = this.clients.get(sessionId);\r\n\r\n if (client) {\r\n await client.clearSession();\r\n client.disconnect();\r\n this.clients.delete(sessionId);\r\n } else {\r\n // Handle orphaned sessions (e.g., OAuth flow failed before client was stored)\r\n // Directly remove from storage since there's no active client\r\n await storage.removeSession(this.identity, sessionId);\r\n }\r\n\r\n return { success: true };\r\n }\r\n\r\n /**\r\n * Get an existing client or create and connect a new one for the session.\r\n */\r\n private async getOrCreateClient(sessionId: string): Promise<MCPClient> {\r\n const existing = this.clients.get(sessionId);\r\n if (existing) {\r\n return existing;\r\n }\r\n\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId,\r\n });\r\n\r\n // Subscribe to events before connecting\r\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\r\n client.onObservabilityEvent((event) => this.sendEvent(event));\r\n\r\n await client.connect();\r\n this.clients.set(sessionId, client);\r\n\r\n return client;\r\n }\r\n\r\n /**\r\n * List tools from a session\r\n */\r\n private async listTools(params: SessionParams): Promise<ListToolsRpcResult> {\r\n const { sessionId } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.listTools();\r\n return { tools: result.tools };\r\n }\r\n\r\n /**\r\n * Call a tool on the MCP server\r\n */\r\n private async callTool(params: CallToolParams): Promise<CallToolResult> {\r\n const { sessionId, toolName, toolArgs } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.callTool(toolName, toolArgs);\r\n\r\n // Inject sessionId into meta so client knows who handled it\r\n // This allows AppHost to auto-launch without scanning all sessions\r\n const meta = result._meta || {};\r\n\r\n return {\r\n ...result,\r\n _meta: {\r\n ...meta,\r\n sessionId,\r\n }\r\n };\r\n }\r\n\r\n /**\r\n * Restore and validate an existing session\r\n */\r\n private async restoreSession(params: SessionParams): Promise<RestoreSessionResult> {\r\n const { sessionId } = params;\r\n\r\n const session = await storage.getSession(this.identity, sessionId);\r\n if (!session) {\r\n throw new Error('Session not found');\r\n }\r\n\r\n this.emitConnectionEvent({\r\n type: 'state_changed',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n serverName: session.serverName ?? 'Unknown',\r\n serverUrl: session.serverUrl,\r\n state: 'VALIDATING',\r\n previousState: 'DISCONNECTED',\r\n timestamp: Date.now(),\r\n });\r\n\r\n try {\r\n const clientMetadata = await this.getResolvedClientMetadata();\r\n\r\n const client = new MCPClient({\r\n identity: this.identity,\r\n sessionId,\r\n ...clientMetadata,\r\n });\r\n\r\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\r\n client.onObservabilityEvent((event) => this.sendEvent(event));\r\n\r\n await client.connect();\r\n this.clients.set(sessionId, client);\r\n\r\n const tools = await client.listTools();\r\n\r\n return { success: true, toolCount: tools.tools.length };\r\n } catch (error) {\r\n this.emitConnectionEvent({\r\n type: 'error',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n error: error instanceof Error ? error.message : 'Validation failed',\r\n errorType: 'validation',\r\n timestamp: Date.now(),\r\n });\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Complete OAuth authorization flow\r\n */\r\n private async finishAuth(params: FinishAuthParams): Promise<FinishAuthResult> {\n const { sessionId, code } = params;\n\n const session = await storage.getSession(this.identity, sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n\n try {\n const client = new MCPClient({\n identity: this.identity,\n sessionId,\n });\r\n\r\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\r\n\r\n await client.finishAuth(code);\r\n this.clients.set(sessionId, client);\r\n\r\n const tools = await client.listTools();\r\n\r\n return { success: true, toolCount: tools.tools.length };\r\n } catch (error) {\r\n this.emitConnectionEvent({\r\n type: 'error',\r\n sessionId,\r\n serverId: session.serverId ?? 'unknown',\r\n error: error instanceof Error ? error.message : 'OAuth completion failed',\r\n errorType: 'auth',\r\n timestamp: Date.now(),\r\n });\r\n\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * List prompts from a session\r\n */\r\n private async listPrompts(params: SessionParams): Promise<ListPromptsResult> {\r\n const { sessionId } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.listPrompts();\r\n return { prompts: result.prompts };\r\n }\r\n\r\n /**\r\n * Get a specific prompt\r\n */\r\n private async getPrompt(params: GetPromptParams): Promise<unknown> {\r\n const { sessionId, name, args } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n return await client.getPrompt(name, args);\r\n }\r\n\r\n /**\r\n * List resources from a session\r\n */\r\n private async listResources(params: SessionParams): Promise<ListResourcesResult> {\r\n const { sessionId } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n const result = await client.listResources();\r\n return { resources: result.resources };\r\n }\r\n\r\n /**\r\n * Read a specific resource\r\n */\r\n private async readResource(params: ReadResourceParams): Promise<unknown> {\r\n const { sessionId, uri } = params;\r\n const client = await this.getOrCreateClient(sessionId);\r\n return client.readResource(uri);\r\n }\r\n\r\n /**\r\n * Emit connection event\r\n */\r\n private emitConnectionEvent(event: McpConnectionEvent): void {\r\n this.sendEvent(event);\r\n }\r\n\r\n /**\r\n * Cleanup and close all connections\r\n */\r\n dispose(): void {\r\n this.isActive = false;\r\n\r\n if (this.heartbeatTimer) {\r\n clearInterval(this.heartbeatTimer);\r\n }\r\n\r\n for (const client of this.clients.values()) {\r\n client.disconnect();\r\n }\r\n\r\n this.clients.clear();\r\n }\r\n}\r\n\r\n// ============================================\r\n// SSE Handler Factory\r\n// ============================================\r\n\r\n/**\r\n * Create an SSE endpoint handler compatible with Node.js HTTP frameworks.\r\n * Handles both SSE streaming (GET) and RPC requests (POST).\r\n */\r\nexport function createSSEHandler(options: SSEHandlerOptions) {\n return async (req: { method?: string; on: Function }, res: { writeHead: Function; write: Function }) => {\n // Set SSE headers\r\n res.writeHead(200, {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache',\r\n 'Connection': 'keep-alive',\r\n 'Access-Control-Allow-Origin': '*',\r\n });\r\n\r\n // Send initial connection acknowledgment\r\n writeSSEEvent(res, 'connected', { timestamp: Date.now() });\r\n\r\n // Create connection manager with event routing\n const manager = new SSEConnectionManager(options, (event) => {\n if (isRpcResponseEvent(event)) {\n writeSSEEvent(res, 'rpc-response', event);\n } else if (isConnectionEvent(event)) {\n writeSSEEvent(res, 'connection', event);\n } else {\n writeSSEEvent(res, 'observability', event);\n }\n });\r\n\r\n // Cleanup on client disconnect\r\n req.on('close', () => manager.dispose());\r\n\r\n // Handle RPC requests via POST\r\n if (req.method === 'POST') {\r\n let body = '';\r\n req.on('data', (chunk: Buffer) => {\r\n body += chunk.toString();\r\n });\r\n req.on('end', async () => {\r\n try {\r\n const request: McpRpcRequest = JSON.parse(body);\r\n await manager.handleRequest(request);\r\n } catch {\r\n // Request parsing/handling errors are sent via SSE error events\r\n }\r\n });\r\n }\r\n };\r\n}\r\n\r\n// ============================================\r\n// Utilities\r\n// ============================================\r\n\r\n/**\r\n * Write an SSE event to the response stream\r\n */\r\nfunction writeSSEEvent(res: { write: Function }, event: string, data: unknown): void {\n res.write(`event: ${event}\\n`);\n res.write(`data: ${JSON.stringify(data)}\\n\\n`);\n}\n","/**\r\n * Next.js App Router Handler for MCP\r\n * Stateless transport for serverless environments:\r\n * - POST + `Accept: text/event-stream` streams progress + rpc-response\r\n * - POST + JSON accepts direct RPC result response\r\n */\r\n\r\nimport { SSEConnectionManager, type ClientMetadata } from './sse-handler.js';\nimport type { McpConnectionEvent, McpObservabilityEvent } from '../../shared/events.js';\nimport { isConnectionEvent, isRpcResponseEvent } from '../../shared/event-routing.js';\nimport type { McpRpcResponse } from '../../shared/types.js';\n\r\nexport interface NextMcpHandlerOptions {\r\n /**\r\n * Extract identity from request (default: from 'identity' query param)\r\n */\r\n getIdentity?: (request: Request) => string | null;\r\n\r\n /**\r\n * Extract auth token from request (default: from 'token' query param or Authorization header)\r\n */\r\n getAuthToken?: (request: Request) => string | null;\r\n\r\n /**\r\n * Authenticate user and verify access (optional)\r\n * Return true if user is authenticated, false otherwise\r\n */\r\n authenticate?: (identity: string, token: string | null) => Promise<boolean> | boolean;\r\n\r\n /**\r\n * Heartbeat interval in milliseconds (default: 30000)\r\n */\r\n heartbeatInterval?: number;\r\n\r\n /**\r\n * Static OAuth client metadata defaults (for all connections)\r\n */\r\n clientDefaults?: ClientMetadata;\r\n\r\n /**\r\n * Dynamic OAuth client metadata getter (per-request)\r\n */\r\n getClientMetadata?: (request: Request) => ClientMetadata | Promise<ClientMetadata>;\r\n}\r\n\r\nexport function createNextMcpHandler(options: NextMcpHandlerOptions = {}) {\r\n const {\r\n getIdentity = (request: Request) => new URL(request.url).searchParams.get('identity'),\r\n getAuthToken = (request: Request) => {\r\n const url = new URL(request.url);\r\n return url.searchParams.get('token') || request.headers.get('authorization');\r\n },\r\n authenticate = () => true,\r\n heartbeatInterval = 30000,\r\n clientDefaults,\r\n getClientMetadata,\r\n } = options;\r\n\r\n const toManagerOptions = (identity: string, resolvedClientMetadata?: ClientMetadata) => ({\r\n identity,\r\n heartbeatInterval,\r\n clientDefaults: resolvedClientMetadata,\r\n });\r\n\r\n async function resolveClientMetadata(request: Request): Promise<ClientMetadata | undefined> {\r\n return getClientMetadata ? await getClientMetadata(request) : clientDefaults;\r\n }\r\n\r\n async function GET(): Promise<Response> {\r\n return Response.json(\r\n {\r\n error: {\r\n code: 'METHOD_NOT_ALLOWED',\r\n message: 'Use POST /api/mcp. For streaming use Accept: text/event-stream.',\r\n },\r\n },\r\n { status: 405 }\r\n );\r\n }\r\n\r\n async function POST(request: Request): Promise<Response> {\r\n const identity = getIdentity(request);\r\n const authToken = getAuthToken(request);\r\n const acceptsEventStream = (request.headers.get('accept') || '').toLowerCase().includes('text/event-stream');\r\n\r\n if (!identity) {\r\n return Response.json({ error: { code: 'MISSING_IDENTITY', message: 'Missing identity' } }, { status: 400 });\r\n }\r\n\r\n const isAuthorized = await authenticate(identity, authToken);\r\n if (!isAuthorized) {\r\n return Response.json({ error: { code: 'UNAUTHORIZED', message: 'Unauthorized' } }, { status: 401 });\r\n }\r\n\r\n let rawBody = '';\r\n try {\r\n rawBody = await request.text();\r\n const body = rawBody ? JSON.parse(rawBody) : null;\r\n\r\n if (!body || typeof body !== 'object') {\r\n return Response.json(\r\n {\r\n error: {\r\n code: 'INVALID_REQUEST',\r\n message: 'Invalid JSON-RPC request body',\r\n },\r\n },\r\n { status: 400 }\r\n );\r\n }\r\n\r\n const resolvedClientMetadata = await resolveClientMetadata(request);\r\n\r\n if (!acceptsEventStream) {\r\n const manager = new SSEConnectionManager(\r\n toManagerOptions(identity, resolvedClientMetadata),\r\n () => { }\r\n );\r\n try {\r\n const response = await manager.handleRequest(body as any);\r\n return Response.json(response);\r\n } finally {\r\n manager.dispose();\r\n }\r\n }\r\n\r\n const stream = new TransformStream();\r\n const writer = stream.writable.getWriter();\r\n const encoder = new TextEncoder();\r\n let streamWritable = true;\r\n\r\n const sendSSE = (event: string, data: unknown) => {\r\n if (!streamWritable) return;\r\n const message = `event: ${event}\\ndata: ${JSON.stringify(data)}\\n\\n`;\r\n writer.write(encoder.encode(message)).catch(() => {\r\n streamWritable = false;\r\n });\r\n };\r\n\r\n const manager = new SSEConnectionManager(\r\n toManagerOptions(identity, resolvedClientMetadata),\r\n (event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse) => {\n if (isRpcResponseEvent(event)) {\n sendSSE('rpc-response', event);\n } else if (isConnectionEvent(event)) {\n sendSSE('connection', event);\n } else {\n sendSSE('observability', event);\n }\n }\r\n );\r\n\r\n sendSSE('connected', { timestamp: Date.now() });\r\n\r\n void (async () => {\r\n try {\r\n await manager.handleRequest(body as any);\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error('Unknown error');\r\n sendSSE('rpc-response', {\r\n id: (body as any).id || 'unknown',\r\n error: {\r\n code: 'EXECUTION_ERROR',\r\n message: err.message,\r\n },\r\n } satisfies McpRpcResponse);\r\n } finally {\r\n streamWritable = false;\r\n manager.dispose();\r\n writer.close().catch(() => { });\r\n }\r\n })();\r\n\r\n return new Response(stream.readable, {\r\n status: 200,\r\n headers: {\r\n 'Content-Type': 'text/event-stream',\r\n 'Cache-Control': 'no-cache, no-transform',\r\n 'Connection': 'keep-alive',\r\n 'X-Accel-Buffering': 'no',\r\n },\r\n });\r\n } catch (error) {\r\n const err = error instanceof Error ? error : new Error('Unknown error');\r\n console.error('[MCP Next Handler] Failed to handle RPC', {\r\n identity,\r\n message: err.message,\r\n stack: err.stack,\r\n rawBody: rawBody.slice(0, 500),\r\n });\r\n return Response.json(\r\n {\r\n error: {\r\n code: 'EXECUTION_ERROR',\r\n message: err.message,\r\n },\r\n },\r\n { status: 500 }\r\n );\r\n }\r\n }\r\n\r\n return { GET, POST };\r\n}\r\n","/**\r\n * Stateless RPC-over-stream client for MCP connections.\r\n *\r\n * Uses single POST requests with `Accept: text/event-stream` for every RPC call.\r\n * Progress events and the final rpc-response are delivered in the same response.\r\n */\r\n\r\nimport { nanoid } from 'nanoid';\r\nimport type {\r\n McpConnectionEvent,\r\n McpObservabilityEvent,\r\n McpAppsUIEvent\r\n} from '../../shared/events.js';\r\nimport type {\r\n McpRpcRequest,\r\n McpRpcResponse,\r\n McpRpcMethod,\r\n McpRpcParams,\r\n ConnectParams,\r\n SessionListResult,\r\n ConnectResult,\r\n DisconnectResult,\r\n RestoreSessionResult,\r\n FinishAuthResult,\r\n ListToolsRpcResult,\r\n ListPromptsResult,\r\n ListResourcesResult,\r\n} from '../../shared/types.js';\r\n\r\nexport interface SSEClientOptions {\r\n /** MCP endpoint URL */\r\n url: string;\r\n\r\n /** User/Client identifier */\r\n identity: string;\r\n\r\n /** Optional auth token for authenticated requests */\r\n authToken?: string;\r\n\r\n /** Callback for MCP connection state changes */\r\n onConnectionEvent?: (event: McpConnectionEvent) => void;\r\n\r\n /** Callback for observability/logging events */\r\n onObservabilityEvent?: (event: McpObservabilityEvent) => void;\r\n\r\n /** Callback for connection status changes */\r\n onStatusChange?: (status: ConnectionStatus) => void;\r\n\r\n /** Callback for MCP App UI events */\r\n onEvent?: (event: McpAppsUIEvent) => void;\r\n\r\n /** Enable debug logging @default false */\r\n debug?: boolean;\r\n}\r\n\r\nexport type ConnectionStatus = 'connecting' | 'connected' | 'disconnected' | 'error';\r\n\r\nconst CONNECTION_EVENT_INTERVAL_MS = 300;\r\n\r\ninterface ToolUiMetadata {\r\n resourceUri?: string;\r\n uri?: string;\r\n visibility?: string[];\r\n}\r\n\r\nexport class SSEClient {\r\n private resourceCache = new Map<string, Promise<unknown>>();\r\n private connected = false;\r\n\r\n constructor(private readonly options: SSEClientOptions) {}\r\n\r\n connect(): void {\r\n if (this.connected) {\r\n return;\r\n }\r\n this.connected = true;\r\n this.options.onStatusChange?.('connected');\r\n this.log('RPC mode: post_stream');\r\n }\r\n\r\n disconnect(): void {\r\n this.connected = false;\r\n this.options.onStatusChange?.('disconnected');\r\n }\r\n\r\n isConnected(): boolean {\r\n return this.connected;\r\n }\r\n\r\n async getSessions(): Promise<SessionListResult> {\r\n return this.sendRequest<SessionListResult>('getSessions');\r\n }\r\n\r\n async connectToServer(params: ConnectParams): Promise<ConnectResult> {\r\n return this.sendRequest<ConnectResult>('connect', params);\r\n }\r\n\r\n async disconnectFromServer(sessionId: string): Promise<DisconnectResult> {\r\n return this.sendRequest<DisconnectResult>('disconnect', { sessionId });\r\n }\r\n\r\n async listTools(sessionId: string): Promise<ListToolsRpcResult> {\r\n return this.sendRequest<ListToolsRpcResult>('listTools', { sessionId });\r\n }\r\n\r\n async callTool(\r\n sessionId: string,\r\n toolName: string,\r\n toolArgs: Record<string, unknown>\r\n ): Promise<unknown> {\r\n const result = await this.sendRequest('callTool', { sessionId, toolName, toolArgs });\r\n this.emitUiEventIfPresent(result, sessionId, toolName);\r\n return result;\r\n }\r\n\r\n async restoreSession(sessionId: string): Promise<RestoreSessionResult> {\r\n return this.sendRequest<RestoreSessionResult>('restoreSession', { sessionId });\r\n }\r\n\r\n async finishAuth(sessionId: string, code: string): Promise<FinishAuthResult> {\r\n return this.sendRequest<FinishAuthResult>('finishAuth', { sessionId, code });\r\n }\r\n\r\n async listPrompts(sessionId: string): Promise<ListPromptsResult> {\r\n return this.sendRequest<ListPromptsResult>('listPrompts', { sessionId });\r\n }\r\n\r\n async getPrompt(sessionId: string, name: string, args?: Record<string, string>): Promise<unknown> {\r\n return this.sendRequest('getPrompt', { sessionId, name, args });\r\n }\r\n\r\n async listResources(sessionId: string): Promise<ListResourcesResult> {\r\n return this.sendRequest<ListResourcesResult>('listResources', { sessionId });\r\n }\r\n\r\n async readResource(sessionId: string, uri: string): Promise<unknown> {\r\n return this.sendRequest('readResource', { sessionId, uri });\r\n }\r\n\r\n preloadToolUiResources(sessionId: string, tools: Array<{ name: string; _meta?: unknown }>): void {\r\n for (const tool of tools) {\r\n const uri = this.extractUiResourceUri(tool);\r\n if (!uri || this.resourceCache.has(uri)) continue;\r\n const promise = this.sendRequest('readResource', { sessionId, uri }).catch((err) => {\r\n this.log(`Failed to preload resource ${uri}: ${err.message}`, 'warn');\r\n this.resourceCache.delete(uri);\r\n return null;\r\n });\r\n this.resourceCache.set(uri, promise);\r\n }\r\n }\r\n\r\n getOrFetchResource(sessionId: string, uri: string): Promise<unknown> {\r\n const cached = this.resourceCache.get(uri);\r\n if (cached) return cached;\r\n const promise = this.sendRequest('readResource', { sessionId, uri });\r\n this.resourceCache.set(uri, promise);\r\n return promise;\r\n }\r\n\r\n hasPreloadedResource(uri: string): boolean {\r\n return this.resourceCache.has(uri);\r\n }\r\n\r\n clearResourceCache(): void {\r\n this.resourceCache.clear();\r\n }\r\n\r\n private async sendRequest<T = unknown>(method: McpRpcMethod, params?: McpRpcParams): Promise<T> {\r\n if (!this.connected) {\r\n this.connect();\r\n }\r\n\r\n this.log(`RPC request via post_stream: ${method}`);\r\n\r\n const request: McpRpcRequest = {\r\n id: `rpc_${nanoid(10)}`,\r\n method,\r\n params,\r\n };\r\n\r\n const response = await fetch(this.buildUrl(), {\r\n method: 'POST',\r\n headers: this.buildHeaders(),\r\n body: JSON.stringify(request),\r\n });\r\n\r\n if (!response.ok) {\r\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\r\n }\r\n\r\n const contentType = (response.headers.get('content-type') || '').toLowerCase();\r\n if (!contentType.includes('text/event-stream')) {\r\n const data = await response.json() as McpRpcResponse;\r\n return this.parseRpcResponse<T>(data);\r\n }\r\n\r\n const data = await this.readRpcResponseFromStream(response, {\r\n delayConnectionEvents:\r\n method === 'connect' ||\r\n method === 'restoreSession' ||\r\n method === 'finishAuth',\r\n });\r\n return this.parseRpcResponse<T>(data);\r\n }\r\n\r\n private async readRpcResponseFromStream(\r\n response: Response,\r\n options: { delayConnectionEvents?: boolean } = {}\r\n ): Promise<McpRpcResponse> {\r\n if (!response.body) {\r\n throw new Error('Streaming response body is missing');\r\n }\r\n\r\n const reader = response.body.getReader();\r\n const decoder = new TextDecoder();\r\n let buffer = '';\r\n let rpcResponse: McpRpcResponse | null = null;\r\n\r\n const dispatchBlock = async (block: string) => {\r\n const lines = block.split('\\n');\r\n let eventName = 'message';\r\n const dataLines: string[] = [];\r\n\r\n for (const rawLine of lines) {\r\n const line = rawLine.replace(/\\r$/, '');\r\n if (!line || line.startsWith(':')) continue;\r\n if (line.startsWith('event:')) {\r\n eventName = line.slice('event:'.length).trim();\r\n continue;\r\n }\r\n if (line.startsWith('data:')) {\r\n dataLines.push(line.slice('data:'.length).trimStart());\r\n }\r\n }\r\n\r\n if (!dataLines.length) return;\r\n const payloadText = dataLines.join('\\n');\r\n let payload: unknown = payloadText;\r\n try {\r\n payload = JSON.parse(payloadText);\r\n } catch {\r\n // Keep raw text\r\n }\r\n\r\n switch (eventName) {\r\n case 'connected':\r\n this.options.onStatusChange?.('connected');\r\n break;\r\n case 'connection':\r\n this.options.onConnectionEvent?.(payload as McpConnectionEvent);\r\n if (options.delayConnectionEvents) {\r\n await this.sleep(CONNECTION_EVENT_INTERVAL_MS);\r\n }\r\n break;\r\n case 'observability':\r\n this.options.onObservabilityEvent?.(payload as McpObservabilityEvent);\r\n break;\r\n case 'rpc-response':\r\n rpcResponse = payload as McpRpcResponse;\r\n break;\r\n default:\r\n break;\r\n }\r\n };\r\n\r\n while (true) {\r\n const { value, done } = await reader.read();\r\n if (done) break;\r\n buffer += decoder.decode(value, { stream: true });\r\n\r\n let separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\r\n while (separatorMatch && separatorMatch.index !== undefined) {\r\n const separatorIndex = separatorMatch.index;\r\n const separatorLength = separatorMatch[0].length;\r\n const block = buffer.slice(0, separatorIndex);\r\n buffer = buffer.slice(separatorIndex + separatorLength);\r\n await dispatchBlock(block);\r\n separatorMatch = buffer.match(/\\r?\\n\\r?\\n/);\r\n }\r\n }\r\n\r\n if (buffer.trim()) {\r\n await dispatchBlock(buffer);\r\n }\r\n\r\n if (!rpcResponse) {\r\n throw new Error('Missing rpc-response event in streamed RPC result');\r\n }\r\n\r\n return rpcResponse;\r\n }\r\n\r\n private sleep(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n\r\n private parseRpcResponse<T>(data: McpRpcResponse): T {\r\n if ('result' in data) {\r\n return data.result as T;\r\n }\r\n if ('error' in data && data.error) {\r\n throw new Error(data.error.message || 'Unknown RPC error');\r\n }\r\n // JSON omits `result` when it is `undefined` (response becomes `{ id: ... }`).\r\n // Treat that shape as a successful void result.\r\n if (data && typeof data === 'object' && 'id' in data) {\r\n return undefined as T;\r\n }\r\n throw new Error('Invalid RPC response format');\r\n }\r\n\r\n private buildUrl(): string {\r\n const url = new URL(this.options.url, globalThis.location?.origin);\r\n url.searchParams.set('identity', this.options.identity);\r\n if (this.options.authToken) {\r\n url.searchParams.set('token', this.options.authToken);\r\n }\r\n return url.toString();\r\n }\r\n\r\n private buildHeaders(): HeadersInit {\r\n const headers: HeadersInit = {\r\n 'Content-Type': 'application/json',\r\n 'Accept': 'text/event-stream',\r\n };\r\n if (this.options.authToken) {\r\n headers['Authorization'] = `Bearer ${this.options.authToken}`;\r\n }\r\n return headers;\r\n }\r\n\r\n private extractUiResourceUri(tool: { name: string; _meta?: unknown }): string | undefined {\r\n const meta = (tool._meta as { ui?: ToolUiMetadata })?.ui;\r\n if (!meta || typeof meta !== 'object') return undefined;\r\n if (meta.visibility && !meta.visibility.includes('app')) return undefined;\r\n return meta.resourceUri ?? meta.uri;\r\n }\r\n\r\n private emitUiEventIfPresent(result: unknown, sessionId: string, toolName: string): void {\r\n const meta = (result as { _meta?: { ui?: ToolUiMetadata } })?._meta;\r\n const resourceUri = meta?.ui?.resourceUri ?? (meta as any)?.['ui/resourceUri'];\r\n\r\n if (resourceUri) {\r\n this.options.onEvent?.({\r\n type: 'mcp-apps-ui',\r\n sessionId,\r\n resourceUri,\r\n toolName,\r\n result,\r\n timestamp: Date.now(),\r\n });\r\n }\r\n }\r\n\r\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\r\n if (!this.options.debug && level === 'info') return;\r\n\r\n const prefix = '[SSEClient]';\r\n switch (level) {\r\n case 'warn':\r\n console.warn(prefix, message);\r\n break;\r\n case 'error':\r\n console.error(prefix, message);\r\n break;\r\n default:\r\n console.log(prefix, message);\r\n }\r\n }\r\n}\r\n","/**\r\n * MCP App Host\r\n *\r\n * Bridges the gap between an iframe (MCP App) and the SSEClient (MCP Server).\r\n * Handles secure iframe sandboxing, resource loading, and bi-directional\r\n * communication via the AppBridge protocol.\r\n *\r\n * Key features:\r\n * - Secure iframe sandboxing with minimal permissions\r\n * - Resource preloading for instant MCP App UI loading\r\n * - Cache-aware resource fetching (SSEClient cache → local cache → direct fetch)\r\n * - Support for ui:// and mcp-app:// resource URIs\r\n */\r\n\r\nimport { AppBridge, PostMessageTransport } from '@modelcontextprotocol/ext-apps/app-bridge';\r\nimport type { AppHostClient } from './types';\r\n\r\n// ============================================\r\n// Types & Interfaces\r\n// ============================================\r\n\r\nexport interface AppHostOptions {\r\n /** Enable debug logging @default false */\r\n debug?: boolean;\r\n}\r\n\r\nexport interface AppMessageParams {\r\n role: string;\r\n content: unknown;\r\n}\r\n\r\ninterface ToolCallParams {\r\n name: string;\r\n arguments?: Record<string, unknown>;\r\n}\r\n\r\ninterface ResourceContent {\r\n blob?: string;\r\n text?: string;\r\n}\r\n\r\ninterface ResourceResponse {\r\n contents: ResourceContent[];\r\n}\r\n\r\n// ============================================\r\n// Constants\r\n// ============================================\r\n\r\nconst HOST_INFO = { name: 'mcp-ts-host', version: '1.0.0' };\r\n\r\n/** Sandbox permissions - minimal set required for MCP Apps to function */\r\nconst SANDBOX_PERMISSIONS = [\r\n 'allow-scripts', // Required for app JavaScript execution\r\n 'allow-forms', // Required for form submissions\r\n 'allow-same-origin', // Required for Blob URL correctness\r\n 'allow-modals', // Required for dialogs/alerts\r\n 'allow-popups', // Required for opening links\r\n 'allow-downloads' // Required for file downloads\r\n].join(' ');\r\n\r\n/** Supported MCP App URI schemes */\r\nconst MCP_URI_SCHEMES = ['ui://', 'mcp-app://'] as const;\r\n\r\n// ============================================\r\n// AppHost Class\r\n// ============================================\r\n\r\n/**\r\n * Host for MCP Apps embedded in iframes.\r\n * Manages secure communication between the app and the MCP server.\r\n */\r\nexport class AppHost {\r\n private bridge: AppBridge;\r\n private sessionId?: string;\r\n private resourceCache = new Map<string, Promise<ResourceResponse | null>>();\r\n private debug: boolean;\r\n\r\n /** Callback for app messages (e.g., chat messages from the app) */\r\n public onAppMessage?: (params: AppMessageParams) => void;\r\n\r\n constructor(\r\n private readonly client: AppHostClient,\r\n private readonly iframe: HTMLIFrameElement,\r\n options?: AppHostOptions\r\n ) {\r\n this.debug = options?.debug ?? false;\r\n this.configureSandbox();\r\n this.bridge = this.initializeBridge();\r\n }\r\n\r\n // ============================================\r\n // Public API\r\n // ============================================\r\n\r\n /**\r\n * Start the host. This prepares the bridge handlers but doesn't connect yet.\r\n * The actual connection happens in launch() after HTML is loaded.\r\n * @returns Promise that resolves immediately (bridge connects during launch)\r\n */\r\n async start(): Promise<void> {\r\n // Bridge handlers are already registered in constructor.\r\n // Connection happens in launch() after HTML is loaded.\r\n this.log('Host started, ready to launch');\r\n }\r\n\r\n /**\r\n * Preload UI resources to enable instant app loading.\r\n * Call this when tools are discovered to cache their UI resources.\r\n */\r\n preload(tools: Array<{ _meta?: unknown }>): void {\r\n for (const tool of tools) {\r\n const uri = this.extractUiResourceUri(tool);\r\n if (!uri || this.resourceCache.has(uri)) continue;\r\n\r\n const promise = this.preloadResource(uri);\r\n this.resourceCache.set(uri, promise);\r\n }\r\n }\r\n\r\n /**\r\n * Launch an MCP App from a URL or MCP resource URI.\r\n * Loads the HTML first, then establishes bridge connection.\r\n */\r\n async launch(url: string, sessionId?: string): Promise<void> {\r\n if (sessionId) this.sessionId = sessionId;\r\n\r\n // Set up initialization promise BEFORE connecting\r\n const initializedPromise = this.onAppReady();\r\n\r\n // Load HTML into iframe first\r\n if (this.isMcpUri(url)) {\r\n await this.launchMcpApp(url);\r\n } else {\r\n this.iframe.src = url;\r\n }\r\n\r\n // Wait for iframe to load before connecting bridge\r\n await this.onIframeReady();\r\n\r\n // Connect the bridge (HTML is loaded, contentWindow is ready)\r\n await this.connectBridge();\r\n\r\n // Wait for app to signal it's initialized (with timeout)\r\n this.log('Waiting for app initialization');\r\n await Promise.race([\r\n initializedPromise,\r\n new Promise<void>((resolve) => setTimeout(() => {\r\n this.log('Initialization timeout - continuing anyway', 'warn');\r\n resolve();\r\n }, 3000))\r\n ]);\r\n this.log('App launched and ready');\r\n }\r\n\r\n /**\r\n * Wait for app to signal initialization complete\r\n */\r\n private onAppReady(): Promise<void> {\r\n return new Promise<void>((resolve) => {\r\n const originalHandler = this.bridge.oninitialized;\r\n this.bridge.oninitialized = (...args) => {\r\n this.log('App initialized');\r\n resolve();\r\n this.bridge.oninitialized = originalHandler;\r\n originalHandler?.(...args);\r\n };\r\n });\r\n }\r\n\r\n /**\r\n * Wait for iframe to finish loading\r\n */\r\n private onIframeReady(): Promise<void> {\r\n return new Promise((resolve) => {\r\n if (this.iframe.contentDocument?.readyState === 'complete') {\r\n resolve();\r\n return;\r\n }\r\n this.iframe.addEventListener('load', () => resolve(), { once: true });\r\n });\r\n }\r\n\r\n /**\r\n * Send tool input arguments to the MCP App.\r\n * Call this after launch() when tool input is available.\r\n */\r\n sendToolInput(args: Record<string, unknown>): void {\r\n this.log('Sending tool input to app');\r\n this.bridge.sendToolInput({ arguments: args });\r\n }\r\n\r\n /**\r\n * Send tool result to the MCP App.\r\n * Call this when the tool call completes.\r\n */\r\n sendToolResult(result: unknown): void {\r\n this.log('Sending tool result to app');\r\n this.bridge.sendToolResult(result as any);\r\n }\r\n\r\n /**\r\n * Send tool cancellation to the MCP App.\r\n * Call this when the tool call is cancelled or fails.\r\n */\r\n sendToolCancelled(reason: string): void {\r\n this.log('Sending tool cancellation to app');\r\n this.bridge.sendToolCancelled({ reason });\r\n }\r\n\r\n // ============================================\r\n // Private: Initialization\r\n // ============================================\r\n\r\n private configureSandbox(): void {\r\n if (this.iframe.sandbox.value !== SANDBOX_PERMISSIONS) {\r\n this.iframe.sandbox.value = SANDBOX_PERMISSIONS;\r\n }\r\n }\r\n\r\n private initializeBridge(): AppBridge {\r\n const bridge = new AppBridge(\r\n null,\r\n HOST_INFO,\r\n {\r\n openLinks: {},\r\n serverTools: {},\r\n logging: {},\r\n // Declare support for model context updates\r\n updateModelContext: { text: {} },\r\n },\r\n {\r\n // Initial host context\r\n hostContext: {\r\n theme: 'dark',\r\n platform: 'web',\r\n containerDimensions: { maxHeight: 6000 },\r\n displayMode: 'inline',\r\n availableDisplayModes: ['inline', 'fullscreen'],\r\n },\r\n }\r\n );\r\n\r\n // Register handlers - must be done BEFORE connect()\r\n bridge.oncalltool = (params) => this.handleToolCall(params);\r\n bridge.onopenlink = this.handleOpenLink.bind(this);\r\n bridge.onmessage = this.handleMessage.bind(this);\r\n bridge.onloggingmessage = (params) => this.log(`App log [${params.level}]: ${params.data}`);\r\n bridge.onupdatemodelcontext = async () => ({});\r\n bridge.onsizechange = async ({ width, height }) => {\r\n if (height !== undefined) this.iframe.style.height = `${height}px`;\r\n if (width !== undefined) this.iframe.style.minWidth = `min(${width}px, 100%)`;\r\n return {};\r\n };\r\n bridge.onrequestdisplaymode = async (params) => ({\r\n mode: params.mode === 'fullscreen' ? 'fullscreen' : 'inline'\r\n });\r\n\r\n return bridge;\r\n }\r\n\r\n private async connectBridge(): Promise<void> {\r\n this.log('Connecting bridge to iframe');\r\n\r\n const transport = new PostMessageTransport(\r\n this.iframe.contentWindow!,\r\n this.iframe.contentWindow!\r\n );\r\n\r\n try {\r\n await this.bridge.connect(transport);\r\n this.log('Bridge connected successfully');\r\n } catch (error) {\r\n this.log('Bridge connection failed', 'error');\r\n throw error;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Bridge Event Handlers\r\n // ============================================\r\n\r\n private async handleToolCall(params: ToolCallParams) {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client disconnected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n const result = await this.client.callTool(\r\n sessionId,\r\n params.name,\r\n params.arguments ?? {}\r\n );\r\n return result as any;\r\n }\r\n\r\n private async handleOpenLink(params: { url: string }): Promise<Record<string, never>> {\r\n window.open(params.url, '_blank', 'noopener,noreferrer');\r\n return {};\r\n }\r\n\r\n private async handleMessage(params: AppMessageParams): Promise<Record<string, never>> {\r\n this.onAppMessage?.(params);\r\n return {};\r\n }\r\n\r\n // ============================================\r\n // Private: Resource Loading\r\n // ============================================\r\n\r\n private async launchMcpApp(uri: string): Promise<void> {\r\n if (!this.client.isConnected()) {\r\n throw new Error('Client must be connected');\r\n }\r\n\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) {\r\n throw new Error('No active session');\r\n }\r\n\r\n // Fetch resource using cache hierarchy: SSEClient cache → local cache → direct fetch\r\n const response = await this.fetchResourceWithCache(sessionId, uri);\r\n if (!response?.contents?.length) {\r\n throw new Error(`Empty resource: ${uri}`);\r\n }\r\n\r\n const content = response.contents[0];\r\n const html = this.decodeContent(content);\r\n if (!html) {\r\n throw new Error(`Invalid content in resource: ${uri}`);\r\n }\r\n\r\n // Render via Blob URL for clean isolation\r\n const blob = new Blob([html], { type: 'text/html' });\r\n this.iframe.src = URL.createObjectURL(blob);\r\n }\r\n\r\n private async fetchResourceWithCache(sessionId: string, uri: string): Promise<ResourceResponse> {\r\n // Priority 1: SSEClient's built-in cache (best performance)\r\n if (this.hasClientCache()) {\r\n return (this.client as any).getOrFetchResource(sessionId, uri);\r\n }\r\n\r\n // Priority 2: Local preload cache\r\n const cached = this.resourceCache.get(uri);\r\n if (cached) {\r\n const result = await cached;\r\n if (result) return result;\r\n }\r\n\r\n // Priority 3: Direct fetch\r\n return this.client.readResource(sessionId, uri) as Promise<ResourceResponse>;\r\n }\r\n\r\n private async preloadResource(uri: string): Promise<ResourceResponse | null> {\r\n try {\r\n const sessionId = await this.getSessionId();\r\n if (!sessionId) return null;\r\n return await this.client.readResource(sessionId, uri) as ResourceResponse;\r\n } catch (error) {\r\n this.log(`Preload failed for ${uri}`, 'warn');\r\n return null;\r\n }\r\n }\r\n\r\n // ============================================\r\n // Private: Utilities\r\n // ============================================\r\n\r\n private async getSessionId(): Promise<string | undefined> {\r\n if (this.sessionId) return this.sessionId;\r\n const result = await this.client.getSessions();\r\n return result.sessions?.[0]?.sessionId;\r\n }\r\n\r\n private isMcpUri(url: string): boolean {\r\n return MCP_URI_SCHEMES.some(scheme => url.startsWith(scheme));\r\n }\r\n\r\n private hasClientCache(): boolean {\r\n return 'getOrFetchResource' in this.client &&\r\n typeof (this.client as any).getOrFetchResource === 'function';\r\n }\r\n\r\n private extractUiResourceUri(tool: { _meta?: unknown }): string | undefined {\r\n const meta = tool._meta as { ui?: { resourceUri?: string; uri?: string } } | undefined;\r\n if (!meta?.ui) return undefined;\r\n return meta.ui.resourceUri ?? meta.ui.uri;\r\n }\r\n\r\n private decodeContent(content: ResourceContent): string | undefined {\r\n if (content.blob) {\r\n return atob(content.blob);\r\n }\r\n return content.text;\r\n }\r\n\r\n private log(message: string, level: 'info' | 'warn' | 'error' = 'info'): void {\r\n if (!this.debug && level === 'info') return;\r\n\r\n const prefix = '[AppHost]';\r\n switch (level) {\r\n case 'warn':\r\n console.warn(prefix, message);\r\n break;\r\n case 'error':\r\n console.error(prefix, message);\r\n break;\r\n default:\r\n console.log(prefix, message);\r\n }\r\n }\r\n}\r\n","/**\r\n * Type definitions for MCP operations\r\n */\r\n\r\nimport { Tool, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\r\n\r\n// Connect API types\r\nexport interface ConnectRequest {\r\n serverUrl: string;\r\n callbackUrl: string;\r\n}\r\n\r\nexport interface ConnectSuccessResponse {\r\n success: true;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectAuthRequiredResponse {\r\n requiresAuth: true;\r\n authUrl: string;\r\n sessionId: string;\r\n}\r\n\r\nexport interface ConnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ConnectResponse =\r\n | ConnectSuccessResponse\r\n | ConnectAuthRequiredResponse\r\n | ConnectErrorResponse;\r\n\r\n// Callback API types\r\nexport interface CallbackSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface CallbackErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallbackResponse = CallbackSuccessResponse | CallbackErrorResponse;\r\n\r\n// Disconnect API types\r\nexport interface DisconnectRequest {\r\n sessionId: string;\r\n}\r\n\r\nexport interface DisconnectSuccessResponse {\r\n success: true;\r\n message: string;\r\n}\r\n\r\nexport interface DisconnectErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type DisconnectResponse =\r\n | DisconnectSuccessResponse\r\n | DisconnectErrorResponse;\r\n\r\n// List Tools API types\r\nexport interface ListToolsSuccessResponse {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListToolsErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type ListToolsResponse =\r\n | ListToolsSuccessResponse\r\n | ListToolsErrorResponse;\r\n\r\n// Call Tool API types\r\nexport interface CallToolRequest {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface CallToolSuccessResponse {\r\n content: Array<{\r\n type: string;\r\n text?: string;\r\n [key: string]: unknown;\r\n }>;\r\n isError: boolean;\r\n}\r\n\r\nexport interface CallToolErrorResponse {\r\n error: string;\r\n}\r\n\r\nexport type CallToolResponse =\r\n | CallToolSuccessResponse\r\n | CallToolErrorResponse;\r\n\r\n// Helper type guards\r\nexport function isConnectSuccess(\r\n response: ConnectResponse\r\n): response is ConnectSuccessResponse {\r\n return 'success' in response && response.success === true;\r\n}\r\n\r\nexport function isConnectAuthRequired(\r\n response: ConnectResponse\r\n): response is ConnectAuthRequiredResponse {\r\n return 'requiresAuth' in response && response.requiresAuth === true;\r\n}\r\n\r\nexport function isConnectError(\r\n response: ConnectResponse\r\n): response is ConnectErrorResponse {\r\n return 'error' in response;\r\n}\r\n\r\nexport function isListToolsSuccess(\r\n response: ListToolsResponse\r\n): response is ListToolsSuccessResponse {\r\n return 'tools' in response;\r\n}\r\n\r\nexport function isCallToolSuccess(\r\n response: CallToolResponse\r\n): response is CallToolSuccessResponse {\r\n return 'content' in response;\r\n}\r\n\r\n// Generic tool info type\r\nexport type ToolInfo = {\r\n name: string;\r\n description?: string;\r\n inputSchema?: unknown;\r\n};\r\n\r\n// Transport type\r\nexport type TransportType = 'sse' | 'streamable_http';\r\n\r\n// SSE/RPC types\r\nexport type McpRpcMethod =\r\n | 'connect'\r\n | 'disconnect'\r\n | 'listTools'\r\n | 'callTool'\r\n | 'getSessions'\r\n | 'restoreSession'\r\n | 'finishAuth'\r\n | 'listPrompts'\r\n | 'getPrompt'\r\n | 'listResources'\r\n | 'readResource';\r\n\r\nexport interface McpRpcRequest {\r\n id: string;\r\n method: McpRpcMethod;\r\n params?: McpRpcParams;\r\n}\r\n\r\nexport interface McpRpcResponse<T = unknown> {\r\n id: string;\r\n result?: T;\r\n error?: {\r\n code: string;\r\n message: string;\r\n };\r\n}\r\n\r\n// RPC Parameter Types\r\nexport interface ConnectParams {\r\n serverId?: string; // Optional - generated server-side if not provided\r\n serverName: string;\r\n serverUrl: string;\r\n callbackUrl: string;\r\n transportType?: TransportType;\r\n}\r\n\r\nexport interface DisconnectParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface SessionParams {\r\n sessionId: string;\r\n}\r\n\r\nexport interface CallToolParams {\r\n sessionId: string;\r\n toolName: string;\r\n toolArgs: Record<string, unknown>;\r\n}\r\n\r\nexport interface GetPromptParams {\r\n sessionId: string;\r\n name: string;\r\n args?: Record<string, string>;\r\n}\r\n\r\nexport interface ReadResourceParams {\r\n sessionId: string;\r\n uri: string;\r\n}\r\n\r\nexport interface FinishAuthParams {\r\n sessionId: string;\r\n code: string;\r\n}\r\n\r\nexport type McpRpcParams =\r\n | ConnectParams\r\n | DisconnectParams\r\n | SessionParams\r\n | CallToolParams\r\n | GetPromptParams\r\n | ReadResourceParams\r\n | FinishAuthParams\r\n | undefined;\r\n\r\n// RPC Result Types\r\nexport interface SessionInfo {\r\n sessionId: string;\r\n serverId?: string;\r\n serverName?: string;\r\n serverUrl: string;\r\n transport: TransportType;\r\n createdAt: number;\r\n /**\r\n * Session readiness for auto-restore.\r\n * false means auth is pending and should be resumed explicitly by user action.\r\n */\r\n active?: boolean;\r\n}\r\n\r\nexport interface SessionListResult {\r\n sessions: SessionInfo[];\r\n}\r\n\r\nexport interface ConnectResult {\r\n sessionId: string;\r\n success: boolean;\r\n}\r\n\r\nexport interface DisconnectResult {\r\n success: boolean;\r\n}\r\n\r\nexport interface RestoreSessionResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface FinishAuthResult {\r\n success: boolean;\r\n toolCount: number;\r\n}\r\n\r\nexport interface ListToolsRpcResult {\r\n tools: Tool[];\r\n}\r\n\r\nexport interface ListPromptsResult {\r\n prompts: Array<{\r\n name: string;\r\n description?: string;\r\n arguments?: Array<{\r\n name: string;\r\n description?: string;\r\n required?: boolean;\r\n }>;\r\n }>;\r\n}\r\n\r\nexport interface ListResourcesResult {\r\n resources: Array<{\r\n uri: string;\r\n name: string;\r\n description?: string;\r\n mimeType?: string;\r\n }>;\r\n}\r\n\r\nexport type { CallToolResult };\r\n","/**\r\n * Utility functions for working with MCP tool metadata\r\n */\r\n\r\nimport type { ToolInfo } from './types.js';\r\n\r\nexport interface ToolUiConfig {\r\n resourceUri: string;\r\n sessionId: string;\r\n}\r\n\r\n/**\r\n * Extract UI resource URI from tool metadata\r\n *\r\n * @param tool - The tool to extract UI config from\r\n * @returns The resource URI if available, undefined otherwise\r\n *\r\n * @example\r\n * const uri = getToolUiResourceUri(tool);\r\n * if (uri) {\r\n * // Tool has UI configuration\r\n * }\r\n */\r\nexport function getToolUiResourceUri(tool: ToolInfo): string | undefined {\r\n const meta = (tool as any)._meta;\r\n if (!meta?.ui) return undefined;\r\n\r\n const ui = meta.ui;\r\n if (typeof ui !== \"object\" || !ui) return undefined;\r\n\r\n // Check visibility filter - skip if explicitly hidden from app\r\n if (ui.visibility && !ui.visibility.includes(\"app\")) return undefined;\r\n\r\n // Support both 'uri' and 'resourceUri' field names for flexibility\r\n return typeof ui.resourceUri === \"string\"\r\n ? ui.resourceUri\r\n : typeof ui.uri === \"string\"\r\n ? ui.uri\r\n : undefined;\r\n}\r\n\r\n/**\r\n * Find a tool by name within connections\r\n *\r\n * @param connections - Array of MCP connections\r\n * @param toolName - Name of the tool to find\r\n * @returns The tool if found, undefined otherwise\r\n *\r\n * @example\r\n * const tool = findToolByName(connections, \"get_weather\");\r\n */\r\nexport function findToolByName(\r\n connections: Array<{ tools: ToolInfo[] }>,\r\n toolName: string\r\n): ToolInfo | undefined {\r\n for (const conn of connections) {\r\n const tool = conn.tools.find((t) => t.name === toolName);\r\n if (tool) return tool;\r\n }\r\n return undefined;\r\n}\r\n"]}
|