@prmichaelsen/mcp-auth 1.0.0 → 3.0.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.
@@ -51,9 +51,17 @@ export declare class AuthenticatedServerWrapper {
51
51
  */
52
52
  stop(): Promise<void>;
53
53
  /**
54
- * Handle incoming MCP request with authentication
54
+ * Handle SSE request with direct Express req/res access
55
+ * This allows us to use StreamableHTTPServerTransport properly
55
56
  */
56
- private handleRequest;
57
+ private handleSSERequest;
58
+ /**
59
+ * Transform JSON-RPC request to strip resource prefix from tool names
60
+ *
61
+ * Transforms: instagram_get_profile → get_profile
62
+ * This allows platforms to use prefixed names while MCP servers use simple names
63
+ */
64
+ private transformRequest;
57
65
  /**
58
66
  * Get server instance (ephemeral or from pool)
59
67
  */
@@ -1 +1 @@
1
- {"version":3,"file":"server-wrapper.d.ts","sourceRoot":"","sources":["../../src/wrapper/server-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,mBAAmB,EAAiC,MAAM,aAAa,CAAC;AA4BtF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,YAAY,CAAC,CAAiB;gBAE1B,MAAM,EAAE,mBAAmB;IAqBvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAwBvB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C3B;;OAEG;YACW,aAAa;IAuE3B;;OAEG;YACW,iBAAiB;IAW/B;;OAEG;YACW,uBAAuB;IAgDrC;;OAEG;YACW,mBAAmB;IAuBjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAqCvB;;OAEG;YACW,mBAAmB;IAyBjC;;OAEG;YACW,iBAAiB;IAkG/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"}
1
+ {"version":3,"file":"server-wrapper.d.ts","sourceRoot":"","sources":["../../src/wrapper/server-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,OAAO,KAAK,EAAE,mBAAmB,EAAiC,MAAM,aAAa,CAAC;AA4BtF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,qBAAa,0BAA0B;IACrC,OAAO,CAAC,MAAM,CAAgC;IAC9C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,SAAS,CAAkB;IACnC,OAAO,CAAC,YAAY,CAAC,CAAiB;gBAE1B,MAAM,EAAE,mBAAmB;IAqBvC;;OAEG;IACH,OAAO,CAAC,cAAc;IAsBtB;;OAEG;IACH,OAAO,CAAC,eAAe;IAwBvB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8C5B;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IA2C3B;;;OAGG;YACW,gBAAgB;IA6D9B;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAmCxB;;OAEG;YACW,iBAAiB;IAW/B;;OAEG;YACW,uBAAuB;IAgDrC;;OAEG;YACW,mBAAmB;IAuBjC;;OAEG;IACH,OAAO,CAAC,eAAe;IAqCvB;;OAEG;YACW,mBAAmB;IAyBjC;;OAEG;YACW,iBAAiB;IAkG/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"}
@@ -1,4 +1,5 @@
1
1
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
2
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
2
3
  import {
3
4
  AuthenticationError,
4
5
  TokenResolutionError,
@@ -152,21 +153,16 @@ class AuthenticatedServerWrapper {
152
153
  this.logger.info("Server wrapper stopped");
153
154
  }
154
155
  /**
155
- * Handle incoming MCP request with authentication
156
+ * Handle SSE request with direct Express req/res access
157
+ * This allows us to use StreamableHTTPServerTransport properly
156
158
  */
157
- async handleRequest(request, context) {
158
- const requestId = context.requestId ?? `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
159
- const requestLogger = this.logger.child({ requestId });
159
+ async handleSSERequest(req, res, context) {
160
+ const requestLogger = this.logger.child({ requestId: context.requestId });
160
161
  try {
161
- requestLogger.debug("Handling request", {
162
- transport: context.transport,
163
- hasHeaders: !!context.headers
164
- });
162
+ requestLogger.debug("Authenticating request");
165
163
  const authResult = await this.config.authProvider.authenticate(context);
166
164
  if (!authResult.authenticated || !authResult.userId) {
167
- requestLogger.warn("Authentication failed", {
168
- error: authResult.error
169
- });
165
+ requestLogger.warn("Authentication failed", { error: authResult.error });
170
166
  throw new AuthenticationError(authResult.error || "Authentication failed");
171
167
  }
172
168
  const userId = validateUserId(authResult.userId);
@@ -176,31 +172,61 @@ class AuthenticatedServerWrapper {
176
172
  this.config.resourceType
177
173
  );
178
174
  if (!accessToken) {
179
- requestLogger.warn("Token resolution failed", {
180
- userId,
181
- resourceType: this.config.resourceType
182
- });
175
+ requestLogger.warn("Token resolution failed", { userId, resourceType: this.config.resourceType });
183
176
  throw new TokenResolutionError(userId, this.config.resourceType);
184
177
  }
185
178
  validateAccessToken(accessToken);
186
- requestLogger.debug("Token resolved", {
187
- userId,
188
- resourceType: this.config.resourceType,
189
- tokenLength: accessToken.length
190
- });
179
+ requestLogger.debug("Token resolved", { userId, resourceType: this.config.resourceType });
191
180
  const server = await this.getServerInstance(userId, accessToken);
192
- requestLogger.debug("Forwarding request to server instance", { userId });
193
- const response = { success: true, userId, resourceType: this.config.resourceType };
181
+ const transformedBody = this.transformRequest(req.body, requestLogger);
182
+ requestLogger.debug("Forwarding request to MCP server", { userId });
183
+ const transport = new StreamableHTTPServerTransport({
184
+ sessionIdGenerator: void 0
185
+ // Stateless mode
186
+ });
187
+ await server.connect(transport);
188
+ await transport.handleRequest(req, res, transformedBody);
194
189
  requestLogger.info("Request handled successfully", {
195
190
  userId,
196
191
  resourceType: this.config.resourceType
197
192
  });
198
- return response;
199
193
  } catch (error) {
200
- requestLogger.error("Request handling failed", error);
194
+ requestLogger.error("SSE request handling failed", error);
201
195
  throw error;
202
196
  }
203
197
  }
198
+ /**
199
+ * Transform JSON-RPC request to strip resource prefix from tool names
200
+ *
201
+ * Transforms: instagram_get_profile → get_profile
202
+ * This allows platforms to use prefixed names while MCP servers use simple names
203
+ */
204
+ transformRequest(body, logger) {
205
+ if (body?.method !== "tools/call") {
206
+ return body;
207
+ }
208
+ const toolName = body?.params?.name;
209
+ if (!toolName || typeof toolName !== "string") {
210
+ return body;
211
+ }
212
+ const prefix = `${this.config.resourceType}_`;
213
+ if (toolName.startsWith(prefix)) {
214
+ const strippedName = toolName.substring(prefix.length);
215
+ logger.debug("Stripping tool name prefix", {
216
+ original: toolName,
217
+ stripped: strippedName,
218
+ prefix
219
+ });
220
+ return {
221
+ ...body,
222
+ params: {
223
+ ...body.params,
224
+ name: strippedName
225
+ }
226
+ };
227
+ }
228
+ return body;
229
+ }
204
230
  /**
205
231
  * Get server instance (ephemeral or from pool)
206
232
  */
@@ -359,8 +385,7 @@ class AuthenticatedServerWrapper {
359
385
  timestamp: /* @__PURE__ */ new Date(),
360
386
  requestId: req.headers["x-request-id"]
361
387
  };
362
- const result = await this.handleRequest(req.body, context);
363
- res.json(result);
388
+ await this.handleSSERequest(req, res, context);
364
389
  } catch (error) {
365
390
  this.logger.error("SSE request failed", error);
366
391
  if (error instanceof AuthenticationError || error instanceof TokenResolutionError) {
@@ -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 type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport type { ServerWrapperConfig, NormalizedServerWrapperConfig } from './config.js';\nimport type { RequestContext } 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} from '../utils/validation.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 * 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 isRunning: boolean = false;\n private cleanupTimer?: 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 (only used in pooled mode)\n this.serverPool = new Map();\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 if (!config.tokenResolver) {\n throw new ConfigurationError('tokenResolver is required');\n }\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 \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,\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 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\n if (this.config.tokenResolver.initialize) {\n await this.config.tokenResolver.initialize();\n this.logger.debug('Token resolver initialized');\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 timer\n if (this.cleanupTimer) {\n clearTimeout(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n \n // Close all pooled servers\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\n if (this.config.tokenResolver.cleanup) {\n await this.config.tokenResolver.cleanup();\n this.logger.debug('Token resolver cleaned up');\n }\n \n this.isRunning = false;\n \n this.logger.info('Server wrapper stopped');\n }\n \n /**\n * Handle incoming MCP request with authentication\n */\n private async handleRequest(request: any, context: RequestContext): Promise<any> {\n const requestId = context.requestId ?? `req-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n const requestLogger = this.logger.child({ requestId });\n \n try {\n requestLogger.debug('Handling request', {\n transport: context.transport,\n hasHeaders: !!context.headers\n });\n \n // 1. Authenticate request\n const authResult = await this.config.authProvider.authenticate(context);\n \n if (!authResult.authenticated || !authResult.userId) {\n requestLogger.warn('Authentication failed', {\n error: authResult.error\n });\n throw new AuthenticationError(authResult.error || 'Authentication failed');\n }\n \n const userId = validateUserId(authResult.userId);\n \n requestLogger.debug('Authentication successful', { userId });\n \n // 2. Resolve resource token\n const accessToken = await this.config.tokenResolver.resolveToken(\n userId,\n this.config.resourceType\n );\n \n if (!accessToken) {\n requestLogger.warn('Token resolution failed', {\n userId,\n resourceType: this.config.resourceType\n });\n throw new TokenResolutionError(userId, this.config.resourceType);\n }\n \n validateAccessToken(accessToken);\n \n requestLogger.debug('Token resolved', {\n userId,\n resourceType: this.config.resourceType,\n tokenLength: accessToken.length\n });\n \n // 3. Get server instance (ephemeral or pooled)\n const server = await this.getServerInstance(userId, accessToken);\n \n // 4. Forward request to server\n // Note: This is a simplified version. Actual implementation would need\n // to properly handle MCP protocol messages\n requestLogger.debug('Forwarding request to server instance', { userId });\n \n // TODO: Implement actual MCP request forwarding\n // For now, this is a placeholder\n const response = { success: true, userId, resourceType: this.config.resourceType };\n \n requestLogger.info('Request handled successfully', {\n userId,\n resourceType: this.config.resourceType\n });\n \n return response;\n \n } catch (error) {\n requestLogger.error('Request handling failed', error as Error);\n throw error;\n }\n }\n \n /**\n * Get server instance (ephemeral or from pool)\n */\n private async getServerInstance(userId: string, accessToken: string): 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);\n }\n \n // Pooled mode\n return await this.getPooledServerInstance(userId, accessToken);\n }\n \n /**\n * Get or create pooled server instance\n */\n private async getPooledServerInstance(userId: string, accessToken: string): Promise<Server> {\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);\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 // @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 }));\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 endpoints: {\n message: `POST ${basePath}/message`,\n health: `GET ${basePath}/health`\n },\n documentation: 'https://github.com/prmichaelsen/mcp-auth'\n });\n });\n \n // SSE endpoint for MCP messages\n app.post(`${basePath}/message`, async (req: any, res: any) => {\n try {\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 result = await this.handleRequest(req.body, context);\n res.json(result);\n \n } catch (error) {\n this.logger.error('SSE request failed', error as Error);\n \n if (error instanceof AuthenticationError || error instanceof TokenResolutionError) {\n res.status(error.statusCode).json({\n error: error.message,\n code: error.code\n });\n } else {\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\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 poolSize: this.serverPool.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"],
5
- "mappings": "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",
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 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 } from './config.js';\nimport type { RequestContext } 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} from '../utils/validation.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 * 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 isRunning: boolean = false;\n private cleanupTimer?: 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 (only used in pooled mode)\n this.serverPool = new Map();\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 if (!config.tokenResolver) {\n throw new ConfigurationError('tokenResolver is required');\n }\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 \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,\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 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\n if (this.config.tokenResolver.initialize) {\n await this.config.tokenResolver.initialize();\n this.logger.debug('Token resolver initialized');\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 timer\n if (this.cleanupTimer) {\n clearTimeout(this.cleanupTimer);\n this.cleanupTimer = undefined;\n }\n \n // Close all pooled servers\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\n if (this.config.tokenResolver.cleanup) {\n await this.config.tokenResolver.cleanup();\n this.logger.debug('Token resolver cleaned up');\n }\n \n this.isRunning = false;\n \n this.logger.info('Server wrapper stopped');\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 \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 const userId = validateUserId(authResult.userId);\n requestLogger.debug('Authentication successful', { userId });\n \n // 2. Resolve resource token\n const accessToken = await this.config.tokenResolver.resolveToken(\n userId,\n this.config.resourceType\n );\n \n if (!accessToken) {\n requestLogger.warn('Token resolution failed', { userId, resourceType: this.config.resourceType });\n throw new TokenResolutionError(userId, this.config.resourceType);\n }\n \n validateAccessToken(accessToken);\n requestLogger.debug('Token resolved', { userId, resourceType: this.config.resourceType });\n \n // 3. Get server instance\n const server = await this.getServerInstance(userId, accessToken);\n \n // 4. Transform request to strip resource prefix from tool names\n const transformedBody = this.transformRequest(req.body, requestLogger);\n \n // 5. Forward request to server via StreamableHTTPServerTransport\n requestLogger.debug('Forwarding request to MCP server', { userId });\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 transformed request through the transport\n // The transport handles JSON-RPC formatting\n await transport.handleRequest(req, res, transformedBody);\n \n requestLogger.info('Request handled successfully', {\n userId,\n resourceType: this.config.resourceType\n });\n \n } catch (error) {\n requestLogger.error('SSE request handling failed', error as Error);\n throw error;\n }\n }\n \n /**\n * Transform JSON-RPC request to strip resource prefix from tool names\n *\n * Transforms: instagram_get_profile \u2192 get_profile\n * This allows platforms to use prefixed names while MCP servers use simple names\n */\n private transformRequest(body: any, logger: Logger): any {\n // Only transform tools/call requests\n if (body?.method !== 'tools/call') {\n return body;\n }\n \n const toolName = body?.params?.name;\n if (!toolName || typeof toolName !== 'string') {\n return body;\n }\n \n // Strip resource prefix if present\n const prefix = `${this.config.resourceType}_`;\n if (toolName.startsWith(prefix)) {\n const strippedName = toolName.substring(prefix.length);\n \n logger.debug('Stripping tool name prefix', {\n original: toolName,\n stripped: strippedName,\n prefix\n });\n \n return {\n ...body,\n params: {\n ...body.params,\n name: strippedName\n }\n };\n }\n \n // No transformation needed\n return body;\n }\n \n /**\n * Get server instance (ephemeral or from pool)\n */\n private async getServerInstance(userId: string, accessToken: string): 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);\n }\n \n // Pooled mode\n return await this.getPooledServerInstance(userId, accessToken);\n }\n \n /**\n * Get or create pooled server instance\n */\n private async getPooledServerInstance(userId: string, accessToken: string): Promise<Server> {\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);\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 // @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 }));\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 endpoints: {\n message: `POST ${basePath}/message`,\n health: `GET ${basePath}/health`\n },\n documentation: 'https://github.com/prmichaelsen/mcp-auth'\n });\n });\n \n // SSE endpoint for MCP messages\n app.post(`${basePath}/message`, async (req: any, res: any) => {\n try {\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 // Handle request and forward to MCP server via transport\n await this.handleSSERequest(req, res, context);\n \n } catch (error) {\n this.logger.error('SSE request failed', error as Error);\n \n if (error instanceof AuthenticationError || error instanceof TokenResolutionError) {\n res.status(error.statusCode).json({\n error: error.message,\n code: error.code\n });\n } else {\n res.status(500).json({\n error: 'Internal server error',\n code: 'INTERNAL_ERROR'\n });\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 poolSize: this.serverPool.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"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prmichaelsen/mcp-auth",
3
- "version": "1.0.0",
3
+ "version": "3.0.0",
4
4
  "description": "Authentication and multi-tenancy framework for MCP servers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",