@mcp-ts/sdk 2.5.2 → 2.6.0
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 +3 -574
- package/dist/adapters/agui-adapter.d.mts +4 -4
- package/dist/adapters/agui-adapter.d.ts +4 -4
- package/dist/adapters/agui-middleware.d.mts +4 -4
- package/dist/adapters/agui-middleware.d.ts +4 -4
- package/dist/adapters/ai-adapter.d.mts +4 -4
- package/dist/adapters/ai-adapter.d.ts +4 -4
- package/dist/adapters/langchain-adapter.d.mts +4 -4
- package/dist/adapters/langchain-adapter.d.ts +4 -4
- package/dist/adapters/mastra-adapter.d.mts +3 -3
- package/dist/adapters/mastra-adapter.d.ts +3 -3
- package/dist/client/index.d.mts +2 -2
- package/dist/client/index.d.ts +2 -2
- package/dist/client/index.js +3 -0
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs +3 -0
- package/dist/client/index.mjs.map +1 -1
- package/dist/client/react.d.mts +10 -18
- package/dist/client/react.d.ts +10 -18
- package/dist/client/react.js +17 -0
- package/dist/client/react.js.map +1 -1
- package/dist/client/react.mjs +17 -0
- package/dist/client/react.mjs.map +1 -1
- package/dist/client/vue.d.mts +4 -4
- package/dist/client/vue.d.ts +4 -4
- package/dist/client/vue.js +3 -0
- package/dist/client/vue.js.map +1 -1
- package/dist/client/vue.mjs +3 -0
- package/dist/client/vue.mjs.map +1 -1
- package/dist/{index-B3GPsPsi.d.mts → index-BrDkbut5.d.ts} +2 -1
- package/dist/{index-gNdSQTSz.d.ts → index-DHQvlx4K.d.mts} +2 -1
- package/dist/index.d.mts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +1056 -863
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1048 -858
- package/dist/index.mjs.map +1 -1
- package/dist/{multi-session-client-CB4oDrQX.d.ts → multi-session-client-CQzymvHl.d.ts} +183 -227
- package/dist/{multi-session-client-xj3iQIv6.d.mts → multi-session-client-C_Ja2TuV.d.mts} +183 -227
- package/dist/server/index.d.mts +338 -88
- package/dist/server/index.d.ts +338 -88
- package/dist/server/index.js +1054 -864
- package/dist/server/index.js.map +1 -1
- package/dist/server/index.mjs +1046 -859
- package/dist/server/index.mjs.map +1 -1
- package/dist/shared/index.d.mts +4 -4
- package/dist/shared/index.d.ts +4 -4
- package/dist/shared/index.js.map +1 -1
- package/dist/shared/index.mjs.map +1 -1
- package/dist/{tool-router-CsKVXbQB.d.mts → tool-router-C1n7OXbl.d.mts} +1 -1
- package/dist/{tool-router-C-Mw1_BQ.d.ts → tool-router-CBIawFnt.d.ts} +1 -1
- package/dist/{types-6SmXege4.d.mts → types-DX71u9gR.d.mts} +11 -3
- package/dist/{types-6SmXege4.d.ts → types-DX71u9gR.d.ts} +11 -3
- package/migrations/neon/20260513010000_install_mcp_sessions.sql +4 -34
- package/migrations/supabase/20260330195700_install_mcp_sessions.sql +5 -62
- package/package.json +2 -1
- package/src/client/core/sse-client.ts +5 -0
- package/src/client/react/use-mcp.ts +27 -28
- package/src/server/handlers/sse-handler.ts +671 -629
- package/src/server/index.ts +2 -1
- package/src/server/mcp/multi-session-client.ts +34 -10
- package/src/server/mcp/oauth-client.ts +197 -205
- package/src/server/mcp/storage-oauth-provider.ts +149 -29
- package/src/server/mcp/tool-policy-gateway.ts +11 -1
- package/src/server/storage/file-backend.ts +25 -21
- package/src/server/storage/index.ts +71 -0
- package/src/server/storage/memory-backend.ts +24 -12
- package/src/server/storage/neon-backend.ts +70 -72
- package/src/server/storage/redis-backend.ts +26 -36
- package/src/server/storage/sqlite-backend.ts +25 -39
- package/src/server/storage/supabase-backend.ts +45 -54
- package/src/server/storage/types.ts +22 -2
- package/src/shared/types.ts +13 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/server/storage/redis.ts","../../src/shared/utils.ts","../../src/shared/constants.ts","../../src/server/storage/tool-policy.ts","../../src/server/storage/session-lifecycle.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/crypto.ts","../../src/server/storage/supabase-backend.ts","../../src/server/storage/neon-backend.ts","../../src/server/storage/index.ts","../../src/server/mcp/storage-oauth-provider.ts","../../src/shared/events.ts","../../src/shared/errors.ts","../../src/server/mcp/oauth-client.ts","../../src/server/mcp/tool-policy-gateway.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"],"names":["redis","sessions","fs","path2","getRedis","nanoid","SDKUnauthorizedError","manager"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Redis connection management with dependency injection support\n * Allows configuration and testing without environment variables\n */\nimport type { Redis } from 'ioredis';\n\nexport interface RedisConfig {\n /**\n * Redis connection URL (defaults to REDIS_URL env var)\n */\n url?: string;\n\n /**\n * Enable lazy connection (default: true)\n */\n lazyConnect?: boolean;\n\n /**\n * Maximum retries per request (default: 1)\n */\n maxRetriesPerRequest?: number;\n\n /**\n * Enable verbose logging (default: false)\n */\n verbose?: boolean;\n /**\n * @internal For testing only - bypass ioredis import\n */\n RedisConstructor?: any;\n}\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __redis: Redis | undefined;\n var __redisConfig: RedisConfig | undefined;\n}\n\nlet redisInstance: Redis | null = null;\n\n/**\n * Initialize Redis with custom configuration\n * Call this before any Redis operations if you need custom config\n * @param config - Redis configuration options\n */\nexport async function initRedis(config: RedisConfig): Promise<Redis> {\n if (redisInstance) {\n // Already initialized, return existing instance\n return redisInstance;\n }\n\n const url = config.url ?? process.env.REDIS_URL;\n\n if (!url) {\n throw new Error(\n 'Redis URL is required. Set REDIS_URL environment variable or pass url in config.'\n );\n }\n\n let Redis: typeof import('ioredis').Redis;\n if (config.RedisConstructor) {\n Redis = config.RedisConstructor;\n } else {\n try {\n const ioredis = await import('ioredis');\n Redis = ioredis.Redis;\n } catch (error) {\n throw new Error(\n 'ioredis is not installed. Install it with:\\n' +\n ' npm install ioredis\\n\\n' +\n 'Or use a different storage backend:\\n' +\n ' MCP_TS_STORAGE_TYPE=memory (for development)\\n' +\n ' MCP_TS_STORAGE_TYPE=file (for local persistence)'\n );\n }\n }\n\n redisInstance = new Redis(url, {\n lazyConnect: config.lazyConnect ?? true,\n maxRetriesPerRequest: config.maxRetriesPerRequest ?? 1,\n });\n\n if (config.verbose !== false) {\n redisInstance.on('ready', () => {\n console.log('✅ Redis connected');\n });\n\n redisInstance.on('error', (err) => {\n console.error('❌ Redis error:', err.message);\n });\n\n redisInstance.on('reconnecting', () => {\n console.log('🔄 Redis reconnecting...');\n });\n }\n\n // Store globally for hot reloading scenarios\n global.__redis = redisInstance;\n global.__redisConfig = config;\n\n return redisInstance;\n}\n\n/**\n * Get the Redis instance\n * Automatically initializes with default config if not already initialized\n */\nexport async function getRedis(): Promise<Redis> {\n if (redisInstance) {\n return redisInstance;\n }\n\n // Check for existing global instance (hot reload scenario)\n if (global.__redis) {\n redisInstance = global.__redis;\n return redisInstance;\n }\n\n // Initialize with default config\n return await initRedis({});\n}\n\n/**\n * Set a custom Redis instance (useful for testing with mocks)\n * @param instance - Redis instance or mock\n */\nexport function setRedisInstance(instance: Redis): void {\n redisInstance = instance;\n global.__redis = instance;\n}\n\n/**\n * Close Redis connection and clear instance\n */\nexport async function closeRedis(): Promise<void> {\n if (redisInstance) {\n await redisInstance.quit();\n redisInstance = null;\n global.__redis = undefined;\n }\n}\n\n/**\n * Default Redis export for backward compatibility\n * Will auto-initialize on first access\n * Note: This is a lazy proxy that initializes Redis on first method call\n */\nexport const redis = new Proxy({} as Redis, {\n get(_target, prop) {\n // Return a function that handles async initialization\n return async (...args: any[]) => {\n const instance = await getRedis();\n const value = (instance as any)[prop];\n if (typeof value === 'function') {\n return value.apply(instance, args);\n }\n return value;\n };\n },\n});\n","import { customAlphabet, nanoid } from 'nanoid';\n\nconst OAUTH_STATE_SEPARATOR = '.';\n\nconst serverIdAlphabet = customAlphabet(\n 'abcdefghijklmnopqrstuvwxyz0123456789',\n 12\n);\n\n/**\n * Sanitize server name to create a valid server label\n * Must start with a letter and contain only letters, digits, '-' and '_'\n */\nexport function sanitizeServerLabel(name: string): string {\n let sanitized = name\n .replace(/[^a-zA-Z0-9-_]/g, '_')\n .replace(/_{2,}/g, '_')\n .toLowerCase();\n\n if (!/^[a-zA-Z]/.test(sanitized)) {\n sanitized = 's_' + sanitized;\n }\n\n return sanitized;\n}\n\n/**\n * Generates a session ID with a human-readable prefix for easy identification.\n * Format: sess_<21-char nanoid> (26 chars total).\n * Not used in tool names, so length is not constrained.\n */\nexport function generateSessionId(): string {\n return 'sess_' + nanoid(21);\n}\n\n/**\n * Generates a short server ID suitable for use in tool names.\n * 12-char alphanumeric string that keeps tool_<serverId>_<toolName> under 64 chars.\n */\nexport function generateServerId(): string {\n return serverIdAlphabet();\n}\n\nexport interface ParsedOAuthState {\n nonce: string;\n sessionId: string;\n}\n\nexport function formatOAuthState(nonce: string, sessionId: string): string {\n return `${nonce}${OAUTH_STATE_SEPARATOR}${sessionId}`;\n}\n\nexport function parseOAuthState(state: string): ParsedOAuthState | undefined {\n const separatorIndex = state.indexOf(OAUTH_STATE_SEPARATOR);\n if (separatorIndex <= 0 || separatorIndex === state.length - 1) {\n return undefined;\n }\n\n const nonce = state.slice(0, separatorIndex);\n const sessionId = state.slice(separatorIndex + 1);\n if (!nonce || !sessionId || sessionId.includes(OAUTH_STATE_SEPARATOR)) {\n return undefined;\n }\n\n return { nonce, sessionId };\n}\n","/**\n * Centralized constants for MCP Redis library\n * Eliminates magic numbers and enables consistent configuration\n */\n\n// Session lifecycle\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\nexport const PENDING_SESSION_EXPIRATION_SECONDS = Math.floor(STATE_EXPIRATION_MS / 1000);\nexport const DORMANT_SESSION_EXPIRATION_MS = 30 * 24 * 60 * 60 * 1000; // 30 days\nexport const DORMANT_SESSION_EXPIRATION_SECONDS = Math.floor(DORMANT_SESSION_EXPIRATION_MS / 1000);\n\n// Heartbeat and Connection\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\n\n// Redis Key Prefixes\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\n\n// Client Information\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.svg';\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\nexport const SOFTWARE_ID = '@mcp-ts';\nexport const SOFTWARE_VERSION = '2.3.4';\n\n// MCP Client Configuration\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\nexport const MCP_CLIENT_VERSION = '2.0';\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolPolicy } from './types.js';\n\n/**\n * Raw, unvalidated shape of a tool policy as it may arrive from an external\n * source (HTTP request body, database read, etc.). All fields are typed as\n * `unknown` so callers are forced to pass through one of the `normalize*`\n * helpers before using the value as a `ToolPolicy`.\n */\nexport type ToolPolicyInput = {\n mode?: unknown;\n toolIds?: unknown;\n updatedAt?: unknown;\n} | null | undefined;\n\n/**\n * Constructs the canonical tool ID string used throughout the policy system.\n *\n * Tool IDs combine the server ID and the tool name with a `::` separator so\n * they are globally unique across all connected MCP servers:\n * ```\n * \"mn0v3pfwwbxv::delete_mcp_server\"\n * ```\n *\n * @param serverId - The short server identifier (e.g. `\"mn0v3pfwwbxv\"`).\n * @param toolName - The exact tool name as reported by the remote server.\n * @returns A namespaced tool ID string.\n */\nexport function createToolId(serverId: string, toolName: string): string {\n return `${serverId}::${toolName}`;\n}\n\n/**\n * Coerces an arbitrary value into a deduplicated array of trimmed, non-empty\n * strings. Returns an empty array for any non-array or invalid input.\n *\n * @param input - Raw value to normalise (typically from user input or a DB read).\n * @returns A clean `string[]` with duplicates and blank entries removed.\n */\nfunction normalizeToolIds(input?: unknown): string[] {\n if (!Array.isArray(input)) return [];\n\n return Array.from(new Set(\n input\n .filter((id): id is string => typeof id === 'string')\n .map((id) => id.trim())\n .filter(Boolean)\n ));\n}\n\n/**\n * Converts a raw, potentially untrusted `ToolPolicyInput` into a validated\n * `ToolPolicy` object, or `undefined` if the input is absent / malformed.\n *\n * - Invalid `mode` values fall back to `\"all\"` (no restrictions).\n * - Invalid `updatedAt` values fall back to `now`.\n * - `\"all\"` mode always produces an empty `toolIds` array regardless of input.\n *\n * @param input - Raw policy data to normalise (from request body, DB, etc.).\n * @param now - Unix timestamp used as the fallback for `updatedAt`. Defaults to `Date.now()`.\n * @returns A well-formed `ToolPolicy`, or `undefined` if `input` is absent.\n */\nexport function normalizeToolPolicy(input?: ToolPolicyInput, now = Date.now()): ToolPolicy | undefined {\n if (!input || typeof input !== 'object') {\n return undefined;\n }\n\n const mode = input.mode === 'allowlist' || input.mode === 'denylist'\n ? input.mode\n : 'all';\n const updatedAt = typeof input.updatedAt === 'number' && Number.isFinite(input.updatedAt)\n ? input.updatedAt\n : now;\n\n if (mode === 'all') {\n return { mode: 'all', toolIds: [], updatedAt };\n }\n\n return { mode, toolIds: normalizeToolIds(input.toolIds), updatedAt };\n}\n\n/**\n * Same as `normalizeToolPolicy` but guaranteed to return a `ToolPolicy`.\n * Falls back to an unrestricted `{ mode: \"all\" }` policy when the input is\n * absent or invalid.\n *\n * Use this variant when a policy is required (e.g. when persisting an update)\n * rather than when reading an optional policy from the session store.\n *\n * @param input - Raw policy data to normalise.\n * @param now - Unix timestamp used as the fallback for `updatedAt`. Defaults to `Date.now()`.\n * @returns A well-formed `ToolPolicy`, never `undefined`.\n */\nexport function normalizeToolPolicyForUpdate(input: ToolPolicyInput, now = Date.now()): ToolPolicy {\n return normalizeToolPolicy(input, now) ?? { mode: 'all', toolIds: [], updatedAt: now };\n}\n\n/**\n * Determines whether a specific tool is permitted under the given policy.\n *\n * | Policy mode | Allowed when… |\n * |--------------|--------------------------------------------------|\n * | `\"all\"` | Always (no restrictions). |\n * | `\"allowlist\"`| The tool's ID is present in `policy.toolIds`. |\n * | `\"denylist\"` | The tool's ID is **not** in `policy.toolIds`. |\n *\n * Returns `false` when the policy requires a `serverId` for ID construction\n * but none is provided (fail-safe / deny by default).\n *\n * @param policy - The active tool policy, or `undefined` for unrestricted access.\n * @param toolName - The tool name to check (as reported by the remote server).\n * @param serverId - The server that owns the tool (required for `allowlist`/`denylist`).\n * @returns `true` if the tool is allowed, `false` otherwise.\n */\nexport function isToolAllowed(policy: ToolPolicy | undefined, toolName: string, serverId?: string): boolean {\n if (!policy || policy.mode === 'all') return true;\n if (!serverId) return false;\n\n const toolId = createToolId(serverId, toolName);\n if (policy.mode === 'allowlist') {\n return policy.toolIds.includes(toolId);\n }\n\n return !policy.toolIds.includes(toolId);\n}\n\n/**\n * Asserts that a tool call is permitted under the current session policy.\n * Throws a descriptive error if the tool is blocked — call this inside\n * `ToolPolicyGateway.callTool` before proxying the request to the remote server.\n *\n * @param policy - The active tool policy, or `undefined` for unrestricted access.\n * @param toolName - The tool being invoked.\n * @param serverId - The server that owns the tool.\n * @throws {Error} When the tool is not permitted by the policy.\n */\nexport function assertToolAllowed(policy: ToolPolicy | undefined, toolName: string, serverId?: string): void {\n if (isToolAllowed(policy, toolName, serverId)) return;\n throw new Error(`Tool \"${toolName}\" is not allowed for this MCP session`);\n}\n\n/**\n * Returns the subset of `tools` that are permitted under the given policy.\n *\n * When no policy is set (or mode is `\"all\"`), the original array is returned\n * unchanged (no copy is made). Otherwise each tool is tested with\n * `isToolAllowed` and only the passing tools are included.\n *\n * @param tools - The full, unfiltered list of tools from the remote server.\n * @param policy - The active tool policy, or `undefined` for unrestricted access.\n * @param serverId - The server that owns the tools (required for `allowlist`/`denylist`).\n * @returns A filtered array containing only the permitted tools.\n */\nexport function filterToolsByPolicy<T extends Pick<Tool, 'name'>>(\n tools: T[],\n policy: ToolPolicy | undefined,\n serverId?: string\n): T[] {\n if (!policy || policy.mode === 'all') return tools;\n return tools.filter((tool) => isToolAllowed(policy, tool.name, serverId));\n}\n\n/**\n * Validates that every tool ID referenced in a policy actually exists on the\n * connected MCP server. Throws if any ID is unknown.\n *\n * This prevents silent misconfigurations where a user accidentally saves a\n * policy referencing a tool that no longer exists (e.g. after a server update).\n *\n * @param policy - The policy to validate (skipped for `\"all\"` mode).\n * @param tools - The authoritative list of tools from the remote server.\n * @param serverId - Required to construct tool IDs for comparison.\n * @throws {Error} When `serverId` is missing and the policy is not `\"all\"`.\n * @throws {Error} When the policy contains tool IDs not present in `tools`.\n */\nexport function validateToolPolicyAgainstTools(\n policy: ToolPolicy,\n tools: Array<Pick<Tool, 'name'>>,\n serverId?: string\n): void {\n if (policy.mode === 'all') return;\n if (!serverId) {\n throw new Error('Cannot validate MCP tool policy without a serverId');\n }\n\n const availableIds = new Set(tools.map((tool) => createToolId(serverId, tool.name)));\n const unknownIds = policy.toolIds.filter((id) => !availableIds.has(id));\n if (unknownIds.length > 0) {\n throw new Error(`Unknown tool id(s) for this MCP session: ${unknownIds.join(', ')}`);\n }\n}\n","import {\n DORMANT_SESSION_EXPIRATION_MS,\n DORMANT_SESSION_EXPIRATION_SECONDS,\n STATE_EXPIRATION_MS,\n} from '../../shared/constants.js';\nimport type { Session, SessionStatus } from './types.js';\nimport { normalizeToolPolicy } from './tool-policy.js';\n\nexport function resolveSessionExpiresAt(status: SessionStatus = 'pending', referenceTime = Date.now()): number | null {\n return status === 'active' ? null : referenceTime + STATE_EXPIRATION_MS;\n}\n\nexport function resolveSessionRedisTtlSeconds(session: Pick<Session, 'status'>): number {\n return session.status === 'active'\n ? DORMANT_SESSION_EXPIRATION_SECONDS\n : Math.floor(STATE_EXPIRATION_MS / 1000);\n}\n\nexport function normalizeNewSession(session: Session, now = Date.now()): Session {\n const createdAt = session.createdAt || now;\n const updatedAt = session.updatedAt ?? createdAt;\n const status = session.status ?? 'pending';\n\n return {\n ...session,\n status,\n createdAt,\n updatedAt,\n expiresAt: resolveSessionExpiresAt(status, status === 'active' ? updatedAt : createdAt),\n toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt),\n };\n}\n\nexport function mergeSessionUpdate(\n current: Session,\n data: Partial<Session>,\n now = Date.now()\n): Session {\n const updatedAt = data.updatedAt ?? now;\n const updated = {\n ...current,\n ...data,\n updatedAt,\n };\n const status = updated.status ?? 'pending';\n\n return {\n ...updated,\n status,\n expiresAt: resolveSessionExpiresAt(status, updatedAt),\n toolPolicy: normalizeToolPolicy(updated.toolPolicy, updatedAt),\n };\n}\n\nexport function normalizeStoredSession(session: Session): Session {\n const createdAt = session.createdAt || Date.now();\n const updatedAt = session.updatedAt ?? createdAt;\n const status = session.status ?? 'pending';\n const expiresAt = status === 'active'\n ? null\n : session.expiresAt ?? resolveSessionExpiresAt(status, createdAt);\n\n return {\n ...session,\n status,\n createdAt,\n updatedAt,\n expiresAt,\n toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt),\n };\n}\n\nexport function isSessionExpired(session: Session, now = Date.now()): boolean {\n const hydrated = normalizeStoredSession(session);\n\n if (hydrated.status === 'active') {\n return hydrated.updatedAt !== undefined &&\n hydrated.updatedAt < now - DORMANT_SESSION_EXPIRATION_MS;\n }\n\n return typeof hydrated.expiresAt === 'number' && hydrated.expiresAt < now;\n}\n\n","import type { Redis } from 'ioredis';\nimport type { SessionStore, Session, SessionCredentials } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport {\n mergeSessionUpdate,\n normalizeNewSession,\n normalizeStoredSession,\n resolveSessionRedisTtlSeconds,\n} from './session-lifecycle.js';\n\n/**\n * Redis implementation of SessionStore\n */\nexport class RedisStorageBackend implements SessionStore {\n private readonly KEY_PREFIX = 'mcp:session:';\n private readonly CREDENTIALS_KEY_PREFIX = 'mcp:credentials:';\n private readonly USER_ID_KEY_PREFIX = 'mcp:userId:';\n private readonly USER_ID_KEY_SUFFIX = ':sessions';\n\n constructor(private redis: Redis) { }\n \n async init(): Promise<void> {\n try {\n await this.redis.ping();\n console.log('[mcp-ts][Storage] Redis: ✓ Connected to server.');\n } catch (error: any) {\n throw new Error(`[RedisStorageBackend] Failed to connect to Redis: ${error.message}`);\n }\n }\n\n /**\n * Generates Redis key for a specific session\n * @private\n */\n private getSessionKey(userId: string, sessionId: string): string {\n return `${this.KEY_PREFIX}${userId}:${sessionId}`;\n }\n\n private getCredentialsKey(userId: string, sessionId: string): string {\n return `${this.CREDENTIALS_KEY_PREFIX}${userId}:${sessionId}`;\n }\n\n /**\n * Generates Redis key for tracking all sessions for a user\n * @private\n */\n private getUserIdKey(userId: string): string {\n return `${this.USER_ID_KEY_PREFIX}${userId}${this.USER_ID_KEY_SUFFIX}`;\n }\n\n private parseUserIdFromKey(userIdKey: string): string {\n return userIdKey.slice(\n this.USER_ID_KEY_PREFIX.length,\n userIdKey.length - this.USER_ID_KEY_SUFFIX.length\n );\n }\n\n private async scanKeys(pattern: string): Promise<string[]> {\n const redis = this.redis as Redis & {\n scan?: (cursor: string, ...args: Array<string | number>) => Promise<[string, string[]]>;\n };\n\n if (typeof redis.scan !== 'function') {\n return await this.redis.keys(pattern);\n }\n\n const keys = new Set<string>();\n let cursor = '0';\n\n try {\n do {\n const [nextCursor, batch] = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);\n cursor = nextCursor;\n for (const key of batch) {\n keys.add(key);\n }\n } while (cursor !== '0');\n } catch (error) {\n console.warn('[RedisStorageBackend] SCAN failed, falling back to KEYS:', error);\n return await this.redis.keys(pattern);\n }\n\n return Array.from(keys);\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n const userIdKey = this.getUserIdKey(userId);\n const sessionWithLifecycle = normalizeNewSession(session);\n const effectiveTtl = resolveSessionRedisTtlSeconds(sessionWithLifecycle);\n\n const result = await this.redis.set(\n sessionKey,\n JSON.stringify(sessionWithLifecycle),\n 'EX',\n effectiveTtl,\n 'NX'\n );\n\n if (result !== 'OK') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n\n await this.redis.sadd(userIdKey, sessionId);\n }\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n\n /** Lua script for atomic get-and-set with expiration refresh. */\n const script = `\n local currentStr = redis.call(\"GET\", KEYS[1])\n if not currentStr then\n return 0\n end\n\n local current = cjson.decode(currentStr)\n local updated = cjson.decode(ARGV[1])\n\n redis.call(\"SET\", KEYS[1], cjson.encode(updated), \"EX\", ARGV[2])\n return 1\n `;\n\n const current = await this.get(userId, sessionId);\n if (!current) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const updated = mergeSessionUpdate(current, data);\n const effectiveTtl = resolveSessionRedisTtlSeconds(updated);\n\n const result = await this.redis.eval(\n script,\n 1,\n sessionKey,\n JSON.stringify(updated),\n effectiveTtl\n );\n\n if (result === 0) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const credentialsKey = this.getCredentialsKey(userId, sessionId);\n const sessionExists = await this.redis.exists(sessionKey);\n if (!sessionExists) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const session = await this.get(userId, sessionId);\n const currentTtl = await this.redis.ttl(sessionKey);\n const effectiveTtl = currentTtl > 0 && session\n ? currentTtl\n : resolveSessionRedisTtlSeconds(session ?? { status: 'pending' });\n const currentStr = await this.redis.get(credentialsKey);\n const current = currentStr ? JSON.parse(currentStr) as SessionCredentials : { sessionId, userId };\n const credentials = { ...current, ...data, sessionId, userId };\n if (effectiveTtl > 0) {\n await this.redis.set(credentialsKey, JSON.stringify(credentials), 'EX', effectiveTtl);\n } else {\n await this.redis.set(credentialsKey, JSON.stringify(credentials));\n }\n }\n\n async get(userId: string, sessionId: string): Promise<Session | null> {\n try {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const sessionDataStr = await this.redis.get(sessionKey);\n\n if (!sessionDataStr) {\n return null;\n }\n\n const session: Session = JSON.parse(sessionDataStr);\n return normalizeStoredSession(session);\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to get session:', error);\n return null;\n }\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n const session = await this.get(userId, sessionId);\n if (!session) return null;\n\n const credentialsStr = await this.redis.get(this.getCredentialsKey(userId, sessionId));\n return credentialsStr ? JSON.parse(credentialsStr) as SessionCredentials : { sessionId, userId };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async listIds(userId: string): Promise<string[]> {\n const sessions = await this.list(userId);\n return sessions.map((session) => session.sessionId);\n }\n\n async list(userId: string): Promise<Session[]> {\n try {\n const userIdKey = this.getUserIdKey(userId);\n const sessionIds = await this.redis.smembers(userIdKey);\n if (sessionIds.length === 0) return [];\n\n const results = await Promise.all(\n sessionIds.map(async (sessionId) => {\n const data = await this.redis.get(this.getSessionKey(userId, sessionId));\n return data ? (JSON.parse(data) as Session) : null;\n })\n );\n\n const staleSessionIds = sessionIds.filter((_, index) => results[index] === null);\n if (staleSessionIds.length > 0) {\n await this.redis.srem(userIdKey, ...staleSessionIds);\n }\n\n return results\n .filter((session): session is Session => session !== null)\n .map((session) => normalizeStoredSession(session));\n } catch (error) {\n console.error(`[RedisStorageBackend] Failed to get session data for ${userId}:`, error);\n return [];\n }\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n try {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const credentialsKey = this.getCredentialsKey(userId, sessionId);\n const userIdKey = this.getUserIdKey(userId);\n\n await this.redis.srem(userIdKey, sessionId);\n await this.redis.del(sessionKey, credentialsKey);\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to remove session:', error);\n }\n }\n\n async listAllIds(): Promise<string[]> {\n try {\n const keys = await this.scanKeys(`${this.KEY_PREFIX}*`);\n const sessions = await Promise.all(\n keys.map(async (key) => {\n const data = await this.redis.get(key);\n if (!data) {\n return null;\n }\n\n try {\n return normalizeStoredSession(JSON.parse(data) as Session).sessionId;\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to parse session while listing all session IDs:', error);\n return null;\n }\n })\n );\n\n return sessions.filter((sessionId): sessionId is string => sessionId !== null);\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to get all sessions:', error);\n return [];\n }\n }\n\n async clearAll(): Promise<void> {\n try {\n const keys = await this.scanKeys(`${this.KEY_PREFIX}*`);\n const credentialKeys = await this.scanKeys(`${this.CREDENTIALS_KEY_PREFIX}*`);\n const userIdKeys = await this.scanKeys(`${this.USER_ID_KEY_PREFIX}*${this.USER_ID_KEY_SUFFIX}`);\n const allKeys = [...keys, ...credentialKeys, ...userIdKeys];\n if (allKeys.length > 0) {\n await this.redis.del(...allKeys);\n }\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to clear sessions:', error);\n }\n }\n\n async cleanupExpired(): Promise<void> {\n try {\n const userIdKeys = await this.scanKeys(`${this.USER_ID_KEY_PREFIX}*${this.USER_ID_KEY_SUFFIX}`);\n\n for (const userIdKey of userIdKeys) {\n const userId = this.parseUserIdFromKey(userIdKey);\n const sessionIds = await this.redis.smembers(userIdKey);\n\n if (sessionIds.length === 0) {\n await this.redis.del(userIdKey);\n continue;\n }\n\n const existenceChecks = await Promise.all(\n sessionIds.map((sessionId) => this.redis.exists(this.getSessionKey(userId, sessionId)))\n );\n\n const staleSessionIds = sessionIds.filter((_, index) => existenceChecks[index] === 0);\n if (staleSessionIds.length > 0) {\n await this.redis.srem(userIdKey, ...staleSessionIds);\n await this.redis.del(...staleSessionIds.map((sessionId) => this.getCredentialsKey(userId, sessionId)));\n }\n\n const remainingCount = await this.redis.scard(userIdKey);\n if (remainingCount === 0) {\n await this.redis.del(userIdKey);\n }\n }\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to cleanup expired sessions:', error);\n }\n }\n\n async disconnect(): Promise<void> {\n try {\n await this.redis.quit();\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to disconnect:', error);\n }\n }\n}\n","import type { SessionStore, Session, SessionCredentials } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport { isSessionExpired, mergeSessionUpdate, normalizeNewSession } from './session-lifecycle.js';\n\n/**\n * In-memory implementation of SessionStore\n * Useful for local development or testing\n */\nexport class MemoryStorageBackend implements SessionStore {\n // Map<userId:sessionId, Session>\n private sessions = new Map<string, Session>();\n private credentials = new Map<string, SessionCredentials>();\n\n // Map<userId, Set<sessionId>>\n private userIdSessions = new Map<string, Set<string>>();\n\n constructor() { }\n\n async init(): Promise<void> {\n console.log('[mcp-ts][Storage] Memory: ✓ internal memory store active.');\n }\n\n private getSessionKey(userId: string, sessionId: string): string {\n return `${userId}:${sessionId}`;\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (this.sessions.has(sessionKey)) {\n throw new Error(`Session ${sessionId} already exists`);\n }\n\n this.sessions.set(sessionKey, normalizeNewSession(session));\n\n // Update index\n if (!this.userIdSessions.has(userId)) {\n this.userIdSessions.set(userId, new Set());\n }\n this.userIdSessions.get(userId)!.add(sessionId);\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n if (!userId || !sessionId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n const current = this.sessions.get(sessionKey);\n\n if (!current) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n const updated = mergeSessionUpdate(current, data);\n\n this.sessions.set(sessionKey, updated);\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (!this.sessions.has(sessionKey)) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n const current = this.credentials.get(sessionKey) ?? { sessionId, userId };\n this.credentials.set(sessionKey, { ...current, ...data, sessionId, userId });\n }\n\n\n async get(userId: string, sessionId: string): Promise<Session | null> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n return this.sessions.get(sessionKey) || null;\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (!this.sessions.has(sessionKey)) return null;\n return this.credentials.get(sessionKey) ?? { sessionId, userId };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async listIds(userId: string): Promise<string[]> {\n const set = this.userIdSessions.get(userId);\n return set ? Array.from(set) : [];\n }\n\n async list(userId: string): Promise<Session[]> {\n const set = this.userIdSessions.get(userId);\n if (!set) return [];\n\n const results: Session[] = [];\n for (const sessionId of set) {\n const session = this.sessions.get(this.getSessionKey(userId, sessionId));\n if (session) {\n results.push(session);\n }\n }\n return results;\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n this.sessions.delete(sessionKey);\n this.credentials.delete(sessionKey);\n\n const set = this.userIdSessions.get(userId);\n if (set) {\n set.delete(sessionId);\n if (set.size === 0) {\n this.userIdSessions.delete(userId);\n }\n }\n }\n\n async listAllIds(): Promise<string[]> {\n return Array.from(this.sessions.values()).map(s => s.sessionId);\n }\n\n async clearAll(): Promise<void> {\n this.sessions.clear();\n this.credentials.clear();\n this.userIdSessions.clear();\n }\n\n async cleanupExpired(): Promise<void> {\n for (const [key, session] of this.sessions.entries()) {\n if (!isSessionExpired(session)) continue;\n\n this.sessions.delete(key);\n this.credentials.delete(key);\n\n const set = this.userIdSessions.get(session.userId);\n if (set) {\n set.delete(session.sessionId);\n if (set.size === 0) {\n this.userIdSessions.delete(session.userId);\n }\n }\n }\n }\n\n async disconnect(): Promise<void> {\n // No-op for memory\n }\n}\n","import { promises as fs } from 'fs';\nimport * as path from 'path';\nimport type { SessionStore, Session, SessionCredentials } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport {\n mergeSessionUpdate,\n normalizeNewSession,\n normalizeStoredSession,\n isSessionExpired,\n} from './session-lifecycle.js';\n\n/**\n * File system implementation of SessionStore\n * Persists sessions to a JSON file\n */\nexport class FileStorageBackend implements SessionStore {\n private filePath: string;\n private memoryCache: Map<string, Session> | null = null;\n private credentialsCache: Map<string, SessionCredentials> | null = null;\n private initialized = false;\n\n /**\n * @param options.path Path to the JSON file storage (default: ./sessions.json)\n */\n constructor(options: { path?: string } = {}) {\n this.filePath = options.path || './sessions.json';\n }\n\n /**\n * Initialize storage: ensure file exists and load into memory cache\n */\n async init(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Ensure directory exists\n const dir = path.dirname(this.filePath);\n await fs.mkdir(dir, { recursive: true });\n\n // Try to read file\n const data = await fs.readFile(this.filePath, 'utf-8');\n const json = JSON.parse(data);\n\n this.memoryCache = new Map();\n this.credentialsCache = new Map();\n if (Array.isArray(json.sessions)) {\n json.sessions.forEach((s: Session) => {\n const session = normalizeStoredSession(s);\n this.memoryCache!.set(this.getSessionKey(session.userId || 'unknown', session.sessionId), session);\n });\n }\n if (Array.isArray(json.credentials)) {\n json.credentials.forEach((c: SessionCredentials) => {\n this.credentialsCache!.set(this.getSessionKey(c.userId, c.sessionId), c);\n });\n }\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n // File does not exist, initialize empty\n this.memoryCache = new Map();\n this.credentialsCache = new Map();\n await this.flush();\n } else {\n console.error('[FileStorage] Failed to load sessions:', error);\n throw error;\n }\n }\n\n this.initialized = true;\n console.log(`[mcp-ts][Storage] File: ✓ storage directory at ${path.dirname(this.filePath)} verified.`);\n }\n\n private async ensureInitialized() {\n if (!this.initialized) await this.init();\n }\n\n private async flush(): Promise<void> {\n if (!this.memoryCache || !this.credentialsCache) return;\n await fs.writeFile(this.filePath, JSON.stringify({\n sessions: Array.from(this.memoryCache.values()),\n credentials: Array.from(this.credentialsCache.values()),\n }, null, 2), 'utf-8');\n }\n\n private getSessionKey(userId: string, sessionId: string): string {\n return `${userId}:${sessionId}`;\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n await this.ensureInitialized();\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (this.memoryCache!.has(sessionKey)) {\n throw new Error(`Session ${sessionId} already exists`);\n }\n\n this.memoryCache!.set(sessionKey, normalizeNewSession(session));\n await this.flush();\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n await this.ensureInitialized();\n if (!userId || !sessionId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n const current = this.memoryCache!.get(sessionKey);\n\n if (!current) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n const updated = mergeSessionUpdate(current, data);\n\n this.memoryCache!.set(sessionKey, updated);\n await this.flush();\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (!this.memoryCache!.has(sessionKey)) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n const current = this.credentialsCache!.get(sessionKey) ?? { sessionId, userId };\n this.credentialsCache!.set(sessionKey, { ...current, ...data, sessionId, userId });\n await this.flush();\n }\n\n async get(userId: string, sessionId: string): Promise<Session | null> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n return this.memoryCache!.get(sessionKey) || null;\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (!this.memoryCache!.has(sessionKey)) return null;\n return this.credentialsCache!.get(sessionKey) ?? { sessionId, userId };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async list(userId: string): Promise<Session[]> {\n await this.ensureInitialized();\n return Array.from(this.memoryCache!.values()).filter(s => s.userId === userId);\n }\n\n async listIds(userId: string): Promise<string[]> {\n await this.ensureInitialized();\n return Array.from(this.memoryCache!.values())\n .filter(s => s.userId === userId)\n .map(s => s.sessionId);\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n const deleted = this.memoryCache!.delete(sessionKey);\n this.credentialsCache!.delete(sessionKey);\n if (deleted) {\n await this.flush();\n }\n }\n\n async listAllIds(): Promise<string[]> {\n await this.ensureInitialized();\n return Array.from(this.memoryCache!.values()).map(s => s.sessionId);\n }\n\n async clearAll(): Promise<void> {\n await this.ensureInitialized();\n this.memoryCache!.clear();\n this.credentialsCache!.clear();\n await this.flush();\n }\n\n async cleanupExpired(): Promise<void> {\n await this.ensureInitialized();\n let changed = false;\n\n for (const [key, session] of this.memoryCache!.entries()) {\n if (!isSessionExpired(session)) continue;\n\n this.memoryCache!.delete(key);\n this.credentialsCache!.delete(key);\n changed = true;\n }\n\n if (changed) {\n await this.flush();\n }\n }\n\n async disconnect(): Promise<void> {\n // No explicit disconnect needed for file\n }\n}\n","import type { Database } from 'better-sqlite3';\nimport type { SessionStore, Session, SessionCredentials } from './types.js';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { generateSessionId } from '../../shared/utils.js';\nimport {\n mergeSessionUpdate,\n normalizeNewSession,\n normalizeStoredSession,\n isSessionExpired,\n} from './session-lifecycle.js';\n\nexport interface SqliteStorageOptions {\n path?: string;\n table?: string;\n}\n\nexport class SqliteStorage implements SessionStore {\n private db: Database | null = null;\n private table: string;\n private credentialsTable: string;\n private initialized = false;\n private dbPath: string;\n\n constructor(options: SqliteStorageOptions = {}) {\n this.dbPath = options.path || './sessions.db';\n this.table = options.table || 'mcp_sessions';\n this.credentialsTable = `${this.table}_credentials`;\n }\n\n async init(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Dynamic import for peer dependency\n const DatabaseConstructor = (await import('better-sqlite3')).default;\n\n // Ensure directory exists\n const dir = path.dirname(this.dbPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n this.db = new DatabaseConstructor(this.dbPath);\n this.db.pragma('foreign_keys = ON');\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS ${this.table} (\n sessionId TEXT PRIMARY KEY,\n userId TEXT NOT NULL,\n data TEXT NOT NULL,\n expiresAt INTEGER\n );\n CREATE INDEX IF NOT EXISTS idx_${this.table}_userId ON ${this.table}(userId);\n CREATE TABLE IF NOT EXISTS ${this.credentialsTable} (\n sessionId TEXT NOT NULL,\n userId TEXT NOT NULL,\n data TEXT NOT NULL,\n PRIMARY KEY (userId, sessionId),\n FOREIGN KEY (sessionId) REFERENCES ${this.table}(sessionId) ON DELETE CASCADE\n );\n `);\n\n this.initialized = true;\n console.log(`[mcp-ts][Storage] SQLite: ✓ database at ${this.dbPath} verified.`);\n } catch (error: any) {\n if (error.code === 'MODULE_NOT_FOUND' || error.message?.includes('better-sqlite3')) {\n throw new Error(\n 'better-sqlite3 is not installed. Please install it with: npm install better-sqlite3'\n );\n }\n throw error;\n }\n }\n\n private ensureInitialized() {\n if (!this.initialized) {\n throw new Error('SqliteStorage not initialized. Call init() first.');\n }\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n this.ensureInitialized();\n const { sessionId, userId } = session;\n\n if (!sessionId || !userId) {\n throw new Error('userId and sessionId required');\n }\n\n const sessionWithLifecycle = normalizeNewSession(session);\n\n try {\n const stmt = this.db!.prepare(\n `INSERT INTO ${this.table} (sessionId, userId, data, expiresAt) VALUES (?, ?, ?, ?)`\n );\n stmt.run(sessionId, userId, JSON.stringify(sessionWithLifecycle), sessionWithLifecycle.expiresAt ?? null);\n } catch (error: any) {\n if (error.code === 'SQLITE_CONSTRAINT_PRIMARYKEY') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n throw error;\n }\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n this.ensureInitialized();\n if (!sessionId || !userId) {\n throw new Error('userId and sessionId required');\n }\n\n const currentSession = await this.get(userId, sessionId);\n if (!currentSession) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const updatedSession = mergeSessionUpdate(currentSession, data);\n\n const stmt = this.db!.prepare(\n `UPDATE ${this.table} SET data = ?, expiresAt = ? WHERE sessionId = ? AND userId = ?`\n );\n\n stmt.run(JSON.stringify(updatedSession), updatedSession.expiresAt ?? null, sessionId, userId);\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n this.ensureInitialized();\n if (!await this.get(userId, sessionId)) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const current = await this.getCredentials(userId, sessionId) ?? { sessionId, userId };\n const credentials = { ...current, ...data, sessionId, userId };\n const stmt = this.db!.prepare(\n `INSERT INTO ${this.credentialsTable} (sessionId, userId, data)\n VALUES (?, ?, ?)\n ON CONFLICT(userId, sessionId) DO UPDATE SET data = excluded.data`\n );\n stmt.run(sessionId, userId, JSON.stringify(credentials));\n\n }\n\n async get(userId: string, sessionId: string): Promise<Session | null> {\n this.ensureInitialized();\n\n const stmt = this.db!.prepare(\n `SELECT data FROM ${this.table} WHERE sessionId = ? AND userId = ?`\n );\n const row = stmt.get(sessionId, userId) as { data: string } | undefined;\n\n if (!row) return null;\n return normalizeStoredSession(JSON.parse(row.data) as Session);\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n this.ensureInitialized();\n if (!await this.get(userId, sessionId)) return null;\n\n const stmt = this.db!.prepare(\n `SELECT data FROM ${this.credentialsTable} WHERE sessionId = ? AND userId = ?`\n );\n const row = stmt.get(sessionId, userId) as { data: string } | undefined;\n return row ? JSON.parse(row.data) as SessionCredentials : { sessionId, userId };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async list(userId: string): Promise<Session[]> {\n this.ensureInitialized();\n\n const stmt = this.db!.prepare(\n `SELECT data FROM ${this.table} WHERE userId = ?`\n );\n const rows = stmt.all(userId) as { data: string }[];\n\n return rows.map(row => normalizeStoredSession(JSON.parse(row.data) as Session));\n }\n\n async listIds(userId: string): Promise<string[]> {\n this.ensureInitialized();\n\n const stmt = this.db!.prepare(\n `SELECT sessionId FROM ${this.table} WHERE userId = ?`\n );\n const rows = stmt.all(userId) as { sessionId: string }[];\n\n return rows.map(row => row.sessionId);\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n this.ensureInitialized();\n const stmt = this.db!.prepare(\n `DELETE FROM ${this.table} WHERE sessionId = ? AND userId = ?`\n );\n this.db!.prepare(\n `DELETE FROM ${this.credentialsTable} WHERE sessionId = ? AND userId = ?`\n ).run(sessionId, userId);\n stmt.run(sessionId, userId);\n }\n\n async listAllIds(): Promise<string[]> {\n this.ensureInitialized();\n const stmt = this.db!.prepare(`SELECT sessionId FROM ${this.table}`);\n const rows = stmt.all() as { sessionId: string }[];\n return rows.map(row => row.sessionId);\n }\n\n async clearAll(): Promise<void> {\n this.ensureInitialized();\n this.db!.prepare(`DELETE FROM ${this.credentialsTable}`).run();\n const stmt = this.db!.prepare(`DELETE FROM ${this.table}`);\n stmt.run();\n }\n\n async cleanupExpired(): Promise<void> {\n this.ensureInitialized();\n const rows = this.db!.prepare(`SELECT sessionId, userId, data FROM ${this.table}`).all() as {\n sessionId: string;\n userId: string;\n data: string;\n }[];\n const deleteStmt = this.db!.prepare(`DELETE FROM ${this.table} WHERE sessionId = ? AND userId = ?`);\n\n for (const row of rows) {\n const session = normalizeStoredSession(JSON.parse(row.data) as Session);\n if (isSessionExpired(session)) {\n deleteStmt.run(row.sessionId, row.userId);\n }\n }\n\n this.db!.prepare(\n `DELETE FROM ${this.credentialsTable}\n WHERE NOT EXISTS (\n SELECT 1 FROM ${this.table}\n WHERE ${this.table}.sessionId = ${this.credentialsTable}.sessionId\n AND ${this.table}.userId = ${this.credentialsTable}.userId\n )`\n ).run();\n }\n\n async disconnect(): Promise<void> {\n if (this.db) {\n this.db.close();\n }\n }\n}\n","import { randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';\n\nconst ALGORITHM = 'aes-256-gcm';\nconst IV_LENGTH = 12;\nconst ENCRYPTION_PREFIX = 'enc:1:';\n\nlet warningLogged = false;\n\nfunction getKey(): Buffer | null {\n const keyString = process.env.STORAGE_ENCRYPTION_KEY;\n if (!keyString) return null;\n \n // Ensure key is 32 bytes (256 bits)\n if (keyString.length === 64) {\n return Buffer.from(keyString, 'hex');\n } else {\n const keyBuffer = Buffer.alloc(32);\n keyBuffer.write(keyString, 0, 32, 'utf-8');\n return keyBuffer;\n }\n}\n\n/**\n * Encrypts an object into a secure string.\n * Falls back to returning the original object if the encryption key is missing or encryption fails.\n */\nexport function encryptObject(data: any): any {\n if (data === undefined || data === null) return data;\n \n const key = getKey();\n if (!key) {\n if (!warningLogged) {\n console.warn('[mcp-ts][Storage] WARNING: STORAGE_ENCRYPTION_KEY is not set. Saving sensitive data in plain-text.');\n warningLogged = true;\n }\n return data; // Fallback to plain-text\n }\n\n try {\n const text = JSON.stringify(data);\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv(ALGORITHM, key, iv);\n \n let encrypted = cipher.update(text, 'utf-8', 'hex');\n encrypted += cipher.final('hex');\n const authTag = cipher.getAuthTag().toString('hex');\n \n return `${ENCRYPTION_PREFIX}${iv.toString('hex')}:${authTag}:${encrypted}`;\n } catch (e) {\n console.error('[mcp-ts][Storage] Encryption failed, falling back to plain-text.', e);\n return data;\n }\n}\n\n/**\n * Decrypts a secure string back into an object.\n * Returns the original data if it is unencrypted or if decryption fails.\n */\nexport function decryptObject(data: any): any {\n if (data === undefined || data === null) return data;\n if (typeof data !== 'string' || !data.startsWith(ENCRYPTION_PREFIX)) {\n return data; // Already unencrypted or old plain-text data\n }\n\n const key = getKey();\n if (!key) {\n console.warn('[mcp-ts][Storage] WARNING: Found encrypted data but STORAGE_ENCRYPTION_KEY is missing. Returning raw encrypted string.');\n return data;\n }\n\n try {\n const parts = data.split(':');\n if (parts.length !== 5) {\n return data;\n }\n\n const iv = Buffer.from(parts[2], 'hex');\n const authTag = Buffer.from(parts[3], 'hex');\n const encryptedText = parts[4];\n\n const decipher = createDecipheriv(ALGORITHM, key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encryptedText, 'hex', 'utf-8');\n decrypted += decipher.final('utf-8');\n\n return JSON.parse(decrypted);\n } catch (e) {\n console.error('[mcp-ts][Storage] Decryption failed.', e);\n return data;\n }\n}\n","import type { SupabaseClient } from '@supabase/supabase-js';\nimport type { SessionStore, Session, SessionCredentials } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport { encryptObject, decryptObject } from './crypto.js';\nimport { resolveSessionExpiresAt } from './session-lifecycle.js';\nimport { normalizeToolPolicy } from './tool-policy.js';\nimport { DORMANT_SESSION_EXPIRATION_MS } from '../../shared/constants.js';\n\nexport class SupabaseStorageBackend implements SessionStore {\n constructor(private supabase: SupabaseClient) {}\n\n async init(): Promise<void> {\n await this.assertTable('mcp_sessions', 'session_id');\n await this.assertTable('mcp_credentials', 'session_id');\n console.log('[mcp-ts][Storage] Supabase: storage tables verified.');\n }\n\n private async assertTable(table: string, column: string): Promise<void> {\n const { error } = await this.supabase\n .from(table)\n .select(column)\n .limit(0);\n\n if (!error) return;\n\n if (error.code === '42P01') {\n throw new Error(\n `[SupabaseStorage] Table \"${table}\" not found in your database. ` +\n 'Please run \"npx mcp-ts supabase-init\" to set up the required storage schema.'\n );\n }\n\n throw new Error(`[SupabaseStorage] Initialization check failed for \"${table}\": ${error.message}`);\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n private mapRowToSessionData(row: any): Session {\n return {\n sessionId: row.session_id,\n serverId: row.server_id,\n serverName: row.server_name,\n serverUrl: row.server_url,\n transportType: row.transport_type,\n callbackUrl: row.callback_url,\n createdAt: new Date(row.created_at).getTime(),\n updatedAt: new Date(row.updated_at ?? row.created_at).getTime(),\n expiresAt: row.expires_at ? new Date(row.expires_at).getTime() : null,\n userId: row.user_id,\n headers: decryptObject(row.headers),\n authUrl: row.auth_url,\n status: row.status ?? 'pending',\n toolPolicy: normalizeToolPolicy(row.tool_policy),\n };\n }\n\n private mapRowToCredentials(row: any, userId: string, sessionId: string): SessionCredentials {\n return {\n sessionId,\n userId,\n clientInformation: decryptObject(row?.client_information),\n tokens: decryptObject(row?.tokens),\n codeVerifier: decryptObject(row?.code_verifier),\n clientId: row?.client_id,\n oauthState: row?.oauth_state,\n };\n }\n\n private hasCredentialData(data: Partial<SessionCredentials>): boolean {\n return (\n 'clientInformation' in data ||\n 'tokens' in data ||\n 'codeVerifier' in data ||\n 'clientId' in data ||\n 'oauthState' in data\n );\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const status = session.status ?? 'pending';\n const createdAt = new Date(session.createdAt || Date.now()).toISOString();\n const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();\n const expiresAt = resolveSessionExpiresAt(status, new Date(createdAt).getTime());\n\n const insertData: Record<string, unknown> = {\n session_id: sessionId,\n user_id: userId,\n server_id: session.serverId,\n server_name: session.serverName,\n server_url: session.serverUrl,\n transport_type: session.transportType,\n callback_url: session.callbackUrl,\n created_at: createdAt,\n updated_at: updatedAt,\n headers: encryptObject(session.headers),\n auth_url: session.authUrl ?? null,\n status,\n expires_at: expiresAt === null ? null : new Date(expiresAt).toISOString(),\n };\n\n const toolPolicy = normalizeToolPolicy(session.toolPolicy);\n if (toolPolicy) {\n insertData.tool_policy = toolPolicy;\n }\n\n const { error } = await this.supabase\n .from('mcp_sessions')\n .insert(insertData);\n\n if (error) {\n if (error.code === '23505') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n throw new Error(`Failed to create session in Supabase: ${error.message}`);\n }\n\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n const updateData: any = {\n updated_at: new Date().toISOString(),\n };\n\n if ('serverId' in data) updateData.server_id = data.serverId;\n if ('serverName' in data) updateData.server_name = data.serverName;\n if ('serverUrl' in data) updateData.server_url = data.serverUrl;\n if ('transportType' in data) updateData.transport_type = data.transportType;\n if ('callbackUrl' in data) updateData.callback_url = data.callbackUrl;\n if ('status' in data) {\n const status = data.status ?? 'pending';\n const expiresAt = resolveSessionExpiresAt(status);\n updateData.status = status;\n updateData.expires_at = expiresAt === null ? null : new Date(expiresAt).toISOString();\n }\n if ('headers' in data) updateData.headers = encryptObject(data.headers);\n if ('authUrl' in data) updateData.auth_url = data.authUrl ?? null;\n if ('toolPolicy' in data) updateData.tool_policy = normalizeToolPolicy(data.toolPolicy);\n\n const shouldUpdateSession = Object.keys(updateData).some((key) => key !== 'updated_at');\n\n let updatedRows: any[] | null = null;\n if (shouldUpdateSession) {\n const result = await this.supabase\n .from('mcp_sessions')\n .update(updateData)\n .eq('user_id', userId)\n .eq('session_id', sessionId)\n .select('id');\n\n if (result.error) {\n throw new Error(`Failed to update session: ${result.error.message}`);\n }\n updatedRows = result.data;\n } else {\n const result = await this.supabase\n .from('mcp_sessions')\n .select('id')\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (result.error) {\n throw new Error(`Failed to update session: ${result.error.message}`);\n }\n updatedRows = result.data;\n }\n\n if (!updatedRows || updatedRows.length === 0) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n if (!this.hasCredentialData(data)) return;\n\n const row: any = {\n user_id: userId,\n session_id: sessionId,\n updated_at: new Date().toISOString(),\n };\n\n if ('clientInformation' in data) row.client_information = data.clientInformation == null ? null : encryptObject(data.clientInformation);\n if ('tokens' in data) row.tokens = data.tokens == null ? null : encryptObject(data.tokens);\n if ('codeVerifier' in data) row.code_verifier = data.codeVerifier == null ? null : encryptObject(data.codeVerifier);\n if ('clientId' in data) row.client_id = data.clientId ?? null;\n if ('oauthState' in data) row.oauth_state = data.oauthState ?? null;\n\n const { error } = await this.supabase\n .from('mcp_credentials')\n .upsert(row, { onConflict: 'user_id,session_id' });\n\n if (error) {\n throw new Error(`Failed to update credentials: ${error.message}`);\n }\n\n }\n\n async get(userId: string, sessionId: string): Promise<Session | null> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('*')\n .eq('user_id', userId)\n .eq('session_id', sessionId)\n .maybeSingle();\n\n if (error) {\n console.error('[SupabaseStorage] Failed to get session:', error);\n return null;\n }\n\n if (!data) return null;\n\n return this.mapRowToSessionData(data);\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n const { data, error } = await this.supabase\n .from('mcp_credentials')\n .select('*')\n .eq('user_id', userId)\n .eq('session_id', sessionId)\n .maybeSingle();\n\n if (error) {\n console.error('[SupabaseStorage] Failed to get credentials:', error);\n return null;\n }\n\n if (data) {\n return this.mapRowToCredentials(data, userId, sessionId);\n }\n\n const { data: sessionRows, error: sessionError } = await this.supabase\n .from('mcp_sessions')\n .select('id')\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (sessionError || !sessionRows || sessionRows.length === 0) {\n return null;\n }\n\n return { sessionId, userId };\n }\n\n async list(userId: string): Promise<Session[]> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('*')\n .eq('user_id', userId);\n\n if (error) {\n console.error(`[SupabaseStorage] Failed to get session data for ${userId}:`, error);\n return [];\n }\n\n return data.map(row => this.mapRowToSessionData(row));\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n const { error } = await this.supabase\n .from('mcp_credentials')\n .delete()\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (error) {\n throw new Error(`Failed to clear credentials: ${error.message}`);\n }\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n const { error } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (error) {\n console.error('[SupabaseStorage] Failed to remove session:', error);\n }\n }\n\n async listIds(userId: string): Promise<string[]> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('session_id')\n .eq('user_id', userId);\n\n if (error) {\n console.error(`[SupabaseStorage] Failed to get sessions for ${userId}:`, error);\n return [];\n }\n\n return data.map(row => row.session_id);\n }\n\n async listAllIds(): Promise<string[]> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('session_id');\n\n if (error) {\n console.error('[SupabaseStorage] Failed to get all sessions:', error);\n return [];\n }\n\n return data.map(row => row.session_id);\n }\n\n async clearAll(): Promise<void> {\n const { error: credentialsError } = await this.supabase\n .from('mcp_credentials')\n .delete()\n .neq('session_id', '');\n\n if (credentialsError) {\n console.error('[SupabaseStorage] Failed to clear credentials:', credentialsError);\n }\n\n const { error } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .neq('session_id', '');\n\n if (error) {\n console.error('[SupabaseStorage] Failed to clear sessions:', error);\n }\n }\n\n async cleanupExpired(): Promise<void> {\n const { error: transientError } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .not('expires_at', 'is', null)\n .neq('status', 'active')\n .lt('expires_at', new Date().toISOString());\n\n if (transientError) {\n console.error('[SupabaseStorage] Failed to cleanup expired inactive sessions:', transientError);\n }\n\n const dormantCutoff = new Date(Date.now() - DORMANT_SESSION_EXPIRATION_MS).toISOString();\n const { error: dormantError } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .eq('status', 'active')\n .lt('updated_at', dormantCutoff);\n\n if (dormantError) {\n console.error('[SupabaseStorage] Failed to cleanup dormant active sessions:', dormantError);\n }\n }\n\n async disconnect(): Promise<void> {\n // Supabase client handles its own connection pooling over HTTP.\n }\n}\n\n\n","import type { SessionStore, Session, SessionCredentials } from './types.js';\nimport type { SessionStatus } from './types.js';\nimport { DORMANT_SESSION_EXPIRATION_MS } from '../../shared/constants.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport { encryptObject, decryptObject } from './crypto.js';\nimport { resolveSessionExpiresAt } from './session-lifecycle.js';\nimport { normalizeToolPolicy } from './tool-policy.js';\n\nexport interface NeonStorageOptions {\n schema?: string;\n table?: string;\n credentialsTable?: string;\n}\n\ntype NeonSql = {\n query(queryWithPlaceholders: string, params?: unknown[]): Promise<any[]>;\n};\n\ntype NeonSessionRow = {\n id?: string;\n session_id: string;\n server_id?: string | null;\n server_name?: string | null;\n server_url: string;\n transport_type: 'sse' | 'streamable-http';\n callback_url: string;\n created_at: string | Date;\n updated_at?: string | Date | null;\n expires_at?: string | Date | null;\n user_id: string;\n headers?: unknown;\n auth_url?: string | null;\n status?: SessionStatus | null;\n tool_policy?: unknown;\n};\n\ntype NeonCredentialsRow = {\n session_id: string;\n user_id: string;\n client_information?: unknown;\n tokens?: unknown;\n code_verifier?: unknown;\n client_id?: string | null;\n oauth_state?: unknown;\n};\n\nexport class NeonStorageBackend implements SessionStore {\n private readonly tableName: string;\n private readonly credentialsTableName: string;\n\n constructor(\n private readonly sql: NeonSql,\n options: NeonStorageOptions = {}\n ) {\n const schema = options.schema || 'public';\n const table = options.table || 'mcp_sessions';\n const credentialsTable = options.credentialsTable || 'mcp_credentials';\n this.tableName = `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table)}`;\n this.credentialsTableName = `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(credentialsTable)}`;\n }\n\n async init(): Promise<void> {\n await this.assertTable(this.tableName, 'mcp_sessions');\n await this.assertTable(this.credentialsTableName, 'mcp_credentials');\n console.log('[mcp-ts][Storage] Neon: storage tables verified.');\n }\n\n private async assertTable(qualifiedName: string, displayName: string): Promise<void> {\n const [{ exists } = { exists: null }] = await this.sql.query(\n 'SELECT to_regclass($1) AS exists',\n [qualifiedName.replace(/\"/g, '')]\n ) as Array<{ exists: string | null }>;\n\n if (!exists) {\n throw new Error(\n `[NeonStorage] Table \"${displayName}\" not found in your database. ` +\n 'Please create it using the Neon storage guide in docs/storage-backends/neon.md.'\n );\n }\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n private quoteIdentifier(identifier: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {\n throw new Error(`Invalid Neon storage identifier: ${identifier}`);\n }\n return `\"${identifier}\"`;\n }\n\n private mapRowToSessionData(row: NeonSessionRow): Session {\n return {\n sessionId: row.session_id,\n serverId: row.server_id ?? undefined,\n serverName: row.server_name ?? undefined,\n serverUrl: row.server_url,\n transportType: row.transport_type,\n callbackUrl: row.callback_url,\n createdAt: new Date(row.created_at).getTime(),\n updatedAt: new Date(row.updated_at ?? row.created_at).getTime(),\n expiresAt: row.expires_at ? new Date(row.expires_at).getTime() : null,\n userId: row.user_id,\n headers: decryptObject(row.headers),\n authUrl: row.auth_url ?? undefined,\n status: row.status ?? 'pending',\n toolPolicy: normalizeToolPolicy(row.tool_policy as Parameters<typeof normalizeToolPolicy>[0]),\n };\n }\n\n private mapRowToCredentials(row: NeonCredentialsRow, userId: string, sessionId: string): SessionCredentials {\n return {\n sessionId,\n userId,\n clientInformation: decryptObject(row.client_information),\n tokens: decryptObject(row.tokens),\n codeVerifier: decryptObject(row.code_verifier),\n clientId: row.client_id ?? undefined,\n oauthState: row.oauth_state as SessionCredentials['oauthState'],\n };\n }\n\n private hasCredentialData(data: Partial<SessionCredentials>): boolean {\n return (\n 'clientInformation' in data ||\n 'tokens' in data ||\n 'codeVerifier' in data ||\n 'clientId' in data ||\n 'oauthState' in data\n );\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const status = session.status ?? 'pending';\n const createdAt = new Date(session.createdAt || Date.now()).toISOString();\n const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();\n const createdAtMs = new Date(createdAt).getTime();\n const expiresAt = resolveSessionExpiresAt(status, createdAtMs);\n const toolPolicy = normalizeToolPolicy(session.toolPolicy, createdAtMs);\n\n const columns: string[] = [\n 'session_id', 'user_id', 'server_id', 'server_name',\n 'server_url', 'transport_type', 'callback_url',\n 'created_at', 'updated_at', 'headers', 'auth_url',\n 'status', 'expires_at',\n ];\n const values: unknown[] = [\n sessionId, userId, session.serverId, session.serverName,\n session.serverUrl, session.transportType, session.callbackUrl,\n createdAt, updatedAt, encryptObject(session.headers),\n session.authUrl ?? null, status,\n expiresAt === null ? null : new Date(expiresAt).toISOString(),\n ];\n\n if (toolPolicy) {\n columns.push('tool_policy');\n values.push(toolPolicy);\n }\n\n const placeholders = values.map((_, i) => `$${i + 1}`);\n\n try {\n await this.sql.query(\n `INSERT INTO ${this.tableName} (${columns.join(', ')}) VALUES (${placeholders.join(', ')})`,\n values\n );\n } catch (error: any) {\n if (error.code === '23505') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n throw new Error(`Failed to create session in Neon: ${error.message}`);\n }\n\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n const currentSession = await this.get(userId, sessionId);\n if (!currentSession) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const updatedSession = { ...currentSession, ...data };\n const status = updatedSession.status ?? 'pending';\n const expiresAt = resolveSessionExpiresAt(status);\n\n const shouldUpdateSession = (\n 'serverId' in data ||\n 'serverName' in data ||\n 'serverUrl' in data ||\n 'transportType' in data ||\n 'callbackUrl' in data ||\n 'status' in data ||\n 'headers' in data ||\n 'authUrl' in data ||\n 'toolPolicy' in data\n );\n\n if (shouldUpdateSession) {\n const setClauses: string[] = [];\n const values: unknown[] = [];\n let paramIndex = 1;\n\n const addSet = (column: string, value: unknown) => {\n setClauses.push(`${column} = $${paramIndex++}`);\n values.push(value);\n };\n\n addSet('server_id', updatedSession.serverId);\n addSet('server_name', updatedSession.serverName);\n addSet('server_url', updatedSession.serverUrl);\n addSet('transport_type', updatedSession.transportType);\n addSet('callback_url', updatedSession.callbackUrl);\n addSet('status', status);\n addSet('headers', encryptObject(updatedSession.headers));\n addSet('auth_url', updatedSession.authUrl ?? null);\n addSet('expires_at', expiresAt === null ? null : new Date(expiresAt).toISOString());\n\n if ('toolPolicy' in data) {\n const policyUpdatedAt = updatedSession.updatedAt ?? Date.now();\n const toolPolicy = normalizeToolPolicy(updatedSession.toolPolicy, policyUpdatedAt) ?? { mode: 'all' as const, toolIds: [], updatedAt: policyUpdatedAt };\n addSet('tool_policy', toolPolicy);\n }\n\n setClauses.push('updated_at = now()');\n\n const updatedRows = await this.sql.query(\n `UPDATE ${this.tableName}\n SET ${setClauses.join(', ')}\n WHERE user_id = $${paramIndex++} AND session_id = $${paramIndex++}\n RETURNING id`,\n [...values, userId, sessionId]\n ) as Array<{ id: string }>;\n\n if (updatedRows.length === 0) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n }\n\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n if (!this.hasCredentialData(data)) return;\n\n await this.sql.query(\n `INSERT INTO ${this.credentialsTableName} (\n user_id,\n session_id,\n client_information,\n tokens,\n code_verifier,\n client_id,\n oauth_state,\n updated_at\n ) VALUES ($1, $2, $3, $4, $5, $6, $7, now())\n ON CONFLICT (user_id, session_id)\n DO UPDATE SET\n client_information = CASE WHEN $8 THEN EXCLUDED.client_information ELSE ${this.credentialsTableName}.client_information END,\n tokens = CASE WHEN $9 THEN EXCLUDED.tokens ELSE ${this.credentialsTableName}.tokens END,\n code_verifier = CASE WHEN $10 THEN EXCLUDED.code_verifier ELSE ${this.credentialsTableName}.code_verifier END,\n client_id = CASE WHEN $11 THEN EXCLUDED.client_id ELSE ${this.credentialsTableName}.client_id END,\n oauth_state = CASE WHEN $12 THEN EXCLUDED.oauth_state ELSE ${this.credentialsTableName}.oauth_state END,\n updated_at = now()`,\n [\n userId,\n sessionId,\n 'clientInformation' in data ? (data.clientInformation == null ? null : encryptObject(data.clientInformation)) : null,\n 'tokens' in data ? (data.tokens == null ? null : encryptObject(data.tokens)) : null,\n 'codeVerifier' in data ? (data.codeVerifier == null ? null : encryptObject(data.codeVerifier)) : null,\n 'clientId' in data ? (data.clientId ?? null) : null,\n 'oauthState' in data ? (data.oauthState ?? null) : null,\n 'clientInformation' in data,\n 'tokens' in data,\n 'codeVerifier' in data,\n 'clientId' in data,\n 'oauthState' in data,\n ]\n );\n\n }\n\n async get(userId: string, sessionId: string): Promise<Session | null> {\n try {\n const rows = await this.sql.query(\n `SELECT * FROM ${this.tableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n ) as NeonSessionRow[];\n\n if (!rows[0]) return null;\n\n return this.mapRowToSessionData(rows[0]);\n } catch (error) {\n console.error('[NeonStorage] Failed to get session:', error);\n return null;\n }\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n try {\n const credentialRows = await this.sql.query(\n `SELECT * FROM ${this.credentialsTableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n ) as NeonCredentialsRow[];\n\n if (credentialRows[0]) {\n return this.mapRowToCredentials(credentialRows[0], userId, sessionId);\n }\n\n const sessionRows = await this.sql.query(\n `SELECT id FROM ${this.tableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n ) as Array<{ id: string }>;\n\n return sessionRows[0] ? { sessionId, userId } : null;\n } catch (error) {\n console.error('[NeonStorage] Failed to get credentials:', error);\n return null;\n }\n }\n\n async list(userId: string): Promise<Session[]> {\n try {\n const rows = await this.sql.query(\n `SELECT * FROM ${this.tableName} WHERE user_id = $1`,\n [userId]\n ) as NeonSessionRow[];\n return rows.map((row) => this.mapRowToSessionData(row));\n } catch (error) {\n console.error(`[NeonStorage] Failed to get session data for ${userId}:`, error);\n return [];\n }\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n try {\n await this.sql.query(\n `DELETE FROM ${this.credentialsTableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n );\n } catch (error) {\n console.error('[NeonStorage] Failed to clear credentials:', error);\n }\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n try {\n await this.sql.query(\n `DELETE FROM ${this.tableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n );\n } catch (error) {\n console.error('[NeonStorage] Failed to remove session:', error);\n }\n }\n\n async listIds(userId: string): Promise<string[]> {\n try {\n const rows = await this.sql.query(\n `SELECT session_id FROM ${this.tableName} WHERE user_id = $1`,\n [userId]\n ) as Array<{ session_id: string }>;\n return rows.map((row) => row.session_id);\n } catch (error) {\n console.error(`[NeonStorage] Failed to get sessions for ${userId}:`, error);\n return [];\n }\n }\n\n async listAllIds(): Promise<string[]> {\n try {\n const rows = await this.sql.query(\n `SELECT session_id FROM ${this.tableName}`\n ) as Array<{ session_id: string }>;\n return rows.map((row) => row.session_id);\n } catch (error) {\n console.error('[NeonStorage] Failed to get all sessions:', error);\n return [];\n }\n }\n\n async clearAll(): Promise<void> {\n try {\n await this.sql.query(`DELETE FROM ${this.credentialsTableName}`);\n await this.sql.query(`DELETE FROM ${this.tableName}`);\n } catch (error) {\n console.error('[NeonStorage] Failed to clear sessions:', error);\n }\n }\n\n async cleanupExpired(): Promise<void> {\n try {\n await this.sql.query(\n `DELETE FROM ${this.tableName}\n WHERE expires_at IS NOT NULL\n AND expires_at < $1\n AND status <> 'active'`,\n [new Date().toISOString()]\n );\n await this.sql.query(\n `DELETE FROM ${this.tableName}\n WHERE status = 'active' AND updated_at < $1`,\n [new Date(Date.now() - DORMANT_SESSION_EXPIRATION_MS).toISOString()]\n );\n } catch (error) {\n console.error('[NeonStorage] Failed to cleanup expired sessions:', error);\n }\n }\n\n async disconnect(): Promise<void> {\n // Neon HTTP queries do not hold a persistent connection.\n }\n}\n\n\n\n\n","\nimport { RedisStorageBackend } from './redis-backend';\nimport { MemoryStorageBackend } from './memory-backend';\nimport { FileStorageBackend } from './file-backend';\nimport { SqliteStorage } from './sqlite-backend.js';\nimport { SupabaseStorageBackend } from './supabase-backend.js';\nimport { NeonStorageBackend, type NeonStorageOptions } from './neon-backend.js';\nimport type { SessionStore, Session, SessionMutationEvent, SessionMutationListener } from './types.js';\n\n// Re-export types\nexport * from './types.js';\nexport { generateSessionId, generateServerId } from '../../shared/utils.js';\nexport { RedisStorageBackend, MemoryStorageBackend, FileStorageBackend, SqliteStorage, SupabaseStorageBackend, NeonStorageBackend };\n\nexport function createSupabaseStorageBackend(client: any): SupabaseStorageBackend {\n return new SupabaseStorageBackend(client);\n}\n\nexport function createNeonStorageBackend(sql: any, options?: NeonStorageOptions): NeonStorageBackend {\n return new NeonStorageBackend(sql, options);\n}\n\nfunction warnIfNeonConnectionStringIsInsecure(connectionString: string): void {\n try {\n const url = new URL(connectionString);\n const sslMode = url.searchParams.get('sslmode');\n const channelBinding = url.searchParams.get('channel_binding');\n\n if (!sslMode) {\n console.warn('[mcp-ts][Storage] Neon connection string does not include sslmode. Neon recommends sslmode=verify-full for the strongest certificate verification.');\n } else if (!['verify-full', 'require'].includes(sslMode)) {\n console.warn(`[mcp-ts][Storage] Neon connection string uses sslmode=${sslMode}. Use sslmode=verify-full or sslmode=require for secure connections.`);\n }\n\n if (!channelBinding) {\n console.warn('[mcp-ts][Storage] Neon connection string does not include channel_binding=require. Add it when supported by your runtime and connection path.');\n }\n } catch {\n console.warn('[mcp-ts][Storage] Neon connection string could not be parsed for SSL checks.');\n }\n}\n\nlet storageInstance: SessionStore | null = null;\nlet storagePromise: Promise<SessionStore> | null = null;\nconst sessionMutationListeners = new Set<SessionMutationListener>();\n\nfunction emitSessionMutation(event: SessionMutationEvent): void {\n for (const listener of sessionMutationListeners) {\n try {\n const result = listener(event);\n if (result && typeof (result as Promise<void>).catch === 'function') {\n void (result as Promise<void>).catch((error) => {\n console.error('[mcp-ts][Storage] Session mutation listener failed:', error);\n });\n }\n } catch (error) {\n console.error('[mcp-ts][Storage] Session mutation listener failed:', error);\n }\n }\n}\n\nfunction createSessionMutationEvent(prop: PropertyKey, args: any[]): SessionMutationEvent | null {\n const timestamp = Date.now();\n\n if (prop === 'create') {\n const [session] = args as [Session];\n if (!session?.userId || !session?.sessionId) return null;\n return {\n type: 'create',\n userId: session.userId,\n sessionId: session.sessionId,\n session,\n timestamp,\n };\n }\n\n if (prop === 'update') {\n const [userId, sessionId, patch] = args as [string, string, Partial<Session>];\n if (!userId || !sessionId) return null;\n return {\n type: 'update',\n userId,\n sessionId,\n patch,\n timestamp,\n };\n }\n\n if (prop === 'delete') {\n const [userId, sessionId] = args as [string, string];\n if (!userId || !sessionId) return null;\n return {\n type: 'delete',\n userId,\n sessionId,\n timestamp,\n };\n }\n\n return null;\n}\n\nasync function initializeStorage<T extends SessionStore>(store: T): Promise<T> {\n if (typeof store.init === 'function') {\n await store.init();\n }\n return store;\n}\n\nasync function createStorage(): Promise<SessionStore> {\n const type = process.env.MCP_TS_STORAGE_TYPE?.toLowerCase();\n\n // Explicit selection\n if (type === 'redis') {\n if (!process.env.REDIS_URL) {\n console.warn('[Storage] MCP_TS_STORAGE_TYPE is \"redis\" but REDIS_URL is missing');\n }\n try {\n const { getRedis } = await import('./redis.js');\n const redis = await getRedis();\n console.log('[mcp-ts][Storage] Explicit selection: \"redis\"');\n return await initializeStorage(new RedisStorageBackend(redis));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Failed to initialize Redis:', error.message);\n console.log('[mcp-ts][Storage] Falling back to In-Memory storage');\n return await initializeStorage(new MemoryStorageBackend());\n }\n }\n\n if (type === 'file') {\n const filePath = process.env.MCP_TS_STORAGE_FILE;\n console.log(`[mcp-ts][Storage] Explicit selection: \"file\" (${filePath || 'default'})`);\n return await initializeStorage(new FileStorageBackend({ path: filePath }));\n }\n\n if (type === 'sqlite') {\n const dbPath = process.env.MCP_TS_STORAGE_SQLITE_PATH;\n console.log(`[mcp-ts][Storage] Explicit selection: \"sqlite\" (${dbPath || 'default'})`);\n return await initializeStorage(new SqliteStorage({ path: dbPath }));\n }\n\n if (type === 'supabase') {\n const url = process.env.SUPABASE_URL;\n const key = process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY;\n \n if (!url || !key) {\n console.warn('[mcp-ts][Storage] Explicit selection \"supabase\" requires SUPABASE_URL and SUPABASE_SECRET_KEY.');\n } else {\n if (!process.env.SUPABASE_SECRET_KEY) {\n console.warn('[mcp-ts][Storage] ⚠️ Warning: Using \"SUPABASE_ANON_KEY\" for server-side storage. You may encounter RLS policy violations. \"SUPABASE_SECRET_KEY\" is recommended.');\n }\n try {\n const { createClient } = await import('@supabase/supabase-js');\n const client = createClient(url, key);\n console.log('[mcp-ts][Storage] Explicit selection: \"supabase\"');\n return await initializeStorage(new SupabaseStorageBackend(client as any));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Failed to initialize Supabase:', error.message);\n console.log('[mcp-ts][Storage] Falling back to In-Memory storage');\n return await initializeStorage(new MemoryStorageBackend());\n }\n }\n }\n\n if (type === 'neon') {\n const connectionString = process.env.NEON_DATABASE_URL || process.env.DATABASE_URL;\n\n if (!connectionString) {\n console.warn('[mcp-ts][Storage] Explicit selection \"neon\" requires NEON_DATABASE_URL or DATABASE_URL.');\n } else {\n try {\n const { neon } = await import('@neondatabase/serverless');\n warnIfNeonConnectionStringIsInsecure(connectionString);\n const sql = neon(connectionString);\n console.log('[mcp-ts][Storage] Explicit selection: \"neon\"');\n return await initializeStorage(new NeonStorageBackend(sql));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Failed to initialize Neon:', error.message);\n console.log('[mcp-ts][Storage] Falling back to In-Memory storage');\n return await initializeStorage(new MemoryStorageBackend());\n }\n }\n }\n\n if (type === 'memory') {\n console.log('[mcp-ts][Storage] Explicit selection: \"memory\"');\n return await initializeStorage(new MemoryStorageBackend());\n }\n\n // Automatic inference (Fallback)\n if (process.env.REDIS_URL) {\n try {\n const { getRedis } = await import('./redis.js');\n const redis = await getRedis();\n console.log('[mcp-ts][Storage] Auto-detection: \"redis\" (via REDIS_URL)');\n return await initializeStorage(new RedisStorageBackend(redis));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Redis auto-detection failed:', error.message);\n console.log('[mcp-ts][Storage] Falling back to next available backend');\n }\n }\n\n if (process.env.MCP_TS_STORAGE_FILE) {\n console.log(`[mcp-ts][Storage] Auto-detection: \"file\" (${process.env.MCP_TS_STORAGE_FILE})`);\n return await initializeStorage(new FileStorageBackend({ path: process.env.MCP_TS_STORAGE_FILE }));\n }\n\n if (process.env.MCP_TS_STORAGE_SQLITE_PATH) {\n console.log(`[mcp-ts][Storage] Auto-detection: \"sqlite\" (${process.env.MCP_TS_STORAGE_SQLITE_PATH})`);\n return await initializeStorage(new SqliteStorage({ path: process.env.MCP_TS_STORAGE_SQLITE_PATH }));\n }\n\n if (process.env.SUPABASE_URL && (process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY)) {\n try {\n const { createClient } = await import('@supabase/supabase-js');\n const url = process.env.SUPABASE_URL;\n const key = process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY!;\n \n if (!process.env.SUPABASE_SECRET_KEY) {\n console.warn('[mcp-ts][Storage] ⚠️ Warning: Using \"SUPABASE_ANON_KEY\" for server-side storage. You may encounter RLS policy violations. \"SUPABASE_SECRET_KEY\" is recommended.');\n }\n\n const client = createClient(url, key);\n console.log('[mcp-ts][Storage] Auto-detection: \"supabase\" (via SUPABASE_URL)');\n return await initializeStorage(new SupabaseStorageBackend(client as any));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Supabase auto-detection failed:', error.message);\n }\n }\n\n if (process.env.NEON_DATABASE_URL) {\n try {\n const { neon } = await import('@neondatabase/serverless');\n warnIfNeonConnectionStringIsInsecure(process.env.NEON_DATABASE_URL);\n const sql = neon(process.env.NEON_DATABASE_URL);\n console.log('[mcp-ts][Storage] Auto-detection: \"neon\" (via NEON_DATABASE_URL)');\n return await initializeStorage(new NeonStorageBackend(sql));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Neon auto-detection failed:', error.message);\n }\n }\n\n console.log('[mcp-ts][Storage] Defaulting to: \"memory\"');\n return await initializeStorage(new MemoryStorageBackend());\n}\n\nasync function getStorage(): Promise<SessionStore> {\n if (storageInstance) {\n return storageInstance;\n }\n\n if (!storagePromise) {\n storagePromise = createStorage().catch((error) => {\n storagePromise = null;\n throw error;\n });\n }\n\n storageInstance = await storagePromise;\n return storageInstance;\n}\n\n/**\n * Set the storage instance (for testing)\n * @internal\n * @param instance - SessionStore instance or null to reset\n */\nexport function _setStorageInstanceForTesting(instance: SessionStore | null): void {\n storageInstance = instance;\n if (!instance) {\n storagePromise = null;\n }\n}\n\nexport function onSessionMutation(listener: SessionMutationListener): () => void {\n sessionMutationListeners.add(listener);\n return () => {\n sessionMutationListeners.delete(listener);\n };\n}\n\nexport function _resetSessionMutationListenersForTesting(): void {\n sessionMutationListeners.clear();\n}\n\n/**\n * Global session store instance\n * Uses lazy initialization with a Proxy to handle async setup transparently\n */\nexport const sessions: SessionStore = new Proxy({} as SessionStore, {\n get(_target, prop) {\n return async (...args: any[]) => {\n const instance = await getStorage();\n const value = (instance as any)[prop];\n if (typeof value === 'function') {\n const result = await value.apply(instance, args);\n const event = createSessionMutationEvent(prop, args);\n if (event) {\n emitSessionMutation(event);\n }\n return result;\n }\n return value;\n };\n },\n});\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type {\n OAuthClientInformationFull,\n OAuthClientInformationMixed,\n OAuthClientMetadata,\n OAuthTokens\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\nimport { nanoid } from \"nanoid\";\nimport { sessions, type SessionCredentials } from \"../storage/index.js\";\nimport {\n DEFAULT_CLIENT_NAME,\n DEFAULT_CLIENT_URI,\n DEFAULT_LOGO_URI,\n DEFAULT_POLICY_URI,\n SOFTWARE_ID,\n SOFTWARE_VERSION,\n STATE_EXPIRATION_MS,\n} from '../../shared/constants.js';\nimport { formatOAuthState, parseOAuthState } from '../../shared/utils.js';\n\n/**\n * Extension of OAuthClientProvider interface with additional methods\n * Enables server-specific tracking and state management\n */\nexport interface AgentsOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\n consumeState(state: string): Promise<void>;\n deleteCodeVerifier(): Promise<void>;\n}\n\nexport interface StorageOAuthClientProviderOptions {\n userId: string;\n serverId: string;\n sessionId: string;\n redirectUrl: string;\n clientName?: string;\n clientUri?: string;\n logoUri?: string;\n policyUri?: string;\n clientId?: string;\n clientSecret?: string;\n onRedirect?: (url: string) => void;\n}\n\n/**\n * Storage-backed OAuth provider implementation for MCP\n * Stores OAuth tokens, client information, and PKCE verifiers using the configured SessionStore\n */\nexport class StorageOAuthClientProvider implements AgentsOAuthProvider {\n public readonly userId: string;\n public readonly serverId: string;\n public readonly sessionId: string;\n public readonly redirectUrl: string;\n\n private readonly clientName?: string;\n private readonly clientUri?: string;\n private readonly logoUri?: string;\n private readonly policyUri?: string;\n private readonly clientSecret?: string;\n\n private _authUrl: string | undefined;\n private _clientId: string | undefined;\n private onRedirectCallback?: (url: string) => void;\n\n /**\n * Creates a new session-backed OAuth provider\n * @param options - Provider configuration\n */\n constructor(options: StorageOAuthClientProviderOptions) {\n this.userId = options.userId;\n this.serverId = options.serverId;\n this.sessionId = options.sessionId;\n this.redirectUrl = options.redirectUrl;\n this.clientName = options.clientName;\n this.clientUri = options.clientUri;\n this.logoUri = options.logoUri;\n this.policyUri = options.policyUri;\n this._clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.onRedirectCallback = options.onRedirect;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName || DEFAULT_CLIENT_NAME,\n client_uri: this.clientUri || DEFAULT_CLIENT_URI,\n logo_uri: this.logoUri || DEFAULT_LOGO_URI,\n policy_uri: this.policyUri || DEFAULT_POLICY_URI,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: this.clientSecret ? \"client_secret_basic\" : \"none\",\n software_id: SOFTWARE_ID,\n software_version: SOFTWARE_VERSION,\n };\n }\n\n get clientId() {\n return this._clientId;\n }\n\n set clientId(clientId_: string | undefined) {\n this._clientId = clientId_;\n }\n\n /**\n * Loads OAuth credentials from the session store\n * @private\n */\n private async getCredentials(): Promise<SessionCredentials> {\n const data = await sessions.getCredentials(this.userId, this.sessionId);\n if (!data) {\n return { userId: this.userId, sessionId: this.sessionId };\n }\n return data;\n }\n\n /**\n * Saves OAuth credentials to the session store\n * @param data - Partial OAuth credentials to save\n * @private\n * @throws Error if session doesn't exist (session must be created by controller layer)\n */\n private async patchCredentials(data: Partial<SessionCredentials>): Promise<void> {\n await sessions.patchCredentials(this.userId, this.sessionId, data);\n }\n\n /**\n * Retrieves stored OAuth client information\n */\n async clientInformation(): Promise<OAuthClientInformationMixed | undefined> {\n const data = await this.getCredentials();\n\n if (data.clientId && !this._clientId) {\n this._clientId = data.clientId;\n }\n\n if (data.clientInformation) {\n return data.clientInformation;\n }\n\n if (!this._clientId) {\n return undefined;\n }\n\n return {\n client_id: this._clientId,\n ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),\n };\n }\n\n /**\n * Stores OAuth client information\n */\n async saveClientInformation(clientInformation: OAuthClientInformationFull): Promise<void> {\n await this.patchCredentials({\n clientInformation,\n clientId: clientInformation.client_id\n });\n this.clientId = clientInformation.client_id;\n }\n\n /**\n * Stores OAuth tokens\n */\n async saveTokens(tokens: OAuthTokens): Promise<void> {\n await this.patchCredentials({ tokens });\n }\n\n get authUrl() {\n return this._authUrl;\n }\n\n async state(): Promise<string> {\n const nonce = nanoid(32);\n await this.patchCredentials({\n oauthState: {\n nonce,\n sessionId: this.sessionId,\n serverId: this.serverId,\n createdAt: Date.now(),\n },\n codeVerifier: null,\n });\n return formatOAuthState(nonce, this.sessionId);\n }\n\n async checkState(state: string): Promise<{ valid: boolean; serverId?: string; error?: string }> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n return { valid: false, error: \"Invalid OAuth state\" };\n }\n\n if (parsed.sessionId !== this.sessionId) {\n return { valid: false, error: \"OAuth state mismatch\" };\n }\n\n const data = await sessions.getCredentials(this.userId, parsed.sessionId);\n\n if (!data) {\n return { valid: false, error: \"Session not found\" };\n }\n\n const oauthState = data.oauthState;\n if (!oauthState) {\n return { valid: false, error: \"OAuth state not found\" };\n }\n\n if (\n oauthState.nonce !== parsed.nonce ||\n oauthState.sessionId !== parsed.sessionId ||\n oauthState.serverId !== this.serverId\n ) {\n return { valid: false, error: \"OAuth state mismatch\" };\n }\n\n if (Date.now() - oauthState.createdAt > STATE_EXPIRATION_MS) {\n return { valid: false, error: \"OAuth state expired\" };\n }\n\n return { valid: true, serverId: oauthState.serverId };\n }\n\n async consumeState(state: string): Promise<void> {\n const result = await this.checkState(state);\n if (!result.valid) {\n throw new Error(result.error || \"Invalid OAuth state\");\n }\n\n await this.patchCredentials({ oauthState: null });\n }\n\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n this._authUrl = authUrl.toString();\n await sessions.update(this.userId, this.sessionId, { authUrl: this._authUrl });\n if (this.onRedirectCallback) {\n this.onRedirectCallback(authUrl.toString());\n }\n }\n\n async invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\"\n ): Promise<void> {\n if (scope === \"all\") {\n await sessions.delete(this.userId, this.sessionId);\n } else {\n const updates: Partial<SessionCredentials> = {};\n\n if (scope === \"client\") {\n updates.clientInformation = null;\n updates.clientId = null;\n } else if (scope === \"tokens\") {\n updates.tokens = null;\n } else if (scope === \"verifier\") {\n updates.codeVerifier = null;\n }\n await this.patchCredentials(updates);\n }\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n const data = await this.getCredentials();\n if (data.codeVerifier) {\n return;\n }\n\n await this.patchCredentials({ codeVerifier: verifier });\n }\n\n async codeVerifier(): Promise<string> {\n const data = await this.getCredentials();\n\n if (data.clientId && !this._clientId) {\n this._clientId = data.clientId;\n }\n\n if (!data.codeVerifier) {\n throw new Error(\"No code verifier found\");\n }\n return data.codeVerifier;\n }\n\n async deleteCodeVerifier(): Promise<void> {\n await this.patchCredentials({ codeVerifier: null });\n }\n\n async tokens(): Promise<OAuthTokens | undefined> {\n const data = await this.getCredentials();\n\n if (data.clientId && !this._clientId) {\n this._clientId = data.clientId;\n }\n\n return data.tokens ?? undefined;\n }\n}\n","/**\n * Simple event emitter pattern for MCP connection events\n */\n\nexport type Disposable = {\n dispose(): void;\n};\n\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\n\n/**\n * Event emitter class for type-safe event handling\n */\nexport class Emitter<T> {\n private listeners: Set<(event: T) => void> = new Set();\n\n /**\n * Subscribe to events\n * @param listener - Callback function to handle events\n * @returns Disposable to unsubscribe\n */\n get event(): Event<T> {\n return (listener: (event: T) => void) => {\n this.listeners.add(listener);\n return {\n dispose: () => {\n this.listeners.delete(listener);\n },\n };\n };\n }\n\n /**\n * Fire an event to all listeners\n * @param event - Event data to emit\n */\n fire(event: T): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('[Emitter] Error in event listener:', error);\n }\n }\n }\n\n /**\n * Clear all listeners\n */\n dispose(): void {\n this.listeners.clear();\n }\n\n /**\n * Get number of active listeners\n */\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n\n/**\n * Connection state types matching your existing ConnectionStatus\n * Extended with more granular states for better observability\n */\nexport type McpConnectionState =\n | 'DISCONNECTED' // Not connected\n | 'CONNECTING' // Establishing transport connection to MCP server\n | 'AUTHENTICATING' // OAuth flow in progress\n | 'AUTHENTICATED' // OAuth complete, pre-connect\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\n | 'CONNECTED' // Transport connection established\n | 'READY' // Fully connected and ready to use\n | 'VALIDATING' // Validating existing session\n | 'RECONNECTING' // Attempting to reconnect\n | 'INITIALIZING' // Initializing session or connection\n | 'FAILED'; // Connection error at some point\n\n/**\n * MCP Connection Event Types\n * Discriminated union for type-safe event handling\n */\nexport type McpConnectionEvent =\n | {\n type: 'state_changed';\n sessionId: string;\n serverId: string;\n serverName: string;\n serverUrl: string;\n createdAt?: number;\n state: McpConnectionState;\n previousState: McpConnectionState;\n timestamp: number;\n }\n | {\n type: 'tools_discovered';\n sessionId: string;\n serverId: string;\n toolCount: number;\n tools: any[];\n allTools?: any[];\n timestamp: number;\n }\n | {\n type: 'auth_required';\n sessionId: string;\n serverId: string;\n authUrl: string;\n timestamp: number;\n }\n | {\n type: 'error';\n sessionId: string;\n serverId: string;\n error: string;\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\n timestamp: number;\n }\n | {\n type: 'disconnected';\n sessionId: string;\n serverId: string;\n timestamp: number;\n }\n | {\n type: 'progress';\n sessionId: string;\n serverId: string;\n message: string;\n timestamp: number;\n };\n\n/**\n * Event fired when a tool execution returns a UI resource URI\n */\nexport interface McpAppsUIEvent {\n type: 'mcp-apps-ui';\n sessionId: string;\n resourceUri: string;\n toolName: string;\n result: unknown;\n timestamp: number;\n}\n\n/**\n * Observability event for debugging and monitoring\n */\nexport interface McpObservabilityEvent {\n type?: string;\n level?: 'debug' | 'info' | 'warn' | 'error';\n message?: string;\n displayMessage?: string;\n sessionId?: string;\n serverId?: string;\n payload?: Record<string, any>;\n metadata?: Record<string, any>; // Kept for backward compatibility\n timestamp: number;\n id?: string;\n}\n\n/**\n * DisposableStore for managing multiple disposables\n * Useful for cleanup in React hooks\n */\nexport class DisposableStore {\n private disposables: Set<Disposable> = new Set();\n\n add(disposable: Disposable): void {\n this.disposables.add(disposable);\n }\n\n dispose(): void {\n for (const disposable of this.disposables) {\n disposable.dispose();\n }\n this.disposables.clear();\n }\n}\n","/**\n * Standardized error classes for MCP Redis library\n * Provides consistent error handling across the codebase\n */\n\n/**\n * Base error class for all MCP-related errors\n */\nexport class McpError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'McpError';\n // Maintain proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.cause ? { cause: this.cause.message } : {}),\n };\n }\n}\n\n/**\n * Thrown when OAuth authorization is required\n */\nexport class UnauthorizedError extends McpError {\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\n super('UNAUTHORIZED', message, cause);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Thrown when connection to MCP server fails\n */\nexport class ConnectionError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONNECTION_ERROR', message, cause);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Thrown when session is not found or expired\n */\nexport class SessionNotFoundError extends McpError {\n constructor(sessionId: string, cause?: Error) {\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\n this.name = 'SessionNotFoundError';\n }\n}\n\n/**\n * Thrown when session validation fails\n */\nexport class SessionValidationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('SESSION_VALIDATION_ERROR', message, cause);\n this.name = 'SessionValidationError';\n }\n}\n\n/**\n * Thrown when authentication fails\n */\nexport class AuthenticationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('AUTH_ERROR', message, cause);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when OAuth state validation fails\n */\nexport class InvalidStateError extends McpError {\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\n super('INVALID_STATE', message, cause);\n this.name = 'InvalidStateError';\n }\n}\n\n/**\n * Thrown when client is not connected\n */\nexport class NotConnectedError extends McpError {\n constructor(message: string = 'Not connected to server', cause?: Error) {\n super('NOT_CONNECTED', message, cause);\n this.name = 'NotConnectedError';\n }\n}\n\n/**\n * Thrown when required configuration is missing\n */\nexport class ConfigurationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONFIGURATION_ERROR', message, cause);\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Thrown when tool execution fails\n */\nexport class ToolExecutionError extends McpError {\n constructor(toolName: string, message: string, cause?: Error) {\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\n this.name = 'ToolExecutionError';\n }\n}\n\n/**\n * RPC error codes for SSE communication\n */\nexport const RpcErrorCodes = {\n EXECUTION_ERROR: 'EXECUTION_ERROR',\n MISSING_USER_ID: 'MISSING_USER_ID',\n UNAUTHORIZED: 'UNAUTHORIZED',\n NO_CONNECTION: 'NO_CONNECTION',\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\n INVALID_PARAMS: 'INVALID_PARAMS',\n} as const;\n\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { nanoid } from 'nanoid';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport {\n UnauthorizedError as SDKUnauthorizedError,\n} from '@modelcontextprotocol/sdk/client/auth.js';\nimport {\n ListToolsRequest,\n ListToolsResult,\n ListToolsResultSchema,\n CallToolRequest,\n CallToolResult,\n CallToolResultSchema,\n ListPromptsRequest,\n ListPromptsResult,\n ListPromptsResultSchema,\n GetPromptRequest,\n GetPromptResult,\n GetPromptResultSchema,\n ListResourcesRequest,\n ListResourcesResult,\n ListResourcesResultSchema,\n ReadResourceRequest,\n ReadResourceResult,\n ReadResourceResultSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { StorageOAuthClientProvider, type AgentsOAuthProvider } from './storage-oauth-provider.js';\nimport { Emitter, type McpConnectionEvent, type McpObservabilityEvent, type McpConnectionState } from '../../shared/events.js';\nimport { UnauthorizedError } from '../../shared/errors.js';\nimport { sessions } from '../storage/index.js';\nimport type { Session, SessionStatus } from '../storage/types.js';\nimport {\n MCP_CLIENT_NAME,\n MCP_CLIENT_VERSION,\n} from '../../shared/constants.js';\n\n/**\n * Supported MCP transport types\n */\nexport type TransportType = 'sse' | 'streamable-http';\n\n/**\n * Extended capabilities including MCP App support\n */\nimport type { ClientCapabilities } from '@modelcontextprotocol/sdk/types.js';\n\ninterface McpAppClientCapabilities extends Omit<ClientCapabilities, 'extensions'> {\n extensions?: {\n 'io.modelcontextprotocol/ui'?: {\n mimeTypes: string[];\n };\n [key: string]: any;\n };\n}\n\nexport interface MCPOAuthClientOptions {\n serverUrl?: string;\n serverName?: string;\n callbackUrl?: string;\n onRedirect?: (url: string) => void;\n userId: string;\n serverId?: string; /** Optional - loaded from session if not provided */\n sessionId: string; /** Required - primary key for session lookup */\n transportType?: TransportType;\n clientId?: string;\n clientSecret?: string;\n headers?: Record<string, string>;\n /** OAuth Client Metadata (optional - user application info) */\n clientName?: string;\n clientUri?: string;\n logoUri?: string;\n policyUri?: string;\n}\n\n/**\n * MCP Client with OAuth 2.1 authentication support\n * Manages connections to MCP servers with automatic token refresh and session restoration\n * Emits connection lifecycle events for observability\n */\nexport class MCPClient {\n private client: Client;\n public oauthProvider: AgentsOAuthProvider | null = null;\n private transport: StreamableHTTPClientTransport | SSEClientTransport | null = null;\n private userId: string;\n private serverId?: string;\n private sessionId: string;\n private serverName?: string;\n private transportType: TransportType | undefined;\n private serverUrl: string | undefined;\n private callbackUrl: string | undefined;\n private onRedirect: ((url: string) => void) | undefined;\n private clientId?: string;\n private clientSecret?: string;\n private headers?: Record<string, string>;\n /** OAuth Client Metadata */\n private clientName?: string;\n private clientUri?: string;\n private logoUri?: string;\n private policyUri?: string;\n private createdAt?: number;\n\n\n /** Event emitters for connection lifecycle */\n private readonly _onConnectionEvent = new Emitter<McpConnectionEvent>();\n public readonly onConnectionEvent = this._onConnectionEvent.event;\n\n private readonly _onObservabilityEvent = new Emitter<McpObservabilityEvent>();\n public readonly onObservabilityEvent = this._onObservabilityEvent.event;\n\n private currentState: McpConnectionState = 'DISCONNECTED';\n\n /**\n * Creates a new MCP client instance\n * Can be initialized with minimal options (userId + sessionId) for session restoration\n * @param options - Client configuration options\n */\n constructor(options: MCPOAuthClientOptions) {\n this.serverUrl = options.serverUrl;\n this.serverName = options.serverName;\n this.callbackUrl = options.callbackUrl;\n this.onRedirect = options.onRedirect;\n this.userId = options.userId;\n this.serverId = options.serverId;\n this.sessionId = options.sessionId;\n this.transportType = options.transportType;\n this.clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this.headers = options.headers;\n this.clientName = options.clientName;\n this.clientUri = options.clientUri;\n this.logoUri = options.logoUri;\n this.policyUri = options.policyUri;\n\n this.client = new Client(\n {\n name: MCP_CLIENT_NAME,\n version: MCP_CLIENT_VERSION,\n },\n {\n capabilities: {\n extensions: {\n 'io.modelcontextprotocol/ui': {\n mimeTypes: ['text/html+mcp'],\n },\n },\n } as McpAppClientCapabilities,\n }\n );\n }\n\n /**\n * Emit a connection state change event\n * @private\n */\n private emitStateChange(newState: McpConnectionState): void {\n const previousState = this.currentState;\n this.currentState = newState;\n\n if (!this.serverId) return;\n\n this._onConnectionEvent.fire({\n type: 'state_changed',\n sessionId: this.sessionId,\n serverId: this.serverId,\n serverName: this.serverName || this.serverId,\n serverUrl: this.serverUrl || '',\n createdAt: this.createdAt,\n state: newState,\n previousState,\n timestamp: Date.now(),\n });\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:state_change',\n level: 'info',\n message: `Connection state: ${previousState} → ${newState}`,\n displayMessage: `State changed to ${newState}`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n payload: { previousState, newState },\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n /**\n * Emit an error event\n * @private\n */\n private emitError(error: string, errorType: 'connection' | 'auth' | 'validation' | 'unknown' = 'unknown'): void {\n if (!this.serverId) return;\n\n this._onConnectionEvent.fire({\n type: 'error',\n sessionId: this.sessionId,\n serverId: this.serverId,\n error,\n errorType,\n timestamp: Date.now(),\n });\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:error',\n level: 'error',\n message: error,\n displayMessage: error,\n sessionId: this.sessionId,\n serverId: this.serverId,\n payload: { errorType, error },\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n /**\n * Emit a progress event\n * @private\n */\n private emitProgress(message: string): void {\n if (!this.serverId) return;\n\n this._onConnectionEvent.fire({\n type: 'progress',\n sessionId: this.sessionId,\n serverId: this.serverId,\n message,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Get current connection state\n */\n getConnectionState(): McpConnectionState {\n return this.currentState;\n }\n\n /**\n * Helper to create a transport instance\n * @param type - The transport type to create\n * @returns Configured transport instance\n * @private\n */\n private getTransport(type: TransportType): StreamableHTTPClientTransport | SSEClientTransport {\n if (!this.serverUrl) {\n throw new Error('Server URL is required to create transport');\n }\n\n const baseUrl = new URL(this.serverUrl);\n const hasAuthorizationHeader = Object.keys(this.headers || {})\n .some((key) => key.toLowerCase() === 'authorization');\n const transportOptions = {\n ...(!hasAuthorizationHeader && { authProvider: this.oauthProvider! }),\n ...(this.headers && { requestInit: { headers: this.headers } }),\n /**\n * Custom fetch implementation to handle connection timeouts.\n * Observation: SDK 1.24.0+ connections may hang indefinitely in some environments.\n * This wrapper enforces a timeout and properly uses AbortController to unblock the request.\n */\n fetch: async (url: RequestInfo | URL, init?: RequestInit) => {\n const timeout = 30000;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n const signal = init?.signal ?\n // @ts-ignore: AbortSignal.any is available in Node 20+\n (AbortSignal.any ? AbortSignal.any([init.signal, controller.signal]) : controller.signal) :\n controller.signal;\n\n try {\n const response = await fetch(url, { ...init, signal });\n \n const hasSessionHeader = init?.headers && new Headers(init.headers as HeadersInit).has('mcp-session-id');\n\n if (response.status === 404 && hasSessionHeader) {\n throw new Error(\"MCP_SESSION_EXPIRED: Downstream session was not found on the server.\");\n }\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n };\n\n if (type === 'sse') {\n return new SSEClientTransport(baseUrl, transportOptions);\n } else {\n return new StreamableHTTPClientTransport(baseUrl, transportOptions);\n }\n }\n\n /**\n * Ensures session metadata and OAuth provider are loaded.\n * Does NOT create the SDK Client — callers that need one create it themselves.\n * @private\n */\n private async ensureSession(): Promise<void> {\n if (this.oauthProvider) {\n return;\n }\n\n this.emitStateChange('INITIALIZING');\n this.emitProgress('Loading session configuration...');\n\n let existingSession: Session | null = null;\n\n if (!this.serverUrl || !this.callbackUrl || !this.serverId) {\n existingSession = await sessions.get(this.userId, this.sessionId);\n if (!existingSession) {\n throw new Error(`Session not found: ${this.sessionId}`);\n }\n\n this.serverUrl = this.serverUrl || existingSession.serverUrl;\n this.callbackUrl = this.callbackUrl || existingSession.callbackUrl;\n /**\n * Do NOT load transportType from session if not explicitly provided.\n * We want to re-negotiate (try streamable -> sse) on new connections if in \"Auto\" mode.\n * this.transportType = this.transportType || sessionData.transportType; \n */\n this.serverName = this.serverName || existingSession.serverName;\n this.serverId = this.serverId || existingSession.serverId || 'unknown';\n this.headers = this.headers || existingSession.headers;\n this.createdAt = existingSession.createdAt;\n }\n\n if (!this.serverUrl || !this.callbackUrl || !this.serverId) {\n throw new Error('Missing required connection metadata');\n }\n\n if (!this.oauthProvider) {\n if (!this.serverId) {\n throw new Error('serverId required for OAuth provider initialization');\n }\n this.oauthProvider = new StorageOAuthClientProvider({\n userId: this.userId,\n serverId: this.serverId,\n sessionId: this.sessionId,\n redirectUrl: this.callbackUrl!,\n clientName: this.clientName,\n clientUri: this.clientUri,\n logoUri: this.logoUri,\n policyUri: this.policyUri,\n clientId: this.clientId,\n clientSecret: this.clientSecret,\n onRedirect: (redirectUrl: string) => {\n if (this.onRedirect) {\n this.onRedirect(redirectUrl);\n }\n }\n });\n }\n\n // Create session in the session store if it doesn't exist yet\n // This is needed BEFORE OAuth flow starts because the OAuth provider\n // will call saveCodeVerifier() which requires the session to exist\n if (existingSession === null) {\n existingSession = await sessions.get(this.userId, this.sessionId);\n }\n if (!existingSession && this.serverId && this.serverUrl && this.callbackUrl) {\n this.createdAt = Date.now();\n const updatedAt = this.createdAt;\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_created',\n level: 'info',\n message: `Creating pending session ${this.sessionId} for connection setup`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await sessions.create({\n sessionId: this.sessionId,\n userId: this.userId,\n serverId: this.serverId,\n serverName: this.serverName,\n serverUrl: this.serverUrl,\n callbackUrl: this.callbackUrl,\n transportType: this.transportType || 'streamable-http',\n headers: this.headers,\n createdAt: this.createdAt,\n updatedAt,\n status: 'pending',\n });\n }\n }\n\n\n\n /**\n * Saves current session state to the session store\n * Creates new session if it doesn't exist, updates if it does\n * @param status - Session lifecycle status used by storage cleanup\n * @private\n */\n private async saveSession(\n status: SessionStatus = 'active',\n existingSession?: Session | null\n ): Promise<void> {\n if (!this.sessionId || !this.serverId || !this.serverUrl || !this.callbackUrl) {\n return;\n }\n\n const sessionData = {\n sessionId: this.sessionId,\n userId: this.userId,\n serverId: this.serverId,\n serverName: this.serverName,\n serverUrl: this.serverUrl,\n callbackUrl: this.callbackUrl,\n transportType: (this.transportType || 'streamable-http') as TransportType,\n headers: this.headers,\n createdAt: this.createdAt || Date.now(),\n updatedAt: Date.now(),\n status,\n };\n if (status === 'active') {\n (sessionData as typeof sessionData & { authUrl: null }).authUrl = null;\n }\n\n // Try to update first, create if doesn't exist\n if (existingSession === undefined) {\n existingSession = await sessions.get(this.userId, this.sessionId);\n }\n if (existingSession) {\n await sessions.update(this.userId, this.sessionId, sessionData);\n } else {\n await sessions.create(sessionData);\n }\n }\n\n /**\n * Removes transient setup/auth sessions without masking the original error.\n * @private\n */\n private async deleteTransientSession(): Promise<void> {\n try {\n await sessions.delete(this.userId, this.sessionId);\n } catch {\n // Best effort only: preserve the original connection/auth error.\n }\n }\n\n /**\n * Try to connect using available transports\n * @returns The corrected transport type object if successful\n * @private\n */\n private async tryConnect(): Promise<{ transportType: TransportType }> {\n /**\n * If exact transport type is known, only try that.\n * Otherwise (auto mode), try streamable_http first, then sse.\n */\n const transportsToTry: TransportType[] = this.transportType\n ? [this.transportType]\n : ['streamable-http', 'sse'];\n\n let lastError: unknown;\n\n for (const currentType of transportsToTry) {\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\n\n try {\n const transport = this.getTransport(currentType);\n\n /** Update local state with the transport we are about to try */\n this.transport = transport;\n\n /** Race connection against timeout */\n await this.client!.connect(transport);\n\n /** Success! Return the type that worked */\n return { transportType: currentType };\n\n } catch (error: any) {\n lastError = error;\n\n /** Check for Auth Errors - these should fail immediately, no fallback */\n const isAuthError = error instanceof SDKUnauthorizedError ||\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\n\n if (isAuthError) {\n throw error;\n }\n\n /** If this was the last transport to try, throw the error */\n if (isLastAttempt) {\n throw error;\n }\n\n /** Otherwise, log and continue to next transport */\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.emitProgress(`Connection attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\n this._onObservabilityEvent.fire({\n level: 'warn',\n message: `Transport ${currentType} failed, falling back`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n metadata: {\n failedTransport: currentType,\n error: errorMessage\n },\n timestamp: Date.now(),\n });\n }\n }\n\n throw lastError || new Error('No transports available');\n }\n\n /**\n * Connects to the MCP server.\n *\n * Automatically validates and refreshes OAuth tokens if needed.\n * Saves the session to Redis on first successful connection.\n *\n * The in-memory tools cache (`cachedTools`) is cleared at the start of every\n * call so that a reconnection always fetches a fresh tool list from the remote\n * server — even if the same `MCPClient` instance is reused.\n *\n * @throws {UnauthorizedError} When OAuth authorization is required.\n * @throws {Error} When connection fails for other reasons.\n */\n async connect(): Promise<void> {\n this.cachedTools = null;\n // Close any existing transport so we can negotiate a fresh session.\n // The SDK Client throws if asked to connect() while a transport is\n // already attached; close() detaches it cleanly so the same Client\n // instance can be reused.\n if (this.client.transport) {\n this.transport = null;\n try { await this.client.close(); } catch {\n // Closing a transport that may have already failed is best-effort.\n }\n }\n\n await this.ensureSession();\n\n if (!this.oauthProvider) {\n const error = 'OAuth provider not initialized';\n this.emitError(error, 'connection');\n this.emitStateChange('FAILED');\n throw new Error(error);\n }\n\n try {\n this.emitStateChange('CONNECTING');\n\n /** Use the tryConnect loop to handle transport fallbacks */\n const { transportType } = await this.tryConnect();\n\n /** Update transport type to the one that actually worked */\n this.transportType = transportType;\n\n this.emitStateChange('CONNECTED');\n this.emitProgress('Connected successfully');\n\n // Refresh session metadata on every successful connect so active sessions\n // record ongoing usage and don't look dormant to session cleanup jobs.\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_saved',\n level: 'info',\n message: `Saving active session ${this.sessionId} (connect success)`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await this.saveSession('active');\n } catch (error) {\n /** Handle Authentication Errors */\n if (\n error instanceof SDKUnauthorizedError ||\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'))\n ) {\n /** Set when the SDK calls redirectToAuthorization on the OAuth provider */\n let authUrl = '';\n if (this.oauthProvider) {\n authUrl = (this.oauthProvider.authUrl || '').trim();\n }\n\n /**\n * 401 without a usable URL means metadata/DCR failed or the server never started\n * an interactive OAuth flow — not recoverable as \"pending OAuth\".\n */\n if (!authUrl) {\n const detail =\n error instanceof Error && error.message.trim().length > 0\n ? error.message.trim()\n : 'Unauthorized';\n const message =\n detail.toLowerCase() === 'unauthorized'\n ? 'OAuth authorization URL not available'\n : `OAuth authorization URL not available: ${detail}`;\n this.emitError(message, 'auth');\n this.emitStateChange('FAILED');\n \n // Remove terminal setup failures immediately. Active sessions are not\n // deleted here because this branch only runs before OAuth is available.\n await this.deleteTransientSession();\n \n throw new Error(message);\n }\n\n this.emitStateChange('AUTHENTICATING');\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_saved',\n level: 'info',\n message: `Saving pending OAuth session ${this.sessionId}`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await this.saveSession('pending');\n\n if (this.serverId) {\n this._onConnectionEvent.fire({\n type: 'auth_required',\n sessionId: this.sessionId,\n serverId: this.serverId,\n authUrl,\n timestamp: Date.now(),\n });\n\n if (authUrl && this.onRedirect) {\n this.onRedirect(authUrl);\n }\n }\n\n throw new UnauthorizedError('OAuth authorization required');\n }\n\n /** Handle Generic Errors */\n const errorMessage = error instanceof Error ? error.message : 'Connection failed';\n this.emitError(errorMessage, 'connection');\n this.emitStateChange('FAILED');\n\n // Remove transient sessions that failed before becoming restorable.\n // Existing active sessions may still hold usable credentials for reconnect.\n try {\n const existingSession = await sessions.get(this.userId, this.sessionId);\n if (!existingSession || existingSession.status !== 'active') {\n await sessions.delete(this.userId, this.sessionId);\n }\n } catch {\n // Best effort only: preserve the original connection error.\n }\n\n throw error;\n }\n }\n\n /**\n * Completes OAuth authorization flow by exchanging authorization code for tokens\n * Creates new authenticated client and transport, then establishes connection\n * Saves active session to Redis after successful authentication\n * @param authCode - Authorization code received from OAuth callback\n */\n\n // TODO: needs to be optimized\n async finishAuth(authCode: string, state?: string): Promise<void> {\n this.emitStateChange('AUTHENTICATING');\n this.emitProgress('Exchanging authorization code for tokens...');\n\n await this.ensureSession();\n\n if (!this.oauthProvider) {\n const error = 'OAuth provider not initialized';\n this.emitError(error, 'auth');\n this.emitStateChange('FAILED');\n throw new Error(error);\n }\n\n if (state) {\n const stateCheck = await this.oauthProvider.checkState(state);\n if (!stateCheck.valid) {\n const error = stateCheck.error || 'Invalid OAuth state';\n this.emitError(error, 'auth');\n this.emitStateChange('FAILED');\n throw new Error(error);\n }\n\n await this.oauthProvider.consumeState(state);\n }\n\n /**\n * Determine which transports to try for finishing auth\n * If transportType is set, use only that. Otherwise try streamable_http then sse.\n */\n const transportsToTry: TransportType[] = this.transportType\n ? [this.transportType]\n : ['streamable-http', 'sse'];\n\n let lastError: unknown;\n let tokensExchanged = false;\n let authenticatedStateEmitted = false;\n\n for (const currentType of transportsToTry) {\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\n\n try {\n const transport = this.getTransport(currentType);\n\n /** Update local state with the transport we are about to try */\n this.transport = transport;\n\n if (!tokensExchanged) {\n await transport.finishAuth(authCode);\n tokensExchanged = true;\n } else {\n this.emitProgress(`Tokens already exchanged, skipping auth step for ${currentType}...`);\n }\n\n if (!authenticatedStateEmitted) {\n this.emitStateChange('AUTHENTICATED');\n authenticatedStateEmitted = true;\n }\n\n this.emitStateChange('CONNECTING');\n\n // The SDK Client may still have a transport attached from a prior\n // connect() that failed with UnauthorizedError; close it first so\n // we can negotiate a fresh session with the newly-exchanged tokens.\n if (this.client.transport) {\n try { await this.client.close(); } catch {}\n }\n\n await this.client.connect(this.transport);\n\n /** Connection succeeded — lock in the transport type */\n this.transportType = currentType;\n\n this.emitStateChange('CONNECTED');\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_saved',\n level: 'info',\n message: `Saving active session ${this.sessionId} (OAuth complete)`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await this.saveSession('active');\n\n return; // Success, exit function\n\n } catch (error) {\n lastError = error;\n\n const isAuthError = error instanceof SDKUnauthorizedError ||\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\n\n if (isAuthError) {\n throw error;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Don't retry if the authorization code was rejected (it's one-time use)\n if (!tokensExchanged && errorMessage.toLowerCase().includes('invalid authorization code')) {\n const msg = error instanceof Error ? error.message : 'Authentication failed';\n this.emitError(msg, 'auth');\n this.emitStateChange('FAILED');\n await this.deleteTransientSession();\n throw error;\n }\n\n if (isLastAttempt) {\n const msg = error instanceof Error ? error.message : 'Authentication failed';\n this.emitError(msg, 'auth');\n this.emitStateChange('FAILED');\n await this.deleteTransientSession();\n throw error;\n }\n\n // Log and retry\n this.emitProgress(`Auth attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\n }\n }\n\n if (lastError) {\n const errorMessage = lastError instanceof Error ? lastError.message : 'Authentication failed';\n this.emitError(errorMessage, 'auth');\n this.emitStateChange('FAILED');\n await this.deleteTransientSession();\n throw lastError;\n }\n }\n\n /**\n * In-memory cache for the remote server's full tools list.\n *\n * Populated on the first `fetchTools()` call and reused for the lifetime of\n * the connection. Cleared to `null` at the start of `connect()` so that a\n * reconnect always retrieves a fresh list, and also in `dispose()` to release\n * the memory when the client is no longer needed.\n */\n private cachedTools: ListToolsResult | null = null;\n\n /**\n * Lists all available tools from the connected MCP server without emitting\n * discovery events. The result is cached in memory for the lifetime of the\n * connection — subsequent callers (e.g. `gateway.listTools()` running right\n * after `fetchTools()`) pay zero extra network cost.\n *\n * Gateways use this to apply a tool-access policy before publishing the\n * filtered list to agents or UI state.\n *\n * @returns The full `ListToolsResult` from the remote server.\n * @throws {Error} When the client is not connected or the request times out.\n */\n async fetchTools(): Promise<ListToolsResult> {\n if (this.cachedTools) {\n return this.cachedTools;\n }\n const request: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const result = await this.withRetry(() =>\n this.client!.request(request, ListToolsResultSchema)\n );\n this.cachedTools = result;\n return result;\n }\n\n /**\n * Lists all available tools from the connected MCP server\n * @returns List of tools with their schemas and descriptions\n * @throws {Error} When client is not connected\n */\n async listTools(): Promise<ListToolsResult> {\n this.emitStateChange('DISCOVERING');\n\n try {\n const result = await this.fetchTools();\n\n if (this.serverId) {\n this._onConnectionEvent.fire({\n type: 'tools_discovered',\n sessionId: this.sessionId,\n serverId: this.serverId,\n toolCount: result.tools.length,\n tools: result.tools,\n timestamp: Date.now(),\n });\n }\n\n this.emitStateChange('READY');\n this.emitProgress(`Discovered ${result.tools.length} tools`);\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to list tools';\n this.emitError(errorMessage, 'validation');\n this.emitStateChange('FAILED');\n throw error;\n }\n }\n /**\n * Executes a tool on the connected MCP server\n * @param toolName - Name of the tool to execute\n * @param toolArgs - Arguments to pass to the tool\n * @returns Tool execution result\n * @throws {Error} When client is not connected\n */\n async callTool(toolName: string, toolArgs: Record<string, unknown>): Promise<CallToolResult> {\n const request: CallToolRequest = {\n method: 'tools/call',\n params: {\n name: toolName,\n arguments: toolArgs,\n },\n };\n\n try {\n const result = await this.withRetry(() =>\n this.client!.request(request, CallToolResultSchema)\n );\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:tool_call',\n level: 'info',\n message: `Tool ${toolName} called successfully`,\n displayMessage: `Called tool ${toolName}`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n payload: {\n toolName,\n args: toolArgs,\n },\n timestamp: Date.now(),\n id: nanoid(),\n });\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : `Failed to call tool ${toolName}`;\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:error',\n level: 'error',\n message: errorMessage,\n displayMessage: `Failed to call tool ${toolName}`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n payload: {\n errorType: 'tool_execution',\n error: errorMessage,\n toolName,\n args: toolArgs,\n },\n timestamp: Date.now(),\n id: nanoid(),\n });\n\n throw error;\n }\n }\n\n /**\n * Lists all available prompts from the connected MCP server\n * @returns List of available prompts\n * @throws {Error} When client is not connected\n */\n async listPrompts(): Promise<ListPromptsResult> {\n this.emitStateChange('DISCOVERING');\n\n try {\n const request: ListPromptsRequest = {\n method: 'prompts/list',\n params: {},\n };\n\n const result = await this.withRetry(() =>\n this.client!.request(request, ListPromptsResultSchema)\n );\n\n this.emitStateChange('READY');\n this.emitProgress(`Discovered ${result.prompts.length} prompts`);\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to list prompts';\n this.emitError(errorMessage, 'validation');\n this.emitStateChange('FAILED');\n throw error;\n }\n }\n\n /**\n * Gets a specific prompt with arguments\n * @param name - Name of the prompt\n * @param args - Arguments for the prompt\n * @returns Prompt content\n * @throws {Error} When client is not connected\n */\n async getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult> {\n\n const request: GetPromptRequest = {\n method: 'prompts/get',\n params: {\n name,\n arguments: args,\n },\n };\n\n return await this.withRetry(() =>\n this.client!.request(request, GetPromptResultSchema)\n );\n }\n\n /**\n * Lists all available resources from the connected MCP server\n * @returns List of available resources\n * @throws {Error} When client is not connected\n */\n async listResources(): Promise<ListResourcesResult> {\n this.emitStateChange('DISCOVERING');\n\n try {\n const request: ListResourcesRequest = {\n method: 'resources/list',\n params: {},\n };\n\n const result = await this.withRetry(() =>\n this.client!.request(request, ListResourcesResultSchema)\n );\n\n this.emitStateChange('READY');\n this.emitProgress(`Discovered ${result.resources.length} resources`);\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to list resources';\n this.emitError(errorMessage, 'validation');\n this.emitStateChange('FAILED');\n throw error;\n }\n }\n\n /**\n * Reads a specific resource\n * @param uri - URI of the resource to read\n * @returns Resource content\n * @throws {Error} When client is not connected\n */\n async readResource(uri: string): Promise<ReadResourceResult> {\n\n const request: ReadResourceRequest = {\n method: 'resources/read',\n params: {\n uri,\n },\n };\n\n return await this.withRetry(() =>\n this.client!.request(request, ReadResourceResultSchema)\n );\n }\n\n /**\n * Wraps an MCP request with automatic transport-session recovery.\n *\n * When the downstream MCP server rejects the request with a 404 indicating\n * the transport session has expired, this method tears down the stale SDK\n * client and transport, calls {@link reconnect} to negotiate a fresh session,\n * and retries the request once.\n *\n * Non-transient errors (network failures, auth errors, etc.) propagate as-is.\n */\n private async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n if (!(error instanceof Error && error.message.includes('MCP_SESSION_EXPIRED'))) throw error;\n if (this.client.transport) {\n try { await this.client.close(); } catch {}\n this.transport = null;\n }\n await this.reconnect();\n return await fn();\n }\n }\n\n /**\n * Reconnects to MCP server using existing OAuth provider from Redis\n * Used for session restoration in serverless environments\n * Creates new client and transport without re-initializing OAuth provider\n * @throws {Error} When OAuth provider is not initialized\n */\n async reconnect(): Promise<void> {\n await this.ensureSession();\n if (!this.oauthProvider) throw new Error('OAuth provider not initialized');\n await this.connect();\n }\n\n /**\n * Completely removes the session from Redis including all OAuth data\n * Invalidates credentials and disconnects the client\n */\n async clearSession(): Promise<void> {\n try {\n await this.ensureSession();\n } catch (error) {\n this._onObservabilityEvent.fire({\n type: 'mcp:client:error',\n level: 'warn',\n message: 'Initialization failed during clearSession',\n sessionId: this.sessionId,\n serverId: this.serverId,\n payload: { error: String(error) },\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n if (this.oauthProvider) {\n await (this.oauthProvider as any).invalidateCredentials('all');\n }\n\n await sessions.delete(this.userId, this.sessionId);\n await this.disconnect();\n }\n\n /**\n * Checks if the client is currently connected to an MCP server\n * @returns True if connected, false otherwise\n */\n isConnected(): boolean {\n return this.client.transport !== undefined;\n }\n\n /**\n * Disconnects from the MCP server and cleans up resources.\n * Does not remove session from Redis — use clearSession() for that.\n *\n * For Streamable HTTP sessions, sends an HTTP DELETE to the MCP endpoint\n * before closing, as recommended by the MCP Streamable HTTP spec\n * (section \"Session Management\", rule 5). This is best-effort — errors\n * (e.g. server already restarted, 404/405 responses) are silently ignored.\n */\n async disconnect(): Promise<void> {\n // Per the MCP Streamable HTTP spec (2025-11-25), clients SHOULD send an\n // HTTP DELETE with the mcp-session-id header when they no longer need a\n // session. The server MAY respond with 405 if it doesn't support explicit\n // termination — terminateSession() handles that gracefully.\n // SSEClientTransport has no session concept, so we guard with instanceof.\n if (this.transport instanceof StreamableHTTPClientTransport) {\n try {\n await this.transport.terminateSession();\n } catch {\n // Best-effort: server may be unreachable or may have already expired\n // the session. Either way, we proceed with local cleanup.\n }\n }\n\n if (this.client.transport) {\n try { await this.client.close(); } catch {}\n }\n this.oauthProvider = null;\n this.transport = null;\n\n // Emit disconnected event\n if (this.serverId) {\n this._onConnectionEvent.fire({\n type: 'disconnected',\n sessionId: this.sessionId,\n serverId: this.serverId,\n timestamp: Date.now(),\n });\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:disconnect',\n level: 'info',\n message: `Disconnected from ${this.serverId}`,\n sessionId: this.sessionId,\n serverId: this.serverId,\n payload: {},\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n this.emitStateChange('DISCONNECTED');\n }\n\n /**\n * Disposes all event emitters and releases cached state.\n *\n * Clears `cachedTools` to free memory, and disposes the connection and\n * observability event emitters so downstream listeners are unsubscribed.\n * Call this when the client is permanently shut down (not just disconnected).\n */\n dispose(): void {\n this.cachedTools = null;\n this._onConnectionEvent.dispose();\n this._onObservabilityEvent.dispose();\n }\n\n /**\n * Gets the server URL\n * @returns Server URL or empty string if not set\n */\n getServerUrl(): string {\n return this.serverUrl || '';\n }\n\n /**\n * Gets the OAuth callback URL\n * @returns Callback URL or empty string if not set\n */\n getCallbackUrl(): string {\n return this.callbackUrl || '';\n }\n\n /**\n * Gets the transport type being used\n * @returns Transport type (defaults to 'streamable-http')\n */\n getTransportType(): TransportType {\n return this.transportType || 'streamable-http';\n }\n\n /**\n * Gets the human-readable server name\n * @returns Server name or undefined\n */\n getServerName(): string | undefined {\n // Temporarily avoid deriving serverName from serverVersion metadata.\n // const info = (this.client as any)?.getServerVersion();\n // return info?.title ?? info?.name ?? this.serverName;\n return this.serverName;\n }\n\n /**\n * Gets the server ID\n * @returns Server ID or undefined\n */\n getServerId(): string | undefined {\n return this.serverId;\n }\n\n /**\n * Gets the session ID\n * @returns Session ID\n */\n getSessionId(): string {\n return this.sessionId;\n }\n}\n","import type { Tool, ListToolsResult, CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolClient } from '../../shared/types.js';\nimport { sessions } from '../storage/index.js';\nimport type { Session } from '../storage/types.js';\nimport { assertToolAllowed, filterToolsByPolicy } from '../storage/tool-policy.js';\n\n/**\n * Internal shape expected from the underlying MCP client.\n * Extends `ToolClient` with the raw `fetchTools` / `listTools` / `callTool`\n * methods so the gateway can fetch unfiltered results and apply policy on top.\n */\ntype RawToolClient = ToolClient & {\n fetchTools(): Promise<{ tools: Tool[] }>;\n listTools(): Promise<{ tools: Tool[] }>;\n callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult>;\n};\n\n/**\n * A thin policy-enforcement layer that wraps a raw `MCPClient`.\n *\n * Every public method on this class loads the current session's `toolPolicy`\n * from the session store and uses it to filter or guard tool access before\n * delegating to the underlying client.\n *\n * This keeps security logic in one place and prevents agents from calling\n * tools that a user has explicitly blocked via the management UI.\n */\nexport class ToolPolicyGateway implements ToolClient {\n constructor(\n private readonly userId: string,\n private readonly sessionId: string,\n private readonly client: RawToolClient\n ) {}\n\n /**\n * Returns whether the underlying MCP client transport is currently connected.\n */\n isConnected(): boolean {\n return this.client.isConnected();\n }\n\n /**\n * Returns the server ID from the underlying client, if available.\n */\n getServerId(): string | undefined {\n return this.client.getServerId?.();\n }\n\n /**\n * Returns the human-readable server name from the underlying client, if available.\n */\n getServerName(): string | undefined {\n return this.client.getServerName?.();\n }\n\n /**\n * Returns the server URL from the underlying client, if available.\n */\n getServerUrl(): string | undefined {\n return this.client.getServerUrl?.();\n }\n\n /**\n * Returns the session ID — prefers the value reported by the underlying\n * client, falling back to the one injected at construction time.\n */\n getSessionId(): string {\n return this.client.getSessionId?.() ?? this.sessionId;\n }\n\n /**\n * Returns the **policy-filtered** list of tools that the current session\n * is allowed to call.\n *\n * Internally calls `client.fetchTools()` (which is cache-backed) so no\n * extra network round-trip is incurred when called after `fetchTools()`.\n *\n * @returns A `ListToolsResult` containing only the permitted tools.\n * @throws {Error} When the session does not exist in the store.\n */\n async listTools(): Promise<ListToolsResult> {\n const session = await this.getSession();\n const result = await this.client.fetchTools();\n const tools = this.filterTools(session, result.tools);\n\n return {\n ...result,\n tools,\n } as ListToolsResult;\n }\n\n /**\n * Returns the **complete, unfiltered** list of tools from the remote server,\n * bypassing any tool-access policy.\n *\n * Used by the management UI to show all available tools (including blocked\n * ones) so users can toggle individual tool access in the dialog.\n *\n * @returns The raw `ListToolsResult` from the remote server.\n */\n async listAllTools(): Promise<ListToolsResult> {\n return await this.client.fetchTools() as ListToolsResult;\n }\n\n /**\n * Executes a tool call on the remote server after verifying that the tool\n * is permitted by the current session's policy.\n *\n * @param name - The exact tool name to invoke.\n * @param args - Key/value arguments to pass to the tool.\n * @returns The tool's `CallToolResult`.\n * @throws {Error} When the tool is blocked by the session's policy.\n * @throws {Error} When the session does not exist in the store.\n */\n async callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult> {\n const session = await this.getSession();\n this.assertAllowed(session, name);\n return await this.client.callTool(name, args);\n }\n\n /**\n * Filters a raw tools array down to only those permitted by the session's\n * `toolPolicy`.\n *\n * @param session - The session whose policy should be applied.\n * @param tools - The unfiltered list of tools from the remote server.\n * @returns A subset of `tools` that the policy allows.\n */\n filterTools(session: Session, tools: Tool[]): Tool[] {\n return filterToolsByPolicy(tools, session.toolPolicy, this.getPolicyServerId(session));\n }\n\n /**\n * Throws if `toolName` is blocked by the session's policy.\n * Call this before proxying a `callTool` request to the remote server.\n *\n * @param session - The session whose policy should be enforced.\n * @param toolName - The tool being invoked.\n * @throws {Error} When the tool is not permitted.\n */\n assertAllowed(session: Session, toolName: string): void {\n assertToolAllowed(session.toolPolicy, toolName, this.getPolicyServerId(session));\n }\n\n /**\n * Loads the session from the store and throws if it does not exist.\n *\n * @returns The fully-hydrated `Session` record.\n * @throws {Error} When the session cannot be found.\n */\n private async getSession(): Promise<Session> {\n const session = await sessions.get(this.userId, this.sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n return session;\n }\n\n /**\n * Resolves the server ID to use when evaluating tool policy.\n * Prefers the value from the live client (most accurate) and falls back\n * to the server ID stored on the session record.\n */\n private getPolicyServerId(session: Session): string | undefined {\n return this.client.getServerId?.() ?? session.serverId;\n }\n}\n\n/**\n * Factory function that creates a `ToolPolicyGateway` for a specific session.\n *\n * Prefer this over constructing `ToolPolicyGateway` directly — it keeps call\n * sites concise and makes it easier to swap the implementation in tests.\n *\n * @param userId - The owner of the session (used for storage lookups).\n * @param sessionId - The session to enforce policy for.\n * @param client - The raw MCP client that the gateway wraps.\n * @returns A fully configured `ToolPolicyGateway` instance.\n */\nexport function createToolPolicyGateway(\n userId: string,\n sessionId: string,\n client: RawToolClient\n): ToolPolicyGateway {\n return new ToolPolicyGateway(userId, sessionId, client);\n}\n","import { MCPClient } from './oauth-client.js';\nimport { sessions, type Session } from '../storage/index.js';\nimport type { ToolClient, ToolClientProvider } from '../../shared/types.js';\nimport { createToolPolicyGateway } from './tool-policy-gateway.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TIMEOUT_MS = 15000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_RETRY_DELAY_MS = 1000;\nconst CONNECTION_BATCH_SIZE = 5;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MultiSessionOptions {\n /**\n * Connection timeout in milliseconds.\n * @default 15000\n */\n timeout?: number;\n\n /**\n * Maximum number of retry attempts per session.\n * @default 2\n */\n maxRetries?: number;\n\n /**\n * Delay between retry attempts in milliseconds.\n * @default 1000\n */\n retryDelay?: number;\n\n /**\n * Custom session provider. When provided, `connect()` calls this\n * instead of querying the storage backend. Useful when sessions are\n * synced externally (e.g. via Supabase Realtime, WebSocket, or an\n * in-memory cache).\n *\n * Default: reads from the storage backend via `sessions.list(userId)`.\n */\n sessionProvider?: () => Promise<Session[]>;\n\n /**\n * Called after a session is successfully connected.\n */\n onSessionConnected?: (sessionId: string, client: MCPClient) => void;\n\n /**\n * Called when a session is evicted from the in-memory client list\n * because it no longer exists in the active sessions list.\n */\n onSessionEvicted?: (sessionId: string) => void;\n\n /**\n * Called when all retry attempts for a session have been exhausted.\n */\n onSessionFailed?: (sessionId: string, error: unknown) => void;\n}\n\n// ---------------------------------------------------------------------------\n// MultiSessionClient\n// ---------------------------------------------------------------------------\n\n/**\n * Manages multiple MCP client connections for a single user.\n *\n * Cached instances stay alive between requests on long-running servers.\n * On serverless, the underlying session data persists in storage — the\n * client rehydrates from `sessionProvider` (or the default storage backend)\n * each time `connect()` is called.\n *\n * @implements {ToolClientProvider}\n */\nexport class MultiSessionClient implements ToolClientProvider {\n private clients: MCPClient[] = [];\n private connectionPromises = new Map<string, Promise<void>>();\n private userId: string;\n private options: Required<Pick<MultiSessionOptions, 'timeout' | 'maxRetries' | 'retryDelay'>> &\n Pick<MultiSessionOptions, 'sessionProvider' | 'onSessionConnected' | 'onSessionEvicted' | 'onSessionFailed'>;\n\n /**\n * @param userId - Unique identifier for the user (e.g. user ID or email).\n * @param options - Optional tuning and lifecycle hooks.\n */\n constructor(userId: string, options: MultiSessionOptions = {}) {\n this.userId = userId;\n this.options = {\n timeout: DEFAULT_TIMEOUT_MS,\n maxRetries: DEFAULT_MAX_RETRIES,\n retryDelay: DEFAULT_RETRY_DELAY_MS,\n ...options,\n };\n }\n\n // -----------------------------------------------------------------------\n // Public API\n // -----------------------------------------------------------------------\n\n /**\n * Fetches active sessions and establishes connections to all of them.\n *\n * Call this once after creating the client. On long-running servers you\n * can cache the `MultiSessionClient` instance and call `connect()` on\n * each request — already-connected sessions are skipped internally.\n */\n async connect(): Promise<void> {\n const sessions = await this.fetchActiveSessions();\n const activeSessionIds = new Set(sessions.map(s => s.sessionId));\n\n // Evict clients whose sessions no longer appear in the active list.\n // Without this, a stale MCPClient with a live SDK transport would\n // stay in the clients array after its session was deleted externally\n // (e.g. via the SSE handler's clearSession()), causing OAuth refreshes\n // to fail with a FK violation when they try to patchCredentials()\n // against the now-deleted session.\n for (const client of this.clients) {\n if (!activeSessionIds.has(client.getSessionId())) {\n this.options.onSessionEvicted?.(client.getSessionId());\n }\n }\n this.clients = this.clients.filter(c => activeSessionIds.has(c.getSessionId()));\n\n await this.connectInBatches(sessions);\n }\n\n /**\n * Drops all cached `MCPClient` instances and reconnects fresh from storage.\n *\n * Call this when downstream MCP servers have expired their transport sessions\n * (e.g. after a remote server restart) and subsequent tool calls return\n * \"Session not found. Reconnect without session header.\" errors.\n *\n * OAuth tokens are preserved in the storage backend — no re-authentication\n * is required. Only the in-memory transport sessions are cleared.\n */\n async reconnect(): Promise<void> {\n await this.disconnect();\n await this.connect();\n }\n\n /**\n * Returns all currently connected `MCPClient` instances.\n *\n * Use this to enumerate available tools across all connected servers,\n * or to route a tool call to the right client by `serverId`.\n */\n getClients(): ToolClient[] {\n return this.clients.map((client) =>\n createToolPolicyGateway(this.userId, client.getSessionId(), client)\n );\n }\n\n /**\n * Removes and disconnects a single session by ID.\n *\n * @returns `true` if the session was found and removed, `false` if not found.\n */\n async removeSession(sessionId: string): Promise<boolean> {\n const idx = this.clients.findIndex(c => c.getSessionId() === sessionId);\n if (idx === -1) return false;\n const [client] = this.clients.splice(idx, 1);\n await client.disconnect();\n return true;\n }\n\n /**\n * Gracefully disconnects all active MCP clients and clears the internal list.\n *\n * For Streamable HTTP sessions, each client sends an HTTP DELETE to its MCP\n * endpoint per the spec before closing locally. All disconnects run in\n * parallel so shutdown is not serialised across many sessions.\n *\n * Call this during server shutdown or when a user logs out to free up\n * underlying transport resources (SSE streams, HTTP connections, etc.).\n */\n async disconnect(): Promise<void> {\n await Promise.all(this.clients.map((client) => client.disconnect()));\n this.clients = [];\n }\n\n // -----------------------------------------------------------------------\n // Internals\n // -----------------------------------------------------------------------\n\n /**\n * Resolves the list of sessions to connect.\n *\n * Uses the custom `sessionProvider` when provided, otherwise falls back\n * to querying the storage backend via `sessions.list(userId)`.\n */\n private async fetchActiveSessions(): Promise<Session[]> {\n const sessionList = this.options.sessionProvider\n ? await this.options.sessionProvider()\n : await sessions.list(this.userId);\n\n return sessionList.filter(s =>\n s.serverId &&\n s.serverUrl &&\n s.callbackUrl &&\n s.status === 'active'\n );\n }\n\n /**\n * Connects a list of sessions in controlled batches.\n *\n * Batching prevents overwhelming the event loop or external servers when\n * a user has many active MCP sessions. Within each batch, sessions are\n * connected concurrently using `Promise.all`.\n */\n private async connectInBatches(sessions: Session[]): Promise<void> {\n for (let i = 0; i < sessions.length; i += CONNECTION_BATCH_SIZE) {\n const batch = sessions.slice(i, i + CONNECTION_BATCH_SIZE);\n await Promise.all(batch.map(session => this.connectSession(session)));\n }\n }\n\n /**\n * Connects a single session, with deduplication to prevent race conditions.\n *\n * - If a client for this session already exists and is connected, returns\n * immediately.\n * - If the existing client entry is no longer connected (e.g. explicit\n * disconnect), it is evicted so a fresh transport is created.\n * - If a connection attempt for this session is already in-flight, the\n * existing promise is reused as a per-session mutex.\n * - On completion (success or failure), the promise is cleaned up from\n * the connectionPromises map.\n */\n private async connectSession(session: Session): Promise<void> {\n const existing = this.clients.find(c => c.getSessionId() === session.sessionId);\n\n if (existing) {\n if (existing.isConnected()) {\n return;\n }\n\n this.options.onSessionEvicted?.(existing.getSessionId());\n this.clients = this.clients.filter(c => c !== existing);\n }\n\n if (this.connectionPromises.has(session.sessionId)) {\n return this.connectionPromises.get(session.sessionId)!;\n }\n\n const connectPromise = this.establishConnectionWithRetries(session);\n\n this.connectionPromises.set(session.sessionId, connectPromise);\n\n try {\n await connectPromise;\n } finally {\n this.connectionPromises.delete(session.sessionId);\n }\n }\n\n /**\n * Core connection loop for a single session with retry logic.\n *\n * 1. Creates a fresh `MCPClient` from the session data.\n * 2. Races `client.connect()` against a timeout.\n * 3. On success, replaces any stale entry and fires `onSessionConnected`.\n * 4. On failure, waits `retryDelay` ms before the next attempt.\n *\n * If all attempts are exhausted, logs an error and returns silently so\n * a single bad server doesn't block the rest of the batch.\n */\n private async establishConnectionWithRetries(session: Session): Promise<void> {\n const maxRetries = this.options.maxRetries;\n const retryDelay = this.options.retryDelay;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const client = new MCPClient({\n userId: this.userId,\n sessionId: session.sessionId,\n serverId: session.serverId,\n serverUrl: session.serverUrl,\n callbackUrl: session.callbackUrl,\n serverName: session.serverName,\n transportType: session.transportType,\n headers: session.headers,\n });\n\n const timeoutMs = this.options.timeout;\n let timeoutTimer: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutTimer = setTimeout(\n () => reject(new Error(`Connection timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n });\n\n try {\n await Promise.race([client.connect(), timeoutPromise]);\n } finally {\n clearTimeout(timeoutTimer!);\n }\n\n this.clients = this.clients.filter(c => c.getSessionId() !== session.sessionId);\n this.clients.push(client);\n this.options.onSessionConnected?.(session.sessionId, client);\n return;\n\n } catch (error) {\n lastError = error;\n if (attempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, retryDelay));\n }\n }\n }\n\n this.options.onSessionFailed?.(session.sessionId, lastError);\n console.error(\n `[MultiSessionClient] Failed to connect to session ${session.sessionId} ` +\n `after ${maxRetries + 1} attempts:`,\n lastError,\n );\n }\n}\n\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","/**\n * SSE (Server-Sent Events) Handler for MCP Connections\n *\n * Manages real-time bidirectional communication with MCP clients:\n * - SSE stream for server → client events (connection state, tools, logs)\n * - HTTP POST for client → server RPC requests\n *\n * Key features:\n * - Direct HTTP response for RPC calls (bypasses SSE latency)\n * - Automatic session restoration and validation\n * - OAuth 2.1 authentication flow support\n * - Heartbeat to keep connections alive\n */\n\nimport type { McpConnectionEvent, McpObservabilityEvent } from '../../shared/events.js';\nimport type {\n McpRpcRequest,\n McpRpcResponse,\n ConnectParams,\n DisconnectParams,\n ReconnectParams,\n SessionParams,\n CallToolParams,\n GetPromptParams,\n ReadResourceParams,\n FinishAuthParams,\n SessionListResult,\n ConnectResult,\n DisconnectResult,\n GetSessionResult,\n FinishAuthResult,\n ListToolsRpcResult,\n ListPromptsResult,\n ListResourcesResult,\n CallToolResult,\n SetToolPolicyParams,\n SetToolPolicyResult,\n GetToolPolicyParams,\n GetToolPolicyResult,\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 { parseOAuthState } from '../../shared/utils.js';\nimport { MCPClient } from '../mcp/oauth-client.js';\nimport { sessions, generateServerId, type Session } from '../storage/index.js';\nimport { createToolId, isToolAllowed, normalizeToolPolicyForUpdate, validateToolPolicyAgainstTools } from '../storage/tool-policy.js';\nimport { createToolPolicyGateway } from '../mcp/tool-policy-gateway.js';\n\n// ============================================\n// Types & Interfaces\n// ============================================\n\nexport interface ClientMetadata {\n clientName?: string;\n clientUri?: string;\n logoUri?: string;\n policyUri?: string;\n}\n\nexport interface SSEHandlerOptions {\n /** User/Client identifier */\n userId: string;\n\n /** Optional callback for authentication/authorization */\n onAuth?: (userId: string) => Promise<boolean>;\n\n /** Heartbeat interval in milliseconds @default 30000 */\n heartbeatInterval?: number;\n\n /** Static OAuth client metadata defaults (for all connections) */\n clientDefaults?: ClientMetadata;\n\n /** Dynamic OAuth client metadata getter (per-request, useful for multi-tenant) */\n getClientMetadata?: (request?: unknown) => ClientMetadata | Promise<ClientMetadata>;\n}\n\n// ============================================\n// Constants\n// ============================================\n\nconst DEFAULT_HEARTBEAT_INTERVAL = 30000;\n\nfunction normalizeHeaders(headers?: Record<string, string>): Record<string, string> | undefined {\n if (!headers || typeof headers !== 'object') return undefined;\n\n const entries = Object.entries(headers)\n .map(([key, value]) => [key.trim(), String(value).trim()] as const)\n .filter(([key, value]) => key.length > 0 && value.length > 0);\n\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\n// ============================================\n// SSEConnectionManager Class\n// ============================================\n\n/**\n * Manages a single SSE connection and handles MCP operations.\n * Each instance corresponds to one connected browser client.\n */\nexport class SSEConnectionManager {\n private readonly userId: string;\n private readonly clients = new Map<string, MCPClient>();\n private heartbeatTimer?: NodeJS.Timeout;\n private isActive = true;\n\n constructor(\n private readonly options: SSEHandlerOptions,\n private readonly sendEvent: (event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse) => void\n ) {\n this.userId = options.userId;\n this.startHeartbeat();\n }\n\n /**\n * Get resolved client metadata (dynamic > static > defaults)\n */\n private async getResolvedClientMetadata(request?: any): Promise<ClientMetadata> {\n // Priority: getClientMetadata() > clientDefaults > empty object\n let metadata: ClientMetadata = {};\n\n // Start with static defaults\n if (this.options.clientDefaults) {\n metadata = { ...this.options.clientDefaults };\n }\n\n // Override with dynamic metadata if provided\n if (this.options.getClientMetadata) {\n const dynamicMetadata = await this.options.getClientMetadata(request);\n metadata = { ...metadata, ...dynamicMetadata };\n }\n\n return metadata;\n }\n\n /**\n * Start heartbeat to keep connection alive\n */\n private startHeartbeat(): void {\n const interval = this.options.heartbeatInterval ?? DEFAULT_HEARTBEAT_INTERVAL;\n this.heartbeatTimer = setInterval(() => {\n if (this.isActive) {\n this.sendEvent({\n level: 'debug',\n message: 'heartbeat',\n timestamp: Date.now(),\n } as McpObservabilityEvent);\n }\n }, interval);\n }\n\n /**\n * Handle incoming RPC requests\n * Returns the RPC response directly for immediate HTTP response (bypassing SSE latency)\n */\n async handleRequest(request: McpRpcRequest): Promise<McpRpcResponse> {\n try {\n let result: SessionListResult | ConnectResult | DisconnectResult | GetSessionResult | FinishAuthResult | ListToolsRpcResult | SetToolPolicyResult | GetToolPolicyResult | ListPromptsResult | ListResourcesResult | unknown;\n\n switch (request.method) {\n case 'listSessions':\n result = await this.listSessions();\n break;\n\n case 'connect':\n result = await this.connect(request.params as ConnectParams);\n break;\n\n case 'reconnect':\n result = await this.reconnect(request.params as ReconnectParams);\n break;\n\n case 'disconnect':\n result = await this.disconnect(request.params as DisconnectParams);\n break;\n\n case 'listTools':\n result = await this.listTools(request.params as SessionParams);\n break;\n\n case 'setToolPolicy':\n result = await this.setToolPolicy(request.params as SetToolPolicyParams);\n break;\n\n case 'getToolPolicy':\n result = await this.getToolPolicy(request.params as GetToolPolicyParams);\n break;\n\n case 'callTool':\n result = await this.callTool(request.params as CallToolParams);\n break;\n\n case 'getSession':\n result = await this.getSession(request.params as SessionParams);\n break;\n\n case 'finishAuth':\n result = await this.finishAuth(request.params as FinishAuthParams);\n break;\n\n case 'listPrompts':\n result = await this.listPrompts(request.params as SessionParams);\n break;\n\n case 'getPrompt':\n result = await this.getPrompt(request.params as GetPromptParams);\n break;\n\n case 'listResources':\n result = await this.listResources(request.params as SessionParams);\n break;\n\n case 'readResource':\n result = await this.readResource(request.params as ReadResourceParams);\n break;\n\n default:\n throw new Error(`Unknown method: ${request.method}`);\n }\n\n const response: McpRpcResponse = {\n id: request.id,\n result,\n };\n\n // Also send via SSE for backwards compatibility\n this.sendEvent(response);\n\n return response;\n } catch (error) {\n const errorResponse: McpRpcResponse = {\n id: request.id,\n error: {\n code: RpcErrorCodes.EXECUTION_ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n },\n };\n\n // Also send via SSE for backwards compatibility\n this.sendEvent(errorResponse);\n\n return errorResponse;\n }\n }\n\n /**\n * Get all sessions for the current userId\n */\n private async listSessions(): Promise<SessionListResult> {\n const sessionList = await sessions.list(this.userId);\n\n return {\n sessions: sessionList.map((s) => ({\n sessionId: s.sessionId,\n serverId: s.serverId,\n serverName: s.serverName,\n serverUrl: s.serverUrl,\n transport: s.transportType,\n createdAt: s.createdAt,\n updatedAt: s.updatedAt ?? s.createdAt,\n status: s.status ?? 'pending',\n toolPolicy: s.toolPolicy,\n })),\n };\n }\n\n /**\n * Connect to an MCP server\n */\n private async connect(params: ConnectParams): Promise<ConnectResult> {\n const { serverName, serverUrl, callbackUrl, transportType } = params;\n const headers = normalizeHeaders(params.headers);\n\n // Normalize serverId to max 12 chars to keep tool names under 64 chars (DeepSeek/OpenAI limits)\n // Tool name format: tool_<serverId>_<toolName> - with 12 char serverId leaves 46 chars for tool name\n const serverId = params.serverId && params.serverId.length <= 12\n ? params.serverId\n : generateServerId();\n\n // Check for existing connections\n const existingSessions = await sessions.list(this.userId);\n const duplicate = existingSessions.find(s =>\n s.serverId === serverId || s.serverUrl === serverUrl\n );\n\n if (duplicate) {\n // If the existing session is still pending OAuth, treat connect as \"resume auth\"\n // instead of failing with duplicate connection error.\n if (duplicate.status === 'pending') {\n await this.getSession({ sessionId: duplicate.sessionId });\n return {\n sessionId: duplicate.sessionId,\n success: true,\n };\n }\n throw new Error(`Connection already exists for server: ${duplicate.serverUrl || duplicate.serverId} (${duplicate.serverName})`);\n }\n\n // Generate session ID\n const sessionId = await sessions.generateSessionId();\n\n try {\n // Get resolved client metadata\n const clientMetadata = await this.getResolvedClientMetadata();\n\n // Create MCP client\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n serverId,\n serverName,\n serverUrl,\n callbackUrl,\n transportType,\n headers,\n ...clientMetadata, // Spread client metadata (clientName, clientUri, logoUri, policyUri)\n });\n\n // Note: Session will be created by MCPClient after successful connection\n // This ensures sessions only exist for successful or OAuth-pending connections\n\n // Store client\n this.clients.set(sessionId, client);\n\n // Subscribe to client events\n client.onConnectionEvent((event) => {\n this.emitConnectionEvent(event);\n });\n\n client.onObservabilityEvent((event) => {\n this.sendEvent(event);\n });\n\n // Attempt connection\n await client.connect();\n\n // Fetch policy-filtered tools for agent-facing discovery\n await this.listPolicyFilteredTools(sessionId);\n\n return {\n sessionId,\n success: true,\n };\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,\n error: error instanceof Error ? error.message : 'Connection failed',\n errorType: 'connection',\n timestamp: Date.now(),\n });\n\n // Clean up client\n this.clients.delete(sessionId);\n\n throw error;\n }\n }\n\n /**\n * Reconnect to an MCP server — tears down the active client transport/connection\n * and creates a fresh connection while reusing the existing session credentials in a single RPC call.\n */\n private async reconnect(params: ReconnectParams): Promise<ConnectResult> {\n const { serverId: rawServerId, serverName, serverUrl, callbackUrl, transportType } = params;\n const headers = normalizeHeaders(params.headers);\n\n // Normalize serverId the same way connect() does\n const serverId = rawServerId && rawServerId.length <= 12\n ? rawServerId\n : generateServerId();\n\n // Find existing session for the same server to reuse its session ID\n const existingSessions = await sessions.list(this.userId);\n const duplicate = existingSessions.find(s =>\n s.serverId === serverId || s.serverUrl === serverUrl\n );\n\n // Reuse the duplicate sessionId if present, otherwise generate a new one\n const sessionId = duplicate ? duplicate.sessionId : await sessions.generateSessionId();\n\n if (duplicate) {\n // Disconnect any active in-memory client transport without deleting the database session\n const existingClient = this.clients.get(duplicate.sessionId);\n if (existingClient) {\n await existingClient.disconnect();\n this.clients.delete(duplicate.sessionId);\n }\n }\n\n try {\n const clientMetadata = await this.getResolvedClientMetadata();\n\n // Create a new client instantiating the reused session ID (which preserves DCR credentials and tokens)\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n serverId,\n serverName,\n serverUrl,\n callbackUrl,\n transportType,\n headers,\n ...clientMetadata,\n });\n\n this.clients.set(sessionId, client);\n\n client.onConnectionEvent((event) => {\n this.emitConnectionEvent(event);\n });\n\n client.onObservabilityEvent((event) => {\n this.sendEvent(event);\n });\n\n await client.connect();\n await this.listPolicyFilteredTools(sessionId);\n\n return { sessionId, success: true };\n } catch (error) {\n if (error instanceof UnauthorizedError) {\n this.clients.delete(sessionId);\n return { sessionId, success: true };\n }\n\n this.emitConnectionEvent({\n type: 'error',\n sessionId,\n serverId,\n error: error instanceof Error ? error.message : 'Connection failed',\n errorType: 'connection',\n timestamp: Date.now(),\n });\n\n this.clients.delete(sessionId);\n throw error;\n }\n }\n\n /**\n * Disconnect from an MCP server\n */\n private async disconnect(params: DisconnectParams): Promise<DisconnectResult> {\n const { sessionId } = params;\n const client = this.clients.get(sessionId);\n\n if (client) {\n // clearSession() handles DELETE + local cleanup internally.\n await client.clearSession();\n this.clients.delete(sessionId);\n } else {\n // Handle orphaned sessions (e.g., OAuth flow failed before client was stored)\n // Directly remove from storage since there's no active client\n await sessions.delete(this.userId, sessionId);\n }\n\n return { success: true };\n }\n\n /**\n * Get an existing client or create and connect a new one for the session.\n */\n private async getOrCreateClient(sessionId: string): Promise<MCPClient> {\n const existing = this.clients.get(sessionId);\n if (existing) {\n return existing;\n }\n\n const session = await sessions.get(this.userId, sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n // These fields are optional in MCPClient, but when rehydrating a known\n // stored session on the server we pass them explicitly to preserve the\n // original transport/connection metadata instead of relying on lazy\n // reloading during initialize().\n serverId: session.serverId,\n serverName: session.serverName,\n serverUrl: session.serverUrl,\n callbackUrl: session.callbackUrl,\n transportType: session.transportType,\n headers: session.headers,\n });\n\n // Subscribe to events before connecting\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\n client.onObservabilityEvent((event) => this.sendEvent(event));\n\n await client.connect();\n this.clients.set(sessionId, client);\n\n return client;\n }\n\n /**\n * Fetches all tools from the remote MCP server and emits a `tools_discovered` event.\n *\n * Two lists are always published together:\n * - `tools` — policy-filtered list that agents are allowed to call.\n * - `allTools` — the complete, unfiltered list used by the management UI so\n * that blocked tools still appear as checkboxes in the dialog.\n *\n * `fetchTools()` is called first (populates the in-memory cache), then\n * `gateway.listTools()` re-uses that cache internally — so only one remote\n * network round-trip is made regardless of how many callers follow.\n *\n * @param sessionId - The session whose tools should be discovered.\n * @returns The session record and the policy-filtered tool list.\n * @throws {Error} When the session does not exist in the store.\n */\n private async listPolicyFilteredTools(sessionId: string): Promise<{ session: Session; result: ListToolsRpcResult }> {\n const session = await sessions.get(this.userId, sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n\n const client = await this.getOrCreateClient(sessionId);\n const allTools = await client.fetchTools().catch(() => ({ tools: [] }));\n const gateway = createToolPolicyGateway(this.userId, sessionId, client);\n const result = await gateway.listTools();\n\n this.emitConnectionEvent({\n type: 'tools_discovered',\n sessionId,\n serverId: session.serverId ?? 'unknown',\n toolCount: result.tools.length,\n tools: result.tools,\n allTools: allTools.tools,\n timestamp: Date.now(),\n });\n\n return { session, result };\n }\n\n /**\n * Returns the policy-filtered tool list for a session (agent-facing).\n * Internally re-uses `listPolicyFilteredTools` which also emits a\n * `tools_discovered` SSE event to keep client state up to date.\n */\n private async listTools(params: SessionParams): Promise<ListToolsRpcResult> {\n const { sessionId } = params;\n const { result } = await this.listPolicyFilteredTools(sessionId);\n return { tools: result.tools };\n }\n\n /**\n * Get all raw tools with effective access state for management UI.\n */\n private async getToolPolicy(params: GetToolPolicyParams): Promise<GetToolPolicyResult> {\n const { sessionId } = params;\n const session = await sessions.get(this.userId, sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n\n const client = await this.getOrCreateClient(sessionId);\n const allTools = await client.fetchTools();\n const toolPolicy = session.toolPolicy ?? {\n mode: 'all' as const,\n toolIds: [],\n updatedAt: session.updatedAt ?? session.createdAt,\n };\n const serverId = session.serverId ?? 'unknown';\n const tools = allTools.tools.map((tool) => ({\n ...tool,\n toolId: createToolId(serverId, tool.name),\n allowed: isToolAllowed(toolPolicy, tool.name, session.serverId),\n }));\n\n return {\n toolPolicy,\n tools,\n toolCount: tools.length,\n allowedToolCount: tools.filter((tool) => tool.allowed).length,\n };\n }\n\n /**\n * Persists a new tool access policy for a session and broadcasts the updated\n * filtered tool list to all connected browser clients via a `tools_discovered` event.\n *\n * Both `tools` (policy-filtered) and `allTools` (complete list) are emitted\n * so the management UI can immediately reflect the new checkbox states without\n * an additional round-trip to the server.\n *\n * @param params - Session ID and the new `{ mode, toolIds }` policy to apply.\n * @throws {Error} When the session does not exist or the policy references unknown tool IDs.\n */\n private async setToolPolicy(params: SetToolPolicyParams): Promise<SetToolPolicyResult> {\n const { sessionId } = params;\n const session = await sessions.get(this.userId, sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n\n const client = await this.getOrCreateClient(sessionId);\n const allTools = await client.fetchTools();\n const toolPolicy = normalizeToolPolicyForUpdate(params.toolPolicy);\n validateToolPolicyAgainstTools(toolPolicy, allTools.tools, session.serverId);\n\n await sessions.update(this.userId, sessionId, { toolPolicy });\n\n const filteredTools = createToolPolicyGateway(this.userId, sessionId, client).filterTools({ ...session, toolPolicy }, allTools.tools);\n this.emitConnectionEvent({\n type: 'tools_discovered',\n sessionId,\n serverId: session.serverId ?? 'unknown',\n toolCount: filteredTools.length,\n tools: filteredTools,\n allTools: allTools.tools,\n timestamp: Date.now(),\n });\n\n return {\n success: true,\n toolPolicy,\n tools: filteredTools,\n toolCount: filteredTools.length,\n };\n }\n\n /**\n * Proxies a tool invocation to the remote MCP server.\n * Resolves the client for the given session and delegates to the tool router.\n */\n private async callTool(params: CallToolParams): Promise<CallToolResult> {\n const { sessionId, toolName, toolArgs } = params;\n const client = await this.getOrCreateClient(sessionId);\n const result = await createToolPolicyGateway(this.userId, sessionId, client).callTool(toolName, toolArgs);\n\n // Inject sessionId into meta so client knows who handled it\n // This allows AppHost to auto-launch without scanning all sessions\n const meta = result._meta || {};\n\n return {\n ...result,\n _meta: {\n ...meta,\n sessionId,\n }\n };\n }\n\n /**\n * Restore and validate an existing session\n */\n private async getSession(params: SessionParams): Promise<GetSessionResult> {\n const { sessionId } = params;\n\n const session = await sessions.get(this.userId, sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n\n this.emitConnectionEvent({\n type: 'state_changed',\n sessionId,\n serverId: session.serverId ?? 'unknown',\n serverName: session.serverName ?? 'Unknown',\n serverUrl: session.serverUrl,\n state: 'VALIDATING',\n previousState: 'DISCONNECTED',\n timestamp: Date.now(),\n });\n\n try {\n const clientMetadata = await this.getResolvedClientMetadata();\n\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n // These fields are optional in MCPClient, but when rehydrating a known\n // stored session on the server we pass them explicitly to preserve the\n // original transport/connection metadata instead of relying on lazy\n // reloading during initialize().\n serverId: session.serverId,\n serverName: session.serverName,\n serverUrl: session.serverUrl,\n callbackUrl: session.callbackUrl,\n transportType: session.transportType,\n headers: session.headers,\n ...clientMetadata,\n });\n\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\n client.onObservabilityEvent((event) => this.sendEvent(event));\n\n await client.connect();\n this.clients.set(sessionId, client);\n\n const { result: tools } = await this.listPolicyFilteredTools(sessionId);\n\n return { success: true, toolCount: tools.tools.length };\n } catch (error) {\n this.emitConnectionEvent({\n type: 'error',\n sessionId,\n serverId: session.serverId ?? 'unknown',\n error: error instanceof Error ? error.message : 'Validation failed',\n errorType: 'validation',\n timestamp: Date.now(),\n });\n\n throw error;\n }\n }\n\n /**\n * Complete OAuth authorization flow\n */\n private async finishAuth(params: FinishAuthParams): Promise<FinishAuthResult> {\n const { code } = params;\n const oauthState = params.state;\n const parsedState = parseOAuthState(oauthState);\n const sessionId = parsedState?.sessionId || oauthState;\n\n const session = await sessions.get(this.userId, sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n\n try {\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n // These fields are optional in MCPClient, but when rehydrating a known\n // stored session on the server we pass them explicitly to preserve the\n // original connection metadata instead of relying on lazy\n // reloading during initialize().\n serverId: session.serverId,\n serverName: session.serverName,\n serverUrl: session.serverUrl,\n callbackUrl: session.callbackUrl,\n // NOTE: transportType is intentionally omitted here.\n // The session's stored transportType is a placeholder ('streamable-http')\n // set before transport negotiation. Omitting it lets MCPClient auto-negotiate\n // (try streamable_http → SSE fallback), which is critical for servers like\n // Neon that only support SSE transport.\n headers: session.headers,\n });\n\n client.onConnectionEvent((event) => this.emitConnectionEvent(event));\n\n await client.finishAuth(code, oauthState);\n this.clients.set(sessionId, client);\n\n const { result: tools } = await this.listPolicyFilteredTools(sessionId);\n\n return { success: true, toolCount: tools.tools.length };\n } catch (error) {\n this.emitConnectionEvent({\n type: 'error',\n sessionId,\n serverId: session.serverId ?? 'unknown',\n error: error instanceof Error ? error.message : 'OAuth completion failed',\n errorType: 'auth',\n timestamp: Date.now(),\n });\n\n throw error;\n }\n }\n\n /**\n * List prompts from a session\n */\n private async listPrompts(params: SessionParams): Promise<ListPromptsResult> {\n const { sessionId } = params;\n const client = await this.getOrCreateClient(sessionId);\n const result = await client.listPrompts();\n return { prompts: result.prompts };\n }\n\n /**\n * Get a specific prompt\n */\n private async getPrompt(params: GetPromptParams): Promise<unknown> {\n const { sessionId, name, args } = params;\n const client = await this.getOrCreateClient(sessionId);\n return await client.getPrompt(name, args);\n }\n\n /**\n * List resources from a session\n */\n private async listResources(params: SessionParams): Promise<ListResourcesResult> {\n const { sessionId } = params;\n const client = await this.getOrCreateClient(sessionId);\n const result = await client.listResources();\n return { resources: result.resources };\n }\n\n /**\n * Read a specific resource\n */\n private async readResource(params: ReadResourceParams): Promise<unknown> {\n const { sessionId, uri } = params;\n const client = await this.getOrCreateClient(sessionId);\n return client.readResource(uri);\n }\n\n /**\n * Emit connection event\n */\n private emitConnectionEvent(event: McpConnectionEvent): void {\n this.sendEvent(event);\n }\n\n /**\n * Cleanup and close all connections\n */\n async dispose(): Promise<void> {\n this.isActive = false;\n\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n }\n\n // Send HTTP DELETE to each Streamable HTTP server before closing, per spec.\n // Run in parallel so shutdown is not serialised across many sessions.\n await Promise.all(\n Array.from(this.clients.values()).map((client) => client.disconnect())\n );\n\n this.clients.clear();\n }\n}\n\n// ============================================\n// SSE Handler Factory\n// ============================================\n\n/**\n * Create an SSE endpoint handler compatible with Node.js HTTP frameworks.\n * Handles both SSE streaming (GET) and RPC requests (POST).\n */\nexport function createSSEHandler(options: SSEHandlerOptions) {\n return async (req: { method?: string; on: Function }, res: { writeHead: Function; write: Function }) => {\n // Set SSE headers\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n });\n\n // Send initial connection acknowledgment\n writeSSEEvent(res, 'connected', { timestamp: Date.now() });\n\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 });\n\n // Cleanup on client disconnect\n req.on('close', () => manager.dispose());\n\n // Handle RPC requests via POST\n if (req.method === 'POST') {\n let body = '';\n req.on('data', (chunk: Buffer) => {\n body += chunk.toString();\n });\n req.on('end', async () => {\n try {\n const request: McpRpcRequest = JSON.parse(body);\n await manager.handleRequest(request);\n } catch {\n // Request parsing/handling errors are sent via SSE error events\n }\n });\n }\n };\n}\n\n// ============================================\n// Utilities\n// ============================================\n\n/**\n * Write an SSE event to the response stream\n */\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\n\n\n\n\n\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 { isConnectionEvent, isRpcResponseEvent } from '../../shared/event-routing.js';\nimport type { McpRpcResponse } from '../../shared/types.js';\n\nexport interface NextMcpHandlerOptions {\n /**\n * Extract userId from request (default: from 'userId' query param)\n */\n getUserId?: (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?: (userId: 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 getUserId = (request: Request) => request.headers.get('x-mcp-user-id'),\n getAuthToken = (request: Request) => {\n const authHeader = request.headers.get('authorization');\n if (authHeader?.toLowerCase().startsWith('bearer ')) {\n return authHeader.slice(7);\n }\n return authHeader;\n },\n authenticate = () => true,\n heartbeatInterval = 30000,\n clientDefaults,\n getClientMetadata,\n } = options;\n\n const toManagerOptions = (userId: string, resolvedClientMetadata?: ClientMetadata) => ({\n userId,\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 userId = getUserId(request);\n const authToken = getAuthToken(request);\n const acceptsEventStream = (request.headers.get('accept') || '').toLowerCase().includes('text/event-stream');\n\n if (!userId) {\n return Response.json({ error: { code: 'MISSING_userId', message: 'Missing userId' } }, { status: 400 });\n }\n\n const isAuthorized = await authenticate(userId, 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(userId, 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(userId, resolvedClientMetadata),\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 }\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 userId,\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"]}
|
|
1
|
+
{"version":3,"sources":["../../src/server/storage/redis.ts","../../src/shared/utils.ts","../../src/shared/constants.ts","../../src/server/storage/tool-policy.ts","../../src/server/storage/session-lifecycle.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/crypto.ts","../../src/server/storage/supabase-backend.ts","../../src/server/storage/neon-backend.ts","../../src/server/storage/index.ts","../../src/server/mcp/storage-oauth-provider.ts","../../src/shared/events.ts","../../src/shared/errors.ts","../../src/server/mcp/oauth-client.ts","../../src/server/mcp/tool-policy-gateway.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"],"names":["redis","sessions","fs","path2","getRedis","nanoid","existingSession","SDKUnauthorizedError","manager"],"mappings":"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","file":"index.mjs","sourcesContent":["/**\n * Redis connection management with dependency injection support\n * Allows configuration and testing without environment variables\n */\nimport type { Redis } from 'ioredis';\n\nexport interface RedisConfig {\n /**\n * Redis connection URL (defaults to REDIS_URL env var)\n */\n url?: string;\n\n /**\n * Enable lazy connection (default: true)\n */\n lazyConnect?: boolean;\n\n /**\n * Maximum retries per request (default: 1)\n */\n maxRetriesPerRequest?: number;\n\n /**\n * Enable verbose logging (default: false)\n */\n verbose?: boolean;\n /**\n * @internal For testing only - bypass ioredis import\n */\n RedisConstructor?: any;\n}\n\ndeclare global {\n // eslint-disable-next-line no-var\n var __redis: Redis | undefined;\n var __redisConfig: RedisConfig | undefined;\n}\n\nlet redisInstance: Redis | null = null;\n\n/**\n * Initialize Redis with custom configuration\n * Call this before any Redis operations if you need custom config\n * @param config - Redis configuration options\n */\nexport async function initRedis(config: RedisConfig): Promise<Redis> {\n if (redisInstance) {\n // Already initialized, return existing instance\n return redisInstance;\n }\n\n const url = config.url ?? process.env.REDIS_URL;\n\n if (!url) {\n throw new Error(\n 'Redis URL is required. Set REDIS_URL environment variable or pass url in config.'\n );\n }\n\n let Redis: typeof import('ioredis').Redis;\n if (config.RedisConstructor) {\n Redis = config.RedisConstructor;\n } else {\n try {\n const ioredis = await import('ioredis');\n Redis = ioredis.Redis;\n } catch (error) {\n throw new Error(\n 'ioredis is not installed. Install it with:\\n' +\n ' npm install ioredis\\n\\n' +\n 'Or use a different storage backend:\\n' +\n ' MCP_TS_STORAGE_TYPE=memory (for development)\\n' +\n ' MCP_TS_STORAGE_TYPE=file (for local persistence)'\n );\n }\n }\n\n redisInstance = new Redis(url, {\n lazyConnect: config.lazyConnect ?? true,\n maxRetriesPerRequest: config.maxRetriesPerRequest ?? 1,\n });\n\n if (config.verbose !== false) {\n redisInstance.on('ready', () => {\n console.log('✅ Redis connected');\n });\n\n redisInstance.on('error', (err) => {\n console.error('❌ Redis error:', err.message);\n });\n\n redisInstance.on('reconnecting', () => {\n console.log('🔄 Redis reconnecting...');\n });\n }\n\n // Store globally for hot reloading scenarios\n global.__redis = redisInstance;\n global.__redisConfig = config;\n\n return redisInstance;\n}\n\n/**\n * Get the Redis instance\n * Automatically initializes with default config if not already initialized\n */\nexport async function getRedis(): Promise<Redis> {\n if (redisInstance) {\n return redisInstance;\n }\n\n // Check for existing global instance (hot reload scenario)\n if (global.__redis) {\n redisInstance = global.__redis;\n return redisInstance;\n }\n\n // Initialize with default config\n return await initRedis({});\n}\n\n/**\n * Set a custom Redis instance (useful for testing with mocks)\n * @param instance - Redis instance or mock\n */\nexport function setRedisInstance(instance: Redis): void {\n redisInstance = instance;\n global.__redis = instance;\n}\n\n/**\n * Close Redis connection and clear instance\n */\nexport async function closeRedis(): Promise<void> {\n if (redisInstance) {\n await redisInstance.quit();\n redisInstance = null;\n global.__redis = undefined;\n }\n}\n\n/**\n * Default Redis export for backward compatibility\n * Will auto-initialize on first access\n * Note: This is a lazy proxy that initializes Redis on first method call\n */\nexport const redis = new Proxy({} as Redis, {\n get(_target, prop) {\n // Return a function that handles async initialization\n return async (...args: any[]) => {\n const instance = await getRedis();\n const value = (instance as any)[prop];\n if (typeof value === 'function') {\n return value.apply(instance, args);\n }\n return value;\n };\n },\n});\n","import { customAlphabet, nanoid } from 'nanoid';\n\nconst OAUTH_STATE_SEPARATOR = '.';\n\nconst serverIdAlphabet = customAlphabet(\n 'abcdefghijklmnopqrstuvwxyz0123456789',\n 12\n);\n\n/**\n * Sanitize server name to create a valid server label\n * Must start with a letter and contain only letters, digits, '-' and '_'\n */\nexport function sanitizeServerLabel(name: string): string {\n let sanitized = name\n .replace(/[^a-zA-Z0-9-_]/g, '_')\n .replace(/_{2,}/g, '_')\n .toLowerCase();\n\n if (!/^[a-zA-Z]/.test(sanitized)) {\n sanitized = 's_' + sanitized;\n }\n\n return sanitized;\n}\n\n/**\n * Generates a session ID with a human-readable prefix for easy identification.\n * Format: sess_<21-char nanoid> (26 chars total).\n * Not used in tool names, so length is not constrained.\n */\nexport function generateSessionId(): string {\n return 'sess_' + nanoid(21);\n}\n\n/**\n * Generates a short server ID suitable for use in tool names.\n * 12-char alphanumeric string that keeps tool_<serverId>_<toolName> under 64 chars.\n */\nexport function generateServerId(): string {\n return serverIdAlphabet();\n}\n\nexport interface ParsedOAuthState {\n nonce: string;\n sessionId: string;\n}\n\nexport function formatOAuthState(nonce: string, sessionId: string): string {\n return `${nonce}${OAUTH_STATE_SEPARATOR}${sessionId}`;\n}\n\nexport function parseOAuthState(state: string): ParsedOAuthState | undefined {\n const separatorIndex = state.indexOf(OAUTH_STATE_SEPARATOR);\n if (separatorIndex <= 0 || separatorIndex === state.length - 1) {\n return undefined;\n }\n\n const nonce = state.slice(0, separatorIndex);\n const sessionId = state.slice(separatorIndex + 1);\n if (!nonce || !sessionId || sessionId.includes(OAUTH_STATE_SEPARATOR)) {\n return undefined;\n }\n\n return { nonce, sessionId };\n}\n","/**\n * Centralized constants for MCP Redis library\n * Eliminates magic numbers and enables consistent configuration\n */\n\n// Session lifecycle\nexport const STATE_EXPIRATION_MS = 10 * 60 * 1000; // 10 minutes for OAuth state\nexport const PENDING_SESSION_EXPIRATION_SECONDS = Math.floor(STATE_EXPIRATION_MS / 1000);\nexport const DORMANT_SESSION_EXPIRATION_MS = 30 * 24 * 60 * 60 * 1000; // 30 days\nexport const DORMANT_SESSION_EXPIRATION_SECONDS = Math.floor(DORMANT_SESSION_EXPIRATION_MS / 1000);\n\n// Heartbeat and Connection\nexport const DEFAULT_HEARTBEAT_INTERVAL_MS = 30000; // 30 seconds\n\n// Redis Key Prefixes\nexport const REDIS_KEY_PREFIX = 'mcp:session:';\n\n// Client Information\nexport const DEFAULT_CLIENT_NAME = 'MCP Assistant';\nexport const DEFAULT_CLIENT_URI = 'https://mcp-assistant.in';\nexport const DEFAULT_LOGO_URI = 'https://mcp-assistant.in/logo.svg';\nexport const DEFAULT_POLICY_URI = 'https://mcp-assistant.in/privacy';\nexport const SOFTWARE_ID = '@mcp-ts';\nexport const SOFTWARE_VERSION = '2.3.4';\n\n// MCP Client Configuration\nexport const MCP_CLIENT_NAME = 'mcp-ts-oauth-client';\nexport const MCP_CLIENT_VERSION = '2.0';\n","import type { Tool } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolPolicy } from './types.js';\n\n/**\n * Raw, unvalidated shape of a tool policy as it may arrive from an external\n * source (HTTP request body, database read, etc.). All fields are typed as\n * `unknown` so callers are forced to pass through one of the `normalize*`\n * helpers before using the value as a `ToolPolicy`.\n */\nexport type ToolPolicyInput = {\n mode?: unknown;\n toolIds?: unknown;\n updatedAt?: unknown;\n} | null | undefined;\n\n/**\n * Constructs the canonical tool ID string used throughout the policy system.\n *\n * Tool IDs combine the server ID and the tool name with a `::` separator so\n * they are globally unique across all connected MCP servers:\n * ```\n * \"mn0v3pfwwbxv::delete_mcp_server\"\n * ```\n *\n * @param serverId - The short server identifier (e.g. `\"mn0v3pfwwbxv\"`).\n * @param toolName - The exact tool name as reported by the remote server.\n * @returns A namespaced tool ID string.\n */\nexport function createToolId(serverId: string, toolName: string): string {\n return `${serverId}::${toolName}`;\n}\n\n/**\n * Coerces an arbitrary value into a deduplicated array of trimmed, non-empty\n * strings. Returns an empty array for any non-array or invalid input.\n *\n * @param input - Raw value to normalise (typically from user input or a DB read).\n * @returns A clean `string[]` with duplicates and blank entries removed.\n */\nfunction normalizeToolIds(input?: unknown): string[] {\n if (!Array.isArray(input)) return [];\n\n return Array.from(new Set(\n input\n .filter((id): id is string => typeof id === 'string')\n .map((id) => id.trim())\n .filter(Boolean)\n ));\n}\n\n/**\n * Converts a raw, potentially untrusted `ToolPolicyInput` into a validated\n * `ToolPolicy` object, or `undefined` if the input is absent / malformed.\n *\n * - Invalid `mode` values fall back to `\"all\"` (no restrictions).\n * - Invalid `updatedAt` values fall back to `now`.\n * - `\"all\"` mode always produces an empty `toolIds` array regardless of input.\n *\n * @param input - Raw policy data to normalise (from request body, DB, etc.).\n * @param now - Unix timestamp used as the fallback for `updatedAt`. Defaults to `Date.now()`.\n * @returns A well-formed `ToolPolicy`, or `undefined` if `input` is absent.\n */\nexport function normalizeToolPolicy(input?: ToolPolicyInput, now = Date.now()): ToolPolicy | undefined {\n if (!input || typeof input !== 'object') {\n return undefined;\n }\n\n const mode = input.mode === 'allowlist' || input.mode === 'denylist'\n ? input.mode\n : 'all';\n const updatedAt = typeof input.updatedAt === 'number' && Number.isFinite(input.updatedAt)\n ? input.updatedAt\n : now;\n\n if (mode === 'all') {\n return { mode: 'all', toolIds: [], updatedAt };\n }\n\n return { mode, toolIds: normalizeToolIds(input.toolIds), updatedAt };\n}\n\n/**\n * Same as `normalizeToolPolicy` but guaranteed to return a `ToolPolicy`.\n * Falls back to an unrestricted `{ mode: \"all\" }` policy when the input is\n * absent or invalid.\n *\n * Use this variant when a policy is required (e.g. when persisting an update)\n * rather than when reading an optional policy from the session store.\n *\n * @param input - Raw policy data to normalise.\n * @param now - Unix timestamp used as the fallback for `updatedAt`. Defaults to `Date.now()`.\n * @returns A well-formed `ToolPolicy`, never `undefined`.\n */\nexport function normalizeToolPolicyForUpdate(input: ToolPolicyInput, now = Date.now()): ToolPolicy {\n return normalizeToolPolicy(input, now) ?? { mode: 'all', toolIds: [], updatedAt: now };\n}\n\n/**\n * Determines whether a specific tool is permitted under the given policy.\n *\n * | Policy mode | Allowed when… |\n * |--------------|--------------------------------------------------|\n * | `\"all\"` | Always (no restrictions). |\n * | `\"allowlist\"`| The tool's ID is present in `policy.toolIds`. |\n * | `\"denylist\"` | The tool's ID is **not** in `policy.toolIds`. |\n *\n * Returns `false` when the policy requires a `serverId` for ID construction\n * but none is provided (fail-safe / deny by default).\n *\n * @param policy - The active tool policy, or `undefined` for unrestricted access.\n * @param toolName - The tool name to check (as reported by the remote server).\n * @param serverId - The server that owns the tool (required for `allowlist`/`denylist`).\n * @returns `true` if the tool is allowed, `false` otherwise.\n */\nexport function isToolAllowed(policy: ToolPolicy | undefined, toolName: string, serverId?: string): boolean {\n if (!policy || policy.mode === 'all') return true;\n if (!serverId) return false;\n\n const toolId = createToolId(serverId, toolName);\n if (policy.mode === 'allowlist') {\n return policy.toolIds.includes(toolId);\n }\n\n return !policy.toolIds.includes(toolId);\n}\n\n/**\n * Asserts that a tool call is permitted under the current session policy.\n * Throws a descriptive error if the tool is blocked — call this inside\n * `ToolPolicyGateway.callTool` before proxying the request to the remote server.\n *\n * @param policy - The active tool policy, or `undefined` for unrestricted access.\n * @param toolName - The tool being invoked.\n * @param serverId - The server that owns the tool.\n * @throws {Error} When the tool is not permitted by the policy.\n */\nexport function assertToolAllowed(policy: ToolPolicy | undefined, toolName: string, serverId?: string): void {\n if (isToolAllowed(policy, toolName, serverId)) return;\n throw new Error(`Tool \"${toolName}\" is not allowed for this MCP session`);\n}\n\n/**\n * Returns the subset of `tools` that are permitted under the given policy.\n *\n * When no policy is set (or mode is `\"all\"`), the original array is returned\n * unchanged (no copy is made). Otherwise each tool is tested with\n * `isToolAllowed` and only the passing tools are included.\n *\n * @param tools - The full, unfiltered list of tools from the remote server.\n * @param policy - The active tool policy, or `undefined` for unrestricted access.\n * @param serverId - The server that owns the tools (required for `allowlist`/`denylist`).\n * @returns A filtered array containing only the permitted tools.\n */\nexport function filterToolsByPolicy<T extends Pick<Tool, 'name'>>(\n tools: T[],\n policy: ToolPolicy | undefined,\n serverId?: string\n): T[] {\n if (!policy || policy.mode === 'all') return tools;\n return tools.filter((tool) => isToolAllowed(policy, tool.name, serverId));\n}\n\n/**\n * Validates that every tool ID referenced in a policy actually exists on the\n * connected MCP server. Throws if any ID is unknown.\n *\n * This prevents silent misconfigurations where a user accidentally saves a\n * policy referencing a tool that no longer exists (e.g. after a server update).\n *\n * @param policy - The policy to validate (skipped for `\"all\"` mode).\n * @param tools - The authoritative list of tools from the remote server.\n * @param serverId - Required to construct tool IDs for comparison.\n * @throws {Error} When `serverId` is missing and the policy is not `\"all\"`.\n * @throws {Error} When the policy contains tool IDs not present in `tools`.\n */\nexport function validateToolPolicyAgainstTools(\n policy: ToolPolicy,\n tools: Array<Pick<Tool, 'name'>>,\n serverId?: string\n): void {\n if (policy.mode === 'all') return;\n if (!serverId) {\n throw new Error('Cannot validate MCP tool policy without a serverId');\n }\n\n const availableIds = new Set(tools.map((tool) => createToolId(serverId, tool.name)));\n const unknownIds = policy.toolIds.filter((id) => !availableIds.has(id));\n if (unknownIds.length > 0) {\n throw new Error(`Unknown tool id(s) for this MCP session: ${unknownIds.join(', ')}`);\n }\n}\n","import {\n DORMANT_SESSION_EXPIRATION_MS,\n DORMANT_SESSION_EXPIRATION_SECONDS,\n STATE_EXPIRATION_MS,\n} from '../../shared/constants.js';\nimport type { Session, SessionStatus } from './types.js';\nimport { normalizeToolPolicy } from './tool-policy.js';\n\nexport function resolveSessionExpiresAt(status: SessionStatus = 'pending', referenceTime = Date.now()): number | null {\n return status === 'active' ? null : referenceTime + STATE_EXPIRATION_MS;\n}\n\nexport function resolveSessionRedisTtlSeconds(session: Pick<Session, 'status'>): number {\n return session.status === 'active'\n ? DORMANT_SESSION_EXPIRATION_SECONDS\n : Math.floor(STATE_EXPIRATION_MS / 1000);\n}\n\nexport function normalizeNewSession(session: Session, now = Date.now()): Session {\n const createdAt = session.createdAt || now;\n const updatedAt = session.updatedAt ?? createdAt;\n const status = session.status ?? 'pending';\n\n return {\n ...session,\n status,\n createdAt,\n updatedAt,\n expiresAt: resolveSessionExpiresAt(status, status === 'active' ? updatedAt : createdAt),\n toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt),\n };\n}\n\nexport function mergeSessionUpdate(\n current: Session,\n data: Partial<Session>,\n now = Date.now()\n): Session {\n const updatedAt = data.updatedAt ?? now;\n const updated = {\n ...current,\n ...data,\n updatedAt,\n };\n const status = updated.status ?? 'pending';\n\n return {\n ...updated,\n status,\n expiresAt: resolveSessionExpiresAt(status, updatedAt),\n toolPolicy: normalizeToolPolicy(updated.toolPolicy, updatedAt),\n };\n}\n\nexport function normalizeStoredSession(session: Session): Session {\n const createdAt = session.createdAt || Date.now();\n const updatedAt = session.updatedAt ?? createdAt;\n const status = session.status ?? 'pending';\n const expiresAt = status === 'active'\n ? null\n : session.expiresAt ?? resolveSessionExpiresAt(status, createdAt);\n\n return {\n ...session,\n status,\n createdAt,\n updatedAt,\n expiresAt,\n toolPolicy: normalizeToolPolicy(session.toolPolicy, updatedAt),\n };\n}\n\nexport function isSessionExpired(session: Session, now = Date.now()): boolean {\n const hydrated = normalizeStoredSession(session);\n\n if (hydrated.status === 'active') {\n return hydrated.updatedAt !== undefined &&\n hydrated.updatedAt < now - DORMANT_SESSION_EXPIRATION_MS;\n }\n\n return typeof hydrated.expiresAt === 'number' && hydrated.expiresAt < now;\n}\n\n","import type { Redis } from 'ioredis';\nimport type { SessionStore, Session, SessionCredentials, GetOptions, SessionResult } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport {\n mergeSessionUpdate,\n normalizeNewSession,\n normalizeStoredSession,\n resolveSessionRedisTtlSeconds,\n} from './session-lifecycle.js';\n\n/**\n * Redis implementation of SessionStore\n */\nexport class RedisStorageBackend implements SessionStore {\n private readonly KEY_PREFIX = 'mcp:session:';\n private readonly USER_ID_KEY_PREFIX = 'mcp:userId:';\n private readonly USER_ID_KEY_SUFFIX = ':sessions';\n\n constructor(private redis: Redis) { }\n \n async init(): Promise<void> {\n try {\n await this.redis.ping();\n console.log('[mcp-ts][Storage] Redis: ✓ Connected to server.');\n } catch (error: any) {\n throw new Error(`[RedisStorageBackend] Failed to connect to Redis: ${error.message}`);\n }\n }\n\n /**\n * Generates Redis key for a specific session\n * @private\n */\n private getSessionKey(userId: string, sessionId: string): string {\n return `${this.KEY_PREFIX}${userId}:${sessionId}`;\n }\n\n /**\n * Generates Redis key for tracking all sessions for a user\n * @private\n */\n private getUserIdKey(userId: string): string {\n return `${this.USER_ID_KEY_PREFIX}${userId}${this.USER_ID_KEY_SUFFIX}`;\n }\n\n private parseUserIdFromKey(userIdKey: string): string {\n return userIdKey.slice(\n this.USER_ID_KEY_PREFIX.length,\n userIdKey.length - this.USER_ID_KEY_SUFFIX.length\n );\n }\n\n private async scanKeys(pattern: string): Promise<string[]> {\n const redis = this.redis as Redis & {\n scan?: (cursor: string, ...args: Array<string | number>) => Promise<[string, string[]]>;\n };\n\n if (typeof redis.scan !== 'function') {\n return await this.redis.keys(pattern);\n }\n\n const keys = new Set<string>();\n let cursor = '0';\n\n try {\n do {\n const [nextCursor, batch] = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 100);\n cursor = nextCursor;\n for (const key of batch) {\n keys.add(key);\n }\n } while (cursor !== '0');\n } catch (error) {\n console.warn('[RedisStorageBackend] SCAN failed, falling back to KEYS:', error);\n return await this.redis.keys(pattern);\n }\n\n return Array.from(keys);\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n const userIdKey = this.getUserIdKey(userId);\n const sessionWithLifecycle = normalizeNewSession(session);\n const effectiveTtl = resolveSessionRedisTtlSeconds(sessionWithLifecycle);\n\n const result = await this.redis.set(\n sessionKey,\n JSON.stringify(sessionWithLifecycle),\n 'EX',\n effectiveTtl,\n 'NX'\n );\n\n if (result !== 'OK') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n\n await this.redis.sadd(userIdKey, sessionId);\n }\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n\n /** Lua script for atomic get-and-set with expiration refresh. */\n const script = `\n local currentStr = redis.call(\"GET\", KEYS[1])\n if not currentStr then\n return 0\n end\n\n local current = cjson.decode(currentStr)\n local updated = cjson.decode(ARGV[1])\n\n redis.call(\"SET\", KEYS[1], cjson.encode(updated), \"EX\", ARGV[2])\n return 1\n `;\n\n const current = await this.get(userId, sessionId);\n if (!current) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const updated = mergeSessionUpdate(current, data);\n const effectiveTtl = resolveSessionRedisTtlSeconds(updated);\n\n const result = await this.redis.eval(\n script,\n 1,\n sessionKey,\n JSON.stringify(updated),\n effectiveTtl\n );\n\n if (result === 0) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const currentStr = await this.redis.get(sessionKey);\n if (!currentStr) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const current = JSON.parse(currentStr) as Session;\n const updated = { ...current, ...data, sessionId, userId };\n const effectiveTtl = resolveSessionRedisTtlSeconds(updated);\n await this.redis.set(sessionKey, JSON.stringify(updated), 'EX', effectiveTtl);\n }\n\n async get(userId: string, sessionId: string, options?: GetOptions): Promise<SessionResult | null> {\n try {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const sessionDataStr = await this.redis.get(sessionKey);\n if (!sessionDataStr) return null;\n\n const session = normalizeStoredSession(JSON.parse(sessionDataStr) as Session);\n if (!options?.includeCredentials) {\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState, ...sessionOnly } = session;\n return sessionOnly as Session;\n }\n return session;\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to get session:', error);\n return null;\n }\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n const session = await this.get(userId, sessionId, { includeCredentials: true });\n if (!session) return null;\n\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState } = session;\n return {\n sessionId, userId,\n clientInformation, tokens, codeVerifier,\n codeVerifierChallenge, codeVerifierNonce,\n clientId, oauthState,\n };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n codeVerifierChallenge: null,\n codeVerifierNonce: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async listIds(userId: string): Promise<string[]> {\n const sessions = await this.list(userId);\n return sessions.map((session) => session.sessionId);\n }\n\n async list(userId: string): Promise<Session[]> {\n try {\n const userIdKey = this.getUserIdKey(userId);\n const sessionIds = await this.redis.smembers(userIdKey);\n if (sessionIds.length === 0) return [];\n\n const results = await Promise.all(\n sessionIds.map(async (sessionId) => {\n const data = await this.redis.get(this.getSessionKey(userId, sessionId));\n return data ? (JSON.parse(data) as Session) : null;\n })\n );\n\n const staleSessionIds = sessionIds.filter((_, index) => results[index] === null);\n if (staleSessionIds.length > 0) {\n await this.redis.srem(userIdKey, ...staleSessionIds);\n }\n\n return results\n .filter((session): session is Session => session !== null)\n .map((session) => normalizeStoredSession(session));\n } catch (error) {\n console.error(`[RedisStorageBackend] Failed to get session data for ${userId}:`, error);\n return [];\n }\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n try {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const userIdKey = this.getUserIdKey(userId);\n\n await this.redis.srem(userIdKey, sessionId);\n await this.redis.del(sessionKey);\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to remove session:', error);\n }\n }\n\n async listAllIds(): Promise<string[]> {\n try {\n const keys = await this.scanKeys(`${this.KEY_PREFIX}*`);\n const sessions = await Promise.all(\n keys.map(async (key) => {\n const data = await this.redis.get(key);\n if (!data) {\n return null;\n }\n\n try {\n return normalizeStoredSession(JSON.parse(data) as Session).sessionId;\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to parse session while listing all session IDs:', error);\n return null;\n }\n })\n );\n\n return sessions.filter((sessionId): sessionId is string => sessionId !== null);\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to get all sessions:', error);\n return [];\n }\n }\n\n async clearAll(): Promise<void> {\n try {\n const keys = await this.scanKeys(`${this.KEY_PREFIX}*`);\n const userIdKeys = await this.scanKeys(`${this.USER_ID_KEY_PREFIX}*${this.USER_ID_KEY_SUFFIX}`);\n const allKeys = [...keys, ...userIdKeys];\n if (allKeys.length > 0) {\n await this.redis.del(...allKeys);\n }\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to clear sessions:', error);\n }\n }\n\n async cleanupExpired(): Promise<void> {\n try {\n const userIdKeys = await this.scanKeys(`${this.USER_ID_KEY_PREFIX}*${this.USER_ID_KEY_SUFFIX}`);\n\n for (const userIdKey of userIdKeys) {\n const userId = this.parseUserIdFromKey(userIdKey);\n const sessionIds = await this.redis.smembers(userIdKey);\n\n if (sessionIds.length === 0) {\n await this.redis.del(userIdKey);\n continue;\n }\n\n const existenceChecks = await Promise.all(\n sessionIds.map((sessionId) => this.redis.exists(this.getSessionKey(userId, sessionId)))\n );\n\n const staleSessionIds = sessionIds.filter((_, index) => existenceChecks[index] === 0);\n if (staleSessionIds.length > 0) {\n await this.redis.srem(userIdKey, ...staleSessionIds);\n }\n\n const remainingCount = await this.redis.scard(userIdKey);\n if (remainingCount === 0) {\n await this.redis.del(userIdKey);\n }\n }\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to cleanup expired sessions:', error);\n }\n }\n\n async disconnect(): Promise<void> {\n try {\n await this.redis.quit();\n } catch (error) {\n console.error('[RedisStorageBackend] Failed to disconnect:', error);\n }\n }\n}\n","import type { SessionStore, Session, SessionCredentials, GetOptions, SessionResult } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport { isSessionExpired, mergeSessionUpdate, normalizeNewSession } from './session-lifecycle.js';\n\n/**\n * In-memory implementation of SessionStore\n * Useful for local development or testing\n */\nexport class MemoryStorageBackend implements SessionStore {\n // Map<userId:sessionId, Session>\n private sessions = new Map<string, Session>();\n\n // Map<userId, Set<sessionId>>\n private userIdSessions = new Map<string, Set<string>>();\n\n constructor() { }\n\n async init(): Promise<void> {\n console.log('[mcp-ts][Storage] Memory: ✓ internal memory store active.');\n }\n\n private getSessionKey(userId: string, sessionId: string): string {\n return `${userId}:${sessionId}`;\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (this.sessions.has(sessionKey)) {\n throw new Error(`Session ${sessionId} already exists`);\n }\n\n this.sessions.set(sessionKey, normalizeNewSession(session));\n\n // Update index\n if (!this.userIdSessions.has(userId)) {\n this.userIdSessions.set(userId, new Set());\n }\n this.userIdSessions.get(userId)!.add(sessionId);\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n if (!userId || !sessionId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n const current = this.sessions.get(sessionKey);\n\n if (!current) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n const updated = mergeSessionUpdate(current, data);\n\n this.sessions.set(sessionKey, updated);\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const current = this.sessions.get(sessionKey);\n if (!current) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n this.sessions.set(sessionKey, { ...current, ...data, sessionId, userId });\n }\n\n\n async get(userId: string, sessionId: string, options?: GetOptions): Promise<SessionResult | null> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const session = this.sessions.get(sessionKey) || null;\n if (!session) return session;\n if (!options?.includeCredentials) {\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState, ...sessionOnly } = session;\n return sessionOnly as Session;\n }\n return session;\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n const session = this.sessions.get(sessionKey);\n if (!session) return null;\n\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState } = session;\n return {\n sessionId, userId,\n clientInformation, tokens, codeVerifier,\n codeVerifierChallenge, codeVerifierNonce,\n clientId, oauthState,\n };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n codeVerifierChallenge: null,\n codeVerifierNonce: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async listIds(userId: string): Promise<string[]> {\n const set = this.userIdSessions.get(userId);\n return set ? Array.from(set) : [];\n }\n\n async list(userId: string): Promise<Session[]> {\n const set = this.userIdSessions.get(userId);\n if (!set) return [];\n\n const results: Session[] = [];\n for (const sessionId of set) {\n const session = this.sessions.get(this.getSessionKey(userId, sessionId));\n if (session) {\n results.push(session);\n }\n }\n return results;\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n const sessionKey = this.getSessionKey(userId, sessionId);\n this.sessions.delete(sessionKey);\n\n const set = this.userIdSessions.get(userId);\n if (set) {\n set.delete(sessionId);\n if (set.size === 0) {\n this.userIdSessions.delete(userId);\n }\n }\n }\n\n async listAllIds(): Promise<string[]> {\n return Array.from(this.sessions.values()).map(s => s.sessionId);\n }\n\n async clearAll(): Promise<void> {\n this.sessions.clear();\n this.userIdSessions.clear();\n }\n\n async cleanupExpired(): Promise<void> {\n for (const [key, session] of this.sessions.entries()) {\n if (!isSessionExpired(session)) continue;\n\n this.sessions.delete(key);\n\n const set = this.userIdSessions.get(session.userId);\n if (set) {\n set.delete(session.sessionId);\n if (set.size === 0) {\n this.userIdSessions.delete(session.userId);\n }\n }\n }\n }\n\n async disconnect(): Promise<void> {\n // No-op for memory\n }\n}\n","import { promises as fs } from 'fs';\nimport * as path from 'path';\nimport type { SessionStore, Session, SessionCredentials, GetOptions, SessionResult } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport {\n mergeSessionUpdate,\n normalizeNewSession,\n normalizeStoredSession,\n isSessionExpired,\n} from './session-lifecycle.js';\n\n/**\n * File system implementation of SessionStore\n * Persists sessions to a JSON file\n */\nexport class FileStorageBackend implements SessionStore {\n private filePath: string;\n private memoryCache: Map<string, Session> | null = null;\n private initialized = false;\n\n /**\n * @param options.path Path to the JSON file storage (default: ./sessions.json)\n */\n constructor(options: { path?: string } = {}) {\n this.filePath = options.path || './sessions.json';\n }\n\n /**\n * Initialize storage: ensure file exists and load into memory cache\n */\n async init(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Ensure directory exists\n const dir = path.dirname(this.filePath);\n await fs.mkdir(dir, { recursive: true });\n\n // Try to read file\n const data = await fs.readFile(this.filePath, 'utf-8');\n const json = JSON.parse(data);\n\n this.memoryCache = new Map();\n if (Array.isArray(json.sessions)) {\n json.sessions.forEach((s: Session) => {\n const session = normalizeStoredSession(s);\n this.memoryCache!.set(this.getSessionKey(session.userId || 'unknown', session.sessionId), session);\n });\n }\n } catch (error: any) {\n if (error.code === 'ENOENT') {\n // File does not exist, initialize empty\n this.memoryCache = new Map();\n await this.flush();\n } else {\n console.error('[FileStorage] Failed to load sessions:', error);\n throw error;\n }\n }\n\n this.initialized = true;\n console.log(`[mcp-ts][Storage] File: ✓ storage directory at ${path.dirname(this.filePath)} verified.`);\n }\n\n private async ensureInitialized() {\n if (!this.initialized) await this.init();\n }\n\n private async flush(): Promise<void> {\n if (!this.memoryCache) return;\n await fs.writeFile(this.filePath, JSON.stringify({\n sessions: Array.from(this.memoryCache.values()),\n }, null, 2), 'utf-8');\n }\n\n private getSessionKey(userId: string, sessionId: string): string {\n return `${userId}:${sessionId}`;\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n await this.ensureInitialized();\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n if (this.memoryCache!.has(sessionKey)) {\n throw new Error(`Session ${sessionId} already exists`);\n }\n\n this.memoryCache!.set(sessionKey, normalizeNewSession(session));\n await this.flush();\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n await this.ensureInitialized();\n if (!userId || !sessionId) throw new Error('userId and sessionId required');\n\n const sessionKey = this.getSessionKey(userId, sessionId);\n const current = this.memoryCache!.get(sessionKey);\n\n if (!current) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n const updated = mergeSessionUpdate(current, data);\n\n this.memoryCache!.set(sessionKey, updated);\n await this.flush();\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n const current = this.memoryCache!.get(sessionKey);\n if (!current) {\n throw new Error(`Session ${sessionId} not found`);\n }\n\n this.memoryCache!.set(sessionKey, { ...current, ...data, sessionId, userId });\n await this.flush();\n }\n\n async get(userId: string, sessionId: string, options?: GetOptions): Promise<SessionResult | null> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n const session = this.memoryCache!.get(sessionKey) || null;\n if (!session) return null;\n if (!options?.includeCredentials) {\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState, ...sessionOnly } = session;\n return sessionOnly as Session;\n }\n return session;\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n const session = this.memoryCache!.get(sessionKey);\n if (!session) return null;\n\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState } = session;\n return {\n sessionId, userId,\n clientInformation, tokens, codeVerifier,\n codeVerifierChallenge, codeVerifierNonce,\n clientId, oauthState,\n };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n codeVerifierChallenge: null,\n codeVerifierNonce: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async list(userId: string): Promise<Session[]> {\n await this.ensureInitialized();\n return Array.from(this.memoryCache!.values()).filter(s => s.userId === userId);\n }\n\n async listIds(userId: string): Promise<string[]> {\n await this.ensureInitialized();\n return Array.from(this.memoryCache!.values())\n .filter(s => s.userId === userId)\n .map(s => s.sessionId);\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n await this.ensureInitialized();\n const sessionKey = this.getSessionKey(userId, sessionId);\n const deleted = this.memoryCache!.delete(sessionKey);\n if (deleted) {\n await this.flush();\n }\n }\n\n async listAllIds(): Promise<string[]> {\n await this.ensureInitialized();\n return Array.from(this.memoryCache!.values()).map(s => s.sessionId);\n }\n\n async clearAll(): Promise<void> {\n await this.ensureInitialized();\n this.memoryCache!.clear();\n await this.flush();\n }\n\n async cleanupExpired(): Promise<void> {\n await this.ensureInitialized();\n let changed = false;\n\n for (const [key, session] of this.memoryCache!.entries()) {\n if (!isSessionExpired(session)) continue;\n\n this.memoryCache!.delete(key);\n changed = true;\n }\n\n if (changed) {\n await this.flush();\n }\n }\n\n async disconnect(): Promise<void> {\n // No explicit disconnect needed for file\n }\n}\n","import type { Database } from 'better-sqlite3';\nimport type { SessionStore, Session, SessionCredentials, GetOptions, SessionResult } from './types.js';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport { generateSessionId } from '../../shared/utils.js';\nimport {\n mergeSessionUpdate,\n normalizeNewSession,\n normalizeStoredSession,\n isSessionExpired,\n} from './session-lifecycle.js';\n\nexport interface SqliteStorageOptions {\n path?: string;\n table?: string;\n}\n\nexport class SqliteStorage implements SessionStore {\n private db: Database | null = null;\n private table: string;\n private initialized = false;\n private dbPath: string;\n\n constructor(options: SqliteStorageOptions = {}) {\n this.dbPath = options.path || './sessions.db';\n this.table = options.table || 'mcp_sessions';\n }\n\n async init(): Promise<void> {\n if (this.initialized) return;\n\n try {\n // Dynamic import for peer dependency\n const DatabaseConstructor = (await import('better-sqlite3')).default;\n\n // Ensure directory exists\n const dir = path.dirname(this.dbPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n this.db = new DatabaseConstructor(this.dbPath);\n this.db.pragma('foreign_keys = ON');\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS ${this.table} (\n sessionId TEXT PRIMARY KEY,\n userId TEXT NOT NULL,\n data TEXT NOT NULL,\n expiresAt INTEGER\n );\n CREATE INDEX IF NOT EXISTS idx_${this.table}_userId ON ${this.table}(userId);\n `);\n\n this.initialized = true;\n console.log(`[mcp-ts][Storage] SQLite: ✓ database at ${this.dbPath} verified.`);\n } catch (error: any) {\n if (error.code === 'MODULE_NOT_FOUND' || error.message?.includes('better-sqlite3')) {\n throw new Error(\n 'better-sqlite3 is not installed. Please install it with: npm install better-sqlite3'\n );\n }\n throw error;\n }\n }\n\n private ensureInitialized() {\n if (!this.initialized) {\n throw new Error('SqliteStorage not initialized. Call init() first.');\n }\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n async create(session: Session): Promise<void> {\n this.ensureInitialized();\n const { sessionId, userId } = session;\n\n if (!sessionId || !userId) {\n throw new Error('userId and sessionId required');\n }\n\n const sessionWithLifecycle = normalizeNewSession(session);\n\n try {\n const stmt = this.db!.prepare(\n `INSERT INTO ${this.table} (sessionId, userId, data, expiresAt) VALUES (?, ?, ?, ?)`\n );\n stmt.run(sessionId, userId, JSON.stringify(sessionWithLifecycle), sessionWithLifecycle.expiresAt ?? null);\n } catch (error: any) {\n if (error.code === 'SQLITE_CONSTRAINT_PRIMARYKEY') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n throw error;\n }\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n this.ensureInitialized();\n if (!sessionId || !userId) {\n throw new Error('userId and sessionId required');\n }\n\n const currentSession = await this.get(userId, sessionId);\n if (!currentSession) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const updatedSession = mergeSessionUpdate(currentSession, data);\n\n const stmt = this.db!.prepare(\n `UPDATE ${this.table} SET data = ?, expiresAt = ? WHERE sessionId = ? AND userId = ?`\n );\n\n stmt.run(JSON.stringify(updatedSession), updatedSession.expiresAt ?? null, sessionId, userId);\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n this.ensureInitialized();\n const currentSession = await this.get(userId, sessionId, { includeCredentials: true });\n if (!currentSession) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const updated = { ...currentSession, ...data, sessionId, userId };\n const stmt = this.db!.prepare(\n `UPDATE ${this.table} SET data = ? WHERE sessionId = ? AND userId = ?`\n );\n stmt.run(JSON.stringify(updated), sessionId, userId);\n }\n\n async get(userId: string, sessionId: string, options?: GetOptions): Promise<SessionResult | null> {\n this.ensureInitialized();\n\n const stmt = this.db!.prepare(\n `SELECT data FROM ${this.table} WHERE sessionId = ? AND userId = ?`\n );\n const row = stmt.get(sessionId, userId) as { data: string } | undefined;\n\n if (!row) return null;\n\n const session = normalizeStoredSession(JSON.parse(row.data) as Session);\n if (!options?.includeCredentials) {\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState, ...sessionOnly } = session;\n return sessionOnly as Session;\n }\n return session;\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n this.ensureInitialized();\n const session = await this.get(userId, sessionId, { includeCredentials: true });\n if (!session) return null;\n\n const { clientInformation, tokens, codeVerifier, codeVerifierChallenge, codeVerifierNonce, clientId, oauthState } = session;\n return {\n sessionId, userId,\n clientInformation, tokens, codeVerifier,\n codeVerifierChallenge, codeVerifierNonce,\n clientId, oauthState,\n };\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n await this.patchCredentials(userId, sessionId, {\n clientInformation: null,\n tokens: null,\n codeVerifier: null,\n codeVerifierChallenge: null,\n codeVerifierNonce: null,\n clientId: null,\n oauthState: null,\n });\n }\n\n async list(userId: string): Promise<Session[]> {\n this.ensureInitialized();\n\n const stmt = this.db!.prepare(\n `SELECT data FROM ${this.table} WHERE userId = ?`\n );\n const rows = stmt.all(userId) as { data: string }[];\n\n return rows.map(row => normalizeStoredSession(JSON.parse(row.data) as Session));\n }\n\n async listIds(userId: string): Promise<string[]> {\n this.ensureInitialized();\n\n const stmt = this.db!.prepare(\n `SELECT sessionId FROM ${this.table} WHERE userId = ?`\n );\n const rows = stmt.all(userId) as { sessionId: string }[];\n\n return rows.map(row => row.sessionId);\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n this.ensureInitialized();\n const stmt = this.db!.prepare(\n `DELETE FROM ${this.table} WHERE sessionId = ? AND userId = ?`\n );\n stmt.run(sessionId, userId);\n }\n\n async listAllIds(): Promise<string[]> {\n this.ensureInitialized();\n const stmt = this.db!.prepare(`SELECT sessionId FROM ${this.table}`);\n const rows = stmt.all() as { sessionId: string }[];\n return rows.map(row => row.sessionId);\n }\n\n async clearAll(): Promise<void> {\n this.ensureInitialized();\n const stmt = this.db!.prepare(`DELETE FROM ${this.table}`);\n stmt.run();\n }\n\n async cleanupExpired(): Promise<void> {\n this.ensureInitialized();\n const rows = this.db!.prepare(`SELECT sessionId, userId, data FROM ${this.table}`).all() as {\n sessionId: string;\n userId: string;\n data: string;\n }[];\n const deleteStmt = this.db!.prepare(`DELETE FROM ${this.table} WHERE sessionId = ? AND userId = ?`);\n\n for (const row of rows) {\n const session = normalizeStoredSession(JSON.parse(row.data) as Session);\n if (isSessionExpired(session)) {\n deleteStmt.run(row.sessionId, row.userId);\n }\n }\n }\n\n async disconnect(): Promise<void> {\n if (this.db) {\n this.db.close();\n }\n }\n}\n","import { randomBytes, createCipheriv, createDecipheriv } from 'node:crypto';\n\nconst ALGORITHM = 'aes-256-gcm';\nconst IV_LENGTH = 12;\nconst ENCRYPTION_PREFIX = 'enc:1:';\n\nlet warningLogged = false;\n\nfunction getKey(): Buffer | null {\n const keyString = process.env.STORAGE_ENCRYPTION_KEY;\n if (!keyString) return null;\n \n // Ensure key is 32 bytes (256 bits)\n if (keyString.length === 64) {\n return Buffer.from(keyString, 'hex');\n } else {\n const keyBuffer = Buffer.alloc(32);\n keyBuffer.write(keyString, 0, 32, 'utf-8');\n return keyBuffer;\n }\n}\n\n/**\n * Encrypts an object into a secure string.\n * Falls back to returning the original object if the encryption key is missing or encryption fails.\n */\nexport function encryptObject(data: any): any {\n if (data === undefined || data === null) return data;\n \n const key = getKey();\n if (!key) {\n if (!warningLogged) {\n console.warn('[mcp-ts][Storage] WARNING: STORAGE_ENCRYPTION_KEY is not set. Saving sensitive data in plain-text.');\n warningLogged = true;\n }\n return data; // Fallback to plain-text\n }\n\n try {\n const text = JSON.stringify(data);\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv(ALGORITHM, key, iv);\n \n let encrypted = cipher.update(text, 'utf-8', 'hex');\n encrypted += cipher.final('hex');\n const authTag = cipher.getAuthTag().toString('hex');\n \n return `${ENCRYPTION_PREFIX}${iv.toString('hex')}:${authTag}:${encrypted}`;\n } catch (e) {\n console.error('[mcp-ts][Storage] Encryption failed, falling back to plain-text.', e);\n return data;\n }\n}\n\n/**\n * Decrypts a secure string back into an object.\n * Returns the original data if it is unencrypted or if decryption fails.\n */\nexport function decryptObject(data: any): any {\n if (data === undefined || data === null) return data;\n if (typeof data !== 'string' || !data.startsWith(ENCRYPTION_PREFIX)) {\n return data; // Already unencrypted or old plain-text data\n }\n\n const key = getKey();\n if (!key) {\n console.warn('[mcp-ts][Storage] WARNING: Found encrypted data but STORAGE_ENCRYPTION_KEY is missing. Returning raw encrypted string.');\n return data;\n }\n\n try {\n const parts = data.split(':');\n if (parts.length !== 5) {\n return data;\n }\n\n const iv = Buffer.from(parts[2], 'hex');\n const authTag = Buffer.from(parts[3], 'hex');\n const encryptedText = parts[4];\n\n const decipher = createDecipheriv(ALGORITHM, key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encryptedText, 'hex', 'utf-8');\n decrypted += decipher.final('utf-8');\n\n return JSON.parse(decrypted);\n } catch (e) {\n console.error('[mcp-ts][Storage] Decryption failed.', e);\n return data;\n }\n}\n","import type { SupabaseClient } from '@supabase/supabase-js';\nimport type { SessionStore, Session, SessionCredentials, GetOptions, SessionResult } from './types.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport { encryptObject, decryptObject } from './crypto.js';\nimport { resolveSessionExpiresAt } from './session-lifecycle.js';\nimport { normalizeToolPolicy } from './tool-policy.js';\nimport { DORMANT_SESSION_EXPIRATION_MS } from '../../shared/constants.js';\n\nexport class SupabaseStorageBackend implements SessionStore {\n constructor(private supabase: SupabaseClient) {}\n\n async init(): Promise<void> {\n await this.assertTable('mcp_sessions', 'session_id');\n console.log('[mcp-ts][Storage] Supabase: storage tables verified.');\n }\n\n private async assertTable(table: string, column: string): Promise<void> {\n const { error } = await this.supabase\n .from(table)\n .select(column)\n .limit(0);\n\n if (!error) return;\n\n if (error.code === '42P01') {\n throw new Error(\n `[SupabaseStorage] Table \"${table}\" not found in your database. ` +\n 'Please run \"npx mcp-ts supabase-init\" to set up the required storage schema.'\n );\n }\n\n throw new Error(`[SupabaseStorage] Initialization check failed for \"${table}\": ${error.message}`);\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n private mapRowToSessionData(row: any): Session {\n return {\n sessionId: row.session_id,\n serverId: row.server_id,\n serverName: row.server_name,\n serverUrl: row.server_url,\n transportType: row.transport_type,\n callbackUrl: row.callback_url,\n createdAt: new Date(row.created_at).getTime(),\n updatedAt: new Date(row.updated_at ?? row.created_at).getTime(),\n expiresAt: row.expires_at ? new Date(row.expires_at).getTime() : null,\n userId: row.user_id,\n headers: decryptObject(row.headers),\n authUrl: row.auth_url,\n status: row.status ?? 'pending',\n toolPolicy: normalizeToolPolicy(row.tool_policy),\n clientInformation: decryptObject(row.client_information),\n tokens: decryptObject(row.tokens),\n codeVerifier: decryptObject(row.code_verifier),\n clientId: row.client_id,\n oauthState: row.oauth_state,\n enabled: row.enabled ?? true,\n };\n }\n\n private hasCredentialData(data: Partial<SessionCredentials>): boolean {\n return (\n 'clientInformation' in data ||\n 'tokens' in data ||\n 'codeVerifier' in data ||\n 'clientId' in data ||\n 'oauthState' in data\n );\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const status = session.status ?? 'pending';\n const createdAt = new Date(session.createdAt || Date.now()).toISOString();\n const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();\n const expiresAt = resolveSessionExpiresAt(status, new Date(createdAt).getTime());\n\n const insertData: Record<string, unknown> = {\n session_id: sessionId,\n user_id: userId,\n server_id: session.serverId,\n server_name: session.serverName,\n server_url: session.serverUrl,\n transport_type: session.transportType,\n callback_url: session.callbackUrl,\n created_at: createdAt,\n updated_at: updatedAt,\n headers: encryptObject(session.headers),\n auth_url: session.authUrl ?? null,\n status,\n expires_at: expiresAt === null ? null : new Date(expiresAt).toISOString(),\n };\n\n const toolPolicy = normalizeToolPolicy(session.toolPolicy);\n if (toolPolicy) {\n insertData.tool_policy = toolPolicy;\n }\n\n const { error } = await this.supabase\n .from('mcp_sessions')\n .insert(insertData);\n\n if (error) {\n if (error.code === '23505') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n throw new Error(`Failed to create session in Supabase: ${error.message}`);\n }\n\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n const updateData: any = {\n updated_at: new Date().toISOString(),\n };\n\n if ('serverId' in data) updateData.server_id = data.serverId;\n if ('serverName' in data) updateData.server_name = data.serverName;\n if ('serverUrl' in data) updateData.server_url = data.serverUrl;\n if ('transportType' in data) updateData.transport_type = data.transportType;\n if ('callbackUrl' in data) updateData.callback_url = data.callbackUrl;\n if ('status' in data) {\n const status = data.status ?? 'pending';\n const expiresAt = resolveSessionExpiresAt(status);\n updateData.status = status;\n updateData.expires_at = expiresAt === null ? null : new Date(expiresAt).toISOString();\n }\n if ('headers' in data) updateData.headers = encryptObject(data.headers);\n if ('authUrl' in data) updateData.auth_url = data.authUrl ?? null;\n if ('toolPolicy' in data) updateData.tool_policy = normalizeToolPolicy(data.toolPolicy);\n if ('enabled' in data) updateData.enabled = data.enabled;\n\n const shouldUpdateSession = Object.keys(updateData).some((key) => key !== 'updated_at');\n\n let updatedRows: any[] | null = null;\n if (shouldUpdateSession) {\n const result = await this.supabase\n .from('mcp_sessions')\n .update(updateData)\n .eq('user_id', userId)\n .eq('session_id', sessionId)\n .select('id');\n\n if (result.error) {\n throw new Error(`Failed to update session: ${result.error.message}`);\n }\n updatedRows = result.data;\n } else {\n const result = await this.supabase\n .from('mcp_sessions')\n .select('id')\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (result.error) {\n throw new Error(`Failed to update session: ${result.error.message}`);\n }\n updatedRows = result.data;\n }\n\n if (!updatedRows || updatedRows.length === 0) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n if (!this.hasCredentialData(data)) return;\n\n const updateData: Record<string, unknown> = {\n updated_at: new Date().toISOString(),\n };\n\n if ('clientInformation' in data) updateData.client_information = data.clientInformation == null ? null : encryptObject(data.clientInformation);\n if ('tokens' in data) updateData.tokens = data.tokens == null ? null : encryptObject(data.tokens);\n if ('codeVerifier' in data) updateData.code_verifier = data.codeVerifier == null ? null : encryptObject(data.codeVerifier);\n if ('clientId' in data) updateData.client_id = data.clientId ?? null;\n if ('oauthState' in data) updateData.oauth_state = data.oauthState ?? null;\n\n const { error } = await this.supabase\n .from('mcp_sessions')\n .update(updateData)\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (error) {\n throw new Error(`Failed to update credentials: ${error.message}`);\n }\n }\n\n async get(userId: string, sessionId: string, options?: GetOptions): Promise<SessionResult | null> {\n const selection = options?.includeCredentials\n ? '*'\n : 'session_id, user_id, server_id, server_name, server_url, transport_type, callback_url, created_at, updated_at, expires_at, headers, auth_url, status, tool_policy, enabled';\n\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select(selection)\n .eq('user_id', userId)\n .eq('session_id', sessionId)\n .maybeSingle();\n\n if (error) {\n console.error('[SupabaseStorage] Failed to get session:', error);\n return null;\n }\n\n if (!data) return null;\n\n return this.mapRowToSessionData(data);\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('client_information, tokens, code_verifier, client_id, oauth_state')\n .eq('user_id', userId)\n .eq('session_id', sessionId)\n .maybeSingle();\n\n if (error) {\n console.error('[SupabaseStorage] Failed to get credentials:', error);\n return null;\n }\n\n if (!data) return null;\n\n return {\n sessionId,\n userId,\n clientInformation: decryptObject(data.client_information),\n tokens: decryptObject(data.tokens),\n codeVerifier: decryptObject(data.code_verifier),\n clientId: data.client_id,\n oauthState: data.oauth_state,\n };\n }\n\n async list(userId: string): Promise<Session[]> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('*')\n .eq('user_id', userId);\n\n if (error) {\n console.error(`[SupabaseStorage] Failed to get session data for ${userId}:`, error);\n return [];\n }\n\n return data.map(row => this.mapRowToSessionData(row));\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n const { error } = await this.supabase\n .from('mcp_sessions')\n .update({\n client_information: null,\n tokens: null,\n code_verifier: null,\n client_id: null,\n oauth_state: null,\n updated_at: new Date().toISOString(),\n })\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (error) {\n throw new Error(`Failed to clear credentials: ${error.message}`);\n }\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n const { error } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .eq('user_id', userId)\n .eq('session_id', sessionId);\n\n if (error) {\n console.error('[SupabaseStorage] Failed to remove session:', error);\n }\n }\n\n async listIds(userId: string): Promise<string[]> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('session_id')\n .eq('user_id', userId);\n\n if (error) {\n console.error(`[SupabaseStorage] Failed to get sessions for ${userId}:`, error);\n return [];\n }\n\n return data.map(row => row.session_id);\n }\n\n async listAllIds(): Promise<string[]> {\n const { data, error } = await this.supabase\n .from('mcp_sessions')\n .select('session_id');\n\n if (error) {\n console.error('[SupabaseStorage] Failed to get all sessions:', error);\n return [];\n }\n\n return data.map(row => row.session_id);\n }\n\n async clearAll(): Promise<void> {\n const { error } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .neq('session_id', '');\n\n if (error) {\n console.error('[SupabaseStorage] Failed to clear sessions:', error);\n }\n }\n\n async cleanupExpired(): Promise<void> {\n const { error: transientError } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .not('expires_at', 'is', null)\n .neq('status', 'active')\n .lt('expires_at', new Date().toISOString());\n\n if (transientError) {\n console.error('[SupabaseStorage] Failed to cleanup expired inactive sessions:', transientError);\n }\n\n const dormantCutoff = new Date(Date.now() - DORMANT_SESSION_EXPIRATION_MS).toISOString();\n const { error: dormantError } = await this.supabase\n .from('mcp_sessions')\n .delete()\n .eq('status', 'active')\n .lt('updated_at', dormantCutoff);\n\n if (dormantError) {\n console.error('[SupabaseStorage] Failed to cleanup dormant active sessions:', dormantError);\n }\n }\n\n async disconnect(): Promise<void> {\n // Supabase client handles its own connection pooling over HTTP.\n }\n}\n\n\n","import type { SessionStore, Session, SessionCredentials, GetOptions, SessionResult } from './types.js';\nimport type { SessionStatus } from './types.js';\nimport { DORMANT_SESSION_EXPIRATION_MS } from '../../shared/constants.js';\nimport { generateSessionId } from '../../shared/utils.js';\nimport { encryptObject, decryptObject } from './crypto.js';\nimport { resolveSessionExpiresAt } from './session-lifecycle.js';\nimport { normalizeToolPolicy } from './tool-policy.js';\n\nexport interface NeonStorageOptions {\n schema?: string;\n table?: string;\n}\n\ntype NeonSql = {\n query(queryWithPlaceholders: string, params?: unknown[]): Promise<any[]>;\n};\n\ntype NeonSessionRow = {\n id?: string;\n session_id: string;\n server_id?: string | null;\n server_name?: string | null;\n server_url: string;\n transport_type: 'sse' | 'streamable-http';\n callback_url: string;\n created_at: string | Date;\n updated_at?: string | Date | null;\n expires_at?: string | Date | null;\n user_id: string;\n headers?: unknown;\n auth_url?: string | null;\n status?: SessionStatus | null;\n tool_policy?: unknown;\n client_information?: unknown;\n tokens?: unknown;\n code_verifier?: unknown;\n client_id?: string | null;\n oauth_state?: unknown;\n enabled?: boolean;\n};\n\nexport class NeonStorageBackend implements SessionStore {\n private readonly tableName: string;\n\n constructor(\n private readonly sql: NeonSql,\n options: NeonStorageOptions = {}\n ) {\n const schema = options.schema || 'public';\n const table = options.table || 'mcp_sessions';\n this.tableName = `${this.quoteIdentifier(schema)}.${this.quoteIdentifier(table)}`;\n }\n\n async init(): Promise<void> {\n await this.assertTable(this.tableName, 'mcp_sessions');\n console.log('[mcp-ts][Storage] Neon: storage tables verified.');\n }\n\n private async assertTable(qualifiedName: string, displayName: string): Promise<void> {\n const [{ exists } = { exists: null }] = await this.sql.query(\n 'SELECT to_regclass($1) AS exists',\n [qualifiedName.replace(/\"/g, '')]\n ) as Array<{ exists: string | null }>;\n\n if (!exists) {\n throw new Error(\n `[NeonStorage] Table \"${displayName}\" not found in your database. ` +\n 'Please create it using the Neon storage guide in docs/storage-backends/neon.md.'\n );\n }\n }\n\n generateSessionId(): string {\n return generateSessionId();\n }\n\n private quoteIdentifier(identifier: string): string {\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(identifier)) {\n throw new Error(`Invalid Neon storage identifier: ${identifier}`);\n }\n return `\"${identifier}\"`;\n }\n\n private mapRowToSessionData(row: NeonSessionRow): Session {\n return {\n sessionId: row.session_id,\n serverId: row.server_id ?? undefined,\n serverName: row.server_name ?? undefined,\n serverUrl: row.server_url,\n transportType: row.transport_type,\n callbackUrl: row.callback_url,\n createdAt: new Date(row.created_at).getTime(),\n updatedAt: new Date(row.updated_at ?? row.created_at).getTime(),\n expiresAt: row.expires_at ? new Date(row.expires_at).getTime() : null,\n userId: row.user_id,\n headers: decryptObject(row.headers),\n authUrl: row.auth_url ?? undefined,\n status: row.status ?? 'pending',\n toolPolicy: normalizeToolPolicy(row.tool_policy as Parameters<typeof normalizeToolPolicy>[0]),\n clientInformation: decryptObject(row.client_information),\n tokens: decryptObject(row.tokens),\n codeVerifier: decryptObject(row.code_verifier),\n clientId: row.client_id ?? undefined,\n oauthState: row.oauth_state as Session['oauthState'],\n enabled: row.enabled ?? true,\n };\n }\n\n private hasCredentialData(data: Partial<SessionCredentials>): boolean {\n return (\n 'clientInformation' in data ||\n 'tokens' in data ||\n 'codeVerifier' in data ||\n 'clientId' in data ||\n 'oauthState' in data\n );\n }\n\n async create(session: Session): Promise<void> {\n const { sessionId, userId } = session;\n if (!sessionId || !userId) throw new Error('userId and sessionId required');\n\n const status = session.status ?? 'pending';\n const createdAt = new Date(session.createdAt || Date.now()).toISOString();\n const updatedAt = new Date(session.updatedAt ?? session.createdAt ?? Date.now()).toISOString();\n const createdAtMs = new Date(createdAt).getTime();\n const expiresAt = resolveSessionExpiresAt(status, createdAtMs);\n const toolPolicy = normalizeToolPolicy(session.toolPolicy, createdAtMs);\n\n const columns: string[] = [\n 'session_id', 'user_id', 'server_id', 'server_name',\n 'server_url', 'transport_type', 'callback_url',\n 'created_at', 'updated_at', 'headers', 'auth_url',\n 'status', 'expires_at',\n ];\n const values: unknown[] = [\n sessionId, userId, session.serverId, session.serverName,\n session.serverUrl, session.transportType, session.callbackUrl,\n createdAt, updatedAt, encryptObject(session.headers),\n session.authUrl ?? null, status,\n expiresAt === null ? null : new Date(expiresAt).toISOString(),\n ];\n\n if (toolPolicy) {\n columns.push('tool_policy');\n values.push(toolPolicy);\n }\n\n const placeholders = values.map((_, i) => `$${i + 1}`);\n\n try {\n await this.sql.query(\n `INSERT INTO ${this.tableName} (${columns.join(', ')}) VALUES (${placeholders.join(', ')})`,\n values\n );\n } catch (error: any) {\n if (error.code === '23505') {\n throw new Error(`Session ${sessionId} already exists`);\n }\n throw new Error(`Failed to create session in Neon: ${error.message}`);\n }\n\n }\n\n async update(userId: string, sessionId: string, data: Partial<Session>): Promise<void> {\n const currentSession = await this.get(userId, sessionId);\n if (!currentSession) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n\n const updatedSession = { ...currentSession, ...data };\n const status = updatedSession.status ?? 'pending';\n const expiresAt = resolveSessionExpiresAt(status);\n\n const shouldUpdateSession = (\n 'serverId' in data ||\n 'serverName' in data ||\n 'serverUrl' in data ||\n 'transportType' in data ||\n 'callbackUrl' in data ||\n 'status' in data ||\n 'headers' in data ||\n 'authUrl' in data ||\n 'toolPolicy' in data ||\n 'enabled' in data\n );\n\n if (shouldUpdateSession) {\n const setClauses: string[] = [];\n const values: unknown[] = [];\n let paramIndex = 1;\n\n const addSet = (column: string, value: unknown) => {\n setClauses.push(`${column} = $${paramIndex++}`);\n values.push(value);\n };\n\n addSet('server_id', updatedSession.serverId);\n addSet('server_name', updatedSession.serverName);\n addSet('server_url', updatedSession.serverUrl);\n addSet('transport_type', updatedSession.transportType);\n addSet('callback_url', updatedSession.callbackUrl);\n addSet('status', status);\n addSet('headers', encryptObject(updatedSession.headers));\n addSet('auth_url', updatedSession.authUrl ?? null);\n addSet('expires_at', expiresAt === null ? null : new Date(expiresAt).toISOString());\n\n if ('toolPolicy' in data) {\n const policyUpdatedAt = updatedSession.updatedAt ?? Date.now();\n const toolPolicy = normalizeToolPolicy(updatedSession.toolPolicy, policyUpdatedAt) ?? { mode: 'all' as const, toolIds: [], updatedAt: policyUpdatedAt };\n addSet('tool_policy', toolPolicy);\n }\n\n if ('enabled' in data) {\n addSet('enabled', updatedSession.enabled);\n }\n\n setClauses.push('updated_at = now()');\n\n const updatedRows = await this.sql.query(\n `UPDATE ${this.tableName}\n SET ${setClauses.join(', ')}\n WHERE user_id = $${paramIndex++} AND session_id = $${paramIndex++}\n RETURNING id`,\n [...values, userId, sessionId]\n ) as Array<{ id: string }>;\n\n if (updatedRows.length === 0) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n }\n\n }\n\n async patchCredentials(userId: string, sessionId: string, data: Partial<SessionCredentials>): Promise<void> {\n if (!this.hasCredentialData(data)) return;\n const setClauses: string[] = [];\n const values: unknown[] = [];\n let paramIndex = 1;\n\n const addSet = (column: string, value: unknown) => {\n setClauses.push(`${column} = $${paramIndex++}`);\n values.push(value);\n };\n\n if ('clientInformation' in data) {\n addSet('client_information', data.clientInformation == null ? null : encryptObject(data.clientInformation));\n }\n if ('tokens' in data) {\n addSet('tokens', data.tokens == null ? null : encryptObject(data.tokens));\n }\n if ('codeVerifier' in data) {\n addSet('code_verifier', data.codeVerifier == null ? null : encryptObject(data.codeVerifier));\n }\n if ('clientId' in data) {\n addSet('client_id', data.clientId ?? null);\n }\n if ('oauthState' in data) {\n addSet('oauth_state', data.oauthState ?? null);\n }\n\n setClauses.push('updated_at = now()');\n\n const updatedRows = await this.sql.query(\n `UPDATE ${this.tableName}\n SET ${setClauses.join(', ')}\n WHERE user_id = $${paramIndex++} AND session_id = $${paramIndex++}\n RETURNING id`,\n [...values, userId, sessionId]\n ) as Array<{ id: string }>;\n\n if (updatedRows.length === 0) {\n throw new Error(`Session ${sessionId} not found for userId ${userId}`);\n }\n }\n\n async get(userId: string, sessionId: string, options?: GetOptions): Promise<SessionResult | null> {\n try {\n const selection = options?.includeCredentials\n ? '*'\n : 'session_id, user_id, server_id, server_name, server_url, transport_type, callback_url, created_at, updated_at, expires_at, headers, auth_url, status, tool_policy, enabled';\n\n const rows = await this.sql.query(\n `SELECT ${selection} FROM ${this.tableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n ) as NeonSessionRow[];\n\n if (!rows[0]) return null;\n return this.mapRowToSessionData(rows[0]);\n } catch (error) {\n console.error('[NeonStorage] Failed to get session:', error);\n return null;\n }\n }\n\n async getCredentials(userId: string, sessionId: string): Promise<SessionCredentials | null> {\n try {\n const rows = await this.sql.query(\n `SELECT client_information, tokens, code_verifier, client_id, oauth_state\n FROM ${this.tableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n ) as NeonSessionRow[];\n\n if (!rows[0]) return null;\n const row = rows[0];\n return {\n sessionId,\n userId,\n clientInformation: decryptObject(row.client_information),\n tokens: decryptObject(row.tokens),\n codeVerifier: decryptObject(row.code_verifier),\n clientId: row.client_id ?? undefined,\n oauthState: row.oauth_state as SessionCredentials['oauthState'],\n };\n } catch (error) {\n console.error('[NeonStorage] Failed to get credentials:', error);\n return null;\n }\n }\n\n async list(userId: string): Promise<Session[]> {\n try {\n const rows = await this.sql.query(\n `SELECT * FROM ${this.tableName} WHERE user_id = $1`,\n [userId]\n ) as NeonSessionRow[];\n return rows.map((row) => this.mapRowToSessionData(row));\n } catch (error) {\n console.error(`[NeonStorage] Failed to get session data for ${userId}:`, error);\n return [];\n }\n }\n\n async clearCredentials(userId: string, sessionId: string): Promise<void> {\n try {\n await this.sql.query(\n `UPDATE ${this.tableName}\n SET client_information = null, tokens = null, code_verifier = null, client_id = null, oauth_state = null, updated_at = now()\n WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n );\n } catch (error) {\n console.error('[NeonStorage] Failed to clear credentials:', error);\n }\n }\n\n async delete(userId: string, sessionId: string): Promise<void> {\n try {\n await this.sql.query(\n `DELETE FROM ${this.tableName} WHERE user_id = $1 AND session_id = $2`,\n [userId, sessionId]\n );\n } catch (error) {\n console.error('[NeonStorage] Failed to remove session:', error);\n }\n }\n\n async listIds(userId: string): Promise<string[]> {\n try {\n const rows = await this.sql.query(\n `SELECT session_id FROM ${this.tableName} WHERE user_id = $1`,\n [userId]\n ) as Array<{ session_id: string }>;\n return rows.map((row) => row.session_id);\n } catch (error) {\n console.error(`[NeonStorage] Failed to get sessions for ${userId}:`, error);\n return [];\n }\n }\n\n async listAllIds(): Promise<string[]> {\n try {\n const rows = await this.sql.query(\n `SELECT session_id FROM ${this.tableName}`\n ) as Array<{ session_id: string }>;\n return rows.map((row) => row.session_id);\n } catch (error) {\n console.error('[NeonStorage] Failed to get all sessions:', error);\n return [];\n }\n }\n\n async clearAll(): Promise<void> {\n try {\n await this.sql.query(`DELETE FROM ${this.tableName}`);\n } catch (error) {\n console.error('[NeonStorage] Failed to clear sessions:', error);\n }\n }\n\n async cleanupExpired(): Promise<void> {\n try {\n await this.sql.query(\n `DELETE FROM ${this.tableName}\n WHERE expires_at IS NOT NULL\n AND expires_at < $1\n AND status <> 'active'`,\n [new Date().toISOString()]\n );\n await this.sql.query(\n `DELETE FROM ${this.tableName}\n WHERE status = 'active' AND updated_at < $1`,\n [new Date(Date.now() - DORMANT_SESSION_EXPIRATION_MS).toISOString()]\n );\n } catch (error) {\n console.error('[NeonStorage] Failed to cleanup expired sessions:', error);\n }\n }\n\n async disconnect(): Promise<void> {\n // Neon HTTP queries do not hold a persistent connection.\n }\n}\n\n\n\n\n","\nimport { RedisStorageBackend } from './redis-backend';\nimport { MemoryStorageBackend } from './memory-backend';\nimport { FileStorageBackend } from './file-backend';\nimport { SqliteStorage } from './sqlite-backend.js';\nimport { SupabaseStorageBackend } from './supabase-backend.js';\nimport { NeonStorageBackend, type NeonStorageOptions } from './neon-backend.js';\nimport type { SessionStore, Session, SessionMutationEvent, SessionMutationListener } from './types.js';\nimport type { McpObservabilityEvent } from '../../shared/events.js';\n\n// Re-export types\nexport * from './types.js';\nexport { generateSessionId, generateServerId } from '../../shared/utils.js';\nexport { RedisStorageBackend, MemoryStorageBackend, FileStorageBackend, SqliteStorage, SupabaseStorageBackend, NeonStorageBackend };\n\nexport function createSupabaseStorageBackend(client: any): SupabaseStorageBackend {\n return new SupabaseStorageBackend(client);\n}\n\nexport function createNeonStorageBackend(sql: any, options?: NeonStorageOptions): NeonStorageBackend {\n return new NeonStorageBackend(sql, options);\n}\n\nfunction warnIfNeonConnectionStringIsInsecure(connectionString: string): void {\n try {\n const url = new URL(connectionString);\n const sslMode = url.searchParams.get('sslmode');\n const channelBinding = url.searchParams.get('channel_binding');\n\n if (!sslMode) {\n console.warn('[mcp-ts][Storage] Neon connection string does not include sslmode. Neon recommends sslmode=verify-full for the strongest certificate verification.');\n } else if (!['verify-full', 'require'].includes(sslMode)) {\n console.warn(`[mcp-ts][Storage] Neon connection string uses sslmode=${sslMode}. Use sslmode=verify-full or sslmode=require for secure connections.`);\n }\n\n if (!channelBinding) {\n console.warn('[mcp-ts][Storage] Neon connection string does not include channel_binding=require. Add it when supported by your runtime and connection path.');\n }\n } catch {\n console.warn('[mcp-ts][Storage] Neon connection string could not be parsed for SSL checks.');\n }\n}\n\nlet storageInstance: SessionStore | null = null;\nlet storagePromise: Promise<SessionStore> | null = null;\nconst sessionMutationListeners = new Set<SessionMutationListener>();\n\nfunction emitSessionMutation(event: SessionMutationEvent): void {\n for (const listener of sessionMutationListeners) {\n try {\n const result = listener(event);\n if (result && typeof (result as Promise<void>).catch === 'function') {\n void (result as Promise<void>).catch((error) => {\n console.error('[mcp-ts][Storage] Session mutation listener failed:', error);\n });\n }\n } catch (error) {\n console.error('[mcp-ts][Storage] Session mutation listener failed:', error);\n }\n }\n}\n\nfunction createSessionMutationEvent(prop: PropertyKey, args: any[]): SessionMutationEvent | null {\n const timestamp = Date.now();\n\n if (prop === 'create') {\n const [session] = args as [Session];\n if (!session?.userId || !session?.sessionId) return null;\n return {\n type: 'create',\n userId: session.userId,\n sessionId: session.sessionId,\n session,\n timestamp,\n };\n }\n\n if (prop === 'update') {\n const [userId, sessionId, patch] = args as [string, string, Partial<Session>];\n if (!userId || !sessionId) return null;\n return {\n type: 'update',\n userId,\n sessionId,\n patch,\n timestamp,\n };\n }\n\n if (prop === 'delete') {\n const [userId, sessionId] = args as [string, string];\n if (!userId || !sessionId) return null;\n return {\n type: 'delete',\n userId,\n sessionId,\n timestamp,\n };\n }\n\n return null;\n}\n\nasync function initializeStorage<T extends SessionStore>(store: T): Promise<T> {\n if (typeof store.init === 'function') {\n await store.init();\n }\n return store;\n}\n\nasync function createStorage(): Promise<SessionStore> {\n const type = process.env.MCP_TS_STORAGE_TYPE?.toLowerCase();\n\n // Explicit selection\n if (type === 'redis') {\n if (!process.env.REDIS_URL) {\n console.warn('[Storage] MCP_TS_STORAGE_TYPE is \"redis\" but REDIS_URL is missing');\n }\n try {\n const { getRedis } = await import('./redis.js');\n const redis = await getRedis();\n console.log('[mcp-ts][Storage] Explicit selection: \"redis\"');\n return await initializeStorage(new RedisStorageBackend(redis));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Failed to initialize Redis:', error.message);\n console.log('[mcp-ts][Storage] Falling back to In-Memory storage');\n return await initializeStorage(new MemoryStorageBackend());\n }\n }\n\n if (type === 'file') {\n const filePath = process.env.MCP_TS_STORAGE_FILE;\n console.log(`[mcp-ts][Storage] Explicit selection: \"file\" (${filePath || 'default'})`);\n return await initializeStorage(new FileStorageBackend({ path: filePath }));\n }\n\n if (type === 'sqlite') {\n const dbPath = process.env.MCP_TS_STORAGE_SQLITE_PATH;\n console.log(`[mcp-ts][Storage] Explicit selection: \"sqlite\" (${dbPath || 'default'})`);\n return await initializeStorage(new SqliteStorage({ path: dbPath }));\n }\n\n if (type === 'supabase') {\n const url = process.env.SUPABASE_URL;\n const key = process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY;\n \n if (!url || !key) {\n console.warn('[mcp-ts][Storage] Explicit selection \"supabase\" requires SUPABASE_URL and SUPABASE_SECRET_KEY.');\n } else {\n if (!process.env.SUPABASE_SECRET_KEY) {\n console.warn('[mcp-ts][Storage] ⚠️ Warning: Using \"SUPABASE_ANON_KEY\" for server-side storage. You may encounter RLS policy violations. \"SUPABASE_SECRET_KEY\" is recommended.');\n }\n try {\n const { createClient } = await import('@supabase/supabase-js');\n const client = createClient(url, key);\n console.log('[mcp-ts][Storage] Explicit selection: \"supabase\"');\n return await initializeStorage(new SupabaseStorageBackend(client as any));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Failed to initialize Supabase:', error.message);\n console.log('[mcp-ts][Storage] Falling back to In-Memory storage');\n return await initializeStorage(new MemoryStorageBackend());\n }\n }\n }\n\n if (type === 'neon') {\n const connectionString = process.env.NEON_DATABASE_URL || process.env.DATABASE_URL;\n\n if (!connectionString) {\n console.warn('[mcp-ts][Storage] Explicit selection \"neon\" requires NEON_DATABASE_URL or DATABASE_URL.');\n } else {\n try {\n const { neon } = await import('@neondatabase/serverless');\n warnIfNeonConnectionStringIsInsecure(connectionString);\n const sql = neon(connectionString);\n console.log('[mcp-ts][Storage] Explicit selection: \"neon\"');\n return await initializeStorage(new NeonStorageBackend(sql));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Failed to initialize Neon:', error.message);\n console.log('[mcp-ts][Storage] Falling back to In-Memory storage');\n return await initializeStorage(new MemoryStorageBackend());\n }\n }\n }\n\n if (type === 'memory') {\n console.log('[mcp-ts][Storage] Explicit selection: \"memory\"');\n return await initializeStorage(new MemoryStorageBackend());\n }\n\n // Automatic inference (Fallback)\n if (process.env.REDIS_URL) {\n try {\n const { getRedis } = await import('./redis.js');\n const redis = await getRedis();\n console.log('[mcp-ts][Storage] Auto-detection: \"redis\" (via REDIS_URL)');\n return await initializeStorage(new RedisStorageBackend(redis));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Redis auto-detection failed:', error.message);\n console.log('[mcp-ts][Storage] Falling back to next available backend');\n }\n }\n\n if (process.env.MCP_TS_STORAGE_FILE) {\n console.log(`[mcp-ts][Storage] Auto-detection: \"file\" (${process.env.MCP_TS_STORAGE_FILE})`);\n return await initializeStorage(new FileStorageBackend({ path: process.env.MCP_TS_STORAGE_FILE }));\n }\n\n if (process.env.MCP_TS_STORAGE_SQLITE_PATH) {\n console.log(`[mcp-ts][Storage] Auto-detection: \"sqlite\" (${process.env.MCP_TS_STORAGE_SQLITE_PATH})`);\n return await initializeStorage(new SqliteStorage({ path: process.env.MCP_TS_STORAGE_SQLITE_PATH }));\n }\n\n if (process.env.SUPABASE_URL && (process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY)) {\n try {\n const { createClient } = await import('@supabase/supabase-js');\n const url = process.env.SUPABASE_URL;\n const key = process.env.SUPABASE_SECRET_KEY || process.env.SUPABASE_ANON_KEY!;\n \n if (!process.env.SUPABASE_SECRET_KEY) {\n console.warn('[mcp-ts][Storage] ⚠️ Warning: Using \"SUPABASE_ANON_KEY\" for server-side storage. You may encounter RLS policy violations. \"SUPABASE_SECRET_KEY\" is recommended.');\n }\n\n const client = createClient(url, key);\n console.log('[mcp-ts][Storage] Auto-detection: \"supabase\" (via SUPABASE_URL)');\n return await initializeStorage(new SupabaseStorageBackend(client as any));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Supabase auto-detection failed:', error.message);\n }\n }\n\n if (process.env.NEON_DATABASE_URL) {\n try {\n const { neon } = await import('@neondatabase/serverless');\n warnIfNeonConnectionStringIsInsecure(process.env.NEON_DATABASE_URL);\n const sql = neon(process.env.NEON_DATABASE_URL);\n console.log('[mcp-ts][Storage] Auto-detection: \"neon\" (via NEON_DATABASE_URL)');\n return await initializeStorage(new NeonStorageBackend(sql));\n } catch (error: any) {\n console.error('[mcp-ts][Storage] Neon auto-detection failed:', error.message);\n }\n }\n\n console.log('[mcp-ts][Storage] Defaulting to: \"memory\"');\n return await initializeStorage(new MemoryStorageBackend());\n}\n\nasync function getStorage(): Promise<SessionStore> {\n if (storageInstance) {\n return storageInstance;\n }\n\n if (!storagePromise) {\n storagePromise = createStorage().catch((error) => {\n storagePromise = null;\n throw error;\n });\n }\n\n storageInstance = await storagePromise;\n return storageInstance;\n}\n\n/**\n * Set the storage instance (for testing)\n * @internal\n * @param instance - SessionStore instance or null to reset\n */\nexport function _setStorageInstanceForTesting(instance: SessionStore | null): void {\n storageInstance = instance;\n if (!instance) {\n storagePromise = null;\n }\n}\n\nexport function onSessionMutation(listener: SessionMutationListener): () => void {\n sessionMutationListeners.add(listener);\n return () => {\n sessionMutationListeners.delete(listener);\n };\n}\n\nexport function _resetSessionMutationListenersForTesting(): void {\n sessionMutationListeners.clear();\n}\n\n/**\n * Wraps a SessionStore with a Proxy that emits an McpObservabilityEvent for every\n * method call — reads (`db:read`) and writes (`db:write`) — including duration\n * and any error. Useful for debugging connection flows end-to-end.\n *\n * Usage:\n * ```ts\n * import { sessions, withDbObservability } from '@mcp-ts/sdk/server/storage';\n * const db = withDbObservability(sessions, (event) => console.log('[DB]', event));\n * // Use `db` instead of `sessions` throughout the request\n * ```\n *\n * @param store - The underlying SessionStore instance to wrap.\n * @param emit - Called synchronously after each store method completes\n * (or rejects) with a typed observability event.\n * @returns A drop-in SessionStore replacement.\n */\nexport function withDbObservability(\n store: SessionStore,\n emit: (event: McpObservabilityEvent) => void,\n): SessionStore {\n const readMethods = new Set<keyof SessionStore>([\n 'get', 'getCredentials', 'list', 'listIds', 'listAllIds',\n ]);\n\n return new Proxy(store, {\n get(target, prop, receiver) {\n const original = Reflect.get(target, prop, receiver);\n if (typeof original !== 'function') return original;\n\n return (...args: any[]) => {\n const method = prop as string;\n const isRead = readMethods.has(prop as keyof SessionStore);\n const start = performance.now();\n\n const emitEvent = (error?: string) => {\n emit({\n type: isRead ? 'db:read' : 'db:write',\n level: error ? 'error' : 'debug',\n message: `${method}(${args.map(a =>\n typeof a === 'string' ? a.slice(0, 24) : typeof a,\n ).join(', ')})`,\n sessionId: typeof args[1] === 'string' ? args[1] : undefined,\n payload: {\n method,\n argTypes: args.map(a => typeof a),\n durationMs: performance.now() - start,\n ...(error ? { error } : {}),\n },\n timestamp: Date.now(),\n });\n };\n\n try {\n const result = original.apply(target, args);\n if (result instanceof Promise) {\n return result.then(r => { emitEvent(); return r; })\n .catch(e => { emitEvent(String(e)); throw e; });\n }\n emitEvent();\n return result;\n } catch (e) {\n emitEvent(String(e));\n throw e;\n }\n };\n },\n });\n}\n\n/**\n * Global session store instance\n * Uses lazy initialization with a Proxy to handle async setup transparently\n */\nexport const sessions: SessionStore = new Proxy({} as SessionStore, {\n get(_target, prop) {\n return async (...args: any[]) => {\n const instance = await getStorage();\n const value = (instance as any)[prop];\n if (typeof value === 'function') {\n const result = await value.apply(instance, args);\n const event = createSessionMutationEvent(prop, args);\n if (event) {\n emitSessionMutation(event);\n }\n return result;\n }\n return value;\n };\n },\n});\n","import { AsyncLocalStorage } from 'node:async_hooks';\nimport type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type {\n OAuthClientInformationFull,\n OAuthClientInformationMixed,\n OAuthClientMetadata,\n OAuthTokens\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\nimport { nanoid } from \"nanoid\";\nimport { sessions, type SessionCredentials, type SessionStore } from \"../storage/index.js\";\nimport {\n DEFAULT_CLIENT_NAME,\n DEFAULT_CLIENT_URI,\n DEFAULT_LOGO_URI,\n DEFAULT_POLICY_URI,\n SOFTWARE_ID,\n SOFTWARE_VERSION,\n STATE_EXPIRATION_MS,\n} from '../../shared/constants.js';\nimport { formatOAuthState, parseOAuthState } from '../../shared/utils.js';\n\n/**\n * Context stored in AsyncLocalStorage for callback-time code verifier resolution.\n * Stores the raw verifier and method directly, matching Cloudflare's DurableObjectOAuthClientProvider.\n * This avoids a DB read in codeVerifier() — the verifier is loaded once by the caller\n * (from session.credentials after get({includeCredentials: true})) and propagated through ALS.\n */\ninterface CodeVerifierContext {\n verifier: string;\n method: 'S256';\n}\n\nconst codeVerifierContext = new AsyncLocalStorage<CodeVerifierContext>();\n\n/**\n * Run a function inside a code verifier context, providing the raw verifier and method\n * so that codeVerifier() can return them without a DB read.\n */\nexport function runWithCodeVerifierState<T>(\n verifier: string,\n method: 'S256',\n fn: () => Promise<T>\n): Promise<T> {\n return codeVerifierContext.run({ verifier, method }, fn);\n}\n\nfunction base64UrlEncode(bytes: Uint8Array): string {\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nasync function createCodeChallenge(verifier: string): Promise<string> {\n const digest = await crypto.subtle.digest(\n \"SHA-256\",\n new TextEncoder().encode(verifier)\n );\n return base64UrlEncode(new Uint8Array(digest));\n}\n\n/**\n * Extension of OAuthClientProvider interface with additional methods\n * Enables server-specific tracking and state management\n */\nexport interface AgentsOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n serverId: string | undefined;\n checkState(\n state: string\n ): Promise<{ valid: boolean; serverId?: string; error?: string }>;\n consumeState(state: string): Promise<void>;\n deleteCodeVerifier(): Promise<void>;\n}\n\nexport interface StorageOAuthClientProviderOptions {\n userId: string;\n serverId: string;\n sessionId: string;\n redirectUrl: string;\n clientName?: string;\n clientUri?: string;\n logoUri?: string;\n policyUri?: string;\n clientId?: string;\n clientSecret?: string;\n cachedTokens?: OAuthTokens;\n sessionStore?: SessionStore;\n onRedirect?: (url: string) => void;\n}\n\n/**\n * Storage-backed OAuth provider implementation for MCP\n * Stores OAuth tokens, client information, and PKCE verifiers using the configured SessionStore\n */\nexport class StorageOAuthClientProvider implements AgentsOAuthProvider {\n public readonly userId: string;\n public readonly serverId: string;\n public readonly sessionId: string;\n public readonly redirectUrl: string;\n\n private readonly clientName?: string;\n private readonly clientUri?: string;\n private readonly logoUri?: string;\n private readonly policyUri?: string;\n private readonly clientSecret?: string;\n\n private _store: SessionStore;\n private _authUrl: string | undefined;\n private _clientId: string | undefined;\n private _cachedCodeVerifier: string | undefined;\n private _hasCodeVerifier = false;\n private _cachedTokens: OAuthTokens | null | undefined;\n private onRedirectCallback?: (url: string) => void;\n\n /**\n * Creates a new session-backed OAuth provider\n * @param options - Provider configuration\n */\n constructor(options: StorageOAuthClientProviderOptions) {\n this.userId = options.userId;\n this.serverId = options.serverId;\n this.sessionId = options.sessionId;\n this.redirectUrl = options.redirectUrl;\n this.clientName = options.clientName;\n this.clientUri = options.clientUri;\n this.logoUri = options.logoUri;\n this.policyUri = options.policyUri;\n this._clientId = options.clientId;\n this.clientSecret = options.clientSecret;\n this._cachedTokens = options.cachedTokens;\n this._store = options.sessionStore ?? sessions;\n this.onRedirectCallback = options.onRedirect;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n client_name: this.clientName || DEFAULT_CLIENT_NAME,\n client_uri: this.clientUri || DEFAULT_CLIENT_URI,\n logo_uri: this.logoUri || DEFAULT_LOGO_URI,\n policy_uri: this.policyUri || DEFAULT_POLICY_URI,\n grant_types: [\"authorization_code\", \"refresh_token\"],\n redirect_uris: [this.redirectUrl],\n response_types: [\"code\"],\n token_endpoint_auth_method: this.clientSecret ? \"client_secret_basic\" : \"none\",\n software_id: SOFTWARE_ID,\n software_version: SOFTWARE_VERSION,\n };\n }\n\n get clientId() {\n return this._clientId;\n }\n\n set clientId(clientId_: string | undefined) {\n this._clientId = clientId_;\n }\n\n /**\n * Loads OAuth credentials from the session store\n * @private\n */\n private async getCredentials(): Promise<SessionCredentials> {\n const data = await this._store.getCredentials(this.userId, this.sessionId);\n if (!data) {\n return { userId: this.userId, sessionId: this.sessionId };\n }\n return data;\n }\n\n /**\n * Saves OAuth credentials to the session store\n * @param data - Partial OAuth credentials to save\n * @private\n * @throws Error if session doesn't exist (session must be created by controller layer)\n */\n private async patchCredentials(data: Partial<SessionCredentials>): Promise<void> {\n await this._store.patchCredentials(this.userId, this.sessionId, data);\n }\n\n /**\n * Retrieves stored OAuth client information.\n */\n async clientInformation(): Promise<OAuthClientInformationMixed | undefined> {\n if (this._clientId) {\n return {\n client_id: this._clientId,\n ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),\n };\n }\n\n const data = await this.getCredentials();\n\n // Pre-cache tokens (or absent sentinel) so subsequent tokens() call is 0 DB reads\n if (this._cachedTokens === undefined) {\n this._cachedTokens = data.tokens ?? null;\n }\n\n if (data.clientId) {\n this._clientId = data.clientId;\n if (data.clientInformation) {\n return data.clientInformation;\n }\n return {\n client_id: data.clientId,\n ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),\n };\n }\n\n return undefined;\n }\n\n /**\n * Stores OAuth client information\n */\n async saveClientInformation(clientInformation: OAuthClientInformationFull): Promise<void> {\n await this.patchCredentials({\n clientInformation,\n clientId: clientInformation.client_id\n });\n this.clientId = clientInformation.client_id;\n }\n\n /**\n * Stores OAuth tokens\n */\n async saveTokens(tokens: OAuthTokens): Promise<void> {\n await this.patchCredentials({ tokens });\n this._cachedTokens = tokens;\n }\n\n /**\n * Persists static client credentials to DB immediately on creation.\n * Ensures getOrCreateClient() finds them on rehydration, even when the\n * server allows anonymous connect and never triggers DCR.\n */\n async initializeCredentials(): Promise<void> {\n if (this._clientId) {\n await this.patchCredentials({\n clientId: this._clientId,\n clientInformation: {\n client_id: this._clientId,\n ...(this.clientSecret ? { client_secret: this.clientSecret } : {}),\n },\n });\n }\n }\n\n get authUrl() {\n return this._authUrl;\n }\n\n async state(): Promise<string> {\n this._cachedCodeVerifier = undefined;\n this._hasCodeVerifier = false;\n const nonce = nanoid(32);\n await this.patchCredentials({\n oauthState: {\n nonce,\n sessionId: this.sessionId,\n serverId: this.serverId,\n createdAt: Date.now(),\n },\n codeVerifier: null,\n });\n return formatOAuthState(nonce, this.sessionId);\n }\n\n async checkState(state: string): Promise<{ valid: boolean; serverId?: string; error?: string }> {\n const parsed = parseOAuthState(state);\n if (!parsed) {\n return { valid: false, error: \"Invalid OAuth state\" };\n }\n\n if (parsed.sessionId !== this.sessionId) {\n return { valid: false, error: \"OAuth state mismatch\" };\n }\n\n const data = await this._store.getCredentials(this.userId, parsed.sessionId);\n\n if (!data) {\n return { valid: false, error: \"Session not found\" };\n }\n\n const oauthState = data.oauthState;\n if (!oauthState) {\n return { valid: false, error: \"OAuth state not found\" };\n }\n\n if (\n oauthState.nonce !== parsed.nonce ||\n oauthState.sessionId !== parsed.sessionId ||\n oauthState.serverId !== this.serverId\n ) {\n return { valid: false, error: \"OAuth state mismatch\" };\n }\n\n if (Date.now() - oauthState.createdAt > STATE_EXPIRATION_MS) {\n return { valid: false, error: \"OAuth state expired\" };\n }\n\n return { valid: true, serverId: oauthState.serverId };\n }\n\n async consumeState(state: string): Promise<void> {\n const result = await this.checkState(state);\n if (!result.valid) {\n throw new Error(result.error || \"Invalid OAuth state\");\n }\n\n await this.patchCredentials({ oauthState: null });\n }\n\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n this._authUrl = authUrl.toString();\n\n // Extract PKCE parameters from auth URL and persist verifier\n // keyed by state nonce for callback-time retrieval.\n const codeChallenge = authUrl.searchParams.get(\"code_challenge\");\n const state = authUrl.searchParams.get(\"state\");\n\n if (this._cachedCodeVerifier && codeChallenge && state) {\n const expectedChallenge = await createCodeChallenge(this._cachedCodeVerifier);\n if (expectedChallenge === codeChallenge) {\n const parsed = parseOAuthState(state);\n if (parsed) {\n await this.patchCredentials({\n codeVerifier: this._cachedCodeVerifier,\n });\n }\n }\n }\n\n if (this.onRedirectCallback) {\n this.onRedirectCallback(authUrl.toString());\n }\n }\n\n async invalidateCredentials(\n scope: \"all\" | \"client\" | \"tokens\" | \"verifier\"\n ): Promise<void> {\n if (scope === \"all\") {\n this._cachedTokens = undefined;\n await this._store.delete(this.userId, this.sessionId);\n } else {\n const updates: Partial<SessionCredentials> = {};\n\n if (scope === \"client\") {\n updates.clientInformation = null;\n updates.clientId = null;\n } else if (scope === \"tokens\") {\n this._cachedTokens = undefined;\n updates.tokens = null;\n } else if (scope === \"verifier\") {\n this._cachedCodeVerifier = undefined;\n this._hasCodeVerifier = false;\n updates.codeVerifier = null;\n }\n await this.patchCredentials(updates);\n }\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n if (this._hasCodeVerifier) {\n return;\n }\n\n this._cachedCodeVerifier = verifier;\n this._hasCodeVerifier = true;\n }\n\n async codeVerifier(): Promise<string> {\n if (this._cachedCodeVerifier) {\n return this._cachedCodeVerifier;\n }\n\n // ALS context carries the raw verifier directly (set by the caller via\n // runWithCodeVerifierState), avoiding a DB read at callback time.\n const ctx = codeVerifierContext.getStore();\n if (ctx?.verifier) {\n return ctx.verifier;\n }\n\n // Cross-instance fallback: read verifier from DB (no ALS context).\n const data = await this.getCredentials();\n if (data.codeVerifier) {\n return data.codeVerifier;\n }\n\n throw new Error(\"No code verifier found\");\n }\n\n async deleteCodeVerifier(): Promise<void> {\n this._cachedCodeVerifier = undefined;\n this._hasCodeVerifier = false;\n await this.patchCredentials({\n codeVerifier: null,\n });\n }\n\n async tokens(): Promise<OAuthTokens | undefined> {\n if (this._cachedTokens !== undefined) {\n return this._cachedTokens ?? undefined;\n }\n\n const data = await this.getCredentials();\n\n this._cachedTokens = data.tokens ?? null;\n\n if (data.clientId && !this._clientId) {\n this._clientId = data.clientId;\n }\n\n return data.tokens ?? undefined;\n }\n}\n","/**\n * Simple event emitter pattern for MCP connection events\n */\n\nexport type Disposable = {\n dispose(): void;\n};\n\nexport type Event<T> = (listener: (event: T) => void) => Disposable;\n\n/**\n * Event emitter class for type-safe event handling\n */\nexport class Emitter<T> {\n private listeners: Set<(event: T) => void> = new Set();\n\n /**\n * Subscribe to events\n * @param listener - Callback function to handle events\n * @returns Disposable to unsubscribe\n */\n get event(): Event<T> {\n return (listener: (event: T) => void) => {\n this.listeners.add(listener);\n return {\n dispose: () => {\n this.listeners.delete(listener);\n },\n };\n };\n }\n\n /**\n * Fire an event to all listeners\n * @param event - Event data to emit\n */\n fire(event: T): void {\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch (error) {\n console.error('[Emitter] Error in event listener:', error);\n }\n }\n }\n\n /**\n * Clear all listeners\n */\n dispose(): void {\n this.listeners.clear();\n }\n\n /**\n * Get number of active listeners\n */\n get listenerCount(): number {\n return this.listeners.size;\n }\n}\n\n/**\n * Connection state types matching your existing ConnectionStatus\n * Extended with more granular states for better observability\n */\nexport type McpConnectionState =\n | 'DISCONNECTED' // Not connected\n | 'CONNECTING' // Establishing transport connection to MCP server\n | 'AUTHENTICATING' // OAuth flow in progress\n | 'AUTHENTICATED' // OAuth complete, pre-connect\n | 'DISCOVERING' // Discovering server capabilities (tools, resources, prompts)\n | 'CONNECTED' // Transport connection established\n | 'READY' // Fully connected and ready to use\n | 'VALIDATING' // Validating existing session\n | 'RECONNECTING' // Attempting to reconnect\n | 'INITIALIZING' // Initializing session or connection\n | 'FAILED'; // Connection error at some point\n\n/**\n * MCP Connection Event Types\n * Discriminated union for type-safe event handling\n */\nexport type McpConnectionEvent =\n | {\n type: 'state_changed';\n sessionId: string;\n serverId: string;\n serverName: string;\n serverUrl: string;\n createdAt?: number;\n state: McpConnectionState;\n previousState: McpConnectionState;\n timestamp: number;\n }\n | {\n type: 'tools_discovered';\n sessionId: string;\n serverId: string;\n toolCount: number;\n tools: any[];\n allTools?: any[];\n timestamp: number;\n }\n | {\n type: 'auth_required';\n sessionId: string;\n serverId: string;\n authUrl: string;\n timestamp: number;\n }\n | {\n type: 'error';\n sessionId: string;\n serverId: string;\n error: string;\n errorType: 'connection' | 'auth' | 'validation' | 'unknown';\n timestamp: number;\n }\n | {\n type: 'disconnected';\n sessionId: string;\n serverId: string;\n timestamp: number;\n }\n | {\n type: 'progress';\n sessionId: string;\n serverId: string;\n message: string;\n timestamp: number;\n };\n\n/**\n * Event fired when a tool execution returns a UI resource URI\n */\nexport interface McpAppsUIEvent {\n type: 'mcp-apps-ui';\n sessionId: string;\n resourceUri: string;\n toolName: string;\n result: unknown;\n timestamp: number;\n}\n\n/**\n * Observability event for debugging and monitoring\n */\nexport interface McpObservabilityEvent {\n type?: string;\n level?: 'debug' | 'info' | 'warn' | 'error';\n message?: string;\n displayMessage?: string;\n sessionId?: string;\n serverId?: string;\n payload?: Record<string, any>;\n metadata?: Record<string, any>; // Kept for backward compatibility\n timestamp: number;\n id?: string;\n}\n\n/**\n * DisposableStore for managing multiple disposables\n * Useful for cleanup in React hooks\n */\nexport class DisposableStore {\n private disposables: Set<Disposable> = new Set();\n\n add(disposable: Disposable): void {\n this.disposables.add(disposable);\n }\n\n dispose(): void {\n for (const disposable of this.disposables) {\n disposable.dispose();\n }\n this.disposables.clear();\n }\n}\n","/**\n * Standardized error classes for MCP Redis library\n * Provides consistent error handling across the codebase\n */\n\n/**\n * Base error class for all MCP-related errors\n */\nexport class McpError extends Error {\n constructor(\n public readonly code: string,\n message: string,\n public readonly cause?: Error\n ) {\n super(message);\n this.name = 'McpError';\n // Maintain proper prototype chain for instanceof checks\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n toJSON() {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.cause ? { cause: this.cause.message } : {}),\n };\n }\n}\n\n/**\n * Thrown when OAuth authorization is required\n */\nexport class UnauthorizedError extends McpError {\n constructor(message: string = 'OAuth authorization required', cause?: Error) {\n super('UNAUTHORIZED', message, cause);\n this.name = 'UnauthorizedError';\n }\n}\n\n/**\n * Thrown when connection to MCP server fails\n */\nexport class ConnectionError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONNECTION_ERROR', message, cause);\n this.name = 'ConnectionError';\n }\n}\n\n/**\n * Thrown when session is not found or expired\n */\nexport class SessionNotFoundError extends McpError {\n constructor(sessionId: string, cause?: Error) {\n super('SESSION_NOT_FOUND', `Session not found: ${sessionId}`, cause);\n this.name = 'SessionNotFoundError';\n }\n}\n\n/**\n * Thrown when session validation fails\n */\nexport class SessionValidationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('SESSION_VALIDATION_ERROR', message, cause);\n this.name = 'SessionValidationError';\n }\n}\n\n/**\n * Thrown when authentication fails\n */\nexport class AuthenticationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('AUTH_ERROR', message, cause);\n this.name = 'AuthenticationError';\n }\n}\n\n/**\n * Thrown when OAuth state validation fails\n */\nexport class InvalidStateError extends McpError {\n constructor(message: string = 'Invalid OAuth state', cause?: Error) {\n super('INVALID_STATE', message, cause);\n this.name = 'InvalidStateError';\n }\n}\n\n/**\n * Thrown when client is not connected\n */\nexport class NotConnectedError extends McpError {\n constructor(message: string = 'Not connected to server', cause?: Error) {\n super('NOT_CONNECTED', message, cause);\n this.name = 'NotConnectedError';\n }\n}\n\n/**\n * Thrown when required configuration is missing\n */\nexport class ConfigurationError extends McpError {\n constructor(message: string, cause?: Error) {\n super('CONFIGURATION_ERROR', message, cause);\n this.name = 'ConfigurationError';\n }\n}\n\n/**\n * Thrown when tool execution fails\n */\nexport class ToolExecutionError extends McpError {\n constructor(toolName: string, message: string, cause?: Error) {\n super('TOOL_EXECUTION_ERROR', `Tool '${toolName}' failed: ${message}`, cause);\n this.name = 'ToolExecutionError';\n }\n}\n\n/**\n * RPC error codes for SSE communication\n */\nexport const RpcErrorCodes = {\n EXECUTION_ERROR: 'EXECUTION_ERROR',\n MISSING_USER_ID: 'MISSING_USER_ID',\n UNAUTHORIZED: 'UNAUTHORIZED',\n NO_CONNECTION: 'NO_CONNECTION',\n UNKNOWN_METHOD: 'UNKNOWN_METHOD',\n INVALID_PARAMS: 'INVALID_PARAMS',\n} as const;\n\nexport type RpcErrorCode = typeof RpcErrorCodes[keyof typeof RpcErrorCodes];\n","import { Client } from '@modelcontextprotocol/sdk/client/index.js';\nimport { nanoid } from 'nanoid';\nimport { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';\nimport { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';\nimport {\n UnauthorizedError as SDKUnauthorizedError,\n} from '@modelcontextprotocol/sdk/client/auth.js';\nimport {\n ListToolsRequest,\n ListToolsResult,\n ListToolsResultSchema,\n CallToolRequest,\n CallToolResult,\n CallToolResultSchema,\n ListPromptsRequest,\n ListPromptsResult,\n ListPromptsResultSchema,\n GetPromptRequest,\n GetPromptResult,\n GetPromptResultSchema,\n ListResourcesRequest,\n ListResourcesResult,\n ListResourcesResultSchema,\n ReadResourceRequest,\n ReadResourceResult,\n ReadResourceResultSchema,\n type Implementation,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { StorageOAuthClientProvider, type AgentsOAuthProvider } from './storage-oauth-provider.js';\nimport { Emitter, type McpConnectionEvent, type McpObservabilityEvent, type McpConnectionState } from '../../shared/events.js';\nimport { UnauthorizedError } from '../../shared/errors.js';\nimport { sessions } from '../storage/index.js';\nimport type { Session, SessionStatus, SessionStore } from '../storage/types.js';\nimport {\n MCP_CLIENT_NAME,\n MCP_CLIENT_VERSION,\n} from '../../shared/constants.js';\nimport type { OAuthTokens } from '@modelcontextprotocol/sdk/shared/auth.js';\nimport type { OAuthClientProvider } from '@modelcontextprotocol/sdk/client/auth.js';\n\n/**\n * Supported MCP transport types\n */\nexport type TransportType = 'sse' | 'streamable-http';\n\n/**\n * Extended capabilities including MCP App support\n */\nimport type { ClientCapabilities } from '@modelcontextprotocol/sdk/types.js';\n\ninterface McpAppClientCapabilities extends Omit<ClientCapabilities, 'extensions'> {\n extensions?: {\n 'io.modelcontextprotocol/ui'?: {\n mimeTypes: string[];\n };\n [key: string]: any;\n };\n}\n\nexport interface MCPOAuthClientOptions {\n serverUrl?: string;\n serverName?: string;\n callbackUrl?: string;\n onRedirect?: (url: string) => void;\n userId: string;\n serverId?: string; /** Optional - loaded from session if not provided */\n sessionId: string; /** Required - primary key for session lookup */\n transportType?: TransportType;\n clientId?: string;\n clientSecret?: string;\n headers?: Record<string, string>;\n /** OAuth Client Metadata (optional - user application info) */\n clientName?: string;\n clientUri?: string;\n logoUri?: string;\n policyUri?: string;\n /**\n * Credentials already loaded by the caller (e.g. via get({includeCredentials: true})).\n * When provided, the StorageOAuthClientProvider uses these cached values to\n * skip redundant DB reads for tokens() calls during reconnection.\n */\n cachedCredentials?: { tokens?: OAuthTokens };\n /**\n * When true, skips the redundant session-existence check in ensureSession().\n * Set by callers that have already confirmed the session exists in storage\n * (e.g. getOrCreateClient, getSession, finishAuth in sse-handler).\n * Saves one round-trip per reconnection.\n */\n hasSession?: boolean;\n /**\n * Custom session store override. When provided, all storage operations\n * (get/create/update/delete) use this store instead of the default global.\n * Used for wrapping with DB observability or other decorators.\n */\n sessionStore?: SessionStore;\n}\n\n/**\n * MCP Client with OAuth 2.1 authentication support\n * Manages connections to MCP servers with automatic token refresh and session restoration\n * Emits connection lifecycle events for observability\n */\nexport class MCPClient {\n private client: Client;\n public oauthProvider: OAuthClientProvider | null = null;\n private transport: StreamableHTTPClientTransport | SSEClientTransport | null = null;\n private config!: MCPOAuthClientOptions;\n private createdAt?: number;\n private _serverInfo: Implementation | undefined;\n private _store!: SessionStore;\n\n /** Event emitters for connection lifecycle */\n private readonly _onConnectionEvent = new Emitter<McpConnectionEvent>();\n public readonly onConnectionEvent = this._onConnectionEvent.event;\n\n private readonly _onObservabilityEvent = new Emitter<McpObservabilityEvent>();\n public readonly onObservabilityEvent = this._onObservabilityEvent.event;\n\n private currentState: McpConnectionState = 'DISCONNECTED';\n\n /**\n * Creates a new MCP client instance\n * Can be initialized with minimal options (userId + sessionId) for session restoration\n * @param options - Client configuration options\n */\n constructor(options: MCPOAuthClientOptions) {\n this.config = { ...options };\n this._store = options.sessionStore ?? sessions;\n\n this.client = new Client(\n {\n name: MCP_CLIENT_NAME,\n version: MCP_CLIENT_VERSION,\n },\n {\n capabilities: {\n extensions: {\n 'io.modelcontextprotocol/ui': {\n mimeTypes: ['text/html+mcp'],\n },\n },\n } as McpAppClientCapabilities,\n }\n );\n }\n\n /** Shared session-shaped data for ensureSession and saveSession */\n private get session() {\n return {\n sessionId: this.config.sessionId,\n userId: this.config.userId,\n serverId: this.config.serverId!,\n serverName: this.config.serverName,\n serverUrl: this.config.serverUrl!,\n callbackUrl: this.config.callbackUrl!,\n transportType: (this.config.transportType || 'streamable-http') as TransportType,\n headers: this.config.headers,\n createdAt: this.createdAt ?? Date.now(),\n updatedAt: Date.now(),\n };\n }\n\n /**\n * Emit a connection state change event\n * @private\n */\n private emitStateChange(newState: McpConnectionState): void {\n const previousState = this.currentState;\n this.currentState = newState;\n\n if (!this.config.serverId) return;\n\n this._onConnectionEvent.fire({\n type: 'state_changed',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n serverName: this.config.serverName || this.config.serverId,\n serverUrl: this.config.serverUrl || '',\n createdAt: this.createdAt,\n state: newState,\n previousState,\n timestamp: Date.now(),\n });\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:state_change',\n level: 'info',\n message: `Connection state: ${previousState} → ${newState}`,\n displayMessage: `State changed to ${newState}`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n payload: { previousState, newState },\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n /**\n * Emit an error event\n * @private\n */\n private emitError(error: string, errorType: 'connection' | 'auth' | 'validation' | 'unknown' = 'unknown'): void {\n if (!this.config.serverId) return;\n\n this._onConnectionEvent.fire({\n type: 'error',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n error,\n errorType,\n timestamp: Date.now(),\n });\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:error',\n level: 'error',\n message: error,\n displayMessage: error,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n payload: { errorType, error },\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n /**\n * Emit a progress event\n * @private\n */\n private emitProgress(message: string): void {\n if (!this.config.serverId) return;\n\n this._onConnectionEvent.fire({\n type: 'progress',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n message,\n timestamp: Date.now(),\n });\n }\n\n /**\n * Get current connection state\n */\n getConnectionState(): McpConnectionState {\n return this.currentState;\n }\n\n /**\n * Helper to create a transport instance\n * @param type - The transport type to create\n * @returns Configured transport instance\n * @private\n */\n private getTransport(type: TransportType): StreamableHTTPClientTransport | SSEClientTransport {\n if (!this.config.serverUrl) {\n throw new Error('Server URL is required to create transport');\n }\n\n const baseUrl = new URL(this.config.serverUrl);\n const hasAuthorizationHeader = Object.keys(this.config.headers || {})\n .some((key) => key.toLowerCase() === 'authorization');\n const transportOptions: Record<string, any> = {\n ...(!hasAuthorizationHeader && { authProvider: this.oauthProvider }),\n ...(this.config.headers && { requestInit: { headers: this.config.headers } }),\n /**\n * Custom fetch implementation to handle connection timeouts.\n * Observation: SDK 1.24.0+ connections may hang indefinitely in some environments.\n * This wrapper enforces a timeout and properly uses AbortController to unblock the request.\n */\n fetch: async (url: RequestInfo | URL, init?: RequestInit) => {\n const timeout = 30000;\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), timeout);\n const signal = init?.signal ?\n // @ts-ignore: AbortSignal.any is available in Node 20+\n (AbortSignal.any ? AbortSignal.any([init.signal, controller.signal]) : controller.signal) :\n controller.signal;\n\n try {\n const response = await fetch(url, { ...init, signal });\n \n const hasSessionHeader = init?.headers && new Headers(init.headers as HeadersInit).has('mcp-session-id');\n\n if (response.status === 404 && hasSessionHeader) {\n throw new Error(\"MCP_SESSION_EXPIRED: Downstream session was not found on the server.\");\n }\n\n return response;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n };\n\n if (type === 'sse') {\n return new SSEClientTransport(baseUrl, transportOptions);\n } else {\n return new StreamableHTTPClientTransport(baseUrl, transportOptions);\n }\n }\n\n /**\n * Ensures session metadata and OAuth provider are loaded.\n * Does NOT create the SDK Client — callers that need one create it themselves.\n * @private\n */\n private async ensureSession(): Promise<void> {\n if (this.oauthProvider) return;\n\n this.emitStateChange('INITIALIZING');\n this.emitProgress('Loading session configuration...');\n\n if (!this.config.serverUrl || !this.config.callbackUrl || !this.config.serverId) {\n const existingSession = await this._store.get(this.config.userId, this.config.sessionId);\n if (!existingSession) {\n throw new Error(`Session not found: ${this.config.sessionId}`);\n }\n\n this.config.serverUrl = this.config.serverUrl || existingSession.serverUrl;\n this.config.callbackUrl = this.config.callbackUrl || existingSession.callbackUrl;\n this.config.serverName = this.config.serverName || existingSession.serverName;\n this.config.serverId = this.config.serverId || existingSession.serverId || 'unknown';\n this.config.headers = this.config.headers || existingSession.headers;\n this.createdAt = existingSession.createdAt;\n }\n\n if (!this.config.serverUrl || !this.config.callbackUrl || !this.config.serverId) {\n throw new Error('Missing required connection metadata');\n }\n\n this.oauthProvider = new StorageOAuthClientProvider({\n userId: this.config.userId,\n serverId: this.config.serverId!,\n sessionId: this.config.sessionId,\n redirectUrl: this.config.callbackUrl!,\n clientName: this.config.clientName,\n clientUri: this.config.clientUri,\n logoUri: this.config.logoUri,\n policyUri: this.config.policyUri,\n clientId: this.config.clientId,\n clientSecret: this.config.clientSecret,\n cachedTokens: this.config.cachedCredentials?.tokens,\n sessionStore: this._store,\n onRedirect: (redirectUrl: string) => {\n if (this.config.serverId) {\n this._onConnectionEvent.fire({\n type: 'auth_required',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n authUrl: redirectUrl,\n timestamp: Date.now(),\n });\n }\n if (this.config.onRedirect) {\n this.config.onRedirect(redirectUrl);\n }\n },\n });\n\n // Create session row BEFORE persisting credentials (FK constraint on mcp_credentials)\n // When hasSession is set by the caller, the session is guaranteed\n // to exist — skip the redundant round-trip.\n const existingSession = this.config.hasSession ? {} as Session : await this._store.get(this.config.userId, this.config.sessionId);\n if (!existingSession) {\n this.createdAt = Date.now();\n const updatedAt = this.createdAt;\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_created',\n level: 'info',\n message: `Creating pending session ${this.config.sessionId} for connection setup`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await this._store.create({\n ...this.session,\n updatedAt,\n status: 'pending',\n });\n }\n\n // Only persist credentials on first connect. Existing sessions already have\n // credentials from the initial connect — no DB read needed to verify.\n if (!existingSession && this.oauthProvider instanceof StorageOAuthClientProvider) {\n await this.oauthProvider.initializeCredentials();\n }\n }\n\n /**\n * Saves current session state to the session store\n * Creates new session if it doesn't exist, updates if it does\n * @param status - Session lifecycle status used by storage cleanup\n * @private\n */\n private async saveSession(status: SessionStatus = 'active'): Promise<void> {\n if (!this.config.sessionId || !this.config.serverId || !this.config.serverUrl || !this.config.callbackUrl) {\n return;\n }\n\n await this._store.update(this.config.userId, this.config.sessionId, {\n ...this.session,\n status,\n });\n }\n\n /**\n * Removes transient setup/auth sessions without masking the original error.\n * @private\n */\n private async deleteTransientSession(): Promise<void> {\n try {\n await this._store.delete(this.config.userId, this.config.sessionId);\n } catch {\n // Best effort only: preserve the original connection/auth error.\n }\n }\n\n /**\n * Try to connect using available transports\n * @returns The corrected transport type object if successful\n * @private\n */\n private async tryConnect(): Promise<{ transportType: TransportType }> {\n /**\n * If exact transport type is known, only try that.\n * Otherwise (auto mode), try streamable_http first, then sse.\n */\n const transportsToTry: TransportType[] = this.config.transportType\n ? [this.config.transportType]\n : ['streamable-http', 'sse'];\n\n let lastError: unknown;\n\n for (const currentType of transportsToTry) {\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\n\n try {\n const transport = this.getTransport(currentType);\n\n /** Update local state with the transport we are about to try */\n this.transport = transport;\n\n /** Race connection against timeout */\n await this.client!.connect(transport);\n\n /** Capture server metadata from the initialize response */\n this._serverInfo = this.client.getServerVersion();\n\n /** Success! Return the type that worked */\n return { transportType: currentType };\n\n } catch (error: any) {\n lastError = error;\n\n /** Check for Auth Errors - these should fail immediately, no fallback */\n const isAuthError = error instanceof SDKUnauthorizedError ||\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\n\n if (isAuthError) {\n throw error;\n }\n\n /** If this was the last transport to try, throw the error */\n if (isLastAttempt) {\n throw error;\n }\n\n /** Otherwise, log and continue to next transport */\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.emitProgress(`Connection attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\n this._onObservabilityEvent.fire({\n level: 'warn',\n message: `Transport ${currentType} failed, falling back`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n metadata: {\n failedTransport: currentType,\n error: errorMessage\n },\n timestamp: Date.now(),\n });\n }\n }\n\n throw lastError || new Error('No transports available');\n }\n\n /**\n * Connects to the MCP server.\n *\n * Automatically validates and refreshes OAuth tokens if needed.\n * Saves the session to Redis on first successful connection.\n *\n * The in-memory tools cache (`cachedTools`) is cleared at the start of every\n * call so that a reconnection always fetches a fresh tool list from the remote\n * server — even if the same `MCPClient` instance is reused.\n *\n * @throws {UnauthorizedError} When OAuth authorization is required.\n * @throws {Error} When connection fails for other reasons.\n */\n async connect(): Promise<void> {\n this.cachedTools = null;\n // Close any existing transport so we can negotiate a fresh session.\n // The SDK Client throws if asked to connect() while a transport is\n // already attached; close() detaches it cleanly so the same Client\n // instance can be reused.\n if (this.client.transport) {\n this.transport = null;\n try { await this.client.close(); } catch {\n // Closing a transport that may have already failed is best-effort.\n }\n }\n\n await this.ensureSession();\n\n if (!this.oauthProvider) {\n const error = 'OAuth provider not initialized';\n this.emitError(error, 'connection');\n this.emitStateChange('FAILED');\n throw new Error(error);\n }\n\n try {\n this.emitStateChange('CONNECTING');\n\n /** Use the tryConnect loop to handle transport fallbacks */\n const { transportType } = await this.tryConnect();\n\n /** Update transport type to the one that actually worked */\n this.config.transportType = transportType;\n\n this.emitStateChange('CONNECTED');\n this.emitProgress('Connected successfully');\n\n // Refresh session metadata on every successful connect so active sessions\n // record ongoing usage and don't look dormant to session cleanup jobs.\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_saved',\n level: 'info',\n message: `Saving active session ${this.config.sessionId} (connect success)`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await this.saveSession('active');\n } catch (error) {\n /** Handle Authentication Errors */\n if (\n error instanceof SDKUnauthorizedError ||\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'))\n ) {\n /** Set when the SDK calls redirectToAuthorization on the OAuth provider */\n let authUrl = '';\n if (this.oauthProvider) {\n authUrl = ((this.oauthProvider as any).authUrl || '').trim();\n }\n /**\n * 401 without a usable URL means metadata/DCR failed or the server never started\n * an interactive OAuth flow — not recoverable as \"pending OAuth\".\n */\n if (!authUrl) {\n const detail =\n error instanceof Error && error.message.trim().length > 0\n ? error.message.trim()\n : 'Unauthorized';\n const message =\n detail.toLowerCase() === 'unauthorized'\n ? 'OAuth authorization URL not available'\n : `OAuth authorization URL not available: ${detail}`;\n this.emitError(message, 'auth');\n this.emitStateChange('FAILED');\n \n // Remove terminal setup failures immediately. Active sessions are not\n // deleted here because this branch only runs before OAuth is available.\n await this.deleteTransientSession();\n \n throw new Error(message);\n }\n\n this.emitStateChange('AUTHENTICATING');\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_saved',\n level: 'info',\n message: `Saving pending OAuth session ${this.config.sessionId}`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await this.saveSession('pending');\n\n if (this.config.serverId) {\n this._onConnectionEvent.fire({\n type: 'auth_required',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n authUrl,\n timestamp: Date.now(),\n });\n\n if (authUrl && this.config.onRedirect) {\n this.config.onRedirect(authUrl);\n }\n }\n\n throw new UnauthorizedError('OAuth authorization required');\n }\n\n /** Handle Generic Errors */\n const errorMessage = error instanceof Error ? error.message : 'Connection failed';\n this.emitError(errorMessage, 'connection');\n this.emitStateChange('FAILED');\n\n // Remove transient sessions that failed before becoming restorable.\n // Existing active sessions may still hold usable credentials for reconnect.\n try {\n const existingSession = await this._store.get(this.config.userId, this.config.sessionId);\n if (!existingSession || existingSession.status !== 'active') {\n await this._store.delete(this.config.userId, this.config.sessionId);\n }\n } catch {\n // Best effort only: preserve the original connection error.\n }\n\n throw error;\n }\n }\n\n /**\n * Completes OAuth authorization flow by exchanging authorization code for tokens\n * Creates new authenticated client and transport, then establishes connection\n * Saves active session to Redis after successful authentication\n * @param authCode - Authorization code received from OAuth callback\n */\n\n // TODO: needs to be optimized\n async finishAuth(authCode: string, state?: string): Promise<void> {\n this.emitStateChange('AUTHENTICATING');\n this.emitProgress('Exchanging authorization code for tokens...');\n\n await this.ensureSession();\n\n if (!this.oauthProvider) {\n const error = 'OAuth provider not initialized';\n this.emitError(error, 'auth');\n this.emitStateChange('FAILED');\n throw new Error(error);\n }\n\n if (state) {\n try {\n await (this.oauthProvider as AgentsOAuthProvider).consumeState(state);\n } catch (error) {\n const msg = error instanceof Error ? error.message : 'Invalid OAuth state';\n this.emitError(msg, 'auth');\n this.emitStateChange('FAILED');\n throw error;\n }\n }\n\n /**\n * Determine which transports to try for finishing auth\n * If transportType is set, use only that. Otherwise try streamable_http then sse.\n */\n const transportsToTry: TransportType[] = this.config.transportType\n ? [this.config.transportType]\n : ['streamable-http', 'sse'];\n\n let lastError: unknown;\n let tokensExchanged = false;\n let authenticatedStateEmitted = false;\n\n for (const currentType of transportsToTry) {\n const isLastAttempt = currentType === transportsToTry[transportsToTry.length - 1];\n\n try {\n const transport = this.getTransport(currentType);\n\n /** Update local state with the transport we are about to try */\n this.transport = transport;\n\n if (!tokensExchanged) {\n await transport.finishAuth(authCode);\n tokensExchanged = true;\n } else {\n this.emitProgress(`Tokens already exchanged, skipping auth step for ${currentType}...`);\n }\n\n if (!authenticatedStateEmitted) {\n this.emitStateChange('AUTHENTICATED');\n authenticatedStateEmitted = true;\n }\n\n this.emitStateChange('CONNECTING');\n\n // The SDK Client may still have a transport attached from a prior\n // connect() that failed with UnauthorizedError; close it first so\n // we can negotiate a fresh session with the newly-exchanged tokens.\n if (this.client.transport) {\n try { await this.client.close(); } catch {}\n }\n\n await this.client.connect(this.transport);\n\n /** Capture server metadata from the initialize response */\n this._serverInfo = this.client.getServerVersion();\n\n /** Connection succeeded — lock in the transport type */\n this.config.transportType = currentType;\n\n this.emitStateChange('CONNECTED');\n this._onObservabilityEvent.fire({\n type: 'mcp:client:session_saved',\n level: 'info',\n message: `Saving active session ${this.config.sessionId} (OAuth complete)`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n timestamp: Date.now(),\n id: nanoid(),\n });\n await this.saveSession('active');\n\n return; // Success, exit function\n\n } catch (error) {\n lastError = error;\n\n const isAuthError = error instanceof SDKUnauthorizedError ||\n (error instanceof Error && error.message.toLowerCase().includes('unauthorized'));\n\n if (isAuthError) {\n throw error;\n }\n\n const errorMessage = error instanceof Error ? error.message : String(error);\n\n // Don't retry if the authorization code was rejected (it's one-time use)\n if (!tokensExchanged && errorMessage.toLowerCase().includes('invalid authorization code')) {\n const msg = error instanceof Error ? error.message : 'Authentication failed';\n this.emitError(msg, 'auth');\n this.emitStateChange('FAILED');\n await this.deleteTransientSession();\n throw error;\n }\n\n if (isLastAttempt) {\n const msg = error instanceof Error ? error.message : 'Authentication failed';\n this.emitError(msg, 'auth');\n this.emitStateChange('FAILED');\n await this.deleteTransientSession();\n throw error;\n }\n\n // Log and retry\n this.emitProgress(`Auth attempt with ${currentType} failed: ${errorMessage}. Retrying...`);\n }\n }\n\n if (lastError) {\n const errorMessage = lastError instanceof Error ? lastError.message : 'Authentication failed';\n this.emitError(errorMessage, 'auth');\n this.emitStateChange('FAILED');\n await this.deleteTransientSession();\n throw lastError;\n }\n }\n\n /**\n * In-memory cache for the remote server's full tools list.\n *\n * Populated on the first `fetchTools()` call and reused for the lifetime of\n * the connection. Cleared to `null` at the start of `connect()` so that a\n * reconnect always retrieves a fresh list, and also in `dispose()` to release\n * the memory when the client is no longer needed.\n */\n private cachedTools: ListToolsResult | null = null;\n\n /**\n * Lists all available tools from the connected MCP server without emitting\n * discovery events. The result is cached in memory for the lifetime of the\n * connection — subsequent callers (e.g. `gateway.listTools()` running right\n * after `fetchTools()`) pay zero extra network cost.\n *\n * Gateways use this to apply a tool-access policy before publishing the\n * filtered list to agents or UI state.\n *\n * @returns The full `ListToolsResult` from the remote server.\n * @throws {Error} When the client is not connected or the request times out.\n */\n async fetchTools(): Promise<ListToolsResult> {\n if (this.cachedTools) {\n return this.cachedTools;\n }\n const request: ListToolsRequest = {\n method: 'tools/list',\n params: {},\n };\n\n const result = await this.withRetry(() =>\n this.client!.request(request, ListToolsResultSchema)\n );\n this.cachedTools = result;\n return result;\n }\n\n /**\n * Lists all available tools from the connected MCP server\n * @returns List of tools with their schemas and descriptions\n * @throws {Error} When client is not connected\n */\n async listTools(): Promise<ListToolsResult> {\n this.emitStateChange('DISCOVERING');\n\n try {\n const result = await this.fetchTools();\n\n if (this.config.serverId) {\n this._onConnectionEvent.fire({\n type: 'tools_discovered',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n toolCount: result.tools.length,\n tools: result.tools,\n timestamp: Date.now(),\n });\n }\n\n this.emitStateChange('READY');\n this.emitProgress(`Discovered ${result.tools.length} tools`);\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to list tools';\n this.emitError(errorMessage, 'validation');\n this.emitStateChange('FAILED');\n throw error;\n }\n }\n /**\n * Executes a tool on the connected MCP server\n * @param toolName - Name of the tool to execute\n * @param toolArgs - Arguments to pass to the tool\n * @returns Tool execution result\n * @throws {Error} When client is not connected\n */\n async callTool(toolName: string, toolArgs: Record<string, unknown>): Promise<CallToolResult> {\n const request: CallToolRequest = {\n method: 'tools/call',\n params: {\n name: toolName,\n arguments: toolArgs,\n },\n };\n\n try {\n const result = await this.withRetry(() =>\n this.client!.request(request, CallToolResultSchema)\n );\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:tool_call',\n level: 'info',\n message: `Tool ${toolName} called successfully`,\n displayMessage: `Called tool ${toolName}`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n payload: {\n toolName,\n args: toolArgs,\n },\n timestamp: Date.now(),\n id: nanoid(),\n });\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : `Failed to call tool ${toolName}`;\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:error',\n level: 'error',\n message: errorMessage,\n displayMessage: `Failed to call tool ${toolName}`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n payload: {\n errorType: 'tool_execution',\n error: errorMessage,\n toolName,\n args: toolArgs,\n },\n timestamp: Date.now(),\n id: nanoid(),\n });\n\n throw error;\n }\n }\n\n /**\n * Lists all available prompts from the connected MCP server\n * @returns List of available prompts\n * @throws {Error} When client is not connected\n */\n async listPrompts(): Promise<ListPromptsResult> {\n this.emitStateChange('DISCOVERING');\n\n try {\n const request: ListPromptsRequest = {\n method: 'prompts/list',\n params: {},\n };\n\n const result = await this.withRetry(() =>\n this.client!.request(request, ListPromptsResultSchema)\n );\n\n this.emitStateChange('READY');\n this.emitProgress(`Discovered ${result.prompts.length} prompts`);\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to list prompts';\n this.emitError(errorMessage, 'validation');\n this.emitStateChange('FAILED');\n throw error;\n }\n }\n\n /**\n * Gets a specific prompt with arguments\n * @param name - Name of the prompt\n * @param args - Arguments for the prompt\n * @returns Prompt content\n * @throws {Error} When client is not connected\n */\n async getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult> {\n\n const request: GetPromptRequest = {\n method: 'prompts/get',\n params: {\n name,\n arguments: args,\n },\n };\n\n return await this.withRetry(() =>\n this.client!.request(request, GetPromptResultSchema)\n );\n }\n\n /**\n * Lists all available resources from the connected MCP server\n * @returns List of available resources\n * @throws {Error} When client is not connected\n */\n async listResources(): Promise<ListResourcesResult> {\n this.emitStateChange('DISCOVERING');\n\n try {\n const request: ListResourcesRequest = {\n method: 'resources/list',\n params: {},\n };\n\n const result = await this.withRetry(() =>\n this.client!.request(request, ListResourcesResultSchema)\n );\n\n this.emitStateChange('READY');\n this.emitProgress(`Discovered ${result.resources.length} resources`);\n\n return result;\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Failed to list resources';\n this.emitError(errorMessage, 'validation');\n this.emitStateChange('FAILED');\n throw error;\n }\n }\n\n /**\n * Reads a specific resource\n * @param uri - URI of the resource to read\n * @returns Resource content\n * @throws {Error} When client is not connected\n */\n async readResource(uri: string): Promise<ReadResourceResult> {\n\n const request: ReadResourceRequest = {\n method: 'resources/read',\n params: {\n uri,\n },\n };\n\n return await this.withRetry(() =>\n this.client!.request(request, ReadResourceResultSchema)\n );\n }\n\n /**\n * Wraps an MCP request with automatic transport-session recovery.\n *\n * When the downstream MCP server rejects the request with a 404 indicating\n * the transport session has expired, this method tears down the stale SDK\n * client and transport, calls {@link reconnect} to negotiate a fresh session,\n * and retries the request once.\n *\n * Non-transient errors (network failures, auth errors, etc.) propagate as-is.\n */\n private async withRetry<T>(fn: () => Promise<T>): Promise<T> {\n try {\n return await fn();\n } catch (error) {\n if (!(error instanceof Error && error.message.includes('MCP_SESSION_EXPIRED'))) throw error;\n if (this.client.transport) {\n try { await this.client.close(); } catch {}\n this.transport = null;\n }\n await this.reconnect();\n return await fn();\n }\n }\n\n /**\n * Reconnects to MCP server using existing OAuth provider from Redis\n * Used for session restoration in serverless environments\n * Creates new client and transport without re-initializing OAuth provider\n * @throws {Error} When OAuth provider is not initialized\n */\n async reconnect(): Promise<void> {\n await this.ensureSession();\n if (!this.oauthProvider) throw new Error('OAuth provider not initialized');\n await this.connect();\n }\n\n /**\n * Completely removes the session from Redis including all OAuth data\n * Invalidates credentials and disconnects the client\n */\n async clearSession(): Promise<void> {\n try {\n await this.ensureSession();\n } catch (error) {\n this._onObservabilityEvent.fire({\n type: 'mcp:client:error',\n level: 'warn',\n message: 'Initialization failed during clearSession',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n payload: { error: String(error) },\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n if (this.oauthProvider) {\n await (this.oauthProvider as any).invalidateCredentials('all');\n }\n\n await this._store.delete(this.config.userId, this.config.sessionId);\n await this.disconnect();\n }\n\n /**\n * Checks if the client is currently connected to an MCP server\n * @returns True if connected, false otherwise\n */\n isConnected(): boolean {\n return this.client.transport !== undefined;\n }\n\n /**\n * Disconnects from the MCP server and cleans up resources.\n * Does not remove session from Redis — use clearSession() for that.\n *\n * For Streamable HTTP sessions, sends an HTTP DELETE to the MCP endpoint\n * before closing, as recommended by the MCP Streamable HTTP spec\n * (section \"Session Management\", rule 5). This is best-effort — errors\n * (e.g. server already restarted, 404/405 responses) are silently ignored.\n */\n async disconnect(): Promise<void> {\n // Per the MCP Streamable HTTP spec (2025-11-25), clients SHOULD send an\n // HTTP DELETE with the mcp-session-id header when they no longer need a\n // session. The server MAY respond with 405 if it doesn't support explicit\n // termination — terminateSession() handles that gracefully.\n // SSEClientTransport has no session concept, so we guard with instanceof.\n if (this.transport instanceof StreamableHTTPClientTransport) {\n try {\n await this.transport.terminateSession();\n } catch {\n // Best-effort: server may be unreachable or may have already expired\n // the session. Either way, we proceed with local cleanup.\n }\n }\n\n if (this.client.transport) {\n try { await this.client.close(); } catch {}\n }\n this.oauthProvider = null;\n this.transport = null;\n\n // Emit disconnected event\n if (this.config.serverId) {\n this._onConnectionEvent.fire({\n type: 'disconnected',\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n timestamp: Date.now(),\n });\n\n this._onObservabilityEvent.fire({\n type: 'mcp:client:disconnect',\n level: 'info',\n message: `Disconnected from ${this.config.serverId}`,\n sessionId: this.config.sessionId,\n serverId: this.config.serverId,\n payload: {},\n timestamp: Date.now(),\n id: nanoid(),\n });\n }\n\n this.emitStateChange('DISCONNECTED');\n }\n\n /**\n * Disposes all event emitters and releases cached state.\n *\n * Clears `cachedTools` to free memory, and disposes the connection and\n * observability event emitters so downstream listeners are unsubscribed.\n * Call this when the client is permanently shut down (not just disconnected).\n */\n dispose(): void {\n this.cachedTools = null;\n this._onConnectionEvent.dispose();\n this._onObservabilityEvent.dispose();\n }\n\n /**\n * Gets the server URL\n * @returns Server URL or empty string if not set\n */\n getServerUrl(): string {\n return this.config.serverUrl || '';\n }\n\n /**\n * Gets the OAuth callback URL\n * @returns Callback URL or empty string if not set\n */\n getCallbackUrl(): string {\n return this.config.callbackUrl || '';\n }\n\n /**\n * Gets the transport type being used\n * @returns Transport type (defaults to 'streamable-http')\n */\n getTransportType(): TransportType {\n return this.config.transportType || 'streamable-http';\n }\n\n /**\n * Gets the full server metadata from the MCP initialize response.\n * Includes name, version, icons, title, description, and website URL.\n * Returns undefined if the client hasn't connected yet.\n */\n getServerInfo(): Implementation | undefined {\n return this._serverInfo;\n }\n\n /**\n * Gets the human-readable server name.\n * Prefers the server's reported title/name from the initialize response,\n * falling back to the name provided at construction or session metadata.\n * @returns Server name or undefined\n */\n getServerName(): string | undefined {\n // Temporarily avoid deriving serverName from serverVersion metadata.\n // const info = (this.client as any)?.getServerVersion();\n // return info?.title ?? info?.name ?? this.config.serverName;\n return this.config.serverName;\n }\n\n /**\n * Gets the server ID\n * @returns Server ID or undefined\n */\n getServerId(): string | undefined {\n return this.config.serverId;\n }\n\n /**\n * Gets the session ID\n * @returns Session ID\n */\n getSessionId(): string {\n return this.config.sessionId;\n }\n}\n","import type { Tool, ListToolsResult, CallToolResult, Implementation } from '@modelcontextprotocol/sdk/types.js';\nimport type { ToolClient } from '../../shared/types.js';\nimport { sessions } from '../storage/index.js';\nimport type { Session } from '../storage/types.js';\nimport { assertToolAllowed, filterToolsByPolicy } from '../storage/tool-policy.js';\n\n/**\n * Internal shape expected from the underlying MCP client.\n * Extends `ToolClient` with the raw `fetchTools` / `listTools` / `callTool`\n * methods so the gateway can fetch unfiltered results and apply policy on top.\n */\ntype RawToolClient = ToolClient & {\n fetchTools(): Promise<{ tools: Tool[] }>;\n listTools(): Promise<{ tools: Tool[] }>;\n callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult>;\n getServerInfo?(): Implementation | undefined;\n};\n\n/**\n * A thin policy-enforcement layer that wraps a raw `MCPClient`.\n *\n * Every public method on this class loads the current session's `toolPolicy`\n * from the session store and uses it to filter or guard tool access before\n * delegating to the underlying client.\n *\n * This keeps security logic in one place and prevents agents from calling\n * tools that a user has explicitly blocked via the management UI.\n */\nexport class ToolPolicyGateway implements ToolClient {\n constructor(\n private readonly userId: string,\n private readonly sessionId: string,\n private readonly client: RawToolClient\n ) {}\n\n /**\n * Returns whether the underlying MCP client transport is currently connected.\n */\n isConnected(): boolean {\n return this.client.isConnected();\n }\n\n /**\n * Returns the server ID from the underlying client, if available.\n */\n getServerId(): string | undefined {\n return this.client.getServerId?.();\n }\n\n /**\n * Returns the full server metadata from the underlying client, if available.\n * Includes name, version, icons, title, description, and website URL.\n * Available only after the client has connected and completed initialization.\n */\n getServerInfo(): Implementation | undefined {\n return this.client.getServerInfo?.();\n }\n\n /**\n * Returns the human-readable server name from the underlying client, if available.\n */\n getServerName(): string | undefined {\n return this.client.getServerName?.();\n }\n\n /**\n * Returns the server URL from the underlying client, if available.\n */\n getServerUrl(): string | undefined {\n return this.client.getServerUrl?.();\n }\n\n /**\n * Returns the session ID — prefers the value reported by the underlying\n * client, falling back to the one injected at construction time.\n */\n getSessionId(): string {\n return this.client.getSessionId?.() ?? this.sessionId;\n }\n\n /**\n * Returns the **policy-filtered** list of tools that the current session\n * is allowed to call.\n *\n * Internally calls `client.fetchTools()` (which is cache-backed) so no\n * extra network round-trip is incurred when called after `fetchTools()`.\n *\n * @returns A `ListToolsResult` containing only the permitted tools.\n * @throws {Error} When the session does not exist in the store.\n */\n async listTools(): Promise<ListToolsResult> {\n const session = await this.getSession();\n const result = await this.client.fetchTools();\n const tools = this.filterTools(session, result.tools);\n\n return {\n ...result,\n tools,\n } as ListToolsResult;\n }\n\n /**\n * Returns the **complete, unfiltered** list of tools from the remote server,\n * bypassing any tool-access policy.\n *\n * Used by the management UI to show all available tools (including blocked\n * ones) so users can toggle individual tool access in the dialog.\n *\n * @returns The raw `ListToolsResult` from the remote server.\n */\n async listAllTools(): Promise<ListToolsResult> {\n return await this.client.fetchTools() as ListToolsResult;\n }\n\n /**\n * Executes a tool call on the remote server after verifying that the tool\n * is permitted by the current session's policy.\n *\n * @param name - The exact tool name to invoke.\n * @param args - Key/value arguments to pass to the tool.\n * @returns The tool's `CallToolResult`.\n * @throws {Error} When the tool is blocked by the session's policy.\n * @throws {Error} When the session does not exist in the store.\n */\n async callTool(name: string, args: Record<string, unknown>): Promise<CallToolResult> {\n const session = await this.getSession();\n this.assertAllowed(session, name);\n return await this.client.callTool(name, args);\n }\n\n /**\n * Filters a raw tools array down to only those permitted by the session's\n * `toolPolicy`.\n *\n * @param session - The session whose policy should be applied.\n * @param tools - The unfiltered list of tools from the remote server.\n * @returns A subset of `tools` that the policy allows.\n */\n filterTools(session: Session, tools: Tool[]): Tool[] {\n return filterToolsByPolicy(tools, session.toolPolicy, this.getPolicyServerId(session));\n }\n\n /**\n * Throws if `toolName` is blocked by the session's policy.\n * Call this before proxying a `callTool` request to the remote server.\n *\n * @param session - The session whose policy should be enforced.\n * @param toolName - The tool being invoked.\n * @throws {Error} When the tool is not permitted.\n */\n assertAllowed(session: Session, toolName: string): void {\n assertToolAllowed(session.toolPolicy, toolName, this.getPolicyServerId(session));\n }\n\n /**\n * Loads the session from the store and throws if it does not exist.\n *\n * @returns The fully-hydrated `Session` record.\n * @throws {Error} When the session cannot be found.\n */\n private async getSession(): Promise<Session> {\n const session = await sessions.get(this.userId, this.sessionId);\n if (!session) {\n throw new Error('Session not found');\n }\n return session;\n }\n\n /**\n * Resolves the server ID to use when evaluating tool policy.\n * Prefers the value from the live client (most accurate) and falls back\n * to the server ID stored on the session record.\n */\n private getPolicyServerId(session: Session): string | undefined {\n return this.client.getServerId?.() ?? session.serverId;\n }\n}\n\n/**\n * Factory function that creates a `ToolPolicyGateway` for a specific session.\n *\n * Prefer this over constructing `ToolPolicyGateway` directly — it keeps call\n * sites concise and makes it easier to swap the implementation in tests.\n *\n * @param userId - The owner of the session (used for storage lookups).\n * @param sessionId - The session to enforce policy for.\n * @param client - The raw MCP client that the gateway wraps.\n * @returns A fully configured `ToolPolicyGateway` instance.\n */\nexport function createToolPolicyGateway(\n userId: string,\n sessionId: string,\n client: RawToolClient\n): ToolPolicyGateway {\n return new ToolPolicyGateway(userId, sessionId, client);\n}\n","import { MCPClient } from './oauth-client.js';\nimport { sessions, withDbObservability, type Session, type SessionStore } from '../storage/index.js';\nimport type { ToolClient, ToolClientProvider } from '../../shared/types.js';\nimport { createToolPolicyGateway } from './tool-policy-gateway.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_TIMEOUT_MS = 15000;\nconst DEFAULT_MAX_RETRIES = 2;\nconst DEFAULT_RETRY_DELAY_MS = 1000;\nconst CONNECTION_BATCH_SIZE = 5;\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface MultiSessionOptions {\n /**\n * Connection timeout in milliseconds.\n * @default 15000\n */\n timeout?: number;\n\n /**\n * Maximum number of retry attempts per session.\n * @default 2\n */\n maxRetries?: number;\n\n /**\n * Delay between retry attempts in milliseconds.\n * @default 1000\n */\n retryDelay?: number;\n\n /**\n * Custom session store. When provided, all DB operations go through\n * this store instead of the default global `sessions` singleton.\n * Useful for wrapping with `withDbObservability()` for debugging.\n */\n sessionStore?: SessionStore;\n\n /**\n * Custom session provider. When provided, `connect()` calls this\n * instead of querying the storage backend. Useful when sessions are\n * synced externally (e.g. via Supabase Realtime, WebSocket, or an\n * in-memory cache).\n *\n * Default: reads from the storage backend via `sessions.list(userId)`.\n */\n sessionProvider?: () => Promise<Session[]>;\n\n /**\n * Attached to each MCPClient before connect() so all connection lifecycle\n * events (INITIALIZING, CONNECTING, CONNECTED, etc.) are captured.\n */\n onObservabilityEvent?: McpObservabilityEventHandler;\n\n /**\n * Called after a session is successfully connected.\n */\n onSessionConnected?: (sessionId: string, client: MCPClient) => void;\n\n /**\n * Called when a session is evicted from the in-memory client list\n * because it no longer exists in the active sessions list.\n */\n onSessionEvicted?: (sessionId: string) => void;\n\n /**\n * Called when all retry attempts for a session have been exhausted.\n */\n onSessionFailed?: (sessionId: string, error: unknown) => void;\n}\n\n/** @internal */\ntype McpObservabilityEventHandler = (event: import('../../shared/events.js').McpObservabilityEvent) => void;\n\n// ---------------------------------------------------------------------------\n// MultiSessionClient\n// ---------------------------------------------------------------------------\n\n/**\n * Manages multiple MCP client connections for a single user.\n *\n * Cached instances stay alive between requests on long-running servers.\n * On serverless, the underlying session data persists in storage — the\n * client rehydrates from `sessionProvider` (or the default storage backend)\n * each time `connect()` is called.\n *\n * @implements {ToolClientProvider}\n */\nexport class MultiSessionClient implements ToolClientProvider {\n private clients: MCPClient[] = [];\n private connectionPromises = new Map<string, Promise<void>>();\n private userId: string;\n private options: Required<Pick<MultiSessionOptions, 'timeout' | 'maxRetries' | 'retryDelay'>> &\n Pick<MultiSessionOptions, 'sessionProvider' | 'onObservabilityEvent' | 'onSessionConnected' | 'onSessionEvicted' | 'onSessionFailed'>;\n\n /**\n * @param userId - Unique identifier for the user (e.g. user ID or email).\n * @param options - Optional tuning and lifecycle hooks.\n */\n constructor(userId: string, options: MultiSessionOptions = {}) {\n this.userId = userId;\n this.options = {\n timeout: DEFAULT_TIMEOUT_MS,\n maxRetries: DEFAULT_MAX_RETRIES,\n retryDelay: DEFAULT_RETRY_DELAY_MS,\n ...options,\n };\n\n this._store = options.onObservabilityEvent\n ? withDbObservability(options.sessionStore ?? sessions, options.onObservabilityEvent)\n : (options.sessionStore ?? sessions);\n }\n\n private _store: SessionStore;\n\n // -----------------------------------------------------------------------\n // Public API\n // -----------------------------------------------------------------------\n\n /**\n * Fetches active sessions and establishes connections to all of them.\n *\n * Call this once after creating the client. On long-running servers you\n * can cache the `MultiSessionClient` instance and call `connect()` on\n * each request — already-connected sessions are skipped internally.\n */\n async connect(): Promise<void> {\n const sessions = await this.fetchActiveSessions();\n const activeSessionIds = new Set(sessions.map(s => s.sessionId));\n\n for (const client of this.clients) {\n if (!activeSessionIds.has(client.getSessionId())) {\n this.options.onSessionEvicted?.(client.getSessionId());\n }\n }\n this.clients = this.clients.filter(c => activeSessionIds.has(c.getSessionId()));\n\n await this.connectInBatches(sessions);\n }\n\n /**\n * Drops all cached `MCPClient` instances and reconnects fresh from storage.\n *\n * Call this when downstream MCP servers have expired their transport sessions\n * (e.g. after a remote server restart) and subsequent tool calls return\n * \"Session not found. Reconnect without session header.\" errors.\n *\n * OAuth tokens are preserved in the storage backend — no re-authentication\n * is required. Only the in-memory transport sessions are cleared.\n */\n async reconnect(): Promise<void> {\n await this.disconnect();\n await this.connect();\n }\n\n /**\n * Returns all currently connected `MCPClient` instances.\n *\n * Use this to enumerate available tools across all connected servers,\n * or to route a tool call to the right client by `serverId`.\n */\n getClients(): ToolClient[] {\n return this.clients.map((client) =>\n createToolPolicyGateway(this.userId, client.getSessionId(), client)\n );\n }\n\n /**\n * Removes and disconnects a single session by ID.\n *\n * @returns `true` if the session was found and removed, `false` if not found.\n */\n async removeSession(sessionId: string): Promise<boolean> {\n const idx = this.clients.findIndex(c => c.getSessionId() === sessionId);\n if (idx === -1) return false;\n const [client] = this.clients.splice(idx, 1);\n await client.disconnect();\n return true;\n }\n\n /**\n * Gracefully disconnects all active MCP clients and clears the internal list.\n *\n * For Streamable HTTP sessions, each client sends an HTTP DELETE to its MCP\n * endpoint per the spec before closing locally. All disconnects run in\n * parallel so shutdown is not serialised across many sessions.\n *\n * Call this during server shutdown or when a user logs out to free up\n * underlying transport resources (SSE streams, HTTP connections, etc.).\n */\n async disconnect(): Promise<void> {\n await Promise.all(this.clients.map((client) => client.disconnect()));\n this.clients = [];\n }\n\n // -----------------------------------------------------------------------\n // Internals\n // -----------------------------------------------------------------------\n\n /**\n * Resolves the list of sessions to connect.\n *\n * Uses the custom `sessionProvider` when provided, otherwise falls back\n * to querying the storage backend via `sessions.list(userId)`.\n */\n private async fetchActiveSessions(): Promise<Session[]> {\n const sessionList = this.options.sessionProvider\n ? await this.options.sessionProvider()\n : await this._store.list(this.userId);\n\n return sessionList.filter(s =>\n s.serverId &&\n s.serverUrl &&\n s.callbackUrl &&\n s.status === 'active' &&\n s.enabled !== false\n );\n }\n\n /**\n * Connects a list of sessions in controlled batches.\n *\n * Batching prevents overwhelming the event loop or external servers when\n * a user has many active MCP sessions. Within each batch, sessions are\n * connected concurrently using `Promise.all`.\n */\n private async connectInBatches(sessions: Session[]): Promise<void> {\n for (let i = 0; i < sessions.length; i += CONNECTION_BATCH_SIZE) {\n const batch = sessions.slice(i, i + CONNECTION_BATCH_SIZE);\n await Promise.all(batch.map(session => this.connectSession(session)));\n }\n }\n\n /**\n * Connects a single session, with deduplication to prevent race conditions.\n *\n * - If a client for this session already exists and is connected, returns\n * immediately.\n * - If the existing client entry is no longer connected (e.g. explicit\n * disconnect), it is evicted so a fresh transport is created.\n * - If a connection attempt for this session is already in-flight, the\n * existing promise is reused as a per-session mutex.\n * - On completion (success or failure), the promise is cleaned up from\n * the connectionPromises map.\n */\n private async connectSession(session: Session): Promise<void> {\n const existing = this.clients.find(c => c.getSessionId() === session.sessionId);\n\n if (existing) {\n if (existing.isConnected()) {\n return;\n }\n\n this.options.onSessionEvicted?.(existing.getSessionId());\n this.clients = this.clients.filter(c => c !== existing);\n }\n\n if (this.connectionPromises.has(session.sessionId)) {\n return this.connectionPromises.get(session.sessionId)!;\n }\n\n const connectPromise = this.establishConnectionWithRetries(session);\n\n this.connectionPromises.set(session.sessionId, connectPromise);\n\n try {\n await connectPromise;\n } finally {\n this.connectionPromises.delete(session.sessionId);\n }\n }\n\n /**\n * Core connection loop for a single session with retry logic.\n *\n * 1. Creates a fresh `MCPClient` from the session data.\n * 2. Races `client.connect()` against a timeout.\n * 3. On success, replaces any stale entry and fires `onSessionConnected`.\n * 4. On failure, waits `retryDelay` ms before the next attempt.\n *\n * If all attempts are exhausted, logs an error and returns silently so\n * a single bad server doesn't block the rest of the batch.\n */\n private async establishConnectionWithRetries(session: Session): Promise<void> {\n const maxRetries = this.options.maxRetries;\n const retryDelay = this.options.retryDelay;\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n const client = new MCPClient({\n userId: this.userId,\n sessionId: session.sessionId,\n serverId: session.serverId,\n serverUrl: session.serverUrl,\n callbackUrl: session.callbackUrl,\n serverName: session.serverName,\n transportType: session.transportType,\n headers: session.headers,\n hasSession: true,\n sessionStore: this._store,\n });\n\n // Attach observability listener BEFORE connect to capture all lifecycle events\n if (this.options.onObservabilityEvent) {\n client.onObservabilityEvent(this.options.onObservabilityEvent);\n }\n\n const timeoutMs = this.options.timeout;\n let timeoutTimer: ReturnType<typeof setTimeout>;\n const timeoutPromise = new Promise<never>((_, reject) => {\n timeoutTimer = setTimeout(\n () => reject(new Error(`Connection timed out after ${timeoutMs}ms`)),\n timeoutMs,\n );\n });\n\n try {\n await Promise.race([client.connect(), timeoutPromise]);\n } finally {\n clearTimeout(timeoutTimer!);\n }\n\n this.clients = this.clients.filter(c => c.getSessionId() !== session.sessionId);\n this.clients.push(client);\n this.options.onSessionConnected?.(session.sessionId, client);\n return;\n\n } catch (error) {\n lastError = error;\n if (attempt < maxRetries) {\n await new Promise(resolve => setTimeout(resolve, retryDelay));\n }\n }\n }\n\n this.options.onSessionFailed?.(session.sessionId, lastError);\n console.error(\n `[MultiSessionClient] Failed to connect to session ${session.sessionId} ` +\n `after ${maxRetries + 1} attempts:`,\n lastError,\n );\n }\n}\n\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","/**\n * SSE (Server-Sent Events) Handler for MCP Connections.\n *\n * Provides real-time bidirectional communication between browser clients and\n * MCP servers via a single HTTP endpoint:\n * - GET → opens an SSE stream for server → client events\n * - POST → delivers client → server RPC requests with direct HTTP response\n *\n * Built on {@link SSEConnectionManager} which handles the RPC dispatch logic,\n * session lifecycle, OAuth 2.1 flows, tool-policy enforcement, and heartbeat\n * keep-alive — all while remaining stateless across serverless invocations.\n *\n * @module sse-handler\n */\n\nimport type { McpConnectionEvent, McpObservabilityEvent } from '../../shared/events.js';\nimport type {\n McpRpcRequest,\n McpRpcResponse,\n ConnectParams,\n DisconnectParams,\n ReconnectParams,\n SessionParams,\n CallToolParams,\n GetPromptParams,\n ReadResourceParams,\n FinishAuthParams,\n SessionListResult,\n ConnectResult,\n DisconnectResult,\n GetSessionResult,\n FinishAuthResult,\n ListToolsRpcResult,\n ListPromptsResult,\n ListResourcesResult,\n CallToolResult,\n SetToolPolicyParams,\n SetToolPolicyResult,\n GetToolPolicyParams,\n GetToolPolicyResult,\n UpdateSessionParams,\n UpdateSessionResult,\n} from '../../shared/types.js';\nimport { RpcErrorCodes, UnauthorizedError } from '../../shared/errors.js';\nimport { isConnectionEvent, isRpcResponseEvent } from '../../shared/event-routing.js';\nimport { parseOAuthState } from '../../shared/utils.js';\nimport { MCPClient } from '../mcp/oauth-client.js';\nimport { sessions, generateServerId, withDbObservability, type Session, type SessionStore } from '../storage/index.js';\nimport {\n createToolId,\n isToolAllowed,\n normalizeToolPolicyForUpdate,\n validateToolPolicyAgainstTools,\n} from '../storage/tool-policy.js';\nimport { createToolPolicyGateway } from '../mcp/tool-policy-gateway.js';\nimport { runWithCodeVerifierState } from '../mcp/storage-oauth-provider.js';\n\n// ---------------------------------------------------------------------------\n// Public Types\n// ---------------------------------------------------------------------------\n\n/** OAuth client metadata surfaced during connection and authorization. */\nexport interface ClientMetadata {\n clientName?: string;\n clientUri?: string;\n logoUri?: string;\n policyUri?: string;\n}\n\n/** Options passed to {@link createSSEHandler}. */\nexport interface SSEHandlerOptions {\n /** Authenticated user / tenant identifier. */\n userId: string;\n\n /** Optional auth check — called per-request before any RPC dispatch. */\n onAuth?: (userId: string) => Promise<boolean>;\n\n /** SSE heartbeat interval in milliseconds. @default 30000 */\n heartbeatInterval?: number;\n\n /** Static OAuth client metadata applied to all connections. */\n clientDefaults?: ClientMetadata;\n\n /**\n * Dynamic OAuth client metadata resolver, called once per connection.\n * Overrides `clientDefaults`. Useful for multi-tenant scenarios where\n * metadata varies by request (headers, subdomain, etc.).\n */\n getClientMetadata?: (request?: unknown) => ClientMetadata | Promise<ClientMetadata>;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst DEFAULT_HEARTBEAT_MS = 30_000;\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Normalizes a raw headers object: trims keys & string values,\n * drops entries with empty key or value, returns `undefined` when nothing remains.\n */\nfunction normalizeHeaders(\n headers?: Record<string, string>,\n): Record<string, string> | undefined {\n if (!headers || typeof headers !== 'object') return undefined;\n\n const entries = Object.entries(headers)\n .map(([k, v]) => [k.trim(), String(v).trim()] as const)\n .filter(([k, v]) => k.length > 0 && v.length > 0);\n\n return entries.length > 0 ? Object.fromEntries(entries) : undefined;\n}\n\n/**\n * Formats a {@link McpConnectionEvent} `state_changed` payload for consistent\n * `VALIDATING` → `DISCONNECTED` transitions emitted during session restore.\n */\nfunction validatingStateEvent(\n sessionId: string,\n session: Session,\n): McpConnectionEvent {\n return {\n type: 'state_changed',\n sessionId,\n serverId: session.serverId ?? 'unknown',\n serverName: session.serverName ?? 'Unknown',\n serverUrl: session.serverUrl,\n state: 'VALIDATING',\n previousState: 'DISCONNECTED',\n timestamp: Date.now(),\n };\n}\n\n/**\n * Builds a `connection_error` event with the appropriate error type discriminator.\n */\nfunction connectionErrorEvent(\n sessionId: string,\n serverId: string | undefined,\n error: unknown,\n errorType: 'connection' | 'validation' | 'auth',\n): McpConnectionEvent {\n return {\n type: 'error',\n sessionId,\n serverId: serverId ?? 'unknown',\n error: error instanceof Error ? error.message : 'Connection failed',\n errorType,\n timestamp: Date.now(),\n };\n}\n\n// ---------------------------------------------------------------------------\n// SSEConnectionManager\n// ---------------------------------------------------------------------------\n\n/**\n * Manages a single browser-facing SSE connection and all MCP server sessions\n * owned by the associated user.\n *\n * ## Responsibilities\n * - RPC method dispatch (`connect`, `disconnect`, `callTool`, `listTools`, …)\n * - Session lifecycle: create, restore, re-validate, OAuth completion\n * - In-memory client cache (`Map<string, MCPClient>`) for active transports\n * - SSE event emission for connection state, tool discovery, and errors\n * - Periodic heartbeat to prevent proxy/CDN timeouts\n * - Unified observability: RPC timing, DB operations, connection lifecycle\n *\n * Each instance is tied to one browser client. It is **not** a singleton —\n * a new instance is created per incoming SSE connection.\n */\nexport class SSEConnectionManager {\n // -----------------------------------------------------------------------\n // State\n // -----------------------------------------------------------------------\n\n private readonly userId: string;\n\n /** Active MCP transports keyed by sessionId. */\n private readonly clients = new Map<string, MCPClient>();\n\n /** Instrumented session store — always wraps `sessions` with DB observability. */\n private readonly observedStore: SessionStore;\n\n private heartbeatTimer: ReturnType<typeof setInterval> | undefined;\n private active = true;\n\n // -----------------------------------------------------------------------\n // Constructor\n // -----------------------------------------------------------------------\n\n /**\n * @param options - Handler configuration (userId, auth, metadata, heartbeat, observability).\n * @param sendEvent - Callback that writes a typed event onto the SSE stream.\n */\n constructor(\n private readonly options: SSEHandlerOptions,\n private readonly sendEvent: (\n event: McpConnectionEvent | McpObservabilityEvent | McpRpcResponse,\n ) => void,\n ) {\n this.userId = options.userId;\n this.observedStore = withDbObservability(sessions, (event) => this.sendEvent(event));\n this.startHeartbeat();\n }\n\n // -----------------------------------------------------------------------\n // Public API\n // -----------------------------------------------------------------------\n\n /**\n * Dispatches an incoming RPC request, emits timing observability,\n * and returns the response.\n *\n * Emits `rpc:start` before dispatch and `rpc:end` on completion\n * (success or error), each carrying the method name, sessionId, and\n * duration. All events flow through the unified `onObservability`\n * and the SSE stream.\n *\n * @param request - The deserialized RPC envelope.\n * @returns The RPC response (success or error).\n */\n async handleRequest(request: McpRpcRequest): Promise<McpRpcResponse> {\n const method = request.method;\n const sessionId = (request.params as Record<string, unknown> | undefined)?.sessionId as string | undefined;\n const t0 = performance.now();\n\n this.sendEvent({\n type: 'rpc:start',\n level: 'debug',\n message: method,\n sessionId,\n timestamp: Date.now(),\n });\n\n try {\n const result = await this.dispatchImpl(request);\n\n this.sendEvent({\n type: 'rpc:end',\n level: 'debug',\n message: method,\n sessionId,\n payload: { durationMs: performance.now() - t0 },\n timestamp: Date.now(),\n });\n\n const response: McpRpcResponse = { id: request.id, result };\n this.sendEvent(response);\n return response;\n } catch (error) {\n this.sendEvent({\n type: 'rpc:end',\n level: 'error',\n message: method,\n sessionId,\n payload: { durationMs: performance.now() - t0, error: String(error) },\n timestamp: Date.now(),\n });\n\n const response: McpRpcResponse = {\n id: request.id,\n error: {\n code: RpcErrorCodes.EXECUTION_ERROR,\n message: error instanceof Error ? error.message : 'Unknown error',\n },\n };\n this.sendEvent(response);\n return response;\n }\n }\n\n /**\n * Tears down all active MCP transports and stops the heartbeat timer.\n *\n * Disconnects are issued in parallel across all sessions. After calling\n * this method the manager instance should be discarded.\n */\n async dispose(): Promise<void> {\n this.active = false;\n if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);\n\n await Promise.all(\n Array.from(this.clients.values()).map((c) => c.disconnect()),\n );\n\n this.clients.clear();\n }\n\n // -----------------------------------------------------------------------\n // RPC Dispatch (raw — called by handleRequest which adds timing)\n // -----------------------------------------------------------------------\n\n /**\n * Routes an RPC method name to the appropriate private handler.\n *\n * @throws {Error} When the method name is unrecognized.\n */\n private async dispatchImpl(request: McpRpcRequest): Promise<unknown> {\n switch (request.method) {\n case 'listSessions': return this.listSessions();\n case 'connect': return this.connect(request.params as ConnectParams);\n case 'reconnect': return this.reconnect(request.params as ReconnectParams);\n case 'disconnect': return this.disconnect(request.params as DisconnectParams);\n case 'listTools': return this.listTools(request.params as SessionParams);\n case 'setToolPolicy': return this.setToolPolicy(request.params as SetToolPolicyParams);\n case 'getToolPolicy': return this.getToolPolicy(request.params as GetToolPolicyParams);\n case 'updateSession': return this.updateSession(request.params as UpdateSessionParams);\n case 'callTool': return this.callTool(request.params as CallToolParams);\n case 'getSession': return this.getSession(request.params as SessionParams);\n case 'finishAuth': return this.finishAuth(request.params as FinishAuthParams);\n case 'listPrompts': return this.listPrompts(request.params as SessionParams);\n case 'getPrompt': return this.getPrompt(request.params as GetPromptParams);\n case 'listResources': return this.listResources(request.params as SessionParams);\n case 'readResource': return this.readResource(request.params as ReadResourceParams);\n default:\n throw new Error(`Unknown RPC method: ${request.method}`);\n }\n }\n\n // -----------------------------------------------------------------------\n // Session Query\n // -----------------------------------------------------------------------\n\n /**\n * Lists all sessions owned by the current user.\n *\n * Returns a lightweight view — session metadata only, no credential fields.\n */\n private async listSessions(): Promise<SessionListResult> {\n const all = await sessions.list(this.userId);\n return {\n sessions: all.map((s) => ({\n sessionId: s.sessionId,\n serverId: s.serverId,\n serverName: s.serverName,\n serverUrl: s.serverUrl,\n transport: s.transportType,\n createdAt: s.createdAt,\n updatedAt: s.updatedAt ?? s.createdAt,\n status: s.status ?? 'pending',\n toolPolicy: s.toolPolicy,\n enabled: s.enabled ?? true,\n })),\n };\n }\n\n /**\n * Restores and validates a previously persisted session.\n *\n * Loads the full session row (including credentials) from storage, creates\n * a new MCP transport, connects to the remote server, and emits the\n * discovered (policy-filtered) tool list via SSE.\n */\n private async getSession(params: SessionParams): Promise<GetSessionResult> {\n const session = await this.requireSession(params.sessionId);\n this.sendEvent(validatingStateEvent(params.sessionId, session));\n\n try {\n const client = this.restoreClient(session);\n this.attachClientEvents(client);\n\n await client.connect();\n this.clients.set(params.sessionId, client);\n\n const { result } = await this.listPolicyFilteredTools(params.sessionId);\n return { success: true, toolCount: result.tools.length };\n } catch (error) {\n this.sendEvent(connectionErrorEvent(params.sessionId, session.serverId, error, 'validation'));\n throw error;\n }\n }\n\n // -----------------------------------------------------------------------\n // Connection Lifecycle\n // -----------------------------------------------------------------------\n\n /**\n * Initiates a connection to a new MCP server.\n *\n * If a session for the same `serverId` or `serverUrl` already exists and\n * is still in a `pending` (OAuth) state, the existing session is resumed\n * instead of creating a duplicate.\n *\n * `UnauthorizedError` is treated as a pending-auth state and returned as\n * a successful result (the client will then redirect to the auth URL).\n */\n private async connect(params: ConnectParams): Promise<ConnectResult> {\n const headers = normalizeHeaders(params.headers);\n const serverId = this.normalizeServerId(params.serverId);\n\n const existing = await this.findExistingSession(serverId, params.serverUrl);\n if (existing) {\n if (existing.status === 'pending') {\n return this.getSession({ sessionId: existing.sessionId }).then(() => ({\n sessionId: existing.sessionId,\n success: true,\n }));\n }\n throw new Error(\n `Connection already exists for server: ${existing.serverUrl ?? existing.serverId} (${existing.serverName})`,\n );\n }\n\n const sessionId = await sessions.generateSessionId();\n const metadata = await this.getResolvedClientMetadata();\n\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n serverId,\n serverName: params.serverName,\n serverUrl: params.serverUrl,\n callbackUrl: params.callbackUrl,\n transportType: params.transportType,\n headers,\n sessionStore: this.observedStore,\n ...metadata,\n });\n\n this.cacheClient(sessionId, client);\n return this.connectAndDiscover(client, sessionId, serverId);\n }\n\n /**\n * Reconnects to an MCP server by tearing down the active transport if one\n * exists and instantiating a fresh connection, reusing the existing session\n * (and its stored credentials / DCR client info) from the database.\n */\n private async reconnect(params: ReconnectParams): Promise<ConnectResult> {\n const headers = normalizeHeaders(params.headers);\n const serverId = this.normalizeServerId(params.serverId);\n\n const existing = await this.findExistingSession(serverId, params.serverUrl);\n const sessionId = existing ? existing.sessionId : await sessions.generateSessionId();\n\n if (existing) {\n const staleClient = this.clients.get(existing.sessionId);\n if (staleClient) {\n await staleClient.disconnect();\n this.clients.delete(existing.sessionId);\n }\n }\n\n const metadata = await this.getResolvedClientMetadata();\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n serverId,\n serverName: params.serverName,\n serverUrl: params.serverUrl,\n callbackUrl: params.callbackUrl,\n transportType: params.transportType,\n headers,\n sessionStore: this.observedStore,\n ...metadata,\n });\n\n this.cacheClient(sessionId, client);\n return this.connectAndDiscover(client, sessionId, serverId);\n }\n\n /**\n * Disconnects from an MCP server.\n *\n * If an active in-memory transport exists it delegates to `clearSession()`\n * (which sends the server an HTTP DELETE per the Streamable spec). If no\n * active transport is available (orphaned session from a failed OAuth flow),\n * the session row is removed directly from storage.\n */\n private async disconnect(params: DisconnectParams): Promise<DisconnectResult> {\n const client = this.clients.get(params.sessionId);\n if (client) {\n await client.clearSession();\n this.clients.delete(params.sessionId);\n } else {\n await sessions.delete(this.userId, params.sessionId);\n }\n return { success: true };\n }\n\n // -----------------------------------------------------------------------\n // OAuth\n // -----------------------------------------------------------------------\n\n /**\n * Completes the OAuth 2.1 authorization code flow for a pending session.\n *\n * Loads the stored session (with credentials), creates a fresh `MCPClient`,\n * and calls `finishAuth` inside a {@link runWithCodeVerifierState} context\n * so the PKCE code verifier is available without a DB read.\n *\n * The session's stored `transportType` is intentionally **omitted** from the\n * client config — this lets `MCPClient` auto-negotiate (try Streamable HTTP\n * first, fall back to SSE), which is required for servers like Neon that\n * only support SSE transport.\n */\n private async finishAuth(params: FinishAuthParams): Promise<FinishAuthResult> {\n const parsed = parseOAuthState(params.state);\n const sessionId = parsed?.sessionId ?? params.state;\n const session = await this.requireSession(sessionId);\n\n try {\n const clientId = session.clientId ?? undefined;\n const clientSecret = (session.clientInformation as any)?.client_secret ?? undefined;\n\n const client = new MCPClient({\n userId: this.userId,\n sessionId,\n serverId: session.serverId,\n serverName: session.serverName,\n serverUrl: session.serverUrl,\n callbackUrl: session.callbackUrl,\n headers: session.headers,\n clientId,\n clientSecret,\n hasSession: true,\n cachedCredentials: { tokens: session.tokens ?? undefined },\n sessionStore: this.observedStore,\n });\n\n this.attachClientEvents(client);\n\n await runWithCodeVerifierState(session.codeVerifier ?? '', 'S256', () =>\n client.finishAuth(params.code, params.state),\n );\n\n this.clients.set(sessionId, client);\n\n const { result } = await this.listPolicyFilteredTools(sessionId);\n return { success: true, toolCount: result.tools.length };\n } catch (error) {\n this.sendEvent(connectionErrorEvent(sessionId, session.serverId, error, 'auth'));\n throw error;\n }\n }\n\n // -----------------------------------------------------------------------\n // Tool Discovery & Policy\n // -----------------------------------------------------------------------\n\n /**\n * Fetches the complete tool list from the remote MCP server and emits a\n * `tools_discovered` SSE event with two lists:\n *\n * - `tools` — policy-filtered (what agents are allowed to call)\n * - `allTools` — complete, unfiltered (used by the management UI)\n *\n * Only a single network round-trip is made: `fetchTools()` populates the\n * in-memory cache, then `gateway.listTools()` reuses that cache.\n *\n * @param sessionId - The session to discover tools for.\n * @returns The session record and the filtered tool result.\n * @throws {Error} If the session does not exist in storage.\n */\n private async listPolicyFilteredTools(\n sessionId: string,\n ): Promise<{ session: Session; result: ListToolsRpcResult }> {\n const session = await this.requireSession(sessionId);\n const client = await this.getOrCreateClient(sessionId);\n\n const allTools = await client.fetchTools().catch(() => ({ tools: [] as any[] }));\n const gateway = createToolPolicyGateway(this.userId, sessionId, client);\n const result = await gateway.listTools();\n\n this.sendEvent({\n type: 'tools_discovered',\n sessionId,\n serverId: session.serverId ?? 'unknown',\n toolCount: result.tools.length,\n tools: result.tools,\n allTools: allTools.tools,\n timestamp: Date.now(),\n });\n\n return { session, result };\n }\n\n /**\n * Returns the policy-filtered tool list for a session.\n *\n * Delegates to {@link listPolicyFilteredTools}, which also emits a\n * `tools_discovered` SSE event to keep the client state current.\n */\n private async listTools(params: SessionParams): Promise<ListToolsRpcResult> {\n const { result } = await this.listPolicyFilteredTools(params.sessionId);\n return { tools: result.tools };\n }\n\n /**\n * Returns all raw tools annotated with their effective policy state\n * for display in the management UI.\n */\n private async getToolPolicy(\n params: GetToolPolicyParams,\n ): Promise<GetToolPolicyResult> {\n const session = await this.requireSession(params.sessionId);\n const client = await this.getOrCreateClient(params.sessionId);\n const allTools = await client.fetchTools();\n\n const policy = session.toolPolicy ?? {\n mode: 'all' as const,\n toolIds: [],\n updatedAt: session.updatedAt ?? session.createdAt,\n };\n\n const serverId = session.serverId ?? 'unknown';\n const tools = allTools.tools.map((t) => ({\n ...t,\n toolId: createToolId(serverId, t.name),\n allowed: isToolAllowed(policy, t.name, session.serverId),\n }));\n\n return {\n toolPolicy: policy,\n tools,\n toolCount: tools.length,\n allowedToolCount: tools.filter((t) => t.allowed).length,\n };\n }\n\n /**\n * Persists a new tool access policy and broadcasts the updated filtered\n * tool list via a `tools_discovered` SSE event.\n *\n * @throws {Error} If the session does not exist or the policy references\n * tool IDs that don't match any known tool.\n */\n private async setToolPolicy(\n params: SetToolPolicyParams,\n ): Promise<SetToolPolicyResult> {\n const session = await this.requireSession(params.sessionId);\n const client = await this.getOrCreateClient(params.sessionId);\n const allTools = await client.fetchTools();\n\n const policy = normalizeToolPolicyForUpdate(params.toolPolicy);\n validateToolPolicyAgainstTools(policy, allTools.tools, session.serverId);\n await sessions.update(this.userId, params.sessionId, { toolPolicy: policy });\n\n const filtered = createToolPolicyGateway(\n this.userId, params.sessionId, client,\n ).filterTools({ ...session, toolPolicy: policy }, allTools.tools);\n\n this.sendEvent({\n type: 'tools_discovered',\n sessionId: params.sessionId,\n serverId: session.serverId ?? 'unknown',\n toolCount: filtered.length,\n tools: filtered,\n allTools: allTools.tools,\n timestamp: Date.now(),\n });\n\n return { success: true, toolPolicy: policy, tools: filtered, toolCount: filtered.length };\n }\n\n /**\n * Enables or disables a session for agent tool discovery.\n *\n * Disabled sessions retain their OAuth tokens and connection metadata\n * but are hidden from `MultiSessionClient.connect()` and blocked from\n * RPC tool access. Re-enabling does not require re-authentication.\n *\n * @param params - `{ sessionId, enabled: boolean }`\n * @returns `{ success: true }`\n * @throws {Error} If the session does not exist.\n */\n private async updateSession(params: UpdateSessionParams): Promise<UpdateSessionResult> {\n await this.requireSession(params.sessionId);\n await sessions.update(this.userId, params.sessionId, { enabled: params.enabled });\n return { success: true };\n }\n\n // -----------------------------------------------------------------------\n // Tool Execution\n // -----------------------------------------------------------------------\n\n /**\n * Proxies a tool invocation to the remote MCP server.\n *\n * Resolves (or creates) the transport for the given session, runs the call\n * through the tool-policy gateway, and injects `sessionId` into the result\n * metadata so the client can route the response without scanning all sessions.\n */\n private async callTool(params: CallToolParams): Promise<CallToolResult> {\n const client = await this.getOrCreateClient(params.sessionId);\n const result = await createToolPolicyGateway(\n this.userId, params.sessionId, client,\n ).callTool(params.toolName, params.toolArgs);\n\n return { ...result, _meta: { ...(result._meta ?? {}), sessionId: params.sessionId } };\n }\n\n // -----------------------------------------------------------------------\n // Prompts\n // -----------------------------------------------------------------------\n\n /** Lists all prompts exposed by the remote MCP server. */\n private async listPrompts(params: SessionParams): Promise<ListPromptsResult> {\n const client = await this.getOrCreateClient(params.sessionId);\n const result = await client.listPrompts();\n return { prompts: result.prompts };\n }\n\n /** Retrieves a specific prompt by name with optional arguments. */\n private async getPrompt(params: GetPromptParams): Promise<unknown> {\n const client = await this.getOrCreateClient(params.sessionId);\n return client.getPrompt(params.name, params.args);\n }\n\n // -----------------------------------------------------------------------\n // Resources\n // -----------------------------------------------------------------------\n\n /** Lists all resources exposed by the remote MCP server. */\n private async listResources(params: SessionParams): Promise<ListResourcesResult> {\n const client = await this.getOrCreateClient(params.sessionId);\n const result = await client.listResources();\n return { resources: result.resources };\n }\n\n /** Reads a specific resource identified by URI. */\n private async readResource(params: ReadResourceParams): Promise<unknown> {\n const client = await this.getOrCreateClient(params.sessionId);\n return client.readResource(params.uri);\n }\n\n // -----------------------------------------------------------------------\n // Internal Helpers\n // -----------------------------------------------------------------------\n\n /** Resolves client metadata: `getClientMetadata()` → `clientDefaults` → `{}`. */\n private async getResolvedClientMetadata(request?: unknown): Promise<ClientMetadata> {\n let metadata: ClientMetadata = this.options.clientDefaults\n ? { ...this.options.clientDefaults }\n : {};\n\n if (this.options.getClientMetadata) {\n metadata = { ...metadata, ...(await this.options.getClientMetadata(request)) };\n }\n return metadata;\n }\n\n /** Ensures the given session exists in storage and throws otherwise. */\n private async requireSession(sessionId: string): Promise<Session> {\n const session = await sessions.get(this.userId, sessionId, { includeCredentials: true });\n if (!session) throw new Error(`Session ${sessionId} not found`);\n return session;\n }\n\n /** Finds an existing session matching the given serverId or serverUrl. */\n private async findExistingSession(\n serverId: string,\n serverUrl: string,\n ): Promise<Session | undefined> {\n const all = await sessions.list(this.userId);\n return all.find((s) => s.serverId === serverId || s.serverUrl === serverUrl);\n }\n\n /** Normalizes a serverId to max 12 chars (DeepSeek/OpenAI 64-char tool-name limit). */\n private normalizeServerId(raw?: string): string {\n return raw && raw.length <= 12 ? raw : generateServerId();\n }\n\n /**\n * Returns the cached in-memory transport for `sessionId`, or creates one\n * from the persisted session row (with credentials) and connects it.\n */\n private async getOrCreateClient(sessionId: string): Promise<MCPClient> {\n const existing = this.clients.get(sessionId);\n if (existing) return existing;\n\n const session = await this.requireSession(sessionId);\n\n if (session.enabled === false) {\n throw new Error('Session is disabled — re-enable it via updateSession to access tools');\n }\n const client = this.restoreClient(session);\n\n this.attachClientEvents(client);\n\n await client.connect();\n this.clients.set(sessionId, client);\n return client;\n }\n\n /**\n * Builds an `MCPClient` from a stored session row.\n *\n * Extracts `clientId` and `clientSecret` from the session's credential\n * fields and passes `hasSession: true` + `cachedCredentials` so the client\n * can skip redundant existence checks and credential reads.\n */\n private restoreClient(session: Session): MCPClient {\n const clientId = session.clientId ?? undefined;\n const clientSecret = (session.clientInformation as any)?.client_secret ?? undefined;\n\n return new MCPClient({\n userId: this.userId,\n sessionId: session.sessionId,\n serverId: session.serverId,\n serverName: session.serverName,\n serverUrl: session.serverUrl,\n callbackUrl: session.callbackUrl,\n transportType: session.transportType,\n headers: session.headers,\n clientId,\n clientSecret,\n hasSession: true,\n cachedCredentials: { tokens: session.tokens ?? undefined },\n sessionStore: this.observedStore,\n });\n }\n\n /**\n * Wires connection and observability events from the client into the\n * unified observability channel. Connection events go to `sendEvent`\n * (SSE stream); observability events go to `emitObs` (user callback\n * + SSE stream).\n */\n private attachClientEvents(client: MCPClient): void {\n client.onConnectionEvent((e) => this.sendEvent(e));\n client.onObservabilityEvent((e) => this.sendEvent(e));\n }\n\n /**\n * Registers the client in the in-memory cache and attaches its event\n * listeners to the unified observability channel.\n */\n private cacheClient(sessionId: string, client: MCPClient): void {\n this.attachClientEvents(client);\n this.clients.set(sessionId, client);\n }\n\n /**\n * Attempts a `client.connect()` and, on success, discovers tools.\n *\n * If the server responds with `UnauthorizedError`, the session is\n * treated as pending OAuth — a successful result is returned with\n * the sessionId so the browser client can redirect to the auth URL.\n *\n * For any other error an `error` connection event is emitted and the\n * client is removed from the in-memory cache before re-throwing.\n */\n private async connectAndDiscover(\n client: MCPClient,\n sessionId: string,\n serverId: string,\n ): Promise<ConnectResult> {\n try {\n await client.connect();\n await this.listPolicyFilteredTools(sessionId);\n return { sessionId, success: true };\n } catch (error) {\n if (error instanceof UnauthorizedError) {\n this.clients.delete(sessionId);\n return { sessionId, success: true };\n }\n\n this.sendEvent(connectionErrorEvent(sessionId, serverId, error, 'connection'));\n this.clients.delete(sessionId);\n throw error;\n }\n }\n\n /** Starts the periodic heartbeat timer. */\n private startHeartbeat(): void {\n const ms = this.options.heartbeatInterval ?? DEFAULT_HEARTBEAT_MS;\n this.heartbeatTimer = setInterval(() => {\n if (this.active) {\n this.sendEvent({ level: 'debug', message: 'heartbeat', timestamp: Date.now() });\n }\n }, ms);\n }\n}\n\n// ---------------------------------------------------------------------------\n// SSE Handler Factory\n// ---------------------------------------------------------------------------\n\n/**\n * Creates a Node.js-compatible HTTP handler that serves an SSE stream (GET)\n * and accepts RPC calls (POST) for a single browser client.\n *\n * @example\n * ```ts\n * import { createSSEHandler } from '@mcp-ts/sdk/server';\n *\n * const handler = createSSEHandler({ userId: 'user-123' });\n * // Mount `handler` on both GET and POST for your HTTP framework.\n * ```\n *\n * @param options - Handler configuration (userId, optional auth check, metadata).\n * @returns An async function `(req, res) => void` suitable as an HTTP handler.\n */\nexport function createSSEHandler(options: SSEHandlerOptions) {\n return async (\n req: { method?: string; on: (event: string, cb: (...args: any[]) => void) => void },\n res: { writeHead: (status: number, headers: Record<string, string>) => void; write: (chunk: string) => void },\n ) => {\n res.writeHead(200, {\n 'Content-Type': 'text/event-stream',\n 'Cache-Control': 'no-cache',\n 'Connection': 'keep-alive',\n 'Access-Control-Allow-Origin': '*',\n });\n\n writeSSEEvent(res, 'connected', { timestamp: Date.now() });\n\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 });\n\n req.on('close', () => manager.dispose());\n\n if (req.method === 'POST') {\n let body = '';\n req.on('data', (chunk: Buffer) => { body += chunk.toString(); });\n req.on('end', async () => {\n try {\n await manager.handleRequest(JSON.parse(body) as McpRpcRequest);\n } catch {\n // Parsing / handling errors surface through SSE error events\n }\n });\n }\n };\n}\n\n// ---------------------------------------------------------------------------\n// SSE Utilities\n// ---------------------------------------------------------------------------\n\n/**\n * Writes a single SSE event frame onto the response stream.\n *\n * Format: `event: <type>\\ndata: <json>\\n\\n`\n */\nfunction writeSSEEvent(\n res: { write: (chunk: string) => void },\n event: string,\n data: unknown,\n): void {\n res.write(`event: ${event}\\n`);\n res.write(`data: ${JSON.stringify(data)}\\n\\n`);\n}\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 { isConnectionEvent, isRpcResponseEvent } from '../../shared/event-routing.js';\nimport type { McpRpcResponse } from '../../shared/types.js';\n\nexport interface NextMcpHandlerOptions {\n /**\n * Extract userId from request (default: from 'userId' query param)\n */\n getUserId?: (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?: (userId: 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 getUserId = (request: Request) => request.headers.get('x-mcp-user-id'),\n getAuthToken = (request: Request) => {\n const authHeader = request.headers.get('authorization');\n if (authHeader?.toLowerCase().startsWith('bearer ')) {\n return authHeader.slice(7);\n }\n return authHeader;\n },\n authenticate = () => true,\n heartbeatInterval = 30000,\n clientDefaults,\n getClientMetadata,\n } = options;\n\n const toManagerOptions = (userId: string, resolvedClientMetadata?: ClientMetadata) => ({\n userId,\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 userId = getUserId(request);\n const authToken = getAuthToken(request);\n const acceptsEventStream = (request.headers.get('accept') || '').toLowerCase().includes('text/event-stream');\n\n if (!userId) {\n return Response.json({ error: { code: 'MISSING_userId', message: 'Missing userId' } }, { status: 400 });\n }\n\n const isAuthorized = await authenticate(userId, 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(userId, 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(userId, resolvedClientMetadata),\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 }\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 userId,\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"]}
|