@prmichaelsen/mcp-auth 7.0.4 → 7.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +167 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -1
- package/dist/index.js.map +2 -2
- package/dist/types.d.ts +73 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wrapper/config.d.ts +20 -2
- package/dist/wrapper/config.d.ts.map +1 -1
- package/dist/wrapper/index.d.ts +10 -30
- package/dist/wrapper/index.d.ts.map +1 -1
- package/dist/wrapper/index.js +6 -5
- package/dist/wrapper/index.js.map +3 -3
- package/dist/wrapper/instance-pool-manager.d.ts +119 -0
- package/dist/wrapper/instance-pool-manager.d.ts.map +1 -0
- package/dist/wrapper/instance-pool-manager.js +225 -0
- package/dist/wrapper/instance-pool-manager.js.map +7 -0
- package/dist/wrapper/progress-manager.d.ts +101 -0
- package/dist/wrapper/progress-manager.d.ts.map +1 -0
- package/dist/wrapper/progress-manager.js +241 -0
- package/dist/wrapper/progress-manager.js.map +7 -0
- package/dist/wrapper/server-wrapper.d.ts +36 -0
- package/dist/wrapper/server-wrapper.d.ts.map +1 -1
- package/dist/wrapper/server-wrapper.js +196 -5
- package/dist/wrapper/server-wrapper.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -326,6 +326,155 @@ transport: {
|
|
|
326
326
|
}
|
|
327
327
|
```
|
|
328
328
|
|
|
329
|
+
## Progress Streaming
|
|
330
|
+
|
|
331
|
+
mcp-auth supports MCP progress notifications, allowing wrapped servers to stream progress updates to clients during long-running operations.
|
|
332
|
+
|
|
333
|
+
### How It Works
|
|
334
|
+
|
|
335
|
+
When a client provides a `progressToken` in the request, mcp-auth automatically:
|
|
336
|
+
1. Extracts the progress token from the request
|
|
337
|
+
2. Passes it through to the wrapped MCP server
|
|
338
|
+
3. The wrapped server can send progress notifications back to the client
|
|
339
|
+
4. Progress is isolated per user (multi-tenant safe)
|
|
340
|
+
|
|
341
|
+
### Client-Side Usage
|
|
342
|
+
|
|
343
|
+
```typescript
|
|
344
|
+
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
345
|
+
|
|
346
|
+
const client = new Client({
|
|
347
|
+
name: 'my-client',
|
|
348
|
+
version: '1.0.0'
|
|
349
|
+
});
|
|
350
|
+
|
|
351
|
+
// Call tool with progress support
|
|
352
|
+
const result = await client.request({
|
|
353
|
+
method: 'tools/call',
|
|
354
|
+
params: {
|
|
355
|
+
name: 'long_running_operation',
|
|
356
|
+
arguments: { /* ... */ }
|
|
357
|
+
}
|
|
358
|
+
}, {
|
|
359
|
+
progressToken: 'operation-123',
|
|
360
|
+
onprogress: (progress) => {
|
|
361
|
+
console.log(`Progress: ${progress.progress}/${progress.total}`);
|
|
362
|
+
console.log(`Message: ${progress.message}`);
|
|
363
|
+
}
|
|
364
|
+
});
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
### Server-Side Implementation
|
|
368
|
+
|
|
369
|
+
Wrapped MCP servers can send progress notifications:
|
|
370
|
+
|
|
371
|
+
```typescript
|
|
372
|
+
// In your MCP server tool handler
|
|
373
|
+
export async function handleLongOperation(
|
|
374
|
+
args: any,
|
|
375
|
+
extra?: { progressToken?: string | number }
|
|
376
|
+
): Promise<any> {
|
|
377
|
+
const progressToken = extra?.progressToken;
|
|
378
|
+
|
|
379
|
+
if (progressToken) {
|
|
380
|
+
// Send progress notifications
|
|
381
|
+
server.notification({
|
|
382
|
+
method: 'notifications/progress',
|
|
383
|
+
params: {
|
|
384
|
+
progressToken,
|
|
385
|
+
progress: 50,
|
|
386
|
+
total: 100,
|
|
387
|
+
message: 'Processing...'
|
|
388
|
+
}
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
// ... perform operation
|
|
393
|
+
}
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
### Features
|
|
397
|
+
|
|
398
|
+
- ✅ **Automatic Pass-Through**: Progress tokens automatically forwarded to wrapped servers
|
|
399
|
+
- ✅ **Multi-Tenant Safe**: Progress notifications isolated per user
|
|
400
|
+
- ✅ **Backward Compatible**: Works with or without progress token (graceful degradation)
|
|
401
|
+
- ✅ **Zero Configuration**: No additional setup required
|
|
402
|
+
|
|
403
|
+
### Monitoring
|
|
404
|
+
|
|
405
|
+
Monitor active progress streams via authenticated endpoints:
|
|
406
|
+
|
|
407
|
+
**User Stats** (shows your own progress streams):
|
|
408
|
+
```bash
|
|
409
|
+
GET /mcp/progress/stats
|
|
410
|
+
Authorization: Bearer <jwt>
|
|
411
|
+
```
|
|
412
|
+
|
|
413
|
+
**Response**:
|
|
414
|
+
```json
|
|
415
|
+
{
|
|
416
|
+
"user": {
|
|
417
|
+
"userId": "user123",
|
|
418
|
+
"activeStreams": 2,
|
|
419
|
+
"totalMessages": 1543,
|
|
420
|
+
"totalBytes": 45231,
|
|
421
|
+
"oldestStreamAge": 120000
|
|
422
|
+
},
|
|
423
|
+
"global": {
|
|
424
|
+
"activeStreams": 15,
|
|
425
|
+
"totalMessages": 8234,
|
|
426
|
+
"userCount": 8
|
|
427
|
+
},
|
|
428
|
+
"timestamp": "2026-02-23T21:00:00.000Z"
|
|
429
|
+
}
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
**All Metrics** (detailed stream information):
|
|
433
|
+
```bash
|
|
434
|
+
GET /mcp/progress/metrics
|
|
435
|
+
Authorization: Bearer <jwt>
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
**Response**:
|
|
439
|
+
```json
|
|
440
|
+
{
|
|
441
|
+
"metrics": [
|
|
442
|
+
{
|
|
443
|
+
"userId": "user123",
|
|
444
|
+
"progressToken": "op-456",
|
|
445
|
+
"startTime": 1708725600000,
|
|
446
|
+
"lastUpdate": 1708725650000,
|
|
447
|
+
"duration": 50000,
|
|
448
|
+
"messageCount": 125,
|
|
449
|
+
"bytesTransferred": 45231,
|
|
450
|
+
"averageMessageSize": 361.8,
|
|
451
|
+
"messagesPerSecond": 2.5
|
|
452
|
+
}
|
|
453
|
+
],
|
|
454
|
+
"health": {
|
|
455
|
+
"healthy": true,
|
|
456
|
+
"issues": [],
|
|
457
|
+
"warnings": []
|
|
458
|
+
},
|
|
459
|
+
"timestamp": "2026-02-23T21:00:00.000Z"
|
|
460
|
+
}
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
### Performance
|
|
464
|
+
|
|
465
|
+
- **Memory**: ~1KB per active stream
|
|
466
|
+
- **Network**: ~100-500 bytes per progress notification
|
|
467
|
+
- **CPU**: <1% overhead for typical workloads
|
|
468
|
+
- **Cleanup**: Stale streams (>5 minutes idle) automatically removed every minute
|
|
469
|
+
|
|
470
|
+
### Notes
|
|
471
|
+
|
|
472
|
+
- Progress streaming requires SSE or HTTP transport (not available with stdio)
|
|
473
|
+
- Progress tokens are automatically cleaned up after request completion
|
|
474
|
+
- Wrapped servers must implement progress notification support to send updates
|
|
475
|
+
- Health checks detect stale streams and high message rates
|
|
476
|
+
- Monitoring endpoints require authentication
|
|
477
|
+
|
|
329
478
|
## MCP Server Contract
|
|
330
479
|
|
|
331
480
|
To make your MCP server compatible with `wrapServer()`, export a factory function:
|
|
@@ -417,6 +566,24 @@ Working examples coming soon in [`examples/`](./examples/):
|
|
|
417
566
|
- `withTimeout()` - Request timeout
|
|
418
567
|
- `withRetry()` - Automatic retry on failure
|
|
419
568
|
|
|
569
|
+
## Example Projects
|
|
570
|
+
|
|
571
|
+
Real-world projects using `@prmichaelsen/mcp-auth`:
|
|
572
|
+
|
|
573
|
+
### [@prmichaelsen/agentbase-mcp-server](https://github.com/prmichaelsen/agentbase-mcp-server)
|
|
574
|
+
Multi-tenant Instagram MCP server with JWT authentication
|
|
575
|
+
- **Pattern**: Server Wrapping (Dynamic Mode)
|
|
576
|
+
- **Auth**: JWT + API-based token resolution
|
|
577
|
+
- **Use Case**: External API credentials (Instagram)
|
|
578
|
+
- **Transport**: SSE over HTTP
|
|
579
|
+
|
|
580
|
+
### [@prmichaelsen/remember-mcp-server](https://github.com/prmichaelsen/remember-mcp-server)
|
|
581
|
+
Multi-tenant MCP server for remember-mcp with Platform JWT authentication
|
|
582
|
+
- **Pattern**: Server Wrapping (Static Mode)
|
|
583
|
+
- **Auth**: JWT only (no tokenResolver)
|
|
584
|
+
- **Use Case**: User-scoped data in own database
|
|
585
|
+
- **Transport**: SSE over HTTP
|
|
586
|
+
|
|
420
587
|
## License
|
|
421
588
|
|
|
422
589
|
MIT
|
package/dist/index.d.ts
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
*
|
|
10
10
|
* @packageDocumentation
|
|
11
11
|
*/
|
|
12
|
-
export { wrapServer, AuthenticatedServerWrapper, type ServerWrapperConfig, type MCPServerFactory, type NormalizedServerWrapperConfig } from './wrapper/index.js';
|
|
12
|
+
export { wrapServer, AuthenticatedServerWrapper, type ServerWrapperConfig, type MCPServerFactory, type NormalizedServerWrapperConfig, InstancePoolManager, ProgressManager, type ProgressCallback, type ProgressStreamMetrics } from './wrapper/index.js';
|
|
13
13
|
export { AuthenticatedMCPServer, type ServerConfig, type NormalizedServerConfig, withAuth, compose, withLogging, withRateLimit, withTimeout, withRetry, type Tool, AuthenticatedTool, createAuthenticatedTool, type AuthenticatedToolHandler } from './server/index.js';
|
|
14
|
-
export type { TransportType, RequestContext, AuthResult, TransportConfig, RateLimitConfig, LoggingConfig, MiddlewareConfig, PoolingConfig, Result, AsyncFunction, ToolHandler, Middleware } from './types.js';
|
|
14
|
+
export type { TransportType, RequestContext, AuthResult, TransportConfig, RateLimitConfig, LoggingConfig, MiddlewareConfig, InstancePoolConfig, PoolingConfig, Result, AsyncFunction, ToolHandler, Middleware, ProgressNotification, RequestExtra } from './types.js';
|
|
15
15
|
export type { AuthProvider, ResourceTokenResolver, AuthenticatedContext, AuthProviderConfig, TokenResolverConfig } from './auth/types.js';
|
|
16
16
|
export { BaseAuthProvider } from './auth/base-provider.js';
|
|
17
17
|
export { EnvAuthProvider, type EnvAuthProviderConfig, SimpleTokenResolver, type SimpleTokenResolverConfig, JWTAuthProvider, type JWTAuthProviderConfig, type JWTPayload, JWTTokenResolver, type JWTTokenResolverConfig, APITokenResolver, type APITokenResolverConfig } from './auth/providers/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,EACL,UAAU,EACV,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,6BAA6B,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,OAAO,EACL,UAAU,EACV,0BAA0B,EAC1B,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,6BAA6B,EAClC,mBAAmB,EACnB,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC3B,MAAM,oBAAoB,CAAC;AAQ5B,OAAO,EACL,sBAAsB,EACtB,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC3B,QAAQ,EACR,OAAO,EACP,WAAW,EACX,aAAa,EACb,WAAW,EACX,SAAS,EACT,KAAK,IAAI,EACT,iBAAiB,EACjB,uBAAuB,EACvB,KAAK,wBAAwB,EAC9B,MAAM,mBAAmB,CAAC;AAM3B,YAAY,EACV,aAAa,EACb,cAAc,EACd,UAAU,EACV,eAAe,EACf,eAAe,EACf,aAAa,EACb,gBAAgB,EAChB,kBAAkB,EAClB,aAAa,EACb,MAAM,EACN,aAAa,EACb,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,YAAY,EACb,MAAM,YAAY,CAAC;AAMpB,YAAY,EACV,YAAY,EACZ,qBAAqB,EACrB,oBAAoB,EACpB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EACL,eAAe,EACf,KAAK,qBAAqB,EAC1B,mBAAmB,EACnB,KAAK,yBAAyB,EAC9B,eAAe,EACf,KAAK,qBAAqB,EAC1B,KAAK,UAAU,EACf,gBAAgB,EAChB,KAAK,sBAAsB,EAC3B,gBAAgB,EAChB,KAAK,sBAAsB,EAC5B,MAAM,2BAA2B,CAAC;AAQnC,OAAO,EACL,KAAK,sBAAsB,EAC3B,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EACrB,mBAAmB,EACnB,kBAAkB,EAClB,oBAAoB,EACpB,eAAe,EAChB,MAAM,mBAAmB,CAAC;AAM3B,OAAO,EAEL,YAAY,EACZ,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,uBAAuB,EACvB,kBAAkB,EAClB,cAAc,EACd,eAAe,EACf,cAAc,EACd,eAAe,EACf,cAAc,EACd,qBAAqB,EACrB,sBAAsB,EACtB,gBAAgB,EAChB,oBAAoB,EAGpB,MAAM,EACN,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,kBAAkB,EAGlB,sBAAsB,EACtB,WAAW,EACX,sBAAsB,EACtB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,sBAAsB,EACtB,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,kBAAkB,CAAC;AAG1B,YAAY,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAMlD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
wrapServer,
|
|
3
|
-
AuthenticatedServerWrapper
|
|
3
|
+
AuthenticatedServerWrapper,
|
|
4
|
+
InstancePoolManager,
|
|
5
|
+
ProgressManager
|
|
4
6
|
} from "./wrapper/index.js";
|
|
5
7
|
import {
|
|
6
8
|
AuthenticatedMCPServer,
|
|
@@ -74,6 +76,7 @@ export {
|
|
|
74
76
|
BaseAuthProvider,
|
|
75
77
|
ConfigurationError,
|
|
76
78
|
EnvAuthProvider,
|
|
79
|
+
InstancePoolManager,
|
|
77
80
|
InvalidTokenError,
|
|
78
81
|
JWTAuthProvider,
|
|
79
82
|
JWTTokenResolver,
|
|
@@ -81,6 +84,7 @@ export {
|
|
|
81
84
|
Logger,
|
|
82
85
|
MCPAuthError,
|
|
83
86
|
MissingCredentialsError,
|
|
87
|
+
ProgressManager,
|
|
84
88
|
RateLimitError,
|
|
85
89
|
ServerPoolError,
|
|
86
90
|
SimpleTokenResolver,
|
package/dist/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * @prmichaelsen/mcp-auth\n *\n * Authentication and multi-tenancy framework for MCP (Model Context Protocol) servers.\n *\n * Supports two complementary patterns:\n * 1. **Server Wrapping** - Wrap existing MCP servers without modification (MCP-level auth)\n * 2. **Tool-Level Auth** - Build new MCP servers with integrated auth\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// PATTERN 1: SERVER WRAPPING (MCP-Level Auth)\n// ============================================================================\n// Use this to wrap existing MCP servers without modifying them\n// Ideal for multi-tenant services that host multiple MCP servers\n\nexport {\n wrapServer,\n AuthenticatedServerWrapper,\n type ServerWrapperConfig,\n type MCPServerFactory,\n type NormalizedServerWrapperConfig\n} from './wrapper/index.js';\n\n// ============================================================================\n// PATTERN 2: TOOL-LEVEL AUTH\n// ============================================================================\n// Use this to build new MCP servers with integrated authentication\n// Provides fine-grained control over auth per tool\n\nexport {\n AuthenticatedMCPServer,\n type ServerConfig,\n type NormalizedServerConfig,\n withAuth,\n compose,\n withLogging,\n withRateLimit,\n withTimeout,\n withRetry,\n type Tool,\n AuthenticatedTool,\n createAuthenticatedTool,\n type AuthenticatedToolHandler\n} from './server/index.js';\n\n// ============================================================================\n// SHARED: CORE TYPES\n// ============================================================================\n\nexport type {\n TransportType,\n RequestContext,\n AuthResult,\n TransportConfig,\n RateLimitConfig,\n LoggingConfig,\n MiddlewareConfig,\n PoolingConfig,\n Result,\n AsyncFunction,\n ToolHandler,\n Middleware\n} from './types.js';\n\n// ============================================================================\n// SHARED: AUTHENTICATION\n// ============================================================================\n\nexport type {\n AuthProvider,\n ResourceTokenResolver,\n AuthenticatedContext,\n AuthProviderConfig,\n TokenResolverConfig\n} from './auth/types.js';\n\nexport { BaseAuthProvider } from './auth/base-provider.js';\n\n// Providers\nexport {\n EnvAuthProvider,\n type EnvAuthProviderConfig,\n SimpleTokenResolver,\n type SimpleTokenResolverConfig,\n JWTAuthProvider,\n type JWTAuthProviderConfig,\n type JWTPayload,\n JWTTokenResolver,\n type JWTTokenResolverConfig,\n APITokenResolver,\n type APITokenResolverConfig\n} from './auth/providers/index.js';\n\n// ============================================================================\n// TENANT MANAGER INTEGRATION\n// ============================================================================\n// Standard interfaces for tenant manager APIs\n// Helps tenant platforms provide consistent APIs for MCP servers\n\nexport {\n type TenantAPIErrorResponse,\n type CredentialsAPIResponse,\n type CredentialsAPIHeaders,\n type TenantManagerAPI,\n TenantAPIStatusCode,\n TenantAPIErrorCode,\n createTenantAPIError,\n TenantAPIErrors\n} from './tenant/index.js';\n\n// ============================================================================\n// SHARED: UTILITIES\n// ============================================================================\n\nexport {\n // Errors\n MCPAuthError,\n AuthenticationError,\n TokenResolutionError,\n InvalidTokenError,\n MissingCredentialsError,\n ConfigurationError,\n RateLimitError,\n ServerPoolError,\n TransportError,\n ValidationError,\n isMCPAuthError,\n isAuthenticationError,\n isTokenResolutionError,\n isRateLimitError,\n formatErrorForClient,\n \n // Logger\n Logger,\n LogLevel,\n defaultLogger,\n createLogger,\n sanitizeForLogging,\n \n // Validation\n validateNonEmptyString,\n validateUrl,\n validatePositiveNumber,\n validatePort,\n validateEnum,\n validateObject,\n validateFunction,\n validateRequiredFields,\n validateTransportConfig,\n validateRateLimitConfig,\n validateLoggingConfig,\n validatePoolingConfig,\n sanitizeString,\n validateUserId,\n validateResourceType,\n validateAccessToken\n} from './utils/index.js';\n\n// Re-export types for convenience\nexport type { LogEntry } from './utils/logger.js';\n\n// ============================================================================\n// USAGE EXAMPLES\n// ============================================================================\n\n/**\n * @example Server Wrapping Pattern (MCP-Level Auth)\n * ```typescript\n * import { wrapServer, JWTAuthProvider, DatabaseTokenResolver } from '@prmichaelsen/mcp-auth';\n * import { createServer as createInstagramServer } from '@prmichaelsen/instagram-mcp';\n *\n * const wrapped = wrapServer({\n * serverFactory: (accessToken, userId) => createInstagramServer(accessToken, userId),\n * authProvider: new JWTAuthProvider({ jwtSecret: process.env.JWT_SECRET }),\n * tokenResolver: new DatabaseTokenResolver({ database: {...} }),\n * resourceType: 'instagram',\n * transport: { type: 'sse', port: 3000 }\n * });\n *\n * await wrapped.start();\n * ```\n *\n * @example Tool-Level Auth Pattern\n * ```typescript\n * import { AuthenticatedMCPServer, withAuth, EnvAuthProvider } from '@prmichaelsen/mcp-auth';\n *\n * const server = new AuthenticatedMCPServer({\n * name: 'my-server',\n * authProvider: new EnvAuthProvider(),\n * tokenResolver: new SimpleTokenResolver({ tokenEnvVar: 'API_TOKEN' }),\n * resourceType: 'myapi',\n * transport: { type: 'stdio' }\n * });\n *\n * server.registerTool('get_data', withAuth(async (args, accessToken, userId) => {\n * const client = new MyAPIClient(accessToken);\n * return client.getData(args);\n * }));\n *\n * await server.start();\n * ```\n */\n"],
|
|
5
|
-
"mappings": "AAkBA;AAAA,EACE;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["/**\n * @prmichaelsen/mcp-auth\n *\n * Authentication and multi-tenancy framework for MCP (Model Context Protocol) servers.\n *\n * Supports two complementary patterns:\n * 1. **Server Wrapping** - Wrap existing MCP servers without modification (MCP-level auth)\n * 2. **Tool-Level Auth** - Build new MCP servers with integrated auth\n *\n * @packageDocumentation\n */\n\n// ============================================================================\n// PATTERN 1: SERVER WRAPPING (MCP-Level Auth)\n// ============================================================================\n// Use this to wrap existing MCP servers without modifying them\n// Ideal for multi-tenant services that host multiple MCP servers\n\nexport {\n wrapServer,\n AuthenticatedServerWrapper,\n type ServerWrapperConfig,\n type MCPServerFactory,\n type NormalizedServerWrapperConfig,\n InstancePoolManager,\n ProgressManager,\n type ProgressCallback,\n type ProgressStreamMetrics\n} from './wrapper/index.js';\n\n// ============================================================================\n// PATTERN 2: TOOL-LEVEL AUTH\n// ============================================================================\n// Use this to build new MCP servers with integrated authentication\n// Provides fine-grained control over auth per tool\n\nexport {\n AuthenticatedMCPServer,\n type ServerConfig,\n type NormalizedServerConfig,\n withAuth,\n compose,\n withLogging,\n withRateLimit,\n withTimeout,\n withRetry,\n type Tool,\n AuthenticatedTool,\n createAuthenticatedTool,\n type AuthenticatedToolHandler\n} from './server/index.js';\n\n// ============================================================================\n// SHARED: CORE TYPES\n// ============================================================================\n\nexport type {\n TransportType,\n RequestContext,\n AuthResult,\n TransportConfig,\n RateLimitConfig,\n LoggingConfig,\n MiddlewareConfig,\n InstancePoolConfig,\n PoolingConfig,\n Result,\n AsyncFunction,\n ToolHandler,\n Middleware,\n ProgressNotification,\n RequestExtra\n} from './types.js';\n\n// ============================================================================\n// SHARED: AUTHENTICATION\n// ============================================================================\n\nexport type {\n AuthProvider,\n ResourceTokenResolver,\n AuthenticatedContext,\n AuthProviderConfig,\n TokenResolverConfig\n} from './auth/types.js';\n\nexport { BaseAuthProvider } from './auth/base-provider.js';\n\n// Providers\nexport {\n EnvAuthProvider,\n type EnvAuthProviderConfig,\n SimpleTokenResolver,\n type SimpleTokenResolverConfig,\n JWTAuthProvider,\n type JWTAuthProviderConfig,\n type JWTPayload,\n JWTTokenResolver,\n type JWTTokenResolverConfig,\n APITokenResolver,\n type APITokenResolverConfig\n} from './auth/providers/index.js';\n\n// ============================================================================\n// TENANT MANAGER INTEGRATION\n// ============================================================================\n// Standard interfaces for tenant manager APIs\n// Helps tenant platforms provide consistent APIs for MCP servers\n\nexport {\n type TenantAPIErrorResponse,\n type CredentialsAPIResponse,\n type CredentialsAPIHeaders,\n type TenantManagerAPI,\n TenantAPIStatusCode,\n TenantAPIErrorCode,\n createTenantAPIError,\n TenantAPIErrors\n} from './tenant/index.js';\n\n// ============================================================================\n// SHARED: UTILITIES\n// ============================================================================\n\nexport {\n // Errors\n MCPAuthError,\n AuthenticationError,\n TokenResolutionError,\n InvalidTokenError,\n MissingCredentialsError,\n ConfigurationError,\n RateLimitError,\n ServerPoolError,\n TransportError,\n ValidationError,\n isMCPAuthError,\n isAuthenticationError,\n isTokenResolutionError,\n isRateLimitError,\n formatErrorForClient,\n \n // Logger\n Logger,\n LogLevel,\n defaultLogger,\n createLogger,\n sanitizeForLogging,\n \n // Validation\n validateNonEmptyString,\n validateUrl,\n validatePositiveNumber,\n validatePort,\n validateEnum,\n validateObject,\n validateFunction,\n validateRequiredFields,\n validateTransportConfig,\n validateRateLimitConfig,\n validateLoggingConfig,\n validatePoolingConfig,\n sanitizeString,\n validateUserId,\n validateResourceType,\n validateAccessToken\n} from './utils/index.js';\n\n// Re-export types for convenience\nexport type { LogEntry } from './utils/logger.js';\n\n// ============================================================================\n// USAGE EXAMPLES\n// ============================================================================\n\n/**\n * @example Server Wrapping Pattern (MCP-Level Auth)\n * ```typescript\n * import { wrapServer, JWTAuthProvider, DatabaseTokenResolver } from '@prmichaelsen/mcp-auth';\n * import { createServer as createInstagramServer } from '@prmichaelsen/instagram-mcp';\n *\n * const wrapped = wrapServer({\n * serverFactory: (accessToken, userId) => createInstagramServer(accessToken, userId),\n * authProvider: new JWTAuthProvider({ jwtSecret: process.env.JWT_SECRET }),\n * tokenResolver: new DatabaseTokenResolver({ database: {...} }),\n * resourceType: 'instagram',\n * transport: { type: 'sse', port: 3000 }\n * });\n *\n * await wrapped.start();\n * ```\n *\n * @example Tool-Level Auth Pattern\n * ```typescript\n * import { AuthenticatedMCPServer, withAuth, EnvAuthProvider } from '@prmichaelsen/mcp-auth';\n *\n * const server = new AuthenticatedMCPServer({\n * name: 'my-server',\n * authProvider: new EnvAuthProvider(),\n * tokenResolver: new SimpleTokenResolver({ tokenEnvVar: 'API_TOKEN' }),\n * resourceType: 'myapi',\n * transport: { type: 'stdio' }\n * });\n *\n * server.registerTool('get_data', withAuth(async (args, accessToken, userId) => {\n * const client = new MyAPIClient(accessToken);\n * return client.getData(args);\n * }));\n *\n * await server.start();\n * ```\n */\n"],
|
|
5
|
+
"mappings": "AAkBA;AAAA,EACE;AAAA,EACA;AAAA,EAIA;AAAA,EACA;AAAA,OAGK;AAQP;AAAA,EACE;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,OAEK;AAoCP,SAAS,wBAAwB;AAGjC;AAAA,EACE;AAAA,EAEA;AAAA,EAEA;AAAA,EAGA;AAAA,EAEA;AAAA,OAEK;AAQP;AAAA,EAKE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMP;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAGA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -8,6 +8,42 @@
|
|
|
8
8
|
* Transport types supported by the framework
|
|
9
9
|
*/
|
|
10
10
|
export type TransportType = 'stdio' | 'sse' | 'http';
|
|
11
|
+
/**
|
|
12
|
+
* Progress notification parameters
|
|
13
|
+
* Used for streaming progress updates during long-running operations
|
|
14
|
+
*/
|
|
15
|
+
export interface ProgressNotification {
|
|
16
|
+
/**
|
|
17
|
+
* Unique token identifying this progress stream
|
|
18
|
+
*/
|
|
19
|
+
progressToken: string | number;
|
|
20
|
+
/**
|
|
21
|
+
* Current progress value (optional)
|
|
22
|
+
*/
|
|
23
|
+
progress?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Total expected value (optional)
|
|
26
|
+
*/
|
|
27
|
+
total?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Progress message/description (optional)
|
|
30
|
+
*/
|
|
31
|
+
message?: string;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Request extra parameters (from MCP SDK)
|
|
35
|
+
* Contains optional metadata passed with requests
|
|
36
|
+
*/
|
|
37
|
+
export interface RequestExtra {
|
|
38
|
+
/**
|
|
39
|
+
* Progress token for streaming progress notifications
|
|
40
|
+
*/
|
|
41
|
+
progressToken?: string | number;
|
|
42
|
+
/**
|
|
43
|
+
* Additional custom parameters
|
|
44
|
+
*/
|
|
45
|
+
[key: string]: any;
|
|
46
|
+
}
|
|
11
47
|
/**
|
|
12
48
|
* Request context passed to authentication providers
|
|
13
49
|
* Contains information about the incoming request
|
|
@@ -178,8 +214,45 @@ export interface MiddlewareConfig {
|
|
|
178
214
|
*/
|
|
179
215
|
logging?: LoggingConfig;
|
|
180
216
|
}
|
|
217
|
+
/**
|
|
218
|
+
* Instance pool configuration for pooled mode
|
|
219
|
+
*
|
|
220
|
+
* Configures lifecycle management for pooled server instances.
|
|
221
|
+
* Used when instanceMode is 'pooled' to enable instance reuse.
|
|
222
|
+
*/
|
|
223
|
+
export interface InstancePoolConfig {
|
|
224
|
+
/**
|
|
225
|
+
* Maximum number of concurrent instances in the pool
|
|
226
|
+
*
|
|
227
|
+
* When this limit is reached, the least recently used instance
|
|
228
|
+
* will be evicted to make room for new instances.
|
|
229
|
+
*
|
|
230
|
+
* @minimum 1
|
|
231
|
+
*/
|
|
232
|
+
maxSize: number;
|
|
233
|
+
/**
|
|
234
|
+
* Milliseconds before closing an idle instance
|
|
235
|
+
*
|
|
236
|
+
* Instances that haven't been used for this duration will be
|
|
237
|
+
* automatically closed and removed from the pool.
|
|
238
|
+
*
|
|
239
|
+
* @minimum 1000 (1 second)
|
|
240
|
+
*/
|
|
241
|
+
idleTimeout: number;
|
|
242
|
+
/**
|
|
243
|
+
* Milliseconds before forcing an instance refresh
|
|
244
|
+
*
|
|
245
|
+
* Instances older than this duration will be closed and recreated,
|
|
246
|
+
* even if they're still being used. This prevents stale connections
|
|
247
|
+
* and ensures instances don't run indefinitely.
|
|
248
|
+
*
|
|
249
|
+
* @minimum idleTimeout
|
|
250
|
+
*/
|
|
251
|
+
maxLifetime: number;
|
|
252
|
+
}
|
|
181
253
|
/**
|
|
182
254
|
* Server pooling configuration
|
|
255
|
+
* @deprecated Use InstancePoolConfig instead
|
|
183
256
|
*/
|
|
184
257
|
export interface PoolingConfig {
|
|
185
258
|
/**
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAErD;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC;IAExD;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEnC;;OAEG;IACH,SAAS,EAAE,aAAa,CAAC;IAEzB;;OAEG;IACH,SAAS,EAAE,IAAI,CAAC;IAEhB;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB;;OAEG;IACH,aAAa,EAAE,OAAO,CAAC;IAEvB;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,IAAI,EAAE,aAAa,CAAC;IAEpB;;OAEG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAEnE;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;OAEG;IACH,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAE3C;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;;OAGG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,SAAS,CAAC,EAAE,eAAe,CAAC;IAE5B;;OAEG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AAED
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/wrapper/config.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
7
7
|
import type { AuthProvider, ResourceTokenResolver } from '../auth/types.js';
|
|
8
|
-
import type { TransportConfig, MiddlewareConfig } from '../types.js';
|
|
8
|
+
import type { TransportConfig, MiddlewareConfig, InstancePoolConfig } from '../types.js';
|
|
9
9
|
/**
|
|
10
10
|
* MCP Server Factory Function
|
|
11
11
|
*
|
|
@@ -124,6 +124,23 @@ export interface ServerWrapperConfig {
|
|
|
124
124
|
*/
|
|
125
125
|
instanceMode?: 'ephemeral' | 'pooled';
|
|
126
126
|
/**
|
|
127
|
+
* Instance pool configuration (required when instanceMode is 'pooled')
|
|
128
|
+
*
|
|
129
|
+
* Configures lifecycle management for pooled server instances.
|
|
130
|
+
* Enables efficient instance reuse for performance-critical applications.
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```typescript
|
|
134
|
+
* instancePool: {
|
|
135
|
+
* maxSize: 10, // Max 10 concurrent instances
|
|
136
|
+
* idleTimeout: 300000, // Close after 5 min idle
|
|
137
|
+
* maxLifetime: 3600000 // Force refresh after 1 hour
|
|
138
|
+
* }
|
|
139
|
+
* ```
|
|
140
|
+
*/
|
|
141
|
+
instancePool?: InstancePoolConfig;
|
|
142
|
+
/**
|
|
143
|
+
* @deprecated Use instancePool instead
|
|
127
144
|
* Optional: Pooling configuration (only used if instanceMode is 'pooled')
|
|
128
145
|
*
|
|
129
146
|
* Note: Pooling is optional and adds complexity. Ephemeral mode is recommended.
|
|
@@ -160,9 +177,10 @@ export interface ServerWrapperConfig {
|
|
|
160
177
|
* Validated and normalized server wrapper configuration
|
|
161
178
|
* Used internally after validation
|
|
162
179
|
*/
|
|
163
|
-
export interface NormalizedServerWrapperConfig extends Required<Omit<ServerWrapperConfig, 'middleware' | 'pooling' | 'tokenResolver'>> {
|
|
180
|
+
export interface NormalizedServerWrapperConfig extends Required<Omit<ServerWrapperConfig, 'middleware' | 'pooling' | 'tokenResolver' | 'instancePool'>> {
|
|
164
181
|
tokenResolver: ResourceTokenResolver | null;
|
|
165
182
|
middleware: MiddlewareConfig;
|
|
183
|
+
instancePool: InstancePoolConfig | null;
|
|
166
184
|
pooling: {
|
|
167
185
|
maxServersPerUser: number;
|
|
168
186
|
idleTimeoutMs: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/wrapper/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/wrapper/config.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC5E,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEzF;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,gBAAgB,GAAG,CAC7B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,KACX,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAE9B;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;OAUG;IACH,aAAa,EAAE,gBAAgB,CAAC;IAEhC;;;;;;;;;OASG;IACH,YAAY,EAAE,YAAY,CAAC;IAE3B;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,aAAa,CAAC,EAAE,qBAAqB,CAAC;IAEtC;;;;;;OAMG;IACH,YAAY,EAAE,MAAM,CAAC;IAErB;;;;OAIG;IACH,SAAS,EAAE,eAAe,CAAC;IAE3B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;;;;;;;;;OAUG;IACH,YAAY,CAAC,EAAE,WAAW,GAAG,QAAQ,CAAC;IAEtC;;;;;;;;;;;;;;OAcG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAElC;;;;;OAKG;IACH,OAAO,CAAC,EAAE;QACR;;;WAGG;QACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAE3B;;;WAGG;QACH,aAAa,CAAC,EAAE,MAAM,CAAC;QAEvB;;;WAGG;QACH,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IAEF;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;GAGG;AACH,MAAM,WAAW,6BAA8B,SAAQ,QAAQ,CAAC,IAAI,CAAC,mBAAmB,EAAE,YAAY,GAAG,SAAS,GAAG,eAAe,GAAG,cAAc,CAAC,CAAC;IACrJ,aAAa,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC5C,UAAU,EAAE,gBAAgB,CAAC;IAC7B,YAAY,EAAE,kBAAkB,GAAG,IAAI,CAAC;IACxC,OAAO,EAAE;QACP,iBAAiB,EAAE,MAAM,CAAC;QAC1B,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE,MAAM,CAAC;KACzB,CAAC;CACH"}
|
package/dist/wrapper/index.d.ts
CHANGED
|
@@ -1,36 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Server wrapper
|
|
3
|
-
*
|
|
4
|
-
* Provides the main wrapServer() function for wrapping MCP servers with authentication.
|
|
2
|
+
* Server wrapper exports
|
|
5
3
|
*/
|
|
6
|
-
|
|
7
|
-
import type { ServerWrapperConfig } from './config.js';
|
|
8
|
-
export type { ServerWrapperConfig, MCPServerFactory, NormalizedServerWrapperConfig } from './config.js';
|
|
4
|
+
export { wrapServer } from './server-wrapper.js';
|
|
9
5
|
export { AuthenticatedServerWrapper } from './server-wrapper.js';
|
|
6
|
+
export type { ServerWrapperConfig, NormalizedServerWrapperConfig, MCPServerFactory } from './config.js';
|
|
10
7
|
/**
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* This is the main entry point for the server wrapping pattern.
|
|
14
|
-
* It creates an authenticated wrapper around your MCP server factory function.
|
|
15
|
-
*
|
|
16
|
-
* @param config - Server wrapper configuration
|
|
17
|
-
* @returns Authenticated server wrapper instance
|
|
18
|
-
*
|
|
19
|
-
* @example
|
|
20
|
-
* ```typescript
|
|
21
|
-
* import { wrapServer } from '@prmichaelsen/mcp-auth';
|
|
22
|
-
* import { createServer } from '@myorg/my-mcp-server';
|
|
23
|
-
*
|
|
24
|
-
* const wrapped = wrapServer({
|
|
25
|
-
* serverFactory: (accessToken, userId) => createServer(accessToken, userId),
|
|
26
|
-
* authProvider: new JWTAuthProvider({ ... }),
|
|
27
|
-
* tokenResolver: new DatabaseTokenResolver({ ... }),
|
|
28
|
-
* resourceType: 'myapi',
|
|
29
|
-
* transport: { type: 'sse', port: 3000 }
|
|
30
|
-
* });
|
|
31
|
-
*
|
|
32
|
-
* await wrapped.start();
|
|
33
|
-
* ```
|
|
8
|
+
* Instance pool manager exports
|
|
34
9
|
*/
|
|
35
|
-
export
|
|
10
|
+
export { InstancePoolManager } from './instance-pool-manager.js';
|
|
11
|
+
/**
|
|
12
|
+
* Progress manager exports
|
|
13
|
+
*/
|
|
14
|
+
export { ProgressManager, type ProgressStreamMetrics } from './progress-manager.js';
|
|
15
|
+
export type { ProgressCallback } from './progress-manager.js';
|
|
36
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/wrapper/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/wrapper/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AACjE,YAAY,EAAE,mBAAmB,EAAE,6BAA6B,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAExG;;GAEG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAEjE;;GAEG;AACH,OAAO,EAAE,eAAe,EAAE,KAAK,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AACpF,YAAY,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/wrapper/index.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
|
+
import { wrapServer } from "./server-wrapper.js";
|
|
1
2
|
import { AuthenticatedServerWrapper } from "./server-wrapper.js";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
return new AuthenticatedServerWrapper(config);
|
|
5
|
-
}
|
|
3
|
+
import { InstancePoolManager } from "./instance-pool-manager.js";
|
|
4
|
+
import { ProgressManager } from "./progress-manager.js";
|
|
6
5
|
export {
|
|
7
|
-
|
|
6
|
+
AuthenticatedServerWrapper,
|
|
7
|
+
InstancePoolManager,
|
|
8
|
+
ProgressManager,
|
|
8
9
|
wrapServer
|
|
9
10
|
};
|
|
10
11
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/wrapper/index.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Server wrapper
|
|
5
|
-
"mappings": "
|
|
6
|
-
"names": [
|
|
4
|
+
"sourcesContent": ["/**\n * Server wrapper exports\n */\n\nexport { wrapServer } from './server-wrapper.js';\nexport { AuthenticatedServerWrapper } from './server-wrapper.js';\nexport type { ServerWrapperConfig, NormalizedServerWrapperConfig, MCPServerFactory } from './config.js';\n\n/**\n * Instance pool manager exports\n */\nexport { InstancePoolManager } from './instance-pool-manager.js';\n\n/**\n * Progress manager exports\n */\nexport { ProgressManager, type ProgressStreamMetrics } from './progress-manager.js';\nexport type { ProgressCallback } from './progress-manager.js';\n"],
|
|
5
|
+
"mappings": "AAIA,SAAS,kBAAkB;AAC3B,SAAS,kCAAkC;AAM3C,SAAS,2BAA2B;AAKpC,SAAS,uBAAmD;",
|
|
6
|
+
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Instance Pool Manager
|
|
3
|
+
*
|
|
4
|
+
* Manages lifecycle of pooled server instances with configurable
|
|
5
|
+
* size limits, idle timeouts, and maximum lifetimes.
|
|
6
|
+
*/
|
|
7
|
+
import type { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
8
|
+
import type { InstancePoolConfig } from '../types.js';
|
|
9
|
+
import type { Logger } from '../utils/logger.js';
|
|
10
|
+
/**
|
|
11
|
+
* Instance Pool Manager
|
|
12
|
+
*
|
|
13
|
+
* Manages a pool of server instances with automatic lifecycle management:
|
|
14
|
+
* - Reuses instances for the same user
|
|
15
|
+
* - Enforces maximum pool size with LRU eviction
|
|
16
|
+
* - Automatically closes idle instances
|
|
17
|
+
* - Forces refresh of old instances
|
|
18
|
+
* - Periodic cleanup of expired instances
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```typescript
|
|
22
|
+
* const poolManager = new InstancePoolManager({
|
|
23
|
+
* maxSize: 10,
|
|
24
|
+
* idleTimeout: 300000,
|
|
25
|
+
* maxLifetime: 3600000
|
|
26
|
+
* }, logger);
|
|
27
|
+
*
|
|
28
|
+
* const server = await poolManager.getInstance(
|
|
29
|
+
* 'user123',
|
|
30
|
+
* 'token456',
|
|
31
|
+
* (token, userId) => createMyServer(token, userId)
|
|
32
|
+
* );
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export declare class InstancePoolManager {
|
|
36
|
+
private instances;
|
|
37
|
+
private config;
|
|
38
|
+
private logger;
|
|
39
|
+
private cleanupTimer?;
|
|
40
|
+
constructor(config: InstancePoolConfig, logger: Logger);
|
|
41
|
+
/**
|
|
42
|
+
* Get or create a server instance for a user
|
|
43
|
+
*
|
|
44
|
+
* If a valid instance exists for the user, it will be reused.
|
|
45
|
+
* Otherwise, a new instance will be created using the factory function.
|
|
46
|
+
*
|
|
47
|
+
* @param userId - User identifier
|
|
48
|
+
* @param accessToken - Access token for the user
|
|
49
|
+
* @param factory - Factory function to create new server instances
|
|
50
|
+
* @returns Server instance (existing or newly created)
|
|
51
|
+
*/
|
|
52
|
+
getInstance(userId: string, accessToken: string, factory: (accessToken: string, userId: string) => Server | Promise<Server>): Promise<Server>;
|
|
53
|
+
/**
|
|
54
|
+
* Check if an instance is still valid
|
|
55
|
+
*
|
|
56
|
+
* An instance is valid if:
|
|
57
|
+
* - It hasn't exceeded its maximum lifetime
|
|
58
|
+
* - It hasn't been idle for too long
|
|
59
|
+
*
|
|
60
|
+
* @param instance - Instance metadata to check
|
|
61
|
+
* @returns true if instance is valid, false otherwise
|
|
62
|
+
*/
|
|
63
|
+
private isValid;
|
|
64
|
+
/**
|
|
65
|
+
* Evict the least recently used instance
|
|
66
|
+
*
|
|
67
|
+
* Finds the instance with the oldest lastUsed timestamp
|
|
68
|
+
* and removes it from the pool.
|
|
69
|
+
*/
|
|
70
|
+
private evictLeastRecentlyUsed;
|
|
71
|
+
/**
|
|
72
|
+
* Remove an instance from the pool
|
|
73
|
+
*
|
|
74
|
+
* Closes the server instance (if it has a close method)
|
|
75
|
+
* and removes it from the pool.
|
|
76
|
+
*
|
|
77
|
+
* @param userId - User ID of the instance to remove
|
|
78
|
+
*/
|
|
79
|
+
private removeInstance;
|
|
80
|
+
/**
|
|
81
|
+
* Start periodic cleanup timer
|
|
82
|
+
*
|
|
83
|
+
* Runs cleanup every minute to remove expired instances.
|
|
84
|
+
*/
|
|
85
|
+
private startCleanupTimer;
|
|
86
|
+
/**
|
|
87
|
+
* Clean up expired instances
|
|
88
|
+
*
|
|
89
|
+
* Removes all instances that are no longer valid
|
|
90
|
+
* (exceeded max lifetime or idle timeout).
|
|
91
|
+
*/
|
|
92
|
+
private cleanupExpiredInstances;
|
|
93
|
+
/**
|
|
94
|
+
* Close all pooled instances
|
|
95
|
+
*
|
|
96
|
+
* Closes all server instances and clears the pool.
|
|
97
|
+
* Should be called when shutting down the server.
|
|
98
|
+
*/
|
|
99
|
+
closeAll(): Promise<void>;
|
|
100
|
+
/**
|
|
101
|
+
* Get pool statistics
|
|
102
|
+
*
|
|
103
|
+
* Returns current state of the pool for monitoring and debugging.
|
|
104
|
+
*
|
|
105
|
+
* @returns Pool statistics including size and instance details
|
|
106
|
+
*/
|
|
107
|
+
getStats(): {
|
|
108
|
+
size: number;
|
|
109
|
+
maxSize: number;
|
|
110
|
+
instances: {
|
|
111
|
+
userId: string;
|
|
112
|
+
age: number;
|
|
113
|
+
idle: number;
|
|
114
|
+
createdAt: string;
|
|
115
|
+
lastUsed: string;
|
|
116
|
+
}[];
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=instance-pool-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instance-pool-manager.d.ts","sourceRoot":"","sources":["../../src/wrapper/instance-pool-manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,2CAA2C,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAsBjD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,YAAY,CAAC,CAAiB;gBAE1B,MAAM,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM;IAatD;;;;;;;;;;OAUG;IACG,WAAW,CACf,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,GACzE,OAAO,CAAC,MAAM,CAAC;IAgDlB;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO;IAsBf;;;;;OAKG;YACW,sBAAsB;IAqBpC;;;;;;;OAOG;YACW,cAAc;IAqB5B;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;IAYzB;;;;;OAKG;YACW,uBAAuB;IAsBrC;;;;;OAKG;IACG,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAoB/B;;;;;;OAMG;IACH,QAAQ;;;;;;;;;;;CAcT"}
|