@prmichaelsen/mcp-auth 7.5.0 → 7.5.1

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.
@@ -81,6 +81,14 @@ export declare class AuthenticatedServerWrapper {
81
81
  * Create a new stateful session.
82
82
  * Generates a session ID, creates a transport+server pair, and stores them.
83
83
  */
84
+ /**
85
+ * Create a new stateful session.
86
+ *
87
+ * Returns a session object with transport+server connected, but the session
88
+ * is NOT yet registered in the sessions map. Registration happens via the
89
+ * onsessioninitialized callback when the transport processes the initialize
90
+ * request (i.e., after handleRequest is called by the caller).
91
+ */
84
92
  private createSession;
85
93
  /**
86
94
  * Look up an existing session by ID.
@@ -1 +1 @@
1
- {"version":3,"file":"server-wrapper.d.ts","sourceRoot":"","sources":["../../src/wrapper/server-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAyD,MAAM,aAAa,CAAC;AA8C9G;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,WAAW,CAAC,CAAsB;IAC1C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,gBAAgB,CAA2C;IACnE,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,mBAAmB,CAAC,CAAiB;gBAEjC,MAAM,EAAE,mBAAmB;IA2CvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAwDtB;;OAEG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkE3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAK5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAK5B;;;OAGG;YACW,sBAAsB;IAoCpC;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;;OAGG;YACW,aAAa;IA6C3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;OAEG;YACW,YAAY;IAe1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6B9B;;;;;;OAMG;YACW,qBAAqB;IAoDnC;;;OAGG;YACW,gBAAgB;IAmJ9B;;OAEG;YACW,iBAAiB;IAW/B;;OAEG;YACW,uBAAuB;IA2DrC;;OAEG;YACW,mBAAmB;IAuBjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAqCvB;;OAEG;YACW,mBAAmB;IAyBjC;;OAEG;YACW,iBAAiB;IA6Q/B;;OAEG;YACW,kBAAkB;IAUhC;;OAEG;IACH,YAAY,IAAI;QACd,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,KAAK,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,SAAS,EAAE,MAAM,CAAC;YAClB,QAAQ,EAAE,MAAM,CAAC;YACjB,GAAG,EAAE,MAAM,CAAC;YACZ,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC,CAAC;KACJ;IAgBD;;OAEG;IACH,eAAe,IAAI,OAAO;CAG3B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,0BAA0B,CAElF"}
1
+ {"version":3,"file":"server-wrapper.d.ts","sourceRoot":"","sources":["../../src/wrapper/server-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,mBAAmB,EAAyD,MAAM,aAAa,CAAC;AA8C9G;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,WAAW,CAAC,CAAsB;IAC1C,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,YAAY,CAAC,CAAiB;IACtC,OAAO,CAAC,gBAAgB,CAA2C;IACnE,OAAO,CAAC,eAAe,CAAmB;IAC1C,OAAO,CAAC,eAAe,CAAC,CAAiB;IACzC,OAAO,CAAC,QAAQ,CAA0C;IAC1D,OAAO,CAAC,mBAAmB,CAAC,CAAiB;gBAEjC,MAAM,EAAE,mBAAmB;IA2CvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAwDtB;;OAEG;IACH,OAAO,CAAC,eAAe;IA+BvB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAkD5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkE3B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAK5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAI1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAK5B;;;OAGG;YACW,sBAAsB;IAoCpC;;OAEG;IACH,OAAO,CAAC,WAAW;IAanB;;;OAGG;IACH;;;;;;;OAOG;YACW,aAAa;IA4C3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAQlB;;OAEG;YACW,YAAY;IAe1B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA6B9B;;;;;;OAMG;YACW,qBAAqB;IAqDnC;;;OAGG;YACW,gBAAgB;IAmJ9B;;OAEG;YACW,iBAAiB;IAW/B;;OAEG;YACW,uBAAuB;IA2DrC;;OAEG;YACW,mBAAmB;IAuBjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAqCvB;;OAEG;YACW,mBAAmB;IAyBjC;;OAEG;YACW,iBAAiB;IA6Q/B;;OAEG;YACW,kBAAkB;IAUhC;;OAEG;IACH,YAAY,IAAI;QACd,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,KAAK,CAAC;YACf,MAAM,EAAE,MAAM,CAAC;YACf,SAAS,EAAE,MAAM,CAAC;YAClB,QAAQ,EAAE,MAAM,CAAC;YACjB,GAAG,EAAE,MAAM,CAAC;YACZ,QAAQ,EAAE,MAAM,CAAC;SAClB,CAAC,CAAC;KACJ;IAgBD;;OAEG;IACH,eAAe,IAAI,OAAO;CAG3B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,mBAAmB,GAAG,0BAA0B,CAElF"}
@@ -302,6 +302,14 @@ class AuthenticatedServerWrapper {
302
302
  * Create a new stateful session.
303
303
  * Generates a session ID, creates a transport+server pair, and stores them.
304
304
  */
305
+ /**
306
+ * Create a new stateful session.
307
+ *
308
+ * Returns a session object with transport+server connected, but the session
309
+ * is NOT yet registered in the sessions map. Registration happens via the
310
+ * onsessioninitialized callback when the transport processes the initialize
311
+ * request (i.e., after handleRequest is called by the caller).
312
+ */
305
313
  async createSession(userId, accessToken, extras) {
306
314
  if (this.sessions.size >= this.config.session.maxSessions) {
307
315
  throw new TransportError(
@@ -310,29 +318,30 @@ class AuthenticatedServerWrapper {
310
318
  }
311
319
  const server = await this.getServerInstance(userId, accessToken, extras);
312
320
  const transport = new StreamableHTTPServerTransport({
313
- sessionIdGenerator: () => randomUUID()
321
+ sessionIdGenerator: () => randomUUID(),
322
+ onsessioninitialized: (sessionId) => {
323
+ const session = {
324
+ sessionId,
325
+ transport,
326
+ server,
327
+ userId,
328
+ accessToken,
329
+ createdAt: Date.now(),
330
+ lastUsed: Date.now()
331
+ };
332
+ this.sessions.set(sessionId, session);
333
+ transport.onclose = () => {
334
+ this.sessions.delete(sessionId);
335
+ this.logger.debug("Session closed via transport", { sessionId, userId });
336
+ };
337
+ this.logger.info("Session created", { sessionId, userId });
338
+ if (!this.sessionCleanupTimer) {
339
+ this.scheduleSessionCleanup();
340
+ }
341
+ }
314
342
  });
315
343
  await server.connect(transport);
316
- const sessionId = transport.sessionId;
317
- const session = {
318
- sessionId,
319
- transport,
320
- server,
321
- userId,
322
- accessToken,
323
- createdAt: Date.now(),
324
- lastUsed: Date.now()
325
- };
326
- this.sessions.set(sessionId, session);
327
- transport.onclose = () => {
328
- this.sessions.delete(sessionId);
329
- this.logger.debug("Session closed via transport", { sessionId, userId });
330
- };
331
- this.logger.info("Session created", { sessionId, userId });
332
- if (!this.sessionCleanupTimer) {
333
- this.scheduleSessionCleanup();
334
- }
335
- return session;
344
+ return { transport, server };
336
345
  }
337
346
  /**
338
347
  * Look up an existing session by ID.
@@ -396,8 +405,8 @@ class AuthenticatedServerWrapper {
396
405
  const sessionId = req.headers["mcp-session-id"];
397
406
  const method = req.method?.toUpperCase();
398
407
  if (sessionId) {
399
- const session2 = this.getSession(sessionId);
400
- if (!session2) {
408
+ const session = this.getSession(sessionId);
409
+ if (!session) {
401
410
  res.status(404).json({
402
411
  error: "Session not found or expired",
403
412
  code: "SESSION_NOT_FOUND"
@@ -405,8 +414,8 @@ class AuthenticatedServerWrapper {
405
414
  return;
406
415
  }
407
416
  const { userId: userId2 } = await this.authenticateAndResolve(context, requestLogger);
408
- if (userId2 !== session2.userId) {
409
- requestLogger.warn("Session userId mismatch", { sessionId, expected: session2.userId, got: userId2 });
417
+ if (userId2 !== session.userId) {
418
+ requestLogger.warn("Session userId mismatch", { sessionId, expected: session.userId, got: userId2 });
410
419
  res.status(403).json({
411
420
  error: "Session does not belong to this user",
412
421
  code: "SESSION_FORBIDDEN"
@@ -414,7 +423,7 @@ class AuthenticatedServerWrapper {
414
423
  return;
415
424
  }
416
425
  requestLogger.debug("Routing to existing session", { sessionId, method });
417
- await session2.transport.handleRequest(req, res, req.body);
426
+ await session.transport.handleRequest(req, res, req.body);
418
427
  return;
419
428
  }
420
429
  if (method !== "POST") {
@@ -426,9 +435,9 @@ class AuthenticatedServerWrapper {
426
435
  }
427
436
  const { userId, accessToken } = await this.authenticateAndResolve(context, requestLogger);
428
437
  const extras = this.buildExtras(context);
429
- const session = await this.createSession(userId, accessToken, extras);
430
- requestLogger.info("New session initialized", { sessionId: session.sessionId, userId });
431
- await session.transport.handleRequest(req, res, req.body);
438
+ const { transport } = await this.createSession(userId, accessToken, extras);
439
+ await transport.handleRequest(req, res, req.body);
440
+ requestLogger.info("New session initialized", { sessionId: transport.sessionId, userId });
432
441
  }
433
442
  /**
434
443
  * Handle SSE request with direct Express req/res access
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/wrapper/server-wrapper.ts"],
4
- "sourcesContent": ["/**\n * Authenticated server wrapper implementation\n *\n * Wraps MCP servers with authentication and multi-tenancy support.\n * Uses ephemeral instances by default for security.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport type { ServerWrapperConfig, NormalizedServerWrapperConfig, MCPServerFactoryExtras } from './config.js';\nimport type { RequestContext, ProgressNotification } from '../types.js';\nimport {\n AuthenticationError,\n TokenResolutionError,\n ConfigurationError,\n TransportError\n} from '../utils/errors.js';\nimport { createLogger, type Logger } from '../utils/logger.js';\nimport {\n validateRequiredFields,\n validateResourceType,\n validateUserId,\n validateAccessToken,\n validateTransportConfig,\n validatePositiveNumber\n} from '../utils/validation.js';\nimport { ProgressManager } from './progress-manager.js';\nimport { InstancePoolManager } from './instance-pool-manager.js';\n\n/**\n * Server instance metadata (for pooled mode)\n */\ninterface ServerInstance {\n server: Server;\n accessToken: string;\n userId: string;\n createdAt: number;\n lastUsed: number;\n}\n\n/**\n * Managed session for stateful mode\n *\n * Tracks the transport, server, and metadata for a single MCP session.\n */\ninterface ManagedSession {\n sessionId: string;\n transport: StreamableHTTPServerTransport;\n server: Server;\n userId: string;\n accessToken: string;\n createdAt: number;\n lastUsed: number;\n}\n\n/**\n * Authenticated server wrapper\n *\n * Wraps an MCP server with authentication, automatically handling:\n * - Request authentication via AuthProvider\n * - Token resolution via ResourceTokenResolver\n * - Per-user server instance creation (ephemeral or pooled)\n * - Transport management (stdio, SSE, HTTP)\n * \n * @example\n * ```typescript\n * const wrapper = new AuthenticatedServerWrapper({\n * serverFactory: (accessToken, userId) => createInstagramServer(accessToken),\n * authProvider: new JWTAuthProvider({ ... }),\n * tokenResolver: new DatabaseTokenResolver({ ... }),\n * resourceType: 'instagram',\n * transport: { type: 'sse', port: 3000 }\n * });\n * \n * await wrapper.start();\n * ```\n */\nexport class AuthenticatedServerWrapper {\n private config: NormalizedServerWrapperConfig;\n private logger: Logger;\n private serverPool: Map<string, ServerInstance>;\n private poolManager?: InstancePoolManager;\n private isRunning: boolean = false;\n private cleanupTimer?: NodeJS.Timeout;\n private progressContexts: Map<string, string | number> = new Map();\n private progressManager!: ProgressManager;\n private cleanupInterval?: NodeJS.Timeout;\n private sessions: Map<string, ManagedSession> = new Map();\n private sessionCleanupTimer?: NodeJS.Timeout;\n \n constructor(config: ServerWrapperConfig) {\n // Validate configuration\n this.validateConfig(config);\n \n // Normalize configuration with defaults\n this.config = this.normalizeConfig(config);\n \n // Initialize logger\n this.logger = createLogger(this.config.middleware.logging);\n \n // Initialize server pool (legacy - only used in old pooled mode)\n this.serverPool = new Map();\n \n // Initialize pool manager if pooled mode with instancePool config\n if (this.config.instanceMode === 'pooled' && this.config.instancePool) {\n this.poolManager = new InstancePoolManager(\n this.config.instancePool,\n this.logger\n );\n \n this.logger.info('Instance pool manager initialized', {\n maxSize: this.config.instancePool.maxSize,\n idleTimeout: this.config.instancePool.idleTimeout,\n maxLifetime: this.config.instancePool.maxLifetime\n });\n }\n \n // Initialize progress manager\n this.progressManager = new ProgressManager(this.logger);\n \n // Schedule periodic cleanup of stale streams (every minute)\n this.cleanupInterval = setInterval(() => {\n this.progressManager.cleanupStaleStreams();\n }, 60000);\n \n this.logger.info('AuthenticatedServerWrapper created', {\n name: this.config.name,\n resourceType: this.config.resourceType,\n transport: this.config.transport.type,\n instanceMode: this.config.instanceMode\n });\n }\n \n /**\n * Validate wrapper configuration\n */\n private validateConfig(config: ServerWrapperConfig): void {\n // Validate required fields manually for better type safety\n if (!config.serverFactory) {\n throw new ConfigurationError('serverFactory is required');\n }\n if (!config.authProvider) {\n throw new ConfigurationError('authProvider is required');\n }\n // tokenResolver is now optional for static servers\n if (!config.resourceType) {\n throw new ConfigurationError('resourceType is required');\n }\n if (!config.transport) {\n throw new ConfigurationError('transport is required');\n }\n \n validateResourceType(config.resourceType);\n validateTransportConfig(config.transport);\n \n // Validate instance pool config if pooled mode\n if (config.instanceMode === 'pooled') {\n if (!config.instancePool) {\n throw new ConfigurationError(\n 'instancePool configuration required when instanceMode is \"pooled\"'\n );\n }\n \n validatePositiveNumber(config.instancePool.maxSize, 'instancePool.maxSize');\n validatePositiveNumber(config.instancePool.idleTimeout, 'instancePool.idleTimeout');\n validatePositiveNumber(config.instancePool.maxLifetime, 'instancePool.maxLifetime');\n \n if (config.instancePool.maxSize < 1) {\n throw new ConfigurationError('instancePool.maxSize must be at least 1');\n }\n \n if (config.instancePool.idleTimeout < 1000) {\n throw new ConfigurationError('instancePool.idleTimeout must be at least 1000ms (1 second)');\n }\n \n if (config.instancePool.maxLifetime < config.instancePool.idleTimeout) {\n throw new ConfigurationError('instancePool.maxLifetime must be >= idleTimeout');\n }\n }\n \n // Log mode based on tokenResolver presence\n if (config.tokenResolver) {\n this.logger?.info('Token resolver configured - dynamic mode', {\n resolverType: config.tokenResolver.constructor.name\n });\n } else {\n this.logger?.info('No token resolver - static mode', {\n note: 'Server factory will receive empty string as accessToken'\n });\n }\n }\n \n /**\n * Normalize configuration with defaults\n */\n private normalizeConfig(config: ServerWrapperConfig): NormalizedServerWrapperConfig {\n return {\n serverFactory: config.serverFactory,\n authProvider: config.authProvider,\n tokenResolver: config.tokenResolver ?? null, // Convert undefined to null\n resourceType: config.resourceType,\n transport: config.transport,\n name: config.name ?? 'mcp-auth-wrapped-server',\n version: config.version ?? '1.0.0',\n instanceMode: config.instanceMode ?? 'ephemeral',\n instancePool: config.instancePool ?? null, // Convert undefined to null\n sessionMode: config.sessionMode ?? 'stateless',\n session: {\n idleTimeout: config.session?.idleTimeout ?? 300000,\n maxLifetime: config.session?.maxLifetime ?? 3600000,\n maxSessions: config.session?.maxSessions ?? 1000\n },\n middleware: {\n rateLimit: config.middleware?.rateLimit,\n logging: config.middleware?.logging ?? { enabled: true, level: 'info' }\n },\n pooling: {\n maxServersPerUser: config.pooling?.maxServersPerUser ?? 1,\n idleTimeoutMs: config.pooling?.idleTimeoutMs ?? 300000,\n maxTotalServers: config.pooling?.maxTotalServers ?? 100\n },\n requestTimeoutMs: config.requestTimeoutMs ?? 30000,\n enableTracing: config.enableTracing ?? false\n };\n }\n \n /**\n * Start the wrapped server\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new ConfigurationError('Server is already running');\n }\n \n this.logger.info('Starting authenticated server wrapper', {\n name: this.config.name,\n transport: this.config.transport.type\n });\n \n // Initialize auth provider\n if (this.config.authProvider.initialize) {\n await this.config.authProvider.initialize();\n this.logger.debug('Auth provider initialized');\n }\n \n // Initialize token resolver (if configured)\n if (this.config.tokenResolver) {\n if (this.config.tokenResolver.initialize) {\n await this.config.tokenResolver.initialize();\n this.logger.debug('Token resolver initialized');\n }\n } else {\n this.logger.debug('Static mode - no token resolver to initialize');\n }\n \n // Start appropriate transport\n switch (this.config.transport.type) {\n case 'stdio':\n await this.startStdioTransport();\n break;\n case 'sse':\n await this.startSSETransport();\n break;\n case 'http':\n await this.startHTTPTransport();\n break;\n default:\n throw new TransportError(`Unsupported transport type: ${this.config.transport.type}`);\n }\n \n this.isRunning = true;\n \n this.logger.info('Server wrapper started successfully', {\n name: this.config.name,\n transport: this.config.transport.type,\n port: this.config.transport.port\n });\n }\n \n /**\n * Stop the wrapped server\n */\n async stop(): Promise<void> {\n if (!this.isRunning) {\n return;\n }\n \n this.logger.info('Stopping server wrapper');\n \n // Clear cleanup timers\n if (this.cleanupTimer) {\n clearTimeout(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n \n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n \n // Clear session cleanup timer\n if (this.sessionCleanupTimer) {\n clearInterval(this.sessionCleanupTimer);\n this.sessionCleanupTimer = undefined;\n }\n\n // Close all active sessions\n for (const sessionId of [...this.sessions.keys()]) {\n await this.closeSession(sessionId);\n }\n\n // Close pool manager if exists\n if (this.poolManager) {\n await this.poolManager.closeAll();\n }\n \n // Close all pooled servers (legacy)\n if (this.config.instanceMode === 'pooled') {\n for (const [userId, instance] of this.serverPool.entries()) {\n try {\n await instance.server.close();\n this.logger.debug('Closed pooled server instance', { userId });\n } catch (error) {\n this.logger.error('Error closing server instance', error as Error, { userId });\n }\n }\n this.serverPool.clear();\n }\n \n // Cleanup auth provider\n if (this.config.authProvider.cleanup) {\n await this.config.authProvider.cleanup();\n this.logger.debug('Auth provider cleaned up');\n }\n \n // Cleanup token resolver (if configured)\n if (this.config.tokenResolver) {\n if (this.config.tokenResolver.cleanup) {\n await this.config.tokenResolver.cleanup();\n this.logger.debug('Token resolver cleaned up');\n }\n }\n \n this.isRunning = false;\n \n this.logger.info('Server wrapper stopped');\n }\n \n /**\n * Store progress context for a user\n */\n private storeProgressContext(userId: string, progressToken: string | number): void {\n this.progressContexts.set(userId, progressToken);\n this.logger.debug('Stored progress context', { userId, progressToken });\n }\n \n /**\n * Get progress context for a user\n */\n private getProgressContext(userId: string): string | number | undefined {\n return this.progressContexts.get(userId);\n }\n \n /**\n * Clear progress context for a user\n */\n private clearProgressContext(userId: string): void {\n this.progressContexts.delete(userId);\n this.logger.debug('Cleared progress context', { userId });\n }\n \n /**\n * Authenticate a request and resolve the access token.\n * Shared by both stateless and stateful request flows.\n */\n private async authenticateAndResolve(context: RequestContext, requestLogger: Logger): Promise<{ userId: string; accessToken: string }> {\n requestLogger.debug('Authenticating request');\n const authResult = await this.config.authProvider.authenticate(context);\n\n if (!authResult.authenticated || !authResult.userId) {\n requestLogger.warn('Authentication failed', { error: authResult.error });\n throw new AuthenticationError(authResult.error || 'Authentication failed');\n }\n\n const userId = validateUserId(authResult.userId);\n requestLogger.debug('Authentication successful', { userId });\n\n let accessToken: string;\n\n if (this.config.tokenResolver) {\n const resolvedToken = await this.config.tokenResolver.resolveToken(\n userId,\n this.config.resourceType\n );\n\n if (!resolvedToken) {\n requestLogger.warn('Token resolution failed', { userId, resourceType: this.config.resourceType });\n throw new TokenResolutionError(userId, this.config.resourceType);\n }\n\n validateAccessToken(resolvedToken);\n accessToken = resolvedToken;\n requestLogger.debug('Token resolved', { userId, resourceType: this.config.resourceType });\n } else {\n accessToken = '';\n requestLogger.debug('Static mode - no token resolution', { userId, mode: 'static' });\n }\n\n return { userId, accessToken };\n }\n\n /**\n * Build extras from request context (query params + custom X-* headers)\n */\n private buildExtras(context: RequestContext): MCPServerFactoryExtras {\n const customHeaders: Record<string, any> = {};\n if (context.headers) {\n for (const [key, value] of Object.entries(context.headers)) {\n if (key.toLowerCase().startsWith('x-')) {\n const paramKey = key.substring(2).toLowerCase().replace(/-/g, '_');\n customHeaders[paramKey] = value;\n }\n }\n }\n return { ...context.query, ...customHeaders };\n }\n\n /**\n * Create a new stateful session.\n * Generates a session ID, creates a transport+server pair, and stores them.\n */\n private async createSession(userId: string, accessToken: string, extras: MCPServerFactoryExtras): Promise<ManagedSession> {\n if (this.sessions.size >= this.config.session.maxSessions) {\n throw new TransportError(\n `Maximum concurrent sessions (${this.config.session.maxSessions}) reached`\n );\n }\n\n const server = await this.getServerInstance(userId, accessToken, extras);\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n });\n\n await server.connect(transport);\n\n const sessionId = transport.sessionId!;\n\n const session: ManagedSession = {\n sessionId,\n transport,\n server,\n userId,\n accessToken,\n createdAt: Date.now(),\n lastUsed: Date.now()\n };\n\n this.sessions.set(sessionId, session);\n\n // Clean up session when transport closes\n transport.onclose = () => {\n this.sessions.delete(sessionId);\n this.logger.debug('Session closed via transport', { sessionId, userId });\n };\n\n this.logger.info('Session created', { sessionId, userId });\n\n // Start cleanup timer if not already running\n if (!this.sessionCleanupTimer) {\n this.scheduleSessionCleanup();\n }\n\n return session;\n }\n\n /**\n * Look up an existing session by ID.\n */\n private getSession(sessionId: string): ManagedSession | undefined {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.lastUsed = Date.now();\n }\n return session;\n }\n\n /**\n * Close and remove a session.\n */\n private async closeSession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (!session) return;\n\n try {\n await session.transport.close();\n await session.server.close();\n } catch (error) {\n this.logger.error('Error closing session', error as Error, { sessionId });\n }\n\n this.sessions.delete(sessionId);\n this.logger.info('Session removed', { sessionId, userId: session.userId });\n }\n\n /**\n * Schedule periodic cleanup of expired sessions.\n */\n private scheduleSessionCleanup(): void {\n const checkInterval = Math.min(this.config.session.idleTimeout, 60000);\n\n this.sessionCleanupTimer = setInterval(async () => {\n const now = Date.now();\n const toRemove: string[] = [];\n\n for (const [sessionId, session] of this.sessions.entries()) {\n const age = now - session.createdAt;\n const idle = now - session.lastUsed;\n\n if (age > this.config.session.maxLifetime || idle > this.config.session.idleTimeout) {\n toRemove.push(sessionId);\n }\n }\n\n for (const sessionId of toRemove) {\n this.logger.info('Cleaning up expired session', { sessionId });\n await this.closeSession(sessionId);\n }\n\n // Stop timer if no sessions remain\n if (this.sessions.size === 0 && this.sessionCleanupTimer) {\n clearInterval(this.sessionCleanupTimer);\n this.sessionCleanupTimer = undefined;\n }\n }, checkInterval);\n }\n\n /**\n * Handle a stateful request (sessionMode: 'stateful').\n *\n * Routes requests based on Mcp-Session-Id header:\n * - POST without session ID: authenticate + create new session\n * - POST/GET/DELETE with session ID: route to existing session\n */\n private async handleStatefulRequest(req: any, res: any, context: RequestContext): Promise<void> {\n const requestLogger = this.logger.child({ requestId: context.requestId });\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n const method = req.method?.toUpperCase();\n\n if (sessionId) {\n // Route to existing session\n const session = this.getSession(sessionId);\n if (!session) {\n res.status(404).json({\n error: 'Session not found or expired',\n code: 'SESSION_NOT_FOUND'\n });\n return;\n }\n\n // Authenticate to verify the caller owns this session\n const { userId } = await this.authenticateAndResolve(context, requestLogger);\n if (userId !== session.userId) {\n requestLogger.warn('Session userId mismatch', { sessionId, expected: session.userId, got: userId });\n res.status(403).json({\n error: 'Session does not belong to this user',\n code: 'SESSION_FORBIDDEN'\n });\n return;\n }\n\n requestLogger.debug('Routing to existing session', { sessionId, method });\n await session.transport.handleRequest(req, res, req.body);\n return;\n }\n\n // No session ID \u2014 must be POST (initialize)\n if (method !== 'POST') {\n res.status(400).json({\n error: 'Missing Mcp-Session-Id header',\n code: 'SESSION_REQUIRED'\n });\n return;\n }\n\n // Authenticate and create new session\n const { userId, accessToken } = await this.authenticateAndResolve(context, requestLogger);\n const extras = this.buildExtras(context);\n\n const session = await this.createSession(userId, accessToken, extras);\n requestLogger.info('New session initialized', { sessionId: session.sessionId, userId });\n\n // Forward the initialize request through the new session's transport\n await session.transport.handleRequest(req, res, req.body);\n }\n\n /**\n * Handle SSE request with direct Express req/res access\n * This allows us to use StreamableHTTPServerTransport properly\n */\n private async handleSSERequest(req: any, res: any, context: RequestContext): Promise<void> {\n const requestLogger = this.logger.child({ requestId: context.requestId });\n let userId: string | undefined;\n const progressToken = req.body._meta?.progressToken;\n \n try {\n // 1. Authenticate\n requestLogger.debug('Authenticating request');\n const authResult = await this.config.authProvider.authenticate(context);\n \n if (!authResult.authenticated || !authResult.userId) {\n requestLogger.warn('Authentication failed', { error: authResult.error });\n throw new AuthenticationError(authResult.error || 'Authentication failed');\n }\n \n userId = validateUserId(authResult.userId);\n requestLogger.debug('Authentication successful', { userId });\n \n // 2. Resolve resource token (or use empty string for static mode)\n let accessToken: string;\n \n if (this.config.tokenResolver) {\n // Dynamic mode - resolve token from external source\n const resolvedToken = await this.config.tokenResolver.resolveToken(\n userId,\n this.config.resourceType\n );\n \n if (!resolvedToken) {\n requestLogger.warn('Token resolution failed', { userId, resourceType: this.config.resourceType });\n throw new TokenResolutionError(userId, this.config.resourceType);\n }\n \n validateAccessToken(resolvedToken);\n accessToken = resolvedToken;\n requestLogger.debug('Token resolved', { userId, resourceType: this.config.resourceType });\n } else {\n // Static mode - no external token needed\n accessToken = '';\n requestLogger.debug('Static mode - no token resolution', { userId, mode: 'static' });\n }\n \n // 3. Store progress token and register stream if provided\n if (progressToken) {\n this.storeProgressContext(userId, progressToken);\n \n // Register progress stream with callback to forward notifications\n this.progressManager.registerStream(userId, progressToken, (notification) => {\n // Forward notification to client via response\n // Note: In a real implementation, this would use SSE or WebSocket\n // For now, we log that we would forward it\n requestLogger.debug('Would forward progress notification', {\n userId,\n progressToken: notification.progressToken,\n progress: notification.progress,\n total: notification.total\n });\n });\n \n requestLogger.debug('Progress token extracted and stream registered', { userId, progressToken });\n }\n \n // 4. Get server instance (pass query params + custom headers as extras)\n // Extract custom headers (X-* headers) for ghost mode, etc.\n const customHeaders: Record<string, any> = {};\n if (context.headers) {\n for (const [key, value] of Object.entries(context.headers)) {\n if (key.toLowerCase().startsWith('x-')) {\n // Remove 'x-' prefix and convert to snake_case (e.g., X-Ghost-Owner -> ghost_owner)\n const paramKey = key.substring(2).toLowerCase().replace(/-/g, '_');\n customHeaders[paramKey] = value;\n }\n }\n }\n\n const extras = { ...context.query, ...customHeaders };\n const server = await this.getServerInstance(userId, accessToken, extras);\n \n // 5. Intercept server notifications to forward progress\n if (progressToken) {\n const originalNotification = (server as any).notification?.bind(server);\n if (originalNotification) {\n (server as any).notification = (params: any) => {\n // Check if this is a progress notification\n if (params.method === 'notifications/progress') {\n const handled = this.progressManager.forwardNotification(\n params.params as ProgressNotification\n );\n \n if (handled) {\n requestLogger.debug('Progress notification intercepted and forwarded', {\n progressToken: params.params.progressToken\n });\n return; // Don't send through original path\n }\n }\n \n // Forward other notifications normally\n if (originalNotification) {\n originalNotification(params);\n }\n };\n }\n }\n \n // 6. Forward request to server via StreamableHTTPServerTransport\n requestLogger.debug('Forwarding request to MCP server', { userId, hasProgressToken: !!progressToken });\n \n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined // Stateless mode\n });\n \n // Connect server to transport\n await server.connect(transport);\n \n // Forward the request through the transport\n // The transport handles JSON-RPC formatting\n // Tool names are passed through unchanged\n await transport.handleRequest(req, res, req.body);\n \n requestLogger.info('Request handled successfully', {\n userId,\n resourceType: this.config.resourceType,\n hadProgressToken: !!progressToken\n });\n \n // Clean up progress context and stream after request completes\n if (progressToken) {\n this.progressManager.unregisterStream(progressToken);\n this.clearProgressContext(userId);\n }\n \n } catch (error) {\n requestLogger.error('SSE request handling failed', error as Error);\n \n // Clean up progress context and stream on error\n if (progressToken) {\n this.progressManager.unregisterStream(progressToken);\n if (userId) {\n this.clearProgressContext(userId);\n }\n }\n \n throw error;\n }\n }\n \n /**\n * Get server instance (ephemeral or from pool)\n */\n private async getServerInstance(userId: string, accessToken: string, extras?: MCPServerFactoryExtras): Promise<Server> {\n if (this.config.instanceMode === 'ephemeral') {\n // Create new server instance for each request (recommended)\n this.logger.debug('Creating ephemeral server instance', { userId });\n return await this.config.serverFactory(accessToken, userId, extras);\n }\n\n // Pooled mode\n return await this.getPooledServerInstance(userId, accessToken, extras);\n }\n \n /**\n * Get or create pooled server instance\n */\n private async getPooledServerInstance(userId: string, accessToken: string, extras?: MCPServerFactoryExtras): Promise<Server> {\n // Use new InstancePoolManager if configured\n if (this.poolManager) {\n return await this.poolManager.getInstance(\n userId,\n accessToken,\n this.config.serverFactory,\n extras\n );\n }\n \n // Legacy pooling logic (deprecated)\n // Check if we have a cached server instance\n if (this.serverPool.has(userId)) {\n const instance = this.serverPool.get(userId)!;\n \n // Check if token changed (user rotated token)\n if (instance.accessToken !== accessToken) {\n this.logger.info('Token changed, recreating server instance', { userId });\n await instance.server.close();\n this.serverPool.delete(userId);\n } else {\n // Reuse existing instance\n instance.lastUsed = Date.now();\n this.logger.debug('Reusing pooled server instance', { userId });\n return instance.server;\n }\n }\n \n // Check pool size limit\n if (this.serverPool.size >= this.config.pooling.maxTotalServers) {\n this.logger.warn('Server pool limit reached, evicting oldest instance', {\n poolSize: this.serverPool.size,\n maxTotal: this.config.pooling.maxTotalServers\n });\n await this.evictOldestInstance();\n }\n \n // Create new server instance\n this.logger.info('Creating new pooled server instance', { userId });\n const server = await this.config.serverFactory(accessToken, userId, extras);\n \n // Add to pool\n this.serverPool.set(userId, {\n server,\n accessToken,\n userId,\n createdAt: Date.now(),\n lastUsed: Date.now()\n });\n \n // Schedule cleanup if not already scheduled\n if (!this.cleanupTimer) {\n this.scheduleCleanup();\n }\n \n return server;\n }\n \n /**\n * Evict oldest server instance from pool\n */\n private async evictOldestInstance(): Promise<void> {\n let oldestUserId: string | null = null;\n let oldestTime = Infinity;\n \n for (const [userId, instance] of this.serverPool.entries()) {\n if (instance.lastUsed < oldestTime) {\n oldestTime = instance.lastUsed;\n oldestUserId = userId;\n }\n }\n \n if (oldestUserId) {\n const instance = this.serverPool.get(oldestUserId)!;\n await instance.server.close();\n this.serverPool.delete(oldestUserId);\n \n this.logger.debug('Evicted oldest server instance', {\n userId: oldestUserId,\n age: Date.now() - instance.createdAt\n });\n }\n }\n \n /**\n * Schedule cleanup of idle server instances\n */\n private scheduleCleanup(): void {\n const timeout = this.config.pooling.idleTimeoutMs;\n \n this.cleanupTimer = setTimeout(async () => {\n const now = Date.now();\n const toRemove: string[] = [];\n \n for (const [userId, instance] of this.serverPool.entries()) {\n if (now - instance.lastUsed > timeout) {\n toRemove.push(userId);\n }\n }\n \n for (const userId of toRemove) {\n const instance = this.serverPool.get(userId)!;\n try {\n await instance.server.close();\n this.serverPool.delete(userId);\n \n this.logger.debug('Cleaned up idle server instance', {\n userId,\n idleTime: now - instance.lastUsed\n });\n } catch (error) {\n this.logger.error('Error cleaning up server instance', error as Error, { userId });\n }\n }\n \n // Reschedule if pool is not empty\n if (this.serverPool.size > 0) {\n this.scheduleCleanup();\n } else {\n this.cleanupTimer = undefined;\n }\n }, timeout);\n }\n \n /**\n * Start stdio transport (single-user mode)\n */\n private async startStdioTransport(): Promise<void> {\n this.logger.info('Starting stdio transport');\n \n // For stdio, we use environment variable for token\n const envVar = `${this.config.resourceType.toUpperCase()}_ACCESS_TOKEN`;\n const accessToken = process.env[envVar];\n \n if (!accessToken) {\n throw new ConfigurationError(\n `${envVar} environment variable required for stdio mode`\n );\n }\n \n const userId = 'stdio-user';\n \n // Create server instance\n const server = await this.config.serverFactory(accessToken, userId);\n \n // Connect to stdio transport\n const transport = new StdioServerTransport();\n await server.connect(transport);\n \n this.logger.info('Stdio transport started', { userId });\n }\n \n /**\n * Start SSE transport (multi-user mode)\n */\n private async startSSETransport(): Promise<void> {\n this.logger.info('Starting SSE transport', {\n port: this.config.transport.port,\n basePath: this.config.transport.basePath\n });\n \n // Import express dynamically (optional dependency)\n // @ts-ignore - Dynamic import of optional dependency\n const express = await import('express');\n const app = express.default();\n \n // Enable JSON parsing\n app.use(express.json());\n \n // Enable CORS if configured\n if (this.config.transport.cors) {\n // Validate CORS configuration\n if (!this.config.transport.corsOrigin) {\n throw new ConfigurationError(\n 'CORS origin must be explicitly configured when CORS is enabled. ' +\n 'Set transport.corsOrigin to a specific origin (e.g., \"https://app.example.com\") ' +\n 'or an array of allowed origins.'\n );\n }\n \n // Check for wildcard in production\n if (this.config.transport.corsOrigin === '*') {\n const isProduction = process.env.NODE_ENV === 'production';\n \n if (isProduction) {\n throw new ConfigurationError(\n 'CORS wildcard (*) is not allowed in production environments. ' +\n 'Specify explicit origins to prevent CSRF attacks. ' +\n 'Example: corsOrigin: \"https://app.example.com\"'\n );\n }\n \n this.logger.warn(\n 'CORS wildcard (*) detected in development. ' +\n 'This is insecure and should never be used in production.',\n { corsOrigin: this.config.transport.corsOrigin }\n );\n }\n \n // @ts-ignore - Dynamic import of optional dependency\n const cors = await import('cors');\n app.use(cors.default({\n origin: this.config.transport.corsOrigin,\n credentials: true,\n methods: ['GET', 'POST', 'DELETE', 'OPTIONS'],\n allowedHeaders: [\n 'Content-Type', 'Authorization', 'X-Request-ID', 'Mcp-Session-Id',\n ...(this.config.transport.corsAllowedHeaders || []),\n ],\n exposedHeaders: ['X-Request-ID', 'Mcp-Session-Id'],\n maxAge: 86400 // 24 hours\n }));\n \n this.logger.info('CORS enabled', {\n origin: this.config.transport.corsOrigin,\n credentials: true\n });\n }\n \n const basePath = this.config.transport.basePath || '/mcp';\n \n // Root endpoint info\n app.get(basePath, (req: any, res: any) => {\n res.json({\n name: this.config.name,\n version: this.config.version,\n resourceType: this.config.resourceType,\n sessionMode: this.config.sessionMode,\n endpoints: {\n message: `POST ${basePath}/message`,\n health: `GET ${basePath}/health`\n },\n documentation: 'https://github.com/prmichaelsen/mcp-auth'\n });\n });\n\n const isStateful = this.config.sessionMode === 'stateful';\n\n // Error handler shared by all message routes\n const handleError = (error: unknown, res: any) => {\n this.logger.error('Request failed', error as Error);\n\n if (error instanceof AuthenticationError || error instanceof TokenResolutionError) {\n res.status((error as any).statusCode).json({\n error: (error as Error).message,\n code: (error as any).code\n });\n } else if (error instanceof TransportError) {\n res.status(503).json({\n error: (error as Error).message,\n code: 'TRANSPORT_ERROR'\n });\n } else {\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\n }\n };\n\n const buildContext = (req: any): RequestContext => ({\n headers: req.headers as Record<string, string>,\n transport: 'sse',\n timestamp: new Date(),\n requestId: req.headers['x-request-id'] as string | undefined,\n query: req.query as Record<string, string | string[] | undefined>\n });\n\n // POST endpoint for MCP messages\n app.post(`${basePath}/message`, async (req: any, res: any) => {\n try {\n const context = buildContext(req);\n if (isStateful) {\n await this.handleStatefulRequest(req, res, context);\n } else {\n await this.handleSSERequest(req, res, context);\n }\n } catch (error) {\n handleError(error, res);\n }\n });\n\n if (isStateful) {\n // GET endpoint for SSE streams (server\u2192client messages like elicitation)\n app.get(`${basePath}/message`, async (req: any, res: any) => {\n try {\n const context = buildContext(req);\n await this.handleStatefulRequest(req, res, context);\n } catch (error) {\n handleError(error, res);\n }\n });\n\n // DELETE endpoint for session termination\n app.delete(`${basePath}/message`, async (req: any, res: any) => {\n try {\n const context = buildContext(req);\n await this.handleStatefulRequest(req, res, context);\n } catch (error) {\n handleError(error, res);\n }\n });\n\n this.logger.info('Stateful session mode enabled', {\n idleTimeout: this.config.session.idleTimeout,\n maxLifetime: this.config.session.maxLifetime,\n maxSessions: this.config.session.maxSessions\n });\n }\n \n // Progress monitoring endpoint (authenticated)\n app.get(`${basePath}/progress/stats`, async (req: any, res: any) => {\n try {\n // Authenticate request\n const context: RequestContext = {\n headers: req.headers as Record<string, string>,\n transport: 'sse',\n timestamp: new Date(),\n requestId: req.headers['x-request-id'] as string | undefined\n };\n \n const authResult = await this.config.authProvider.authenticate(context);\n \n if (!authResult.authenticated || !authResult.userId) {\n return res.status(401).json({\n error: 'Authentication required',\n code: 'AUTHENTICATION_ERROR'\n });\n }\n \n const userId = authResult.userId;\n \n // Get user-specific metrics\n const userMetrics = this.progressManager.getUserMetrics(userId);\n const globalStats = this.progressManager.getStats();\n \n res.json({\n user: {\n userId,\n ...userMetrics\n },\n global: globalStats,\n timestamp: new Date().toISOString()\n });\n \n } catch (error) {\n this.logger.error('Error fetching progress stats', error as Error);\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\n }\n });\n \n // Detailed metrics endpoint (authenticated)\n app.get(`${basePath}/progress/metrics`, async (req: any, res: any) => {\n try {\n // Authenticate request\n const context: RequestContext = {\n headers: req.headers as Record<string, string>,\n transport: 'sse',\n timestamp: new Date(),\n requestId: req.headers['x-request-id'] as string | undefined\n };\n \n const authResult = await this.config.authProvider.authenticate(context);\n \n if (!authResult.authenticated) {\n return res.status(401).json({\n error: 'Authentication required',\n code: 'AUTHENTICATION_ERROR'\n });\n }\n \n // Get all metrics (could add admin check here)\n const allMetrics = this.progressManager.getAllMetrics();\n const health = this.progressManager.checkHealth();\n \n res.json({\n metrics: allMetrics,\n health,\n timestamp: new Date().toISOString()\n });\n \n } catch (error) {\n this.logger.error('Error fetching progress metrics', error as Error);\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\n }\n });\n \n // Health check endpoint\n app.get(`${basePath}/health`, (req: any, res: any) => {\n res.json({\n status: 'healthy',\n name: this.config.name,\n version: this.config.version,\n resourceType: this.config.resourceType,\n instanceMode: this.config.instanceMode,\n sessionMode: this.config.sessionMode,\n poolSize: this.serverPool.size,\n ...(isStateful ? { activeSessions: this.sessions.size } : {})\n });\n });\n \n // Start server\n const port = this.config.transport.port || 3000;\n const host = this.config.transport.host || '0.0.0.0';\n \n await new Promise<void>((resolve) => {\n app.listen(port, host, () => {\n this.logger.info('SSE transport listening', {\n host,\n port,\n basePath,\n url: `http://${host}:${port}${basePath}`\n });\n resolve();\n });\n });\n }\n \n /**\n * Start HTTP transport (multi-user mode)\n */\n private async startHTTPTransport(): Promise<void> {\n this.logger.info('Starting HTTP transport', {\n port: this.config.transport.port\n });\n \n // HTTP transport is similar to SSE but with different endpoint structure\n // For now, delegate to SSE implementation\n await this.startSSETransport();\n }\n \n /**\n * Get server pool statistics\n */\n getPoolStats(): {\n size: number;\n instances: Array<{\n userId: string;\n createdAt: number;\n lastUsed: number;\n age: number;\n idleTime: number;\n }>;\n } {\n const now = Date.now();\n const instances = Array.from(this.serverPool.entries()).map(([userId, instance]) => ({\n userId,\n createdAt: instance.createdAt,\n lastUsed: instance.lastUsed,\n age: now - instance.createdAt,\n idleTime: now - instance.lastUsed\n }));\n \n return {\n size: this.serverPool.size,\n instances\n };\n }\n \n /**\n * Check if server is running\n */\n isServerRunning(): boolean {\n return this.isRunning;\n }\n}\n\n/**\n * Convenience function to create and configure an authenticated server wrapper\n *\n * @param config - Server wrapper configuration\n * @returns Configured AuthenticatedServerWrapper instance\n *\n * @example\n * ```typescript\n * const wrapped = wrapServer({\n * serverFactory: (accessToken, userId) => createMyServer(accessToken, userId),\n * authProvider: new JWTAuthProvider({ jwtSecret: process.env.JWT_SECRET }),\n * tokenResolver: new APITokenResolver({ ... }),\n * resourceType: 'myapi',\n * transport: { type: 'sse', port: 3000 }\n * });\n *\n * await wrapped.start();\n * ```\n */\nexport function wrapServer(config: ServerWrapperConfig): AuthenticatedServerWrapper {\n return new AuthenticatedServerWrapper(config);\n}\n"],
5
- "mappings": "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",
6
- "names": ["session", "userId"]
4
+ "sourcesContent": ["/**\n * Authenticated server wrapper implementation\n *\n * Wraps MCP servers with authentication and multi-tenancy support.\n * Uses ephemeral instances by default for security.\n */\n\nimport { randomUUID } from 'node:crypto';\nimport type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport type { ServerWrapperConfig, NormalizedServerWrapperConfig, MCPServerFactoryExtras } from './config.js';\nimport type { RequestContext, ProgressNotification } from '../types.js';\nimport {\n AuthenticationError,\n TokenResolutionError,\n ConfigurationError,\n TransportError\n} from '../utils/errors.js';\nimport { createLogger, type Logger } from '../utils/logger.js';\nimport {\n validateRequiredFields,\n validateResourceType,\n validateUserId,\n validateAccessToken,\n validateTransportConfig,\n validatePositiveNumber\n} from '../utils/validation.js';\nimport { ProgressManager } from './progress-manager.js';\nimport { InstancePoolManager } from './instance-pool-manager.js';\n\n/**\n * Server instance metadata (for pooled mode)\n */\ninterface ServerInstance {\n server: Server;\n accessToken: string;\n userId: string;\n createdAt: number;\n lastUsed: number;\n}\n\n/**\n * Managed session for stateful mode\n *\n * Tracks the transport, server, and metadata for a single MCP session.\n */\ninterface ManagedSession {\n sessionId: string;\n transport: StreamableHTTPServerTransport;\n server: Server;\n userId: string;\n accessToken: string;\n createdAt: number;\n lastUsed: number;\n}\n\n/**\n * Authenticated server wrapper\n *\n * Wraps an MCP server with authentication, automatically handling:\n * - Request authentication via AuthProvider\n * - Token resolution via ResourceTokenResolver\n * - Per-user server instance creation (ephemeral or pooled)\n * - Transport management (stdio, SSE, HTTP)\n * \n * @example\n * ```typescript\n * const wrapper = new AuthenticatedServerWrapper({\n * serverFactory: (accessToken, userId) => createInstagramServer(accessToken),\n * authProvider: new JWTAuthProvider({ ... }),\n * tokenResolver: new DatabaseTokenResolver({ ... }),\n * resourceType: 'instagram',\n * transport: { type: 'sse', port: 3000 }\n * });\n * \n * await wrapper.start();\n * ```\n */\nexport class AuthenticatedServerWrapper {\n private config: NormalizedServerWrapperConfig;\n private logger: Logger;\n private serverPool: Map<string, ServerInstance>;\n private poolManager?: InstancePoolManager;\n private isRunning: boolean = false;\n private cleanupTimer?: NodeJS.Timeout;\n private progressContexts: Map<string, string | number> = new Map();\n private progressManager!: ProgressManager;\n private cleanupInterval?: NodeJS.Timeout;\n private sessions: Map<string, ManagedSession> = new Map();\n private sessionCleanupTimer?: NodeJS.Timeout;\n \n constructor(config: ServerWrapperConfig) {\n // Validate configuration\n this.validateConfig(config);\n \n // Normalize configuration with defaults\n this.config = this.normalizeConfig(config);\n \n // Initialize logger\n this.logger = createLogger(this.config.middleware.logging);\n \n // Initialize server pool (legacy - only used in old pooled mode)\n this.serverPool = new Map();\n \n // Initialize pool manager if pooled mode with instancePool config\n if (this.config.instanceMode === 'pooled' && this.config.instancePool) {\n this.poolManager = new InstancePoolManager(\n this.config.instancePool,\n this.logger\n );\n \n this.logger.info('Instance pool manager initialized', {\n maxSize: this.config.instancePool.maxSize,\n idleTimeout: this.config.instancePool.idleTimeout,\n maxLifetime: this.config.instancePool.maxLifetime\n });\n }\n \n // Initialize progress manager\n this.progressManager = new ProgressManager(this.logger);\n \n // Schedule periodic cleanup of stale streams (every minute)\n this.cleanupInterval = setInterval(() => {\n this.progressManager.cleanupStaleStreams();\n }, 60000);\n \n this.logger.info('AuthenticatedServerWrapper created', {\n name: this.config.name,\n resourceType: this.config.resourceType,\n transport: this.config.transport.type,\n instanceMode: this.config.instanceMode\n });\n }\n \n /**\n * Validate wrapper configuration\n */\n private validateConfig(config: ServerWrapperConfig): void {\n // Validate required fields manually for better type safety\n if (!config.serverFactory) {\n throw new ConfigurationError('serverFactory is required');\n }\n if (!config.authProvider) {\n throw new ConfigurationError('authProvider is required');\n }\n // tokenResolver is now optional for static servers\n if (!config.resourceType) {\n throw new ConfigurationError('resourceType is required');\n }\n if (!config.transport) {\n throw new ConfigurationError('transport is required');\n }\n \n validateResourceType(config.resourceType);\n validateTransportConfig(config.transport);\n \n // Validate instance pool config if pooled mode\n if (config.instanceMode === 'pooled') {\n if (!config.instancePool) {\n throw new ConfigurationError(\n 'instancePool configuration required when instanceMode is \"pooled\"'\n );\n }\n \n validatePositiveNumber(config.instancePool.maxSize, 'instancePool.maxSize');\n validatePositiveNumber(config.instancePool.idleTimeout, 'instancePool.idleTimeout');\n validatePositiveNumber(config.instancePool.maxLifetime, 'instancePool.maxLifetime');\n \n if (config.instancePool.maxSize < 1) {\n throw new ConfigurationError('instancePool.maxSize must be at least 1');\n }\n \n if (config.instancePool.idleTimeout < 1000) {\n throw new ConfigurationError('instancePool.idleTimeout must be at least 1000ms (1 second)');\n }\n \n if (config.instancePool.maxLifetime < config.instancePool.idleTimeout) {\n throw new ConfigurationError('instancePool.maxLifetime must be >= idleTimeout');\n }\n }\n \n // Log mode based on tokenResolver presence\n if (config.tokenResolver) {\n this.logger?.info('Token resolver configured - dynamic mode', {\n resolverType: config.tokenResolver.constructor.name\n });\n } else {\n this.logger?.info('No token resolver - static mode', {\n note: 'Server factory will receive empty string as accessToken'\n });\n }\n }\n \n /**\n * Normalize configuration with defaults\n */\n private normalizeConfig(config: ServerWrapperConfig): NormalizedServerWrapperConfig {\n return {\n serverFactory: config.serverFactory,\n authProvider: config.authProvider,\n tokenResolver: config.tokenResolver ?? null, // Convert undefined to null\n resourceType: config.resourceType,\n transport: config.transport,\n name: config.name ?? 'mcp-auth-wrapped-server',\n version: config.version ?? '1.0.0',\n instanceMode: config.instanceMode ?? 'ephemeral',\n instancePool: config.instancePool ?? null, // Convert undefined to null\n sessionMode: config.sessionMode ?? 'stateless',\n session: {\n idleTimeout: config.session?.idleTimeout ?? 300000,\n maxLifetime: config.session?.maxLifetime ?? 3600000,\n maxSessions: config.session?.maxSessions ?? 1000\n },\n middleware: {\n rateLimit: config.middleware?.rateLimit,\n logging: config.middleware?.logging ?? { enabled: true, level: 'info' }\n },\n pooling: {\n maxServersPerUser: config.pooling?.maxServersPerUser ?? 1,\n idleTimeoutMs: config.pooling?.idleTimeoutMs ?? 300000,\n maxTotalServers: config.pooling?.maxTotalServers ?? 100\n },\n requestTimeoutMs: config.requestTimeoutMs ?? 30000,\n enableTracing: config.enableTracing ?? false\n };\n }\n \n /**\n * Start the wrapped server\n */\n async start(): Promise<void> {\n if (this.isRunning) {\n throw new ConfigurationError('Server is already running');\n }\n \n this.logger.info('Starting authenticated server wrapper', {\n name: this.config.name,\n transport: this.config.transport.type\n });\n \n // Initialize auth provider\n if (this.config.authProvider.initialize) {\n await this.config.authProvider.initialize();\n this.logger.debug('Auth provider initialized');\n }\n \n // Initialize token resolver (if configured)\n if (this.config.tokenResolver) {\n if (this.config.tokenResolver.initialize) {\n await this.config.tokenResolver.initialize();\n this.logger.debug('Token resolver initialized');\n }\n } else {\n this.logger.debug('Static mode - no token resolver to initialize');\n }\n \n // Start appropriate transport\n switch (this.config.transport.type) {\n case 'stdio':\n await this.startStdioTransport();\n break;\n case 'sse':\n await this.startSSETransport();\n break;\n case 'http':\n await this.startHTTPTransport();\n break;\n default:\n throw new TransportError(`Unsupported transport type: ${this.config.transport.type}`);\n }\n \n this.isRunning = true;\n \n this.logger.info('Server wrapper started successfully', {\n name: this.config.name,\n transport: this.config.transport.type,\n port: this.config.transport.port\n });\n }\n \n /**\n * Stop the wrapped server\n */\n async stop(): Promise<void> {\n if (!this.isRunning) {\n return;\n }\n \n this.logger.info('Stopping server wrapper');\n \n // Clear cleanup timers\n if (this.cleanupTimer) {\n clearTimeout(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n \n if (this.cleanupInterval) {\n clearInterval(this.cleanupInterval);\n this.cleanupInterval = undefined;\n }\n \n // Clear session cleanup timer\n if (this.sessionCleanupTimer) {\n clearInterval(this.sessionCleanupTimer);\n this.sessionCleanupTimer = undefined;\n }\n\n // Close all active sessions\n for (const sessionId of [...this.sessions.keys()]) {\n await this.closeSession(sessionId);\n }\n\n // Close pool manager if exists\n if (this.poolManager) {\n await this.poolManager.closeAll();\n }\n \n // Close all pooled servers (legacy)\n if (this.config.instanceMode === 'pooled') {\n for (const [userId, instance] of this.serverPool.entries()) {\n try {\n await instance.server.close();\n this.logger.debug('Closed pooled server instance', { userId });\n } catch (error) {\n this.logger.error('Error closing server instance', error as Error, { userId });\n }\n }\n this.serverPool.clear();\n }\n \n // Cleanup auth provider\n if (this.config.authProvider.cleanup) {\n await this.config.authProvider.cleanup();\n this.logger.debug('Auth provider cleaned up');\n }\n \n // Cleanup token resolver (if configured)\n if (this.config.tokenResolver) {\n if (this.config.tokenResolver.cleanup) {\n await this.config.tokenResolver.cleanup();\n this.logger.debug('Token resolver cleaned up');\n }\n }\n \n this.isRunning = false;\n \n this.logger.info('Server wrapper stopped');\n }\n \n /**\n * Store progress context for a user\n */\n private storeProgressContext(userId: string, progressToken: string | number): void {\n this.progressContexts.set(userId, progressToken);\n this.logger.debug('Stored progress context', { userId, progressToken });\n }\n \n /**\n * Get progress context for a user\n */\n private getProgressContext(userId: string): string | number | undefined {\n return this.progressContexts.get(userId);\n }\n \n /**\n * Clear progress context for a user\n */\n private clearProgressContext(userId: string): void {\n this.progressContexts.delete(userId);\n this.logger.debug('Cleared progress context', { userId });\n }\n \n /**\n * Authenticate a request and resolve the access token.\n * Shared by both stateless and stateful request flows.\n */\n private async authenticateAndResolve(context: RequestContext, requestLogger: Logger): Promise<{ userId: string; accessToken: string }> {\n requestLogger.debug('Authenticating request');\n const authResult = await this.config.authProvider.authenticate(context);\n\n if (!authResult.authenticated || !authResult.userId) {\n requestLogger.warn('Authentication failed', { error: authResult.error });\n throw new AuthenticationError(authResult.error || 'Authentication failed');\n }\n\n const userId = validateUserId(authResult.userId);\n requestLogger.debug('Authentication successful', { userId });\n\n let accessToken: string;\n\n if (this.config.tokenResolver) {\n const resolvedToken = await this.config.tokenResolver.resolveToken(\n userId,\n this.config.resourceType\n );\n\n if (!resolvedToken) {\n requestLogger.warn('Token resolution failed', { userId, resourceType: this.config.resourceType });\n throw new TokenResolutionError(userId, this.config.resourceType);\n }\n\n validateAccessToken(resolvedToken);\n accessToken = resolvedToken;\n requestLogger.debug('Token resolved', { userId, resourceType: this.config.resourceType });\n } else {\n accessToken = '';\n requestLogger.debug('Static mode - no token resolution', { userId, mode: 'static' });\n }\n\n return { userId, accessToken };\n }\n\n /**\n * Build extras from request context (query params + custom X-* headers)\n */\n private buildExtras(context: RequestContext): MCPServerFactoryExtras {\n const customHeaders: Record<string, any> = {};\n if (context.headers) {\n for (const [key, value] of Object.entries(context.headers)) {\n if (key.toLowerCase().startsWith('x-')) {\n const paramKey = key.substring(2).toLowerCase().replace(/-/g, '_');\n customHeaders[paramKey] = value;\n }\n }\n }\n return { ...context.query, ...customHeaders };\n }\n\n /**\n * Create a new stateful session.\n * Generates a session ID, creates a transport+server pair, and stores them.\n */\n /**\n * Create a new stateful session.\n *\n * Returns a session object with transport+server connected, but the session\n * is NOT yet registered in the sessions map. Registration happens via the\n * onsessioninitialized callback when the transport processes the initialize\n * request (i.e., after handleRequest is called by the caller).\n */\n private async createSession(userId: string, accessToken: string, extras: MCPServerFactoryExtras): Promise<{ transport: StreamableHTTPServerTransport; server: Server }> {\n if (this.sessions.size >= this.config.session.maxSessions) {\n throw new TransportError(\n `Maximum concurrent sessions (${this.config.session.maxSessions}) reached`\n );\n }\n\n const server = await this.getServerInstance(userId, accessToken, extras);\n\n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => randomUUID(),\n onsessioninitialized: (sessionId: string) => {\n const session: ManagedSession = {\n sessionId,\n transport,\n server,\n userId,\n accessToken,\n createdAt: Date.now(),\n lastUsed: Date.now()\n };\n\n this.sessions.set(sessionId, session);\n\n // Clean up session when transport closes\n transport.onclose = () => {\n this.sessions.delete(sessionId);\n this.logger.debug('Session closed via transport', { sessionId, userId });\n };\n\n this.logger.info('Session created', { sessionId, userId });\n\n // Start cleanup timer if not already running\n if (!this.sessionCleanupTimer) {\n this.scheduleSessionCleanup();\n }\n },\n });\n\n await server.connect(transport);\n\n return { transport, server };\n }\n\n /**\n * Look up an existing session by ID.\n */\n private getSession(sessionId: string): ManagedSession | undefined {\n const session = this.sessions.get(sessionId);\n if (session) {\n session.lastUsed = Date.now();\n }\n return session;\n }\n\n /**\n * Close and remove a session.\n */\n private async closeSession(sessionId: string): Promise<void> {\n const session = this.sessions.get(sessionId);\n if (!session) return;\n\n try {\n await session.transport.close();\n await session.server.close();\n } catch (error) {\n this.logger.error('Error closing session', error as Error, { sessionId });\n }\n\n this.sessions.delete(sessionId);\n this.logger.info('Session removed', { sessionId, userId: session.userId });\n }\n\n /**\n * Schedule periodic cleanup of expired sessions.\n */\n private scheduleSessionCleanup(): void {\n const checkInterval = Math.min(this.config.session.idleTimeout, 60000);\n\n this.sessionCleanupTimer = setInterval(async () => {\n const now = Date.now();\n const toRemove: string[] = [];\n\n for (const [sessionId, session] of this.sessions.entries()) {\n const age = now - session.createdAt;\n const idle = now - session.lastUsed;\n\n if (age > this.config.session.maxLifetime || idle > this.config.session.idleTimeout) {\n toRemove.push(sessionId);\n }\n }\n\n for (const sessionId of toRemove) {\n this.logger.info('Cleaning up expired session', { sessionId });\n await this.closeSession(sessionId);\n }\n\n // Stop timer if no sessions remain\n if (this.sessions.size === 0 && this.sessionCleanupTimer) {\n clearInterval(this.sessionCleanupTimer);\n this.sessionCleanupTimer = undefined;\n }\n }, checkInterval);\n }\n\n /**\n * Handle a stateful request (sessionMode: 'stateful').\n *\n * Routes requests based on Mcp-Session-Id header:\n * - POST without session ID: authenticate + create new session\n * - POST/GET/DELETE with session ID: route to existing session\n */\n private async handleStatefulRequest(req: any, res: any, context: RequestContext): Promise<void> {\n const requestLogger = this.logger.child({ requestId: context.requestId });\n const sessionId = req.headers['mcp-session-id'] as string | undefined;\n const method = req.method?.toUpperCase();\n\n if (sessionId) {\n // Route to existing session\n const session = this.getSession(sessionId);\n if (!session) {\n res.status(404).json({\n error: 'Session not found or expired',\n code: 'SESSION_NOT_FOUND'\n });\n return;\n }\n\n // Authenticate to verify the caller owns this session\n const { userId } = await this.authenticateAndResolve(context, requestLogger);\n if (userId !== session.userId) {\n requestLogger.warn('Session userId mismatch', { sessionId, expected: session.userId, got: userId });\n res.status(403).json({\n error: 'Session does not belong to this user',\n code: 'SESSION_FORBIDDEN'\n });\n return;\n }\n\n requestLogger.debug('Routing to existing session', { sessionId, method });\n await session.transport.handleRequest(req, res, req.body);\n return;\n }\n\n // No session ID \u2014 must be POST (initialize)\n if (method !== 'POST') {\n res.status(400).json({\n error: 'Missing Mcp-Session-Id header',\n code: 'SESSION_REQUIRED'\n });\n return;\n }\n\n // Authenticate and create new session\n const { userId, accessToken } = await this.authenticateAndResolve(context, requestLogger);\n const extras = this.buildExtras(context);\n\n const { transport } = await this.createSession(userId, accessToken, extras);\n\n // Forward the initialize request \u2014 this triggers onsessioninitialized,\n // which registers the session in the sessions map with the generated ID.\n await transport.handleRequest(req, res, req.body);\n requestLogger.info('New session initialized', { sessionId: transport.sessionId, userId });\n }\n\n /**\n * Handle SSE request with direct Express req/res access\n * This allows us to use StreamableHTTPServerTransport properly\n */\n private async handleSSERequest(req: any, res: any, context: RequestContext): Promise<void> {\n const requestLogger = this.logger.child({ requestId: context.requestId });\n let userId: string | undefined;\n const progressToken = req.body._meta?.progressToken;\n \n try {\n // 1. Authenticate\n requestLogger.debug('Authenticating request');\n const authResult = await this.config.authProvider.authenticate(context);\n \n if (!authResult.authenticated || !authResult.userId) {\n requestLogger.warn('Authentication failed', { error: authResult.error });\n throw new AuthenticationError(authResult.error || 'Authentication failed');\n }\n \n userId = validateUserId(authResult.userId);\n requestLogger.debug('Authentication successful', { userId });\n \n // 2. Resolve resource token (or use empty string for static mode)\n let accessToken: string;\n \n if (this.config.tokenResolver) {\n // Dynamic mode - resolve token from external source\n const resolvedToken = await this.config.tokenResolver.resolveToken(\n userId,\n this.config.resourceType\n );\n \n if (!resolvedToken) {\n requestLogger.warn('Token resolution failed', { userId, resourceType: this.config.resourceType });\n throw new TokenResolutionError(userId, this.config.resourceType);\n }\n \n validateAccessToken(resolvedToken);\n accessToken = resolvedToken;\n requestLogger.debug('Token resolved', { userId, resourceType: this.config.resourceType });\n } else {\n // Static mode - no external token needed\n accessToken = '';\n requestLogger.debug('Static mode - no token resolution', { userId, mode: 'static' });\n }\n \n // 3. Store progress token and register stream if provided\n if (progressToken) {\n this.storeProgressContext(userId, progressToken);\n \n // Register progress stream with callback to forward notifications\n this.progressManager.registerStream(userId, progressToken, (notification) => {\n // Forward notification to client via response\n // Note: In a real implementation, this would use SSE or WebSocket\n // For now, we log that we would forward it\n requestLogger.debug('Would forward progress notification', {\n userId,\n progressToken: notification.progressToken,\n progress: notification.progress,\n total: notification.total\n });\n });\n \n requestLogger.debug('Progress token extracted and stream registered', { userId, progressToken });\n }\n \n // 4. Get server instance (pass query params + custom headers as extras)\n // Extract custom headers (X-* headers) for ghost mode, etc.\n const customHeaders: Record<string, any> = {};\n if (context.headers) {\n for (const [key, value] of Object.entries(context.headers)) {\n if (key.toLowerCase().startsWith('x-')) {\n // Remove 'x-' prefix and convert to snake_case (e.g., X-Ghost-Owner -> ghost_owner)\n const paramKey = key.substring(2).toLowerCase().replace(/-/g, '_');\n customHeaders[paramKey] = value;\n }\n }\n }\n\n const extras = { ...context.query, ...customHeaders };\n const server = await this.getServerInstance(userId, accessToken, extras);\n \n // 5. Intercept server notifications to forward progress\n if (progressToken) {\n const originalNotification = (server as any).notification?.bind(server);\n if (originalNotification) {\n (server as any).notification = (params: any) => {\n // Check if this is a progress notification\n if (params.method === 'notifications/progress') {\n const handled = this.progressManager.forwardNotification(\n params.params as ProgressNotification\n );\n \n if (handled) {\n requestLogger.debug('Progress notification intercepted and forwarded', {\n progressToken: params.params.progressToken\n });\n return; // Don't send through original path\n }\n }\n \n // Forward other notifications normally\n if (originalNotification) {\n originalNotification(params);\n }\n };\n }\n }\n \n // 6. Forward request to server via StreamableHTTPServerTransport\n requestLogger.debug('Forwarding request to MCP server', { userId, hasProgressToken: !!progressToken });\n \n const transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: undefined // Stateless mode\n });\n \n // Connect server to transport\n await server.connect(transport);\n \n // Forward the request through the transport\n // The transport handles JSON-RPC formatting\n // Tool names are passed through unchanged\n await transport.handleRequest(req, res, req.body);\n \n requestLogger.info('Request handled successfully', {\n userId,\n resourceType: this.config.resourceType,\n hadProgressToken: !!progressToken\n });\n \n // Clean up progress context and stream after request completes\n if (progressToken) {\n this.progressManager.unregisterStream(progressToken);\n this.clearProgressContext(userId);\n }\n \n } catch (error) {\n requestLogger.error('SSE request handling failed', error as Error);\n \n // Clean up progress context and stream on error\n if (progressToken) {\n this.progressManager.unregisterStream(progressToken);\n if (userId) {\n this.clearProgressContext(userId);\n }\n }\n \n throw error;\n }\n }\n \n /**\n * Get server instance (ephemeral or from pool)\n */\n private async getServerInstance(userId: string, accessToken: string, extras?: MCPServerFactoryExtras): Promise<Server> {\n if (this.config.instanceMode === 'ephemeral') {\n // Create new server instance for each request (recommended)\n this.logger.debug('Creating ephemeral server instance', { userId });\n return await this.config.serverFactory(accessToken, userId, extras);\n }\n\n // Pooled mode\n return await this.getPooledServerInstance(userId, accessToken, extras);\n }\n \n /**\n * Get or create pooled server instance\n */\n private async getPooledServerInstance(userId: string, accessToken: string, extras?: MCPServerFactoryExtras): Promise<Server> {\n // Use new InstancePoolManager if configured\n if (this.poolManager) {\n return await this.poolManager.getInstance(\n userId,\n accessToken,\n this.config.serverFactory,\n extras\n );\n }\n \n // Legacy pooling logic (deprecated)\n // Check if we have a cached server instance\n if (this.serverPool.has(userId)) {\n const instance = this.serverPool.get(userId)!;\n \n // Check if token changed (user rotated token)\n if (instance.accessToken !== accessToken) {\n this.logger.info('Token changed, recreating server instance', { userId });\n await instance.server.close();\n this.serverPool.delete(userId);\n } else {\n // Reuse existing instance\n instance.lastUsed = Date.now();\n this.logger.debug('Reusing pooled server instance', { userId });\n return instance.server;\n }\n }\n \n // Check pool size limit\n if (this.serverPool.size >= this.config.pooling.maxTotalServers) {\n this.logger.warn('Server pool limit reached, evicting oldest instance', {\n poolSize: this.serverPool.size,\n maxTotal: this.config.pooling.maxTotalServers\n });\n await this.evictOldestInstance();\n }\n \n // Create new server instance\n this.logger.info('Creating new pooled server instance', { userId });\n const server = await this.config.serverFactory(accessToken, userId, extras);\n \n // Add to pool\n this.serverPool.set(userId, {\n server,\n accessToken,\n userId,\n createdAt: Date.now(),\n lastUsed: Date.now()\n });\n \n // Schedule cleanup if not already scheduled\n if (!this.cleanupTimer) {\n this.scheduleCleanup();\n }\n \n return server;\n }\n \n /**\n * Evict oldest server instance from pool\n */\n private async evictOldestInstance(): Promise<void> {\n let oldestUserId: string | null = null;\n let oldestTime = Infinity;\n \n for (const [userId, instance] of this.serverPool.entries()) {\n if (instance.lastUsed < oldestTime) {\n oldestTime = instance.lastUsed;\n oldestUserId = userId;\n }\n }\n \n if (oldestUserId) {\n const instance = this.serverPool.get(oldestUserId)!;\n await instance.server.close();\n this.serverPool.delete(oldestUserId);\n \n this.logger.debug('Evicted oldest server instance', {\n userId: oldestUserId,\n age: Date.now() - instance.createdAt\n });\n }\n }\n \n /**\n * Schedule cleanup of idle server instances\n */\n private scheduleCleanup(): void {\n const timeout = this.config.pooling.idleTimeoutMs;\n \n this.cleanupTimer = setTimeout(async () => {\n const now = Date.now();\n const toRemove: string[] = [];\n \n for (const [userId, instance] of this.serverPool.entries()) {\n if (now - instance.lastUsed > timeout) {\n toRemove.push(userId);\n }\n }\n \n for (const userId of toRemove) {\n const instance = this.serverPool.get(userId)!;\n try {\n await instance.server.close();\n this.serverPool.delete(userId);\n \n this.logger.debug('Cleaned up idle server instance', {\n userId,\n idleTime: now - instance.lastUsed\n });\n } catch (error) {\n this.logger.error('Error cleaning up server instance', error as Error, { userId });\n }\n }\n \n // Reschedule if pool is not empty\n if (this.serverPool.size > 0) {\n this.scheduleCleanup();\n } else {\n this.cleanupTimer = undefined;\n }\n }, timeout);\n }\n \n /**\n * Start stdio transport (single-user mode)\n */\n private async startStdioTransport(): Promise<void> {\n this.logger.info('Starting stdio transport');\n \n // For stdio, we use environment variable for token\n const envVar = `${this.config.resourceType.toUpperCase()}_ACCESS_TOKEN`;\n const accessToken = process.env[envVar];\n \n if (!accessToken) {\n throw new ConfigurationError(\n `${envVar} environment variable required for stdio mode`\n );\n }\n \n const userId = 'stdio-user';\n \n // Create server instance\n const server = await this.config.serverFactory(accessToken, userId);\n \n // Connect to stdio transport\n const transport = new StdioServerTransport();\n await server.connect(transport);\n \n this.logger.info('Stdio transport started', { userId });\n }\n \n /**\n * Start SSE transport (multi-user mode)\n */\n private async startSSETransport(): Promise<void> {\n this.logger.info('Starting SSE transport', {\n port: this.config.transport.port,\n basePath: this.config.transport.basePath\n });\n \n // Import express dynamically (optional dependency)\n // @ts-ignore - Dynamic import of optional dependency\n const express = await import('express');\n const app = express.default();\n \n // Enable JSON parsing\n app.use(express.json());\n \n // Enable CORS if configured\n if (this.config.transport.cors) {\n // Validate CORS configuration\n if (!this.config.transport.corsOrigin) {\n throw new ConfigurationError(\n 'CORS origin must be explicitly configured when CORS is enabled. ' +\n 'Set transport.corsOrigin to a specific origin (e.g., \"https://app.example.com\") ' +\n 'or an array of allowed origins.'\n );\n }\n \n // Check for wildcard in production\n if (this.config.transport.corsOrigin === '*') {\n const isProduction = process.env.NODE_ENV === 'production';\n \n if (isProduction) {\n throw new ConfigurationError(\n 'CORS wildcard (*) is not allowed in production environments. ' +\n 'Specify explicit origins to prevent CSRF attacks. ' +\n 'Example: corsOrigin: \"https://app.example.com\"'\n );\n }\n \n this.logger.warn(\n 'CORS wildcard (*) detected in development. ' +\n 'This is insecure and should never be used in production.',\n { corsOrigin: this.config.transport.corsOrigin }\n );\n }\n \n // @ts-ignore - Dynamic import of optional dependency\n const cors = await import('cors');\n app.use(cors.default({\n origin: this.config.transport.corsOrigin,\n credentials: true,\n methods: ['GET', 'POST', 'DELETE', 'OPTIONS'],\n allowedHeaders: [\n 'Content-Type', 'Authorization', 'X-Request-ID', 'Mcp-Session-Id',\n ...(this.config.transport.corsAllowedHeaders || []),\n ],\n exposedHeaders: ['X-Request-ID', 'Mcp-Session-Id'],\n maxAge: 86400 // 24 hours\n }));\n \n this.logger.info('CORS enabled', {\n origin: this.config.transport.corsOrigin,\n credentials: true\n });\n }\n \n const basePath = this.config.transport.basePath || '/mcp';\n \n // Root endpoint info\n app.get(basePath, (req: any, res: any) => {\n res.json({\n name: this.config.name,\n version: this.config.version,\n resourceType: this.config.resourceType,\n sessionMode: this.config.sessionMode,\n endpoints: {\n message: `POST ${basePath}/message`,\n health: `GET ${basePath}/health`\n },\n documentation: 'https://github.com/prmichaelsen/mcp-auth'\n });\n });\n\n const isStateful = this.config.sessionMode === 'stateful';\n\n // Error handler shared by all message routes\n const handleError = (error: unknown, res: any) => {\n this.logger.error('Request failed', error as Error);\n\n if (error instanceof AuthenticationError || error instanceof TokenResolutionError) {\n res.status((error as any).statusCode).json({\n error: (error as Error).message,\n code: (error as any).code\n });\n } else if (error instanceof TransportError) {\n res.status(503).json({\n error: (error as Error).message,\n code: 'TRANSPORT_ERROR'\n });\n } else {\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\n }\n };\n\n const buildContext = (req: any): RequestContext => ({\n headers: req.headers as Record<string, string>,\n transport: 'sse',\n timestamp: new Date(),\n requestId: req.headers['x-request-id'] as string | undefined,\n query: req.query as Record<string, string | string[] | undefined>\n });\n\n // POST endpoint for MCP messages\n app.post(`${basePath}/message`, async (req: any, res: any) => {\n try {\n const context = buildContext(req);\n if (isStateful) {\n await this.handleStatefulRequest(req, res, context);\n } else {\n await this.handleSSERequest(req, res, context);\n }\n } catch (error) {\n handleError(error, res);\n }\n });\n\n if (isStateful) {\n // GET endpoint for SSE streams (server\u2192client messages like elicitation)\n app.get(`${basePath}/message`, async (req: any, res: any) => {\n try {\n const context = buildContext(req);\n await this.handleStatefulRequest(req, res, context);\n } catch (error) {\n handleError(error, res);\n }\n });\n\n // DELETE endpoint for session termination\n app.delete(`${basePath}/message`, async (req: any, res: any) => {\n try {\n const context = buildContext(req);\n await this.handleStatefulRequest(req, res, context);\n } catch (error) {\n handleError(error, res);\n }\n });\n\n this.logger.info('Stateful session mode enabled', {\n idleTimeout: this.config.session.idleTimeout,\n maxLifetime: this.config.session.maxLifetime,\n maxSessions: this.config.session.maxSessions\n });\n }\n \n // Progress monitoring endpoint (authenticated)\n app.get(`${basePath}/progress/stats`, async (req: any, res: any) => {\n try {\n // Authenticate request\n const context: RequestContext = {\n headers: req.headers as Record<string, string>,\n transport: 'sse',\n timestamp: new Date(),\n requestId: req.headers['x-request-id'] as string | undefined\n };\n \n const authResult = await this.config.authProvider.authenticate(context);\n \n if (!authResult.authenticated || !authResult.userId) {\n return res.status(401).json({\n error: 'Authentication required',\n code: 'AUTHENTICATION_ERROR'\n });\n }\n \n const userId = authResult.userId;\n \n // Get user-specific metrics\n const userMetrics = this.progressManager.getUserMetrics(userId);\n const globalStats = this.progressManager.getStats();\n \n res.json({\n user: {\n userId,\n ...userMetrics\n },\n global: globalStats,\n timestamp: new Date().toISOString()\n });\n \n } catch (error) {\n this.logger.error('Error fetching progress stats', error as Error);\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\n }\n });\n \n // Detailed metrics endpoint (authenticated)\n app.get(`${basePath}/progress/metrics`, async (req: any, res: any) => {\n try {\n // Authenticate request\n const context: RequestContext = {\n headers: req.headers as Record<string, string>,\n transport: 'sse',\n timestamp: new Date(),\n requestId: req.headers['x-request-id'] as string | undefined\n };\n \n const authResult = await this.config.authProvider.authenticate(context);\n \n if (!authResult.authenticated) {\n return res.status(401).json({\n error: 'Authentication required',\n code: 'AUTHENTICATION_ERROR'\n });\n }\n \n // Get all metrics (could add admin check here)\n const allMetrics = this.progressManager.getAllMetrics();\n const health = this.progressManager.checkHealth();\n \n res.json({\n metrics: allMetrics,\n health,\n timestamp: new Date().toISOString()\n });\n \n } catch (error) {\n this.logger.error('Error fetching progress metrics', error as Error);\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\n }\n });\n \n // Health check endpoint\n app.get(`${basePath}/health`, (req: any, res: any) => {\n res.json({\n status: 'healthy',\n name: this.config.name,\n version: this.config.version,\n resourceType: this.config.resourceType,\n instanceMode: this.config.instanceMode,\n sessionMode: this.config.sessionMode,\n poolSize: this.serverPool.size,\n ...(isStateful ? { activeSessions: this.sessions.size } : {})\n });\n });\n \n // Start server\n const port = this.config.transport.port || 3000;\n const host = this.config.transport.host || '0.0.0.0';\n \n await new Promise<void>((resolve) => {\n app.listen(port, host, () => {\n this.logger.info('SSE transport listening', {\n host,\n port,\n basePath,\n url: `http://${host}:${port}${basePath}`\n });\n resolve();\n });\n });\n }\n \n /**\n * Start HTTP transport (multi-user mode)\n */\n private async startHTTPTransport(): Promise<void> {\n this.logger.info('Starting HTTP transport', {\n port: this.config.transport.port\n });\n \n // HTTP transport is similar to SSE but with different endpoint structure\n // For now, delegate to SSE implementation\n await this.startSSETransport();\n }\n \n /**\n * Get server pool statistics\n */\n getPoolStats(): {\n size: number;\n instances: Array<{\n userId: string;\n createdAt: number;\n lastUsed: number;\n age: number;\n idleTime: number;\n }>;\n } {\n const now = Date.now();\n const instances = Array.from(this.serverPool.entries()).map(([userId, instance]) => ({\n userId,\n createdAt: instance.createdAt,\n lastUsed: instance.lastUsed,\n age: now - instance.createdAt,\n idleTime: now - instance.lastUsed\n }));\n \n return {\n size: this.serverPool.size,\n instances\n };\n }\n \n /**\n * Check if server is running\n */\n isServerRunning(): boolean {\n return this.isRunning;\n }\n}\n\n/**\n * Convenience function to create and configure an authenticated server wrapper\n *\n * @param config - Server wrapper configuration\n * @returns Configured AuthenticatedServerWrapper instance\n *\n * @example\n * ```typescript\n * const wrapped = wrapServer({\n * serverFactory: (accessToken, userId) => createMyServer(accessToken, userId),\n * authProvider: new JWTAuthProvider({ jwtSecret: process.env.JWT_SECRET }),\n * tokenResolver: new APITokenResolver({ ... }),\n * resourceType: 'myapi',\n * transport: { type: 'sse', port: 3000 }\n * });\n *\n * await wrapped.start();\n * ```\n */\nexport function wrapServer(config: ServerWrapperConfig): AuthenticatedServerWrapper {\n return new AuthenticatedServerWrapper(config);\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["userId"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/mcp-auth",
3
- "version": "7.5.0",
3
+ "version": "7.5.1",
4
4
  "description": "Authentication and multi-tenancy framework for MCP servers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",