@leanmcp/core 0.3.3 → 0.3.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/LICENSE +21 -21
- package/README.md +555 -555
- package/dist/index.d.mts +50 -44
- package/dist/index.d.ts +50 -44
- package/dist/index.js +234 -35
- package/dist/index.mjs +233 -34
- package/package.json +71 -71
package/dist/index.mjs
CHANGED
|
@@ -46,7 +46,7 @@ function Resource(options = {}) {
|
|
|
46
46
|
return (target, propertyKey, descriptor) => {
|
|
47
47
|
const resourceName = String(propertyKey);
|
|
48
48
|
const className = target.constructor.name.toLowerCase().replace("service", "");
|
|
49
|
-
const resourceUri =
|
|
49
|
+
const resourceUri = options.uri ?? `ui://${className}/${resourceName}`;
|
|
50
50
|
Reflect.defineMetadata("resource:uri", resourceUri, descriptor.value);
|
|
51
51
|
Reflect.defineMetadata("resource:name", resourceName, descriptor.value);
|
|
52
52
|
Reflect.defineMetadata("resource:description", options.description || "", descriptor.value);
|
|
@@ -291,6 +291,35 @@ var LogLevel = /* @__PURE__ */ (function(LogLevel2) {
|
|
|
291
291
|
LogLevel2[LogLevel2["NONE"] = 4] = "NONE";
|
|
292
292
|
return LogLevel2;
|
|
293
293
|
})({});
|
|
294
|
+
var COLORS = {
|
|
295
|
+
reset: "\x1B[0m",
|
|
296
|
+
gray: "\x1B[38;5;244m",
|
|
297
|
+
blue: "\x1B[1;34m",
|
|
298
|
+
amber: "\x1B[38;5;214m",
|
|
299
|
+
red: "\x1B[1;31m"
|
|
300
|
+
};
|
|
301
|
+
var levelStyles = {
|
|
302
|
+
[0]: {
|
|
303
|
+
label: "DEBUG",
|
|
304
|
+
color: COLORS.gray
|
|
305
|
+
},
|
|
306
|
+
[1]: {
|
|
307
|
+
label: "INFO",
|
|
308
|
+
color: COLORS.blue
|
|
309
|
+
},
|
|
310
|
+
[2]: {
|
|
311
|
+
label: "WARN",
|
|
312
|
+
color: COLORS.amber
|
|
313
|
+
},
|
|
314
|
+
[3]: {
|
|
315
|
+
label: "ERROR",
|
|
316
|
+
color: COLORS.red
|
|
317
|
+
},
|
|
318
|
+
[4]: {
|
|
319
|
+
label: "NONE",
|
|
320
|
+
color: COLORS.gray
|
|
321
|
+
}
|
|
322
|
+
};
|
|
294
323
|
var Logger = class {
|
|
295
324
|
static {
|
|
296
325
|
__name(this, "Logger");
|
|
@@ -298,38 +327,61 @@ var Logger = class {
|
|
|
298
327
|
level;
|
|
299
328
|
prefix;
|
|
300
329
|
timestamps;
|
|
330
|
+
colorize;
|
|
331
|
+
context;
|
|
332
|
+
handlers;
|
|
301
333
|
constructor(options = {}) {
|
|
302
334
|
this.level = options.level ?? 1;
|
|
303
335
|
this.prefix = options.prefix ?? "";
|
|
304
336
|
this.timestamps = options.timestamps ?? true;
|
|
337
|
+
this.colorize = options.colorize ?? true;
|
|
338
|
+
this.context = options.context;
|
|
339
|
+
this.handlers = options.handlers ?? [];
|
|
305
340
|
}
|
|
306
|
-
format(level, message
|
|
341
|
+
format(level, message) {
|
|
342
|
+
const style = levelStyles[level];
|
|
307
343
|
const timestamp = this.timestamps ? `[${(/* @__PURE__ */ new Date()).toISOString()}]` : "";
|
|
308
344
|
const prefix = this.prefix ? `[${this.prefix}]` : "";
|
|
309
|
-
|
|
345
|
+
const context = this.context ? `[${this.context}]` : "";
|
|
346
|
+
const label = `[${style.label}]`;
|
|
347
|
+
const parts = `${timestamp}${prefix}${context}${label} ${message}`;
|
|
348
|
+
if (!this.colorize) return parts;
|
|
349
|
+
return `${style.color}${parts}${COLORS.reset}`;
|
|
310
350
|
}
|
|
311
351
|
shouldLog(level) {
|
|
312
|
-
return level >= this.level;
|
|
352
|
+
return level >= this.level && this.level !== 4;
|
|
353
|
+
}
|
|
354
|
+
emit(level, message, consoleFn, ...args) {
|
|
355
|
+
if (!this.shouldLog(level)) return;
|
|
356
|
+
const payload = {
|
|
357
|
+
level,
|
|
358
|
+
levelLabel: levelStyles[level].label,
|
|
359
|
+
message,
|
|
360
|
+
args,
|
|
361
|
+
prefix: this.prefix,
|
|
362
|
+
context: this.context,
|
|
363
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
364
|
+
};
|
|
365
|
+
consoleFn(this.format(level, message), ...args);
|
|
366
|
+
this.handlers.forEach((handler) => {
|
|
367
|
+
try {
|
|
368
|
+
handler(payload);
|
|
369
|
+
} catch (err) {
|
|
370
|
+
console.debug("Logger handler error", err);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
313
373
|
}
|
|
314
374
|
debug(message, ...args) {
|
|
315
|
-
|
|
316
|
-
console.debug(this.format("DEBUG", message), ...args);
|
|
317
|
-
}
|
|
375
|
+
this.emit(0, message, console.debug, ...args);
|
|
318
376
|
}
|
|
319
377
|
info(message, ...args) {
|
|
320
|
-
|
|
321
|
-
console.info(this.format("INFO", message), ...args);
|
|
322
|
-
}
|
|
378
|
+
this.emit(1, message, console.info, ...args);
|
|
323
379
|
}
|
|
324
380
|
warn(message, ...args) {
|
|
325
|
-
|
|
326
|
-
console.warn(this.format("WARN", message), ...args);
|
|
327
|
-
}
|
|
381
|
+
this.emit(2, message, console.warn, ...args);
|
|
328
382
|
}
|
|
329
383
|
error(message, ...args) {
|
|
330
|
-
|
|
331
|
-
console.error(this.format("ERROR", message), ...args);
|
|
332
|
-
}
|
|
384
|
+
this.emit(3, message, console.error, ...args);
|
|
333
385
|
}
|
|
334
386
|
setLevel(level) {
|
|
335
387
|
this.level = level;
|
|
@@ -409,7 +461,8 @@ async function createHTTPServer(serverInput, options) {
|
|
|
409
461
|
port: serverOptions.port,
|
|
410
462
|
cors: serverOptions.cors,
|
|
411
463
|
logging: serverOptions.logging,
|
|
412
|
-
sessionTimeout: serverOptions.sessionTimeout
|
|
464
|
+
sessionTimeout: serverOptions.sessionTimeout,
|
|
465
|
+
stateless: serverOptions.stateless
|
|
413
466
|
};
|
|
414
467
|
}
|
|
415
468
|
const [express, { StreamableHTTPServerTransport }, cors] = await Promise.all([
|
|
@@ -482,7 +535,7 @@ async function createHTTPServer(serverInput, options) {
|
|
|
482
535
|
}, "startServerWithPortRetry");
|
|
483
536
|
if (cors && httpOptions.cors) {
|
|
484
537
|
const corsOptions = typeof httpOptions.cors === "object" ? {
|
|
485
|
-
origin: httpOptions.cors.origin ||
|
|
538
|
+
origin: httpOptions.cors.origin || "*",
|
|
486
539
|
methods: [
|
|
487
540
|
"GET",
|
|
488
541
|
"POST",
|
|
@@ -500,21 +553,41 @@ async function createHTTPServer(serverInput, options) {
|
|
|
500
553
|
],
|
|
501
554
|
credentials: httpOptions.cors.credentials ?? false,
|
|
502
555
|
maxAge: 86400
|
|
503
|
-
} :
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
556
|
+
} : {
|
|
557
|
+
// When cors: true, use permissive defaults for development
|
|
558
|
+
origin: "*",
|
|
559
|
+
methods: [
|
|
560
|
+
"GET",
|
|
561
|
+
"POST",
|
|
562
|
+
"DELETE",
|
|
563
|
+
"OPTIONS"
|
|
564
|
+
],
|
|
565
|
+
allowedHeaders: [
|
|
566
|
+
"Content-Type",
|
|
567
|
+
"mcp-session-id",
|
|
568
|
+
"mcp-protocol-version",
|
|
569
|
+
"Authorization"
|
|
570
|
+
],
|
|
571
|
+
exposedHeaders: [
|
|
572
|
+
"mcp-session-id"
|
|
573
|
+
],
|
|
574
|
+
credentials: false,
|
|
575
|
+
maxAge: 86400
|
|
576
|
+
};
|
|
577
|
+
app.use(cors.default(corsOptions));
|
|
507
578
|
}
|
|
508
579
|
app.use(express.json());
|
|
509
|
-
|
|
580
|
+
const isStateless = httpOptions.stateless !== false;
|
|
581
|
+
console.log(`Starting LeanMCP HTTP Server (${isStateless ? "STATELESS" : "STATEFUL"})...`);
|
|
510
582
|
app.get("/health", (req, res) => {
|
|
511
583
|
res.json({
|
|
512
584
|
status: "ok",
|
|
513
|
-
|
|
585
|
+
mode: isStateless ? "stateless" : "stateful",
|
|
586
|
+
activeSessions: isStateless ? 0 : Object.keys(transports).length,
|
|
514
587
|
uptime: process.uptime()
|
|
515
588
|
});
|
|
516
589
|
});
|
|
517
|
-
const
|
|
590
|
+
const handleMCPRequestStateful = /* @__PURE__ */ __name(async (req, res) => {
|
|
518
591
|
const sessionId = req.headers["mcp-session-id"];
|
|
519
592
|
let transport;
|
|
520
593
|
const method = req.body?.method || "unknown";
|
|
@@ -577,9 +650,68 @@ async function createHTTPServer(serverInput, options) {
|
|
|
577
650
|
});
|
|
578
651
|
}
|
|
579
652
|
}
|
|
580
|
-
}, "
|
|
581
|
-
|
|
582
|
-
|
|
653
|
+
}, "handleMCPRequestStateful");
|
|
654
|
+
const handleMCPRequestStateless = /* @__PURE__ */ __name(async (req, res) => {
|
|
655
|
+
const method = req.body?.method || "unknown";
|
|
656
|
+
const params = req.body?.params;
|
|
657
|
+
let logMessage = `${req.method} /mcp - ${method}`;
|
|
658
|
+
if (params?.name) logMessage += ` [${params.name}]`;
|
|
659
|
+
else if (params?.uri) logMessage += ` [${params.uri}]`;
|
|
660
|
+
logger.info(logMessage);
|
|
661
|
+
try {
|
|
662
|
+
const freshServer = await serverFactory();
|
|
663
|
+
if (freshServer && typeof freshServer.waitForInit === "function") {
|
|
664
|
+
await freshServer.waitForInit();
|
|
665
|
+
}
|
|
666
|
+
const transport = new StreamableHTTPServerTransport({
|
|
667
|
+
sessionIdGenerator: void 0
|
|
668
|
+
});
|
|
669
|
+
await freshServer.connect(transport);
|
|
670
|
+
await transport.handleRequest(req, res, req.body);
|
|
671
|
+
res.on("close", () => {
|
|
672
|
+
transport.close();
|
|
673
|
+
freshServer.close();
|
|
674
|
+
});
|
|
675
|
+
} catch (error) {
|
|
676
|
+
logger.error("Error handling MCP request:", error);
|
|
677
|
+
if (!res.headersSent) {
|
|
678
|
+
res.status(500).json({
|
|
679
|
+
jsonrpc: "2.0",
|
|
680
|
+
error: {
|
|
681
|
+
code: -32603,
|
|
682
|
+
message: "Internal server error"
|
|
683
|
+
},
|
|
684
|
+
id: null
|
|
685
|
+
});
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
}, "handleMCPRequestStateless");
|
|
689
|
+
if (isStateless) {
|
|
690
|
+
app.post("/mcp", handleMCPRequestStateless);
|
|
691
|
+
app.get("/mcp", (_req, res) => {
|
|
692
|
+
res.status(405).json({
|
|
693
|
+
jsonrpc: "2.0",
|
|
694
|
+
error: {
|
|
695
|
+
code: -32e3,
|
|
696
|
+
message: "Method not allowed (stateless mode)"
|
|
697
|
+
},
|
|
698
|
+
id: null
|
|
699
|
+
});
|
|
700
|
+
});
|
|
701
|
+
app.delete("/mcp", (_req, res) => {
|
|
702
|
+
res.status(405).json({
|
|
703
|
+
jsonrpc: "2.0",
|
|
704
|
+
error: {
|
|
705
|
+
code: -32e3,
|
|
706
|
+
message: "Method not allowed (stateless mode)"
|
|
707
|
+
},
|
|
708
|
+
id: null
|
|
709
|
+
});
|
|
710
|
+
});
|
|
711
|
+
} else {
|
|
712
|
+
app.post("/mcp", handleMCPRequestStateful);
|
|
713
|
+
app.delete("/mcp", handleMCPRequestStateful);
|
|
714
|
+
}
|
|
583
715
|
return new Promise(async (resolve, reject) => {
|
|
584
716
|
let activeListener;
|
|
585
717
|
try {
|
|
@@ -670,6 +802,7 @@ var MCPServer = class {
|
|
|
670
802
|
if (options.autoDiscover !== false) {
|
|
671
803
|
await this.autoDiscoverServices(options.mcpDir, options.serviceFactories);
|
|
672
804
|
}
|
|
805
|
+
await this.loadUIManifest();
|
|
673
806
|
}
|
|
674
807
|
/**
|
|
675
808
|
* Wait for initialization to complete
|
|
@@ -751,14 +884,18 @@ var MCPServer = class {
|
|
|
751
884
|
this.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
752
885
|
const tools = [];
|
|
753
886
|
for (const [name, tool] of this.tools.entries()) {
|
|
754
|
-
|
|
887
|
+
const toolDef = {
|
|
755
888
|
name,
|
|
756
889
|
description: tool.description,
|
|
757
890
|
inputSchema: tool.inputSchema || {
|
|
758
891
|
type: "object",
|
|
759
892
|
properties: {}
|
|
760
893
|
}
|
|
761
|
-
}
|
|
894
|
+
};
|
|
895
|
+
if (tool._meta && Object.keys(tool._meta).length > 0) {
|
|
896
|
+
toolDef._meta = tool._meta;
|
|
897
|
+
}
|
|
898
|
+
tools.push(toolDef);
|
|
762
899
|
}
|
|
763
900
|
return {
|
|
764
901
|
tools
|
|
@@ -789,7 +926,7 @@ var MCPServer = class {
|
|
|
789
926
|
} else {
|
|
790
927
|
formattedResult = String(result);
|
|
791
928
|
}
|
|
792
|
-
|
|
929
|
+
const response = {
|
|
793
930
|
content: [
|
|
794
931
|
{
|
|
795
932
|
type: "text",
|
|
@@ -797,6 +934,10 @@ var MCPServer = class {
|
|
|
797
934
|
}
|
|
798
935
|
]
|
|
799
936
|
};
|
|
937
|
+
if (tool._meta && Object.keys(tool._meta).length > 0) {
|
|
938
|
+
response._meta = tool._meta;
|
|
939
|
+
}
|
|
940
|
+
return response;
|
|
800
941
|
} catch (error) {
|
|
801
942
|
return {
|
|
802
943
|
content: [
|
|
@@ -835,12 +976,20 @@ var MCPServer = class {
|
|
|
835
976
|
}
|
|
836
977
|
try {
|
|
837
978
|
const result = await resource.method.call(resource.instance);
|
|
979
|
+
let text;
|
|
980
|
+
if (typeof result === "string") {
|
|
981
|
+
text = result;
|
|
982
|
+
} else if (result && typeof result === "object" && "text" in result) {
|
|
983
|
+
text = result.text;
|
|
984
|
+
} else {
|
|
985
|
+
text = JSON.stringify(result, null, 2);
|
|
986
|
+
}
|
|
838
987
|
return {
|
|
839
988
|
contents: [
|
|
840
989
|
{
|
|
841
990
|
uri,
|
|
842
991
|
mimeType: resource.mimeType,
|
|
843
|
-
text
|
|
992
|
+
text
|
|
844
993
|
}
|
|
845
994
|
]
|
|
846
995
|
};
|
|
@@ -986,16 +1135,19 @@ var MCPServer = class {
|
|
|
986
1135
|
if (inputClass) {
|
|
987
1136
|
inputSchema = classToJsonSchemaWithConstraints(inputClass);
|
|
988
1137
|
}
|
|
1138
|
+
const toolMeta = Reflect.getMetadata?.("tool:meta", method) || {};
|
|
989
1139
|
this.tools.set(methodMeta.toolName, {
|
|
990
1140
|
name: methodMeta.toolName,
|
|
991
1141
|
description: methodMeta.toolDescription || "",
|
|
992
1142
|
inputSchema,
|
|
993
1143
|
method,
|
|
994
1144
|
instance,
|
|
995
|
-
propertyKey
|
|
1145
|
+
propertyKey,
|
|
1146
|
+
_meta: Object.keys(toolMeta).length > 0 ? toolMeta : void 0
|
|
996
1147
|
});
|
|
997
1148
|
if (this.logging) {
|
|
998
|
-
|
|
1149
|
+
const hasUi = toolMeta["ui/resourceUri"] ? " (with UI)" : "";
|
|
1150
|
+
this.logger.debug(`Registered tool: ${methodMeta.toolName}${inputClass ? " (class-based schema)" : ""}${hasUi}`);
|
|
999
1151
|
}
|
|
1000
1152
|
}
|
|
1001
1153
|
const promptMethods = getDecoratedMethods(cls, "prompt:name");
|
|
@@ -1048,6 +1200,53 @@ var MCPServer = class {
|
|
|
1048
1200
|
}
|
|
1049
1201
|
}
|
|
1050
1202
|
/**
|
|
1203
|
+
* Load UI manifest and auto-register resources for pre-built @UIApp components.
|
|
1204
|
+
* The manifest is generated by `leanmcp dev` or `leanmcp start` commands.
|
|
1205
|
+
*/
|
|
1206
|
+
async loadUIManifest() {
|
|
1207
|
+
try {
|
|
1208
|
+
const manifestPath = path.join(process.cwd(), "dist", "ui-manifest.json");
|
|
1209
|
+
if (!fs.existsSync(manifestPath)) {
|
|
1210
|
+
return;
|
|
1211
|
+
}
|
|
1212
|
+
const manifest = JSON.parse(fs.readFileSync(manifestPath, "utf-8"));
|
|
1213
|
+
for (const [uri, htmlPath] of Object.entries(manifest)) {
|
|
1214
|
+
if (this.resources.has(uri)) {
|
|
1215
|
+
if (this.logging) {
|
|
1216
|
+
this.logger.debug(`Skipping UI resource ${uri} - already registered`);
|
|
1217
|
+
}
|
|
1218
|
+
continue;
|
|
1219
|
+
}
|
|
1220
|
+
if (!fs.existsSync(htmlPath)) {
|
|
1221
|
+
if (this.logging) {
|
|
1222
|
+
this.logger.warn(`UI HTML file not found: ${htmlPath}`);
|
|
1223
|
+
}
|
|
1224
|
+
continue;
|
|
1225
|
+
}
|
|
1226
|
+
const html = fs.readFileSync(htmlPath, "utf-8");
|
|
1227
|
+
this.resources.set(uri, {
|
|
1228
|
+
uri,
|
|
1229
|
+
name: uri.replace("ui://", "").replace(/\//g, "-"),
|
|
1230
|
+
description: `Auto-generated UI resource from pre-built HTML`,
|
|
1231
|
+
mimeType: "text/html;profile=mcp-app",
|
|
1232
|
+
inputSchema: void 0,
|
|
1233
|
+
method: /* @__PURE__ */ __name(async () => ({
|
|
1234
|
+
text: html
|
|
1235
|
+
}), "method"),
|
|
1236
|
+
instance: null,
|
|
1237
|
+
propertyKey: "getUI"
|
|
1238
|
+
});
|
|
1239
|
+
if (this.logging) {
|
|
1240
|
+
this.logger.debug(`Registered UI resource from manifest: ${uri}`);
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
} catch (error) {
|
|
1244
|
+
if (this.logging) {
|
|
1245
|
+
this.logger.warn(`Failed to load UI manifest: ${error.message}`);
|
|
1246
|
+
}
|
|
1247
|
+
}
|
|
1248
|
+
}
|
|
1249
|
+
/**
|
|
1051
1250
|
* Get the underlying MCP SDK Server instance
|
|
1052
1251
|
* Attaches waitForInit method for HTTP server initialization
|
|
1053
1252
|
*/
|
package/package.json
CHANGED
|
@@ -1,71 +1,71 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@leanmcp/core",
|
|
3
|
-
"version": "0.3.
|
|
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
|
-
"ajv": "^8.12.0",
|
|
29
|
-
"dotenv": "^16.3.1",
|
|
30
|
-
"reflect-metadata": "^0.2.1"
|
|
31
|
-
},
|
|
32
|
-
"peerDependencies": {
|
|
33
|
-
"cors": "^2.8.5",
|
|
34
|
-
"express": "^5.0.0"
|
|
35
|
-
},
|
|
36
|
-
"peerDependenciesMeta": {
|
|
37
|
-
"express": {
|
|
38
|
-
"optional": true
|
|
39
|
-
},
|
|
40
|
-
"cors": {
|
|
41
|
-
"optional": true
|
|
42
|
-
}
|
|
43
|
-
},
|
|
44
|
-
"devDependencies": {
|
|
45
|
-
"@types/cors": "^2.8.0",
|
|
46
|
-
"@types/express": "^5.0.0",
|
|
47
|
-
"@types/node": "^20.0.0"
|
|
48
|
-
},
|
|
49
|
-
"repository": {
|
|
50
|
-
"type": "git",
|
|
51
|
-
"url": "git+https://github.com/LeanMCP/leanmcp-sdk.git",
|
|
52
|
-
"directory": "packages/core"
|
|
53
|
-
},
|
|
54
|
-
"homepage": "https://github.com/LeanMCP/leanmcp-sdk#readme",
|
|
55
|
-
"bugs": {
|
|
56
|
-
"url": "https://github.com/LeanMCP/leanmcp-sdk/issues"
|
|
57
|
-
},
|
|
58
|
-
"keywords": [
|
|
59
|
-
"mcp",
|
|
60
|
-
"model-context-protocol",
|
|
61
|
-
"typescript",
|
|
62
|
-
"decorators",
|
|
63
|
-
"server",
|
|
64
|
-
"runtime"
|
|
65
|
-
],
|
|
66
|
-
"author": "LeanMCP <admin@leanmcp.com>",
|
|
67
|
-
"license": "MIT",
|
|
68
|
-
"publishConfig": {
|
|
69
|
-
"access": "public"
|
|
70
|
-
}
|
|
71
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@leanmcp/core",
|
|
3
|
+
"version": "0.3.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
|
+
"ajv": "^8.12.0",
|
|
29
|
+
"dotenv": "^16.3.1",
|
|
30
|
+
"reflect-metadata": "^0.2.1"
|
|
31
|
+
},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"cors": "^2.8.5",
|
|
34
|
+
"express": "^5.0.0"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"express": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"cors": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/cors": "^2.8.0",
|
|
46
|
+
"@types/express": "^5.0.0",
|
|
47
|
+
"@types/node": "^20.0.0"
|
|
48
|
+
},
|
|
49
|
+
"repository": {
|
|
50
|
+
"type": "git",
|
|
51
|
+
"url": "git+https://github.com/LeanMCP/leanmcp-sdk.git",
|
|
52
|
+
"directory": "packages/core"
|
|
53
|
+
},
|
|
54
|
+
"homepage": "https://github.com/LeanMCP/leanmcp-sdk#readme",
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/LeanMCP/leanmcp-sdk/issues"
|
|
57
|
+
},
|
|
58
|
+
"keywords": [
|
|
59
|
+
"mcp",
|
|
60
|
+
"model-context-protocol",
|
|
61
|
+
"typescript",
|
|
62
|
+
"decorators",
|
|
63
|
+
"server",
|
|
64
|
+
"runtime"
|
|
65
|
+
],
|
|
66
|
+
"author": "LeanMCP <admin@leanmcp.com>",
|
|
67
|
+
"license": "MIT",
|
|
68
|
+
"publishConfig": {
|
|
69
|
+
"access": "public"
|
|
70
|
+
}
|
|
71
|
+
}
|