@leanmcp/core 0.4.2 → 0.4.4
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 +485 -485
- package/dist/index.d.mts +38 -1
- package/dist/index.d.ts +38 -1
- package/dist/index.js +89 -3
- package/dist/index.mjs +82 -3
- package/package.json +78 -78
package/dist/index.d.mts
CHANGED
|
@@ -576,11 +576,20 @@ interface LeanMCPSessionProviderOptions {
|
|
|
576
576
|
ttlSeconds?: number;
|
|
577
577
|
logging?: boolean;
|
|
578
578
|
sessionStore?: ISessionStore;
|
|
579
|
+
/**
|
|
580
|
+
* Force DynamoDB even when not on Lambda (for local testing with real DynamoDB)
|
|
581
|
+
*/
|
|
582
|
+
forceDynamoDB?: boolean;
|
|
579
583
|
}
|
|
580
584
|
/**
|
|
581
585
|
* Drop-in replacement for Map<string, StreamableHTTPServerTransport>
|
|
582
586
|
* Provides automatic session persistence for Lambda deployments
|
|
583
587
|
*
|
|
588
|
+
* Environment auto-detection:
|
|
589
|
+
* - Local development (default): Uses in-memory session store
|
|
590
|
+
* - LeanMCP Lambda (LEANMCP_LAMBDA=true): Uses DynamoDB session store
|
|
591
|
+
* - Explicit override: Pass sessionStore option or forceDynamoDB: true
|
|
592
|
+
*
|
|
584
593
|
* @example
|
|
585
594
|
* // Before: const transports = new Map<string, StreamableHTTPServerTransport>();
|
|
586
595
|
* // After: const sessions = new LeanMCPSessionProvider();
|
|
@@ -590,7 +599,12 @@ interface LeanMCPSessionProviderOptions {
|
|
|
590
599
|
declare class LeanMCPSessionProvider {
|
|
591
600
|
private transports;
|
|
592
601
|
private sessionStore;
|
|
602
|
+
private isUsingDynamoDB;
|
|
593
603
|
constructor(options?: LeanMCPSessionProviderOptions);
|
|
604
|
+
/**
|
|
605
|
+
* Check if using DynamoDB (useful for debugging)
|
|
606
|
+
*/
|
|
607
|
+
get usingDynamoDB(): boolean;
|
|
594
608
|
/**
|
|
595
609
|
* Get transport from memory
|
|
596
610
|
*/
|
|
@@ -691,6 +705,29 @@ declare class DynamoDBSessionStore implements ISessionStore {
|
|
|
691
705
|
deleteSession(sessionId: string): Promise<void>;
|
|
692
706
|
}
|
|
693
707
|
|
|
708
|
+
/**
|
|
709
|
+
* In-memory session store for local development
|
|
710
|
+
* Sessions are stored in memory and lost when the process restarts
|
|
711
|
+
*
|
|
712
|
+
* This is the default for local development - no external dependencies needed
|
|
713
|
+
*/
|
|
714
|
+
declare class InMemorySessionStore implements ISessionStore {
|
|
715
|
+
private sessions;
|
|
716
|
+
sessionExists(sessionId: string): Promise<boolean>;
|
|
717
|
+
createSession(sessionId: string, data?: Record<string, any>): Promise<void>;
|
|
718
|
+
getSession(sessionId: string): Promise<SessionData | null>;
|
|
719
|
+
updateSession(sessionId: string, updates: Partial<SessionData>): Promise<void>;
|
|
720
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
721
|
+
/**
|
|
722
|
+
* Get number of sessions (useful for debugging)
|
|
723
|
+
*/
|
|
724
|
+
get size(): number;
|
|
725
|
+
/**
|
|
726
|
+
* Clear all sessions (useful for testing)
|
|
727
|
+
*/
|
|
728
|
+
clear(): void;
|
|
729
|
+
}
|
|
730
|
+
|
|
694
731
|
interface MCPServerOptions {
|
|
695
732
|
servicesDir: string;
|
|
696
733
|
port?: number;
|
|
@@ -928,4 +965,4 @@ declare class MCPServerRuntime {
|
|
|
928
965
|
*/
|
|
929
966
|
declare function startMCPServer(options: MCPServerOptions): Promise<MCPServerRuntime>;
|
|
930
967
|
|
|
931
|
-
export { Auth, type AuthErrorOptions, type AuthErrorResult, type AuthOptions, DEFAULT_TABLE_NAME, DEFAULT_TTL_SECONDS, Deprecated, DynamoDBSessionStore, type HTTPServerAuthOptions, type HTTPServerInput, type HTTPServerOptions, type ISessionStore, LeanMCPSessionProvider, type LeanMCPSessionProviderOptions, LogLevel, type LogPayload, Logger, type LoggerHandler, type LoggerOptions, MCPServer, type MCPServerConstructorOptions, type MCPServerFactory, type MCPServerOptions, MCPServerRuntime, Optional, Prompt, type PromptOptions, type ProtectedResourceMetadata, Render, Resource, type ResourceOptions, SchemaConstraint, type SecurityScheme, type SessionData, Tool, type ToolOptions, UI, UserEnvs, classToJsonSchema, classToJsonSchemaWithConstraints, createAuthError, createHTTPServer, createProtectedResourceMetadata, defaultLogger, extractBearerToken, getDecoratedMethods, getMethodMetadata, isAuthError, startMCPServer, validateNonEmpty, validatePath, validatePort, validateServiceName, validateUrl };
|
|
968
|
+
export { Auth, type AuthErrorOptions, type AuthErrorResult, type AuthOptions, DEFAULT_TABLE_NAME, DEFAULT_TTL_SECONDS, Deprecated, DynamoDBSessionStore, type HTTPServerAuthOptions, type HTTPServerInput, type HTTPServerOptions, type ISessionStore, InMemorySessionStore, LeanMCPSessionProvider, type LeanMCPSessionProviderOptions, LogLevel, type LogPayload, Logger, type LoggerHandler, type LoggerOptions, MCPServer, type MCPServerConstructorOptions, type MCPServerFactory, type MCPServerOptions, MCPServerRuntime, Optional, Prompt, type PromptOptions, type ProtectedResourceMetadata, Render, Resource, type ResourceOptions, SchemaConstraint, type SecurityScheme, type SessionData, Tool, type ToolOptions, UI, UserEnvs, classToJsonSchema, classToJsonSchemaWithConstraints, createAuthError, createHTTPServer, createProtectedResourceMetadata, defaultLogger, extractBearerToken, getDecoratedMethods, getMethodMetadata, isAuthError, startMCPServer, validateNonEmpty, validatePath, validatePort, validateServiceName, validateUrl };
|
package/dist/index.d.ts
CHANGED
|
@@ -576,11 +576,20 @@ interface LeanMCPSessionProviderOptions {
|
|
|
576
576
|
ttlSeconds?: number;
|
|
577
577
|
logging?: boolean;
|
|
578
578
|
sessionStore?: ISessionStore;
|
|
579
|
+
/**
|
|
580
|
+
* Force DynamoDB even when not on Lambda (for local testing with real DynamoDB)
|
|
581
|
+
*/
|
|
582
|
+
forceDynamoDB?: boolean;
|
|
579
583
|
}
|
|
580
584
|
/**
|
|
581
585
|
* Drop-in replacement for Map<string, StreamableHTTPServerTransport>
|
|
582
586
|
* Provides automatic session persistence for Lambda deployments
|
|
583
587
|
*
|
|
588
|
+
* Environment auto-detection:
|
|
589
|
+
* - Local development (default): Uses in-memory session store
|
|
590
|
+
* - LeanMCP Lambda (LEANMCP_LAMBDA=true): Uses DynamoDB session store
|
|
591
|
+
* - Explicit override: Pass sessionStore option or forceDynamoDB: true
|
|
592
|
+
*
|
|
584
593
|
* @example
|
|
585
594
|
* // Before: const transports = new Map<string, StreamableHTTPServerTransport>();
|
|
586
595
|
* // After: const sessions = new LeanMCPSessionProvider();
|
|
@@ -590,7 +599,12 @@ interface LeanMCPSessionProviderOptions {
|
|
|
590
599
|
declare class LeanMCPSessionProvider {
|
|
591
600
|
private transports;
|
|
592
601
|
private sessionStore;
|
|
602
|
+
private isUsingDynamoDB;
|
|
593
603
|
constructor(options?: LeanMCPSessionProviderOptions);
|
|
604
|
+
/**
|
|
605
|
+
* Check if using DynamoDB (useful for debugging)
|
|
606
|
+
*/
|
|
607
|
+
get usingDynamoDB(): boolean;
|
|
594
608
|
/**
|
|
595
609
|
* Get transport from memory
|
|
596
610
|
*/
|
|
@@ -691,6 +705,29 @@ declare class DynamoDBSessionStore implements ISessionStore {
|
|
|
691
705
|
deleteSession(sessionId: string): Promise<void>;
|
|
692
706
|
}
|
|
693
707
|
|
|
708
|
+
/**
|
|
709
|
+
* In-memory session store for local development
|
|
710
|
+
* Sessions are stored in memory and lost when the process restarts
|
|
711
|
+
*
|
|
712
|
+
* This is the default for local development - no external dependencies needed
|
|
713
|
+
*/
|
|
714
|
+
declare class InMemorySessionStore implements ISessionStore {
|
|
715
|
+
private sessions;
|
|
716
|
+
sessionExists(sessionId: string): Promise<boolean>;
|
|
717
|
+
createSession(sessionId: string, data?: Record<string, any>): Promise<void>;
|
|
718
|
+
getSession(sessionId: string): Promise<SessionData | null>;
|
|
719
|
+
updateSession(sessionId: string, updates: Partial<SessionData>): Promise<void>;
|
|
720
|
+
deleteSession(sessionId: string): Promise<void>;
|
|
721
|
+
/**
|
|
722
|
+
* Get number of sessions (useful for debugging)
|
|
723
|
+
*/
|
|
724
|
+
get size(): number;
|
|
725
|
+
/**
|
|
726
|
+
* Clear all sessions (useful for testing)
|
|
727
|
+
*/
|
|
728
|
+
clear(): void;
|
|
729
|
+
}
|
|
730
|
+
|
|
694
731
|
interface MCPServerOptions {
|
|
695
732
|
servicesDir: string;
|
|
696
733
|
port?: number;
|
|
@@ -928,4 +965,4 @@ declare class MCPServerRuntime {
|
|
|
928
965
|
*/
|
|
929
966
|
declare function startMCPServer(options: MCPServerOptions): Promise<MCPServerRuntime>;
|
|
930
967
|
|
|
931
|
-
export { Auth, type AuthErrorOptions, type AuthErrorResult, type AuthOptions, DEFAULT_TABLE_NAME, DEFAULT_TTL_SECONDS, Deprecated, DynamoDBSessionStore, type HTTPServerAuthOptions, type HTTPServerInput, type HTTPServerOptions, type ISessionStore, LeanMCPSessionProvider, type LeanMCPSessionProviderOptions, LogLevel, type LogPayload, Logger, type LoggerHandler, type LoggerOptions, MCPServer, type MCPServerConstructorOptions, type MCPServerFactory, type MCPServerOptions, MCPServerRuntime, Optional, Prompt, type PromptOptions, type ProtectedResourceMetadata, Render, Resource, type ResourceOptions, SchemaConstraint, type SecurityScheme, type SessionData, Tool, type ToolOptions, UI, UserEnvs, classToJsonSchema, classToJsonSchemaWithConstraints, createAuthError, createHTTPServer, createProtectedResourceMetadata, defaultLogger, extractBearerToken, getDecoratedMethods, getMethodMetadata, isAuthError, startMCPServer, validateNonEmpty, validatePath, validatePort, validateServiceName, validateUrl };
|
|
968
|
+
export { Auth, type AuthErrorOptions, type AuthErrorResult, type AuthOptions, DEFAULT_TABLE_NAME, DEFAULT_TTL_SECONDS, Deprecated, DynamoDBSessionStore, type HTTPServerAuthOptions, type HTTPServerInput, type HTTPServerOptions, type ISessionStore, InMemorySessionStore, LeanMCPSessionProvider, type LeanMCPSessionProviderOptions, LogLevel, type LogPayload, Logger, type LoggerHandler, type LoggerOptions, MCPServer, type MCPServerConstructorOptions, type MCPServerFactory, type MCPServerOptions, MCPServerRuntime, Optional, Prompt, type PromptOptions, type ProtectedResourceMetadata, Render, Resource, type ResourceOptions, SchemaConstraint, type SecurityScheme, type SessionData, Tool, type ToolOptions, UI, UserEnvs, classToJsonSchema, classToJsonSchemaWithConstraints, createAuthError, createHTTPServer, createProtectedResourceMetadata, defaultLogger, extractBearerToken, getDecoratedMethods, getMethodMetadata, isAuthError, startMCPServer, validateNonEmpty, validatePath, validatePort, validateServiceName, validateUrl };
|
package/dist/index.js
CHANGED
|
@@ -1065,7 +1065,12 @@ async function createHTTPServer(serverInput, options) {
|
|
|
1065
1065
|
}, "onsessioninitialized")
|
|
1066
1066
|
});
|
|
1067
1067
|
transports[sessionId] = transport;
|
|
1068
|
-
|
|
1068
|
+
const webTransport = transport._webStandardTransport;
|
|
1069
|
+
if (webTransport) {
|
|
1070
|
+
webTransport._initialized = true;
|
|
1071
|
+
webTransport.sessionId = sessionId;
|
|
1072
|
+
logger.info(`Transport initialized flag set for session: ${sessionId}`);
|
|
1073
|
+
}
|
|
1069
1074
|
transport.onclose = async () => {
|
|
1070
1075
|
if (transport.sessionId) {
|
|
1071
1076
|
delete transports[transport.sessionId];
|
|
@@ -1374,6 +1379,59 @@ var init_session_store = __esm({
|
|
|
1374
1379
|
}
|
|
1375
1380
|
});
|
|
1376
1381
|
|
|
1382
|
+
// src/inmemory-session-store.ts
|
|
1383
|
+
var InMemorySessionStore;
|
|
1384
|
+
var init_inmemory_session_store = __esm({
|
|
1385
|
+
"src/inmemory-session-store.ts"() {
|
|
1386
|
+
"use strict";
|
|
1387
|
+
InMemorySessionStore = class {
|
|
1388
|
+
static {
|
|
1389
|
+
__name(this, "InMemorySessionStore");
|
|
1390
|
+
}
|
|
1391
|
+
sessions = /* @__PURE__ */ new Map();
|
|
1392
|
+
async sessionExists(sessionId) {
|
|
1393
|
+
return this.sessions.has(sessionId);
|
|
1394
|
+
}
|
|
1395
|
+
async createSession(sessionId, data) {
|
|
1396
|
+
const now = /* @__PURE__ */ new Date();
|
|
1397
|
+
this.sessions.set(sessionId, {
|
|
1398
|
+
sessionId,
|
|
1399
|
+
createdAt: now,
|
|
1400
|
+
updatedAt: now,
|
|
1401
|
+
data: data || {}
|
|
1402
|
+
});
|
|
1403
|
+
}
|
|
1404
|
+
async getSession(sessionId) {
|
|
1405
|
+
return this.sessions.get(sessionId) ?? null;
|
|
1406
|
+
}
|
|
1407
|
+
async updateSession(sessionId, updates) {
|
|
1408
|
+
const existing = this.sessions.get(sessionId);
|
|
1409
|
+
if (!existing) return;
|
|
1410
|
+
this.sessions.set(sessionId, {
|
|
1411
|
+
...existing,
|
|
1412
|
+
...updates,
|
|
1413
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1414
|
+
});
|
|
1415
|
+
}
|
|
1416
|
+
async deleteSession(sessionId) {
|
|
1417
|
+
this.sessions.delete(sessionId);
|
|
1418
|
+
}
|
|
1419
|
+
/**
|
|
1420
|
+
* Get number of sessions (useful for debugging)
|
|
1421
|
+
*/
|
|
1422
|
+
get size() {
|
|
1423
|
+
return this.sessions.size;
|
|
1424
|
+
}
|
|
1425
|
+
/**
|
|
1426
|
+
* Clear all sessions (useful for testing)
|
|
1427
|
+
*/
|
|
1428
|
+
clear() {
|
|
1429
|
+
this.sessions.clear();
|
|
1430
|
+
}
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
});
|
|
1434
|
+
|
|
1377
1435
|
// src/session-provider.ts
|
|
1378
1436
|
var import_streamableHttp, LeanMCPSessionProvider;
|
|
1379
1437
|
var init_session_provider = __esm({
|
|
@@ -1381,25 +1439,44 @@ var init_session_provider = __esm({
|
|
|
1381
1439
|
"use strict";
|
|
1382
1440
|
import_streamableHttp = require("@modelcontextprotocol/sdk/server/streamableHttp.js");
|
|
1383
1441
|
init_dynamodb_session_store();
|
|
1442
|
+
init_inmemory_session_store();
|
|
1384
1443
|
LeanMCPSessionProvider = class {
|
|
1385
1444
|
static {
|
|
1386
1445
|
__name(this, "LeanMCPSessionProvider");
|
|
1387
1446
|
}
|
|
1388
1447
|
transports = /* @__PURE__ */ new Map();
|
|
1389
1448
|
sessionStore;
|
|
1449
|
+
isUsingDynamoDB;
|
|
1390
1450
|
constructor(options) {
|
|
1391
1451
|
if (options?.sessionStore) {
|
|
1392
1452
|
this.sessionStore = options.sessionStore;
|
|
1393
|
-
|
|
1453
|
+
this.isUsingDynamoDB = false;
|
|
1454
|
+
} else if (options?.forceDynamoDB || process.env.LEANMCP_LAMBDA === "true") {
|
|
1394
1455
|
this.sessionStore = new DynamoDBSessionStore({
|
|
1395
1456
|
tableName: options?.tableName,
|
|
1396
1457
|
region: options?.region,
|
|
1397
1458
|
ttlSeconds: options?.ttlSeconds,
|
|
1398
1459
|
logging: options?.logging
|
|
1399
1460
|
});
|
|
1461
|
+
this.isUsingDynamoDB = true;
|
|
1462
|
+
if (options?.logging) {
|
|
1463
|
+
console.log("[LeanMCPSessionProvider] Using DynamoDB session store");
|
|
1464
|
+
}
|
|
1465
|
+
} else {
|
|
1466
|
+
this.sessionStore = new InMemorySessionStore();
|
|
1467
|
+
this.isUsingDynamoDB = false;
|
|
1468
|
+
if (options?.logging) {
|
|
1469
|
+
console.log("[LeanMCPSessionProvider] Using in-memory session store (local dev mode)");
|
|
1470
|
+
}
|
|
1400
1471
|
}
|
|
1401
1472
|
}
|
|
1402
1473
|
/**
|
|
1474
|
+
* Check if using DynamoDB (useful for debugging)
|
|
1475
|
+
*/
|
|
1476
|
+
get usingDynamoDB() {
|
|
1477
|
+
return this.isUsingDynamoDB;
|
|
1478
|
+
}
|
|
1479
|
+
/**
|
|
1403
1480
|
* Get transport from memory
|
|
1404
1481
|
*/
|
|
1405
1482
|
get(sessionId) {
|
|
@@ -1429,7 +1506,7 @@ var init_session_provider = __esm({
|
|
|
1429
1506
|
/**
|
|
1430
1507
|
* Get or recreate transport for a session
|
|
1431
1508
|
* This is the key method for Lambda support - handles container recycling
|
|
1432
|
-
*
|
|
1509
|
+
*
|
|
1433
1510
|
* @param sessionId - Session ID to get or recreate
|
|
1434
1511
|
* @param serverFactory - Factory function to create fresh MCP server instances
|
|
1435
1512
|
* @param transportOptions - Optional callbacks for transport lifecycle events
|
|
@@ -1447,6 +1524,12 @@ var init_session_provider = __esm({
|
|
|
1447
1524
|
transportOptions?.onsessioninitialized?.(sid);
|
|
1448
1525
|
}, "onsessioninitialized")
|
|
1449
1526
|
});
|
|
1527
|
+
this.transports.set(sessionId, transport);
|
|
1528
|
+
const webTransport = transport._webStandardTransport;
|
|
1529
|
+
if (webTransport) {
|
|
1530
|
+
webTransport._initialized = true;
|
|
1531
|
+
webTransport.sessionId = sessionId;
|
|
1532
|
+
}
|
|
1450
1533
|
transport.onclose = () => {
|
|
1451
1534
|
this.transports.delete(sessionId);
|
|
1452
1535
|
transportOptions?.onclose?.();
|
|
@@ -1512,6 +1595,7 @@ __export(index_exports, {
|
|
|
1512
1595
|
DEFAULT_TTL_SECONDS: () => DEFAULT_TTL_SECONDS,
|
|
1513
1596
|
Deprecated: () => Deprecated,
|
|
1514
1597
|
DynamoDBSessionStore: () => DynamoDBSessionStore,
|
|
1598
|
+
InMemorySessionStore: () => InMemorySessionStore,
|
|
1515
1599
|
LeanMCPSessionProvider: () => LeanMCPSessionProvider,
|
|
1516
1600
|
LogLevel: () => LogLevel,
|
|
1517
1601
|
Logger: () => Logger,
|
|
@@ -1568,6 +1652,7 @@ var init_index = __esm({
|
|
|
1568
1652
|
init_session_store();
|
|
1569
1653
|
init_session_provider();
|
|
1570
1654
|
init_dynamodb_session_store();
|
|
1655
|
+
init_inmemory_session_store();
|
|
1571
1656
|
init_decorators();
|
|
1572
1657
|
init_schema_generator();
|
|
1573
1658
|
init_logger();
|
|
@@ -2574,6 +2659,7 @@ init_index();
|
|
|
2574
2659
|
DEFAULT_TTL_SECONDS,
|
|
2575
2660
|
Deprecated,
|
|
2576
2661
|
DynamoDBSessionStore,
|
|
2662
|
+
InMemorySessionStore,
|
|
2577
2663
|
LeanMCPSessionProvider,
|
|
2578
2664
|
LogLevel,
|
|
2579
2665
|
Logger,
|
package/dist/index.mjs
CHANGED
|
@@ -763,7 +763,12 @@ async function createHTTPServer(serverInput, options) {
|
|
|
763
763
|
}, "onsessioninitialized")
|
|
764
764
|
});
|
|
765
765
|
transports[sessionId] = transport;
|
|
766
|
-
|
|
766
|
+
const webTransport = transport._webStandardTransport;
|
|
767
|
+
if (webTransport) {
|
|
768
|
+
webTransport._initialized = true;
|
|
769
|
+
webTransport.sessionId = sessionId;
|
|
770
|
+
logger.info(`Transport initialized flag set for session: ${sessionId}`);
|
|
771
|
+
}
|
|
767
772
|
transport.onclose = async () => {
|
|
768
773
|
if (transport.sessionId) {
|
|
769
774
|
delete transports[transport.sessionId];
|
|
@@ -1051,25 +1056,92 @@ __name(createProtectedResourceMetadata, "createProtectedResourceMetadata");
|
|
|
1051
1056
|
|
|
1052
1057
|
// src/session-provider.ts
|
|
1053
1058
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
1059
|
+
|
|
1060
|
+
// src/inmemory-session-store.ts
|
|
1061
|
+
var InMemorySessionStore = class {
|
|
1062
|
+
static {
|
|
1063
|
+
__name(this, "InMemorySessionStore");
|
|
1064
|
+
}
|
|
1065
|
+
sessions = /* @__PURE__ */ new Map();
|
|
1066
|
+
async sessionExists(sessionId) {
|
|
1067
|
+
return this.sessions.has(sessionId);
|
|
1068
|
+
}
|
|
1069
|
+
async createSession(sessionId, data) {
|
|
1070
|
+
const now = /* @__PURE__ */ new Date();
|
|
1071
|
+
this.sessions.set(sessionId, {
|
|
1072
|
+
sessionId,
|
|
1073
|
+
createdAt: now,
|
|
1074
|
+
updatedAt: now,
|
|
1075
|
+
data: data || {}
|
|
1076
|
+
});
|
|
1077
|
+
}
|
|
1078
|
+
async getSession(sessionId) {
|
|
1079
|
+
return this.sessions.get(sessionId) ?? null;
|
|
1080
|
+
}
|
|
1081
|
+
async updateSession(sessionId, updates) {
|
|
1082
|
+
const existing = this.sessions.get(sessionId);
|
|
1083
|
+
if (!existing) return;
|
|
1084
|
+
this.sessions.set(sessionId, {
|
|
1085
|
+
...existing,
|
|
1086
|
+
...updates,
|
|
1087
|
+
updatedAt: /* @__PURE__ */ new Date()
|
|
1088
|
+
});
|
|
1089
|
+
}
|
|
1090
|
+
async deleteSession(sessionId) {
|
|
1091
|
+
this.sessions.delete(sessionId);
|
|
1092
|
+
}
|
|
1093
|
+
/**
|
|
1094
|
+
* Get number of sessions (useful for debugging)
|
|
1095
|
+
*/
|
|
1096
|
+
get size() {
|
|
1097
|
+
return this.sessions.size;
|
|
1098
|
+
}
|
|
1099
|
+
/**
|
|
1100
|
+
* Clear all sessions (useful for testing)
|
|
1101
|
+
*/
|
|
1102
|
+
clear() {
|
|
1103
|
+
this.sessions.clear();
|
|
1104
|
+
}
|
|
1105
|
+
};
|
|
1106
|
+
|
|
1107
|
+
// src/session-provider.ts
|
|
1054
1108
|
var LeanMCPSessionProvider = class {
|
|
1055
1109
|
static {
|
|
1056
1110
|
__name(this, "LeanMCPSessionProvider");
|
|
1057
1111
|
}
|
|
1058
1112
|
transports = /* @__PURE__ */ new Map();
|
|
1059
1113
|
sessionStore;
|
|
1114
|
+
isUsingDynamoDB;
|
|
1060
1115
|
constructor(options) {
|
|
1061
1116
|
if (options?.sessionStore) {
|
|
1062
1117
|
this.sessionStore = options.sessionStore;
|
|
1063
|
-
|
|
1118
|
+
this.isUsingDynamoDB = false;
|
|
1119
|
+
} else if (options?.forceDynamoDB || process.env.LEANMCP_LAMBDA === "true") {
|
|
1064
1120
|
this.sessionStore = new DynamoDBSessionStore({
|
|
1065
1121
|
tableName: options?.tableName,
|
|
1066
1122
|
region: options?.region,
|
|
1067
1123
|
ttlSeconds: options?.ttlSeconds,
|
|
1068
1124
|
logging: options?.logging
|
|
1069
1125
|
});
|
|
1126
|
+
this.isUsingDynamoDB = true;
|
|
1127
|
+
if (options?.logging) {
|
|
1128
|
+
console.log("[LeanMCPSessionProvider] Using DynamoDB session store");
|
|
1129
|
+
}
|
|
1130
|
+
} else {
|
|
1131
|
+
this.sessionStore = new InMemorySessionStore();
|
|
1132
|
+
this.isUsingDynamoDB = false;
|
|
1133
|
+
if (options?.logging) {
|
|
1134
|
+
console.log("[LeanMCPSessionProvider] Using in-memory session store (local dev mode)");
|
|
1135
|
+
}
|
|
1070
1136
|
}
|
|
1071
1137
|
}
|
|
1072
1138
|
/**
|
|
1139
|
+
* Check if using DynamoDB (useful for debugging)
|
|
1140
|
+
*/
|
|
1141
|
+
get usingDynamoDB() {
|
|
1142
|
+
return this.isUsingDynamoDB;
|
|
1143
|
+
}
|
|
1144
|
+
/**
|
|
1073
1145
|
* Get transport from memory
|
|
1074
1146
|
*/
|
|
1075
1147
|
get(sessionId) {
|
|
@@ -1099,7 +1171,7 @@ var LeanMCPSessionProvider = class {
|
|
|
1099
1171
|
/**
|
|
1100
1172
|
* Get or recreate transport for a session
|
|
1101
1173
|
* This is the key method for Lambda support - handles container recycling
|
|
1102
|
-
*
|
|
1174
|
+
*
|
|
1103
1175
|
* @param sessionId - Session ID to get or recreate
|
|
1104
1176
|
* @param serverFactory - Factory function to create fresh MCP server instances
|
|
1105
1177
|
* @param transportOptions - Optional callbacks for transport lifecycle events
|
|
@@ -1117,6 +1189,12 @@ var LeanMCPSessionProvider = class {
|
|
|
1117
1189
|
transportOptions?.onsessioninitialized?.(sid);
|
|
1118
1190
|
}, "onsessioninitialized")
|
|
1119
1191
|
});
|
|
1192
|
+
this.transports.set(sessionId, transport);
|
|
1193
|
+
const webTransport = transport._webStandardTransport;
|
|
1194
|
+
if (webTransport) {
|
|
1195
|
+
webTransport._initialized = true;
|
|
1196
|
+
webTransport.sessionId = sessionId;
|
|
1197
|
+
}
|
|
1120
1198
|
transport.onclose = () => {
|
|
1121
1199
|
this.transports.delete(sessionId);
|
|
1122
1200
|
transportOptions?.onclose?.();
|
|
@@ -2177,6 +2255,7 @@ export {
|
|
|
2177
2255
|
DEFAULT_TTL_SECONDS,
|
|
2178
2256
|
Deprecated,
|
|
2179
2257
|
DynamoDBSessionStore,
|
|
2258
|
+
InMemorySessionStore,
|
|
2180
2259
|
LeanMCPSessionProvider,
|
|
2181
2260
|
LogLevel,
|
|
2182
2261
|
Logger,
|
package/package.json
CHANGED
|
@@ -1,78 +1,78 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@leanmcp/core",
|
|
3
|
-
"version": "0.4.
|
|
4
|
-
"description": "Core library implementing decorators, reflection, and MCP runtime server",
|
|
5
|
-
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.mjs",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"types": "./dist/index.d.ts",
|
|
11
|
-
"require": "./dist/index.js",
|
|
12
|
-
"import": "./dist/index.mjs"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
|
-
"files": [
|
|
16
|
-
"dist",
|
|
17
|
-
"README.md",
|
|
18
|
-
"LICENSE"
|
|
19
|
-
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
22
|
-
"dev": "tsup src/index.ts --format esm,cjs --dts --watch",
|
|
23
|
-
"test": "jest --passWithNoTests",
|
|
24
|
-
"test:watch": "jest --watch"
|
|
25
|
-
},
|
|
26
|
-
"dependencies": {
|
|
27
|
-
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
28
|
-
"@aws-sdk/client-dynamodb": "^3.700.0",
|
|
29
|
-
"@aws-sdk/lib-dynamodb": "^3.700.0",
|
|
30
|
-
"ajv": "^8.12.0",
|
|
31
|
-
"chokidar": "^4.0.0",
|
|
32
|
-
"dotenv": "^16.3.1",
|
|
33
|
-
"reflect-metadata": "^0.2.1"
|
|
34
|
-
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"cors": "^2.8.5",
|
|
37
|
-
"express": "^5.0.0",
|
|
38
|
-
"@leanmcp/auth": "^0.4.0"
|
|
39
|
-
},
|
|
40
|
-
"peerDependenciesMeta": {
|
|
41
|
-
"express": {
|
|
42
|
-
"optional": true
|
|
43
|
-
},
|
|
44
|
-
"cors": {
|
|
45
|
-
"optional": true
|
|
46
|
-
},
|
|
47
|
-
"@leanmcp/auth": {
|
|
48
|
-
"optional": true
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
"devDependencies": {
|
|
52
|
-
"@types/cors": "^2.8.0",
|
|
53
|
-
"@types/express": "^5.0.0",
|
|
54
|
-
"@types/node": "^20.0.0"
|
|
55
|
-
},
|
|
56
|
-
"repository": {
|
|
57
|
-
"type": "git",
|
|
58
|
-
"url": "git+https://github.com/LeanMCP/leanmcp-sdk.git",
|
|
59
|
-
"directory": "packages/core"
|
|
60
|
-
},
|
|
61
|
-
"homepage": "https://github.com/LeanMCP/leanmcp-sdk#readme",
|
|
62
|
-
"bugs": {
|
|
63
|
-
"url": "https://github.com/LeanMCP/leanmcp-sdk/issues"
|
|
64
|
-
},
|
|
65
|
-
"keywords": [
|
|
66
|
-
"mcp",
|
|
67
|
-
"model-context-protocol",
|
|
68
|
-
"typescript",
|
|
69
|
-
"decorators",
|
|
70
|
-
"server",
|
|
71
|
-
"runtime"
|
|
72
|
-
],
|
|
73
|
-
"author": "LeanMCP <admin@leanmcp.com>",
|
|
74
|
-
"license": "MIT",
|
|
75
|
-
"publishConfig": {
|
|
76
|
-
"access": "public"
|
|
77
|
-
}
|
|
78
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@leanmcp/core",
|
|
3
|
+
"version": "0.4.4",
|
|
4
|
+
"description": "Core library implementing decorators, reflection, and MCP runtime server",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"require": "./dist/index.js",
|
|
12
|
+
"import": "./dist/index.mjs"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md",
|
|
18
|
+
"LICENSE"
|
|
19
|
+
],
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsup src/index.ts --format esm,cjs --dts",
|
|
22
|
+
"dev": "tsup src/index.ts --format esm,cjs --dts --watch",
|
|
23
|
+
"test": "jest --passWithNoTests",
|
|
24
|
+
"test:watch": "jest --watch"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
28
|
+
"@aws-sdk/client-dynamodb": "^3.700.0",
|
|
29
|
+
"@aws-sdk/lib-dynamodb": "^3.700.0",
|
|
30
|
+
"ajv": "^8.12.0",
|
|
31
|
+
"chokidar": "^4.0.0",
|
|
32
|
+
"dotenv": "^16.3.1",
|
|
33
|
+
"reflect-metadata": "^0.2.1"
|
|
34
|
+
},
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"cors": "^2.8.5",
|
|
37
|
+
"express": "^5.0.0",
|
|
38
|
+
"@leanmcp/auth": "^0.4.0"
|
|
39
|
+
},
|
|
40
|
+
"peerDependenciesMeta": {
|
|
41
|
+
"express": {
|
|
42
|
+
"optional": true
|
|
43
|
+
},
|
|
44
|
+
"cors": {
|
|
45
|
+
"optional": true
|
|
46
|
+
},
|
|
47
|
+
"@leanmcp/auth": {
|
|
48
|
+
"optional": true
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"@types/cors": "^2.8.0",
|
|
53
|
+
"@types/express": "^5.0.0",
|
|
54
|
+
"@types/node": "^20.0.0"
|
|
55
|
+
},
|
|
56
|
+
"repository": {
|
|
57
|
+
"type": "git",
|
|
58
|
+
"url": "git+https://github.com/LeanMCP/leanmcp-sdk.git",
|
|
59
|
+
"directory": "packages/core"
|
|
60
|
+
},
|
|
61
|
+
"homepage": "https://github.com/LeanMCP/leanmcp-sdk#readme",
|
|
62
|
+
"bugs": {
|
|
63
|
+
"url": "https://github.com/LeanMCP/leanmcp-sdk/issues"
|
|
64
|
+
},
|
|
65
|
+
"keywords": [
|
|
66
|
+
"mcp",
|
|
67
|
+
"model-context-protocol",
|
|
68
|
+
"typescript",
|
|
69
|
+
"decorators",
|
|
70
|
+
"server",
|
|
71
|
+
"runtime"
|
|
72
|
+
],
|
|
73
|
+
"author": "LeanMCP <admin@leanmcp.com>",
|
|
74
|
+
"license": "MIT",
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public"
|
|
77
|
+
}
|
|
78
|
+
}
|