toolception 0.2.3 → 0.2.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FastifyTransport.d.ts","sourceRoot":"","sources":["../../src/http/FastifyTransport.ts"],"names":[],"mappings":"AAAA,OAAgB,EACd,KAAK,eAAe,EAGrB,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAOtB;IACF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAG3B;IACF,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IAGvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAIvB;gBAGH,cAAc,EAAE,kBAAkB,EAClC,YAAY,EAAE,MAAM;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,YAAY,EAAE,kBAAkB,CAAA;KAAE,EAC3E,OAAO,GAAE,uBAA4B,EACrC,YAAY,CAAC,EAAE,MAAM;IAeV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"FastifyTransport.d.ts","sourceRoot":"","sources":["../../src/http/FastifyTransport.ts"],"names":[],"mappings":"AAAA,OAAgB,EACd,KAAK,eAAe,EAGrB,MAAM,SAAS,CAAC;AAGjB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAIxE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB,GAAG,CAAC,EAAE,eAAe,CAAC;CACvB;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAOtB;IACF,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAqB;IACpD,OAAO,CAAC,QAAQ,CAAC,YAAY,CAG3B;IACF,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAS;IAGvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAIvB;gBAGH,cAAc,EAAE,kBAAkB,EAClC,YAAY,EAAE,MAAM;QAAE,MAAM,EAAE,SAAS,CAAC;QAAC,YAAY,EAAE,kBAAkB,CAAA;KAAE,EAC3E,OAAO,GAAE,uBAA4B,EACrC,YAAY,CAAC,EAAE,MAAM;IAeV,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA8LtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAOnC"}
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { z as
|
|
1
|
+
import { z as f } from "zod";
|
|
2
2
|
import p from "fastify";
|
|
3
3
|
import A from "@fastify/cors";
|
|
4
4
|
import { randomUUID as m } from "node:crypto";
|
|
5
|
-
import { StreamableHTTPServerTransport as
|
|
6
|
-
import { isInitializeRequest as
|
|
5
|
+
import { StreamableHTTPServerTransport as w } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
6
|
+
import { isInitializeRequest as b } from "@modelcontextprotocol/sdk/types.js";
|
|
7
7
|
const g = {
|
|
8
8
|
dynamic: [
|
|
9
9
|
"dynamic-tool-discovery",
|
|
@@ -351,12 +351,12 @@ class C {
|
|
|
351
351
|
return this.enableToolsets(e);
|
|
352
352
|
}
|
|
353
353
|
}
|
|
354
|
-
function
|
|
354
|
+
function I(a, e, s) {
|
|
355
355
|
const t = s?.mode ?? "DYNAMIC";
|
|
356
356
|
a.tool(
|
|
357
357
|
"enable_toolset",
|
|
358
358
|
"Enable a toolset by name",
|
|
359
|
-
{ name:
|
|
359
|
+
{ name: f.string().describe("Toolset name") },
|
|
360
360
|
async (o) => {
|
|
361
361
|
const { name: r } = o, i = await e.enableToolset(r);
|
|
362
362
|
return {
|
|
@@ -366,7 +366,7 @@ function M(a, e, s) {
|
|
|
366
366
|
), a.tool(
|
|
367
367
|
"disable_toolset",
|
|
368
368
|
"Disable a toolset by name (state only)",
|
|
369
|
-
{ name:
|
|
369
|
+
{ name: f.string().describe("Toolset name") },
|
|
370
370
|
async (o) => {
|
|
371
371
|
const { name: r } = o, i = await e.disableToolset(r);
|
|
372
372
|
return {
|
|
@@ -401,7 +401,7 @@ function M(a, e, s) {
|
|
|
401
401
|
), a.tool(
|
|
402
402
|
"describe_toolset",
|
|
403
403
|
"Describe a toolset with definition, active status and tools",
|
|
404
|
-
{ name:
|
|
404
|
+
{ name: f.string().describe("Toolset name") },
|
|
405
405
|
async (o) => {
|
|
406
406
|
const { name: r } = o, i = e.getToolsetDefinition(r), l = e.getStatus().toolsetToTools;
|
|
407
407
|
if (!i)
|
|
@@ -461,7 +461,7 @@ class y {
|
|
|
461
461
|
onToolsListChanged: e.notifyToolsListChanged,
|
|
462
462
|
exposurePolicy: e.exposurePolicy,
|
|
463
463
|
toolRegistry: o
|
|
464
|
-
}), e.registerMetaTools !== !1 &&
|
|
464
|
+
}), e.registerMetaTools !== !1 && I(e.server, this.manager, { mode: this.mode });
|
|
465
465
|
const r = t.toolsets;
|
|
466
466
|
r === "ALL" ? this.manager.enableToolsets(this.resolver.getAvailableToolsets()) : Array.isArray(r) && r.length > 0 && this.manager.enableToolsets(r);
|
|
467
467
|
}
|
|
@@ -507,7 +507,7 @@ class y {
|
|
|
507
507
|
return this.manager;
|
|
508
508
|
}
|
|
509
509
|
}
|
|
510
|
-
class
|
|
510
|
+
class M {
|
|
511
511
|
constructor(e = {}) {
|
|
512
512
|
this.storage = /* @__PURE__ */ new Map(), this.maxSize = e.maxSize ?? 1e3, this.ttlMs = e.ttlMs ?? 1e3 * 60 * 60;
|
|
513
513
|
const s = e.pruneIntervalMs ?? 1e3 * 60 * 10;
|
|
@@ -549,7 +549,7 @@ class I {
|
|
|
549
549
|
}
|
|
550
550
|
class L {
|
|
551
551
|
constructor(e, s, t = {}, o) {
|
|
552
|
-
this.app = null, this.clientCache = new
|
|
552
|
+
this.app = null, this.clientCache = new M(), this.defaultManager = e, this.createBundle = s, this.options = {
|
|
553
553
|
host: t.host ?? "0.0.0.0",
|
|
554
554
|
port: t.port ?? 3e3,
|
|
555
555
|
basePath: t.basePath ?? "/",
|
|
@@ -578,23 +578,23 @@ class L {
|
|
|
578
578
|
const r = t.headers["mcp-client-id"]?.trim(), i = r && r.length > 0 ? r : `anon-${m()}`, l = !i.startsWith("anon-");
|
|
579
579
|
let n = l ? this.clientCache.get(i) : null;
|
|
580
580
|
if (!n) {
|
|
581
|
-
const h = this.createBundle();
|
|
581
|
+
const h = this.createBundle(), u = h.sessions;
|
|
582
582
|
n = {
|
|
583
583
|
server: h.server,
|
|
584
584
|
orchestrator: h.orchestrator,
|
|
585
|
-
sessions: /* @__PURE__ */ new Map()
|
|
585
|
+
sessions: u instanceof Map ? u : /* @__PURE__ */ new Map()
|
|
586
586
|
}, l && this.clientCache.set(i, n);
|
|
587
587
|
}
|
|
588
588
|
const c = t.headers["mcp-session-id"];
|
|
589
589
|
let d;
|
|
590
590
|
if (c && n.sessions.get(c))
|
|
591
591
|
d = n.sessions.get(c);
|
|
592
|
-
else if (!c &&
|
|
592
|
+
else if (!c && b(t.body)) {
|
|
593
593
|
const h = m();
|
|
594
|
-
d = new
|
|
594
|
+
d = new w({
|
|
595
595
|
sessionIdGenerator: () => h,
|
|
596
|
-
onsessioninitialized: (
|
|
597
|
-
n.sessions.set(
|
|
596
|
+
onsessioninitialized: (u) => {
|
|
597
|
+
n.sessions.set(u, d);
|
|
598
598
|
}
|
|
599
599
|
});
|
|
600
600
|
try {
|
|
@@ -647,11 +647,22 @@ class L {
|
|
|
647
647
|
id: null
|
|
648
648
|
};
|
|
649
649
|
const n = this.clientCache.get(i), c = n?.sessions.get(l);
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
650
|
+
if (!n || !c)
|
|
651
|
+
return o.code(404), {
|
|
652
|
+
jsonrpc: "2.0",
|
|
653
|
+
error: { code: -32e3, message: "Session not found or expired" },
|
|
654
|
+
id: null
|
|
655
|
+
};
|
|
656
|
+
try {
|
|
657
|
+
if (typeof c.close == "function")
|
|
658
|
+
try {
|
|
659
|
+
await c.close();
|
|
660
|
+
} catch {
|
|
661
|
+
}
|
|
662
|
+
} finally {
|
|
663
|
+
c?.sessionId ? n.sessions.delete(c.sessionId) : n.sessions.delete(l);
|
|
664
|
+
}
|
|
665
|
+
return o.code(204).send(), o;
|
|
655
666
|
}
|
|
656
667
|
), this.options.app || await e.listen({ host: this.options.host, port: this.options.port }), this.app = e;
|
|
657
668
|
}
|
|
@@ -659,7 +670,7 @@ class L {
|
|
|
659
670
|
this.app && (this.options.app || await this.app.close(), this.app = null);
|
|
660
671
|
}
|
|
661
672
|
}
|
|
662
|
-
async function
|
|
673
|
+
async function O(a) {
|
|
663
674
|
const e = a.startup?.mode ?? "DYNAMIC";
|
|
664
675
|
if (typeof a.createServer != "function")
|
|
665
676
|
throw new Error("createMcpServer: `createServer` (factory) is required");
|
|
@@ -686,7 +697,9 @@ async function j(a) {
|
|
|
686
697
|
}), l = new L(
|
|
687
698
|
i.getManager(),
|
|
688
699
|
() => {
|
|
689
|
-
|
|
700
|
+
if (e === "STATIC")
|
|
701
|
+
return { server: s, orchestrator: i };
|
|
702
|
+
const n = a.createServer(), c = new y({
|
|
690
703
|
server: n,
|
|
691
704
|
catalog: a.catalog,
|
|
692
705
|
moduleLoaders: a.moduleLoaders,
|
|
@@ -712,6 +725,6 @@ async function j(a) {
|
|
|
712
725
|
};
|
|
713
726
|
}
|
|
714
727
|
export {
|
|
715
|
-
|
|
728
|
+
O as createMcpServer
|
|
716
729
|
};
|
|
717
730
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/mode/ModeResolver.ts","../src/mode/ModuleResolver.ts","../src/errors/ToolingError.ts","../src/core/ToolRegistry.ts","../src/core/DynamicToolManager.ts","../src/meta/registerMetaTools.ts","../src/core/ServerOrchestrator.ts","../src/session/ClientResourceCache.ts","../src/http/FastifyTransport.ts","../src/server/createMcpServer.ts"],"sourcesContent":["import type { Mode, ToolSetCatalog } from \"../types/index.js\";\n\ninterface ModeResolverKeys {\n dynamic?: string[]; // keys that, when present/true, enable dynamic mode\n toolsets?: string[]; // keys that carry comma-separated toolsets\n}\n\ninterface ModeResolverOptions {\n keys?: ModeResolverKeys;\n}\n\nconst DEFAULT_KEYS: Required<ModeResolverKeys> = {\n dynamic: [\n \"dynamic-tool-discovery\",\n \"dynamicToolDiscovery\",\n \"DYNAMIC_TOOL_DISCOVERY\",\n ],\n toolsets: [\"tool-sets\", \"toolSets\", \"FMP_TOOL_SETS\"],\n};\n\nexport class ToolsetValidator {\n private readonly keys: Required<ModeResolverKeys>;\n\n constructor(options: ModeResolverOptions = {}) {\n this.keys = {\n dynamic: options.keys?.dynamic ?? DEFAULT_KEYS.dynamic,\n toolsets: options.keys?.toolsets ?? DEFAULT_KEYS.toolsets,\n };\n }\n\n public resolveMode(\n env?: Record<string, string | undefined>,\n args?: Record<string, unknown>\n ): Mode | null {\n // Check args first\n if (this.isDynamicEnabled(args)) return \"DYNAMIC\";\n\n const toolsetsFromArgs = this.getToolsetsString(args);\n if (toolsetsFromArgs) return \"STATIC\";\n\n // Check env next\n if (this.isDynamicEnabled(env)) return \"DYNAMIC\";\n\n const toolsetsFromEnv = this.getToolsetsString(env);\n if (toolsetsFromEnv) return \"STATIC\";\n\n return null; // no override\n }\n\n public parseCommaSeparatedToolSets(\n input: string,\n catalog: ToolSetCatalog\n ): string[] {\n if (!input || typeof input !== \"string\") return [];\n const raw = input\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n const valid = new Set(Object.keys(catalog));\n const result: string[] = [];\n for (const name of raw) {\n if (valid.has(name)) result.push(name);\n else\n console.warn(\n `Invalid toolset '${name}' ignored. Available: ${Array.from(\n valid\n ).join(\", \")}`\n );\n }\n return result;\n }\n\n public getModulesForToolSets(\n toolsets: string[],\n catalog: ToolSetCatalog\n ): string[] {\n const modules = new Set<string>();\n for (const name of toolsets) {\n const def = catalog[name];\n if (!def) continue;\n (def.modules || []).forEach((m) => modules.add(m));\n }\n return Array.from(modules);\n }\n\n public validateToolsetName(\n name: unknown,\n catalog: ToolSetCatalog\n ): { isValid: boolean; sanitized?: string; error?: string } {\n if (!name || typeof name !== \"string\") {\n return {\n isValid: false,\n error: `Invalid toolset name provided. Must be a non-empty string. Available toolsets: ${Object.keys(\n catalog\n ).join(\", \")}`,\n };\n }\n const sanitized = name.trim();\n if (sanitized.length === 0) {\n return {\n isValid: false,\n error: `Empty toolset name provided. Available toolsets: ${Object.keys(\n catalog\n ).join(\", \")}`,\n };\n }\n if (!catalog[sanitized]) {\n return {\n isValid: false,\n error: `Toolset '${sanitized}' not found. Available toolsets: ${Object.keys(\n catalog\n ).join(\", \")}`,\n };\n }\n return { isValid: true, sanitized };\n }\n\n public validateToolsetModules(\n toolsetNames: string[],\n catalog: ToolSetCatalog\n ): { isValid: boolean; modules?: string[]; error?: string } {\n try {\n const modules = this.getModulesForToolSets(toolsetNames, catalog);\n if (!modules || modules.length === 0) {\n return {\n isValid: false,\n error: `No modules found for toolsets: ${toolsetNames.join(\", \")}`,\n };\n }\n return { isValid: true, modules };\n } catch (error) {\n return {\n isValid: false,\n error: `Error resolving modules for ${toolsetNames.join(\", \")}: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n };\n }\n }\n\n private isDynamicEnabled(\n source?: Record<string, unknown> | Record<string, string | undefined>\n ): boolean {\n if (!source) return false;\n for (const key of this.keys.dynamic) {\n const value = (source as any)[key];\n if (value === true) return true;\n if (typeof value === \"string\") {\n const v = value.trim().toLowerCase();\n if (v === \"true\") return true;\n }\n }\n return false;\n }\n\n private getToolsetsString(\n source?: Record<string, unknown> | Record<string, string | undefined>\n ): string | undefined {\n if (!source) return undefined;\n for (const key of this.keys.toolsets) {\n const value = (source as any)[key];\n if (typeof value === \"string\" && value.trim().length > 0)\n return value as string;\n }\n return undefined;\n }\n}\n","import type {\n ToolSetCatalog,\n ToolSetDefinition,\n McpToolDefinition,\n ModuleLoader,\n} from \"../types/index.js\";\n\nexport interface ModuleResolverOptions {\n catalog: ToolSetCatalog;\n moduleLoaders?: Record<string, ModuleLoader>;\n}\n\nexport class ModuleResolver {\n private readonly catalog: ToolSetCatalog;\n private readonly moduleLoaders: Record<string, ModuleLoader>;\n\n constructor(options: ModuleResolverOptions) {\n this.catalog = options.catalog;\n this.moduleLoaders = options.moduleLoaders ?? {};\n }\n\n public getAvailableToolsets(): string[] {\n return Object.keys(this.catalog);\n }\n\n public getToolsetDefinition(name: string): ToolSetDefinition | undefined {\n return this.catalog[name];\n }\n\n public validateToolsetName(name: unknown): {\n isValid: boolean;\n sanitized?: string;\n error?: string;\n } {\n if (!name || typeof name !== \"string\") {\n return {\n isValid: false,\n error: `Invalid toolset name provided. Must be a non-empty string. Available toolsets: ${this.getAvailableToolsets().join(\n \", \"\n )}`,\n };\n }\n const sanitized = name.trim();\n if (sanitized.length === 0) {\n return {\n isValid: false,\n error: `Empty toolset name provided. Available toolsets: ${this.getAvailableToolsets().join(\n \", \"\n )}`,\n };\n }\n if (!this.catalog[sanitized]) {\n return {\n isValid: false,\n error: `Toolset '${sanitized}' not found. Available toolsets: ${this.getAvailableToolsets().join(\n \", \"\n )}`,\n };\n }\n return { isValid: true, sanitized };\n }\n\n public async resolveToolsForToolsets(\n toolsets: string[],\n context?: unknown\n ): Promise<McpToolDefinition[]> {\n const collected: McpToolDefinition[] = [];\n for (const name of toolsets) {\n const def = this.catalog[name];\n if (!def) continue;\n if (Array.isArray(def.tools) && def.tools.length > 0) {\n collected.push(...def.tools);\n }\n if (Array.isArray(def.modules) && def.modules.length > 0) {\n for (const modKey of def.modules) {\n const loader = this.moduleLoaders[modKey];\n if (!loader) continue;\n try {\n const loaded = await loader(context);\n if (Array.isArray(loaded) && loaded.length > 0) {\n collected.push(...loaded);\n }\n } catch (err) {\n console.warn(\n `Module loader '${modKey}' failed for toolset '${name}':`,\n err\n );\n }\n }\n }\n }\n return collected;\n }\n}\n","import type { ToolingErrorCode } from \"../types/index.js\";\n\nexport class ToolingError extends Error {\n public readonly code: ToolingErrorCode;\n public readonly details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: ToolingErrorCode,\n details?: Record<string, unknown>,\n _options?: unknown\n ) {\n super(message);\n this.name = \"ToolingError\";\n this.code = code;\n this.details = details;\n }\n}\n","import type { McpToolDefinition } from \"../types/index.js\";\nimport { ToolingError } from \"../errors/ToolingError.js\";\n\nexport interface ToolRegistryOptions {\n namespaceWithToolset?: boolean;\n}\n\nexport class ToolRegistry {\n private readonly options: Required<ToolRegistryOptions>;\n private readonly names = new Set<string>();\n private readonly toolsetToNames = new Map<string, Set<string>>();\n\n constructor(options: ToolRegistryOptions = {}) {\n this.options = {\n namespaceWithToolset: options.namespaceWithToolset ?? true,\n };\n }\n\n public getSafeName(toolsetKey: string, toolName: string): string {\n if (!this.options.namespaceWithToolset) return toolName;\n if (toolName.startsWith(`${toolsetKey}.`)) return toolName;\n return `${toolsetKey}.${toolName}`;\n }\n\n public has(name: string): boolean {\n return this.names.has(name);\n }\n\n public add(name: string): void {\n if (this.names.has(name)) {\n throw new ToolingError(\n `Tool name collision: '${name}' already registered`,\n \"E_TOOL_NAME_CONFLICT\"\n );\n }\n this.names.add(name);\n }\n\n public addForToolset(toolsetKey: string, name: string): void {\n this.add(name);\n const set = this.toolsetToNames.get(toolsetKey) ?? new Set<string>();\n set.add(name);\n this.toolsetToNames.set(toolsetKey, set);\n }\n\n public mapAndValidate(\n toolsetKey: string,\n tools: McpToolDefinition[]\n ): McpToolDefinition[] {\n return tools.map((t) => {\n const safe = this.getSafeName(toolsetKey, t.name);\n if (this.has(safe)) {\n throw new ToolingError(\n `Tool name collision for '${safe}'`,\n \"E_TOOL_NAME_CONFLICT\"\n );\n }\n return { ...t, name: safe };\n });\n }\n\n public list(): string[] {\n return Array.from(this.names);\n }\n\n public listByToolset(): Record<string, string[]> {\n const result: Record<string, string[]> = {};\n for (const [k, v] of this.toolsetToNames.entries()) {\n result[k] = Array.from(v);\n }\n return result;\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type {\n ExposurePolicy,\n McpToolDefinition,\n ToolSetDefinition,\n ToolingErrorCode,\n} from \"../types/index.js\";\nimport { ModuleResolver } from \"../mode/ModuleResolver.js\";\nimport { ToolRegistry } from \"./ToolRegistry.js\";\n\nexport interface DynamicToolManagerOptions {\n server: McpServer;\n resolver: ModuleResolver;\n context?: unknown;\n onToolsListChanged?: () => Promise<void> | void;\n exposurePolicy?: ExposurePolicy;\n toolRegistry?: ToolRegistry;\n}\n\nexport class DynamicToolManager {\n private readonly server: McpServer;\n private readonly resolver: ModuleResolver;\n private readonly context?: unknown;\n private readonly onToolsListChanged?: () => Promise<void> | void;\n private readonly exposurePolicy?: ExposurePolicy;\n private readonly toolRegistry: ToolRegistry;\n\n private readonly activeToolsets = new Set<string>();\n\n constructor(options: DynamicToolManagerOptions) {\n this.server = options.server;\n this.resolver = options.resolver;\n this.context = options.context;\n this.onToolsListChanged = options.onToolsListChanged;\n this.exposurePolicy = options.exposurePolicy;\n this.toolRegistry =\n options.toolRegistry ?? new ToolRegistry({ namespaceWithToolset: true });\n }\n\n public getAvailableToolsets(): string[] {\n return this.resolver.getAvailableToolsets();\n }\n\n public getActiveToolsets(): string[] {\n return Array.from(this.activeToolsets);\n }\n\n public getToolsetDefinition(name: string): ToolSetDefinition | undefined {\n return this.resolver.getToolsetDefinition(name);\n }\n\n public isActive(name: string): boolean {\n return this.activeToolsets.has(name);\n }\n\n public async enableToolset(\n toolsetName: string\n ): Promise<{ success: boolean; message: string }> {\n const validation = this.resolver.validateToolsetName(toolsetName);\n if (!validation.isValid || !validation.sanitized) {\n return {\n success: false,\n message: validation.error || \"Unknown validation error\",\n };\n }\n const sanitized = validation.sanitized;\n if (this.activeToolsets.has(sanitized)) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is already enabled.`,\n };\n }\n\n try {\n const resolvedTools = await this.resolver.resolveToolsForToolsets(\n [sanitized],\n this.context\n );\n\n // Exposure policy checks\n if (\n this.exposurePolicy?.allowlist &&\n !this.exposurePolicy.allowlist.includes(sanitized)\n ) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is not allowed by policy.`,\n };\n }\n if (\n this.exposurePolicy?.denylist &&\n this.exposurePolicy.denylist.includes(sanitized)\n ) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is denied by policy.`,\n };\n }\n if (this.exposurePolicy?.maxActiveToolsets !== undefined) {\n const next = this.activeToolsets.size + 1;\n if (next > this.exposurePolicy.maxActiveToolsets) {\n this.exposurePolicy.onLimitExceeded?.(\n [sanitized],\n Array.from(this.activeToolsets)\n );\n return {\n success: false,\n message: `Activation exceeds maxActiveToolsets (${this.exposurePolicy.maxActiveToolsets}).`,\n };\n }\n }\n\n // Register all resolved tools (direct + module-derived)\n if (resolvedTools && resolvedTools.length > 0) {\n const mapped = this.toolRegistry.mapAndValidate(\n sanitized,\n resolvedTools\n );\n this.registerDirectTools(mapped, sanitized);\n }\n\n // Track state (modules no longer tracked)\n this.activeToolsets.add(sanitized);\n\n // Notify list change\n try {\n await this.onToolsListChanged?.();\n } catch (err) {\n console.warn(`Failed to send tool list change notification:`, err);\n }\n\n return {\n success: true,\n message: `Toolset '${sanitized}' enabled successfully. Registered ${\n resolvedTools?.length ?? 0\n } tools.`,\n };\n } catch (error) {\n this.activeToolsets.delete(sanitized);\n return {\n success: false,\n message: `Failed to enable toolset '${sanitized}': ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n };\n }\n }\n\n public async disableToolset(\n toolsetName: string\n ): Promise<{ success: boolean; message: string }> {\n const validation = this.resolver.validateToolsetName(toolsetName);\n if (!validation.isValid || !validation.sanitized) {\n const activeToolsets =\n Array.from(this.activeToolsets).join(\", \") || \"none\";\n const base = validation.error || \"Unknown validation error\";\n return {\n success: false,\n message: `${base} Active toolsets: ${activeToolsets}`,\n };\n }\n const sanitized = validation.sanitized;\n if (!this.activeToolsets.has(sanitized)) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is not currently active. Active toolsets: ${\n Array.from(this.activeToolsets).join(\", \") || \"none\"\n }`,\n };\n }\n\n // State-only disable; no unregistration support in MCP\n this.activeToolsets.delete(sanitized);\n\n try {\n await this.onToolsListChanged?.();\n } catch (err) {\n console.warn(`Failed to send tool list change notification:`, err);\n }\n\n return {\n success: true,\n message: `Toolset '${sanitized}' disabled successfully. Individual tools remain registered due to MCP limitations.`,\n };\n }\n\n public getStatus() {\n return {\n availableToolsets: this.getAvailableToolsets(),\n activeToolsets: this.getActiveToolsets(),\n registeredModules: [],\n totalToolsets: this.getAvailableToolsets().length,\n activeCount: this.activeToolsets.size,\n tools: this.toolRegistry.list(),\n toolsetToTools: this.toolRegistry.listByToolset(),\n };\n }\n\n public async enableToolsets(toolsetNames: string[]): Promise<{\n success: boolean;\n results: Array<{\n name: string;\n success: boolean;\n message: string;\n code?: ToolingErrorCode;\n }>;\n message: string;\n }> {\n const results: Array<{\n name: string;\n success: boolean;\n message: string;\n code?: ToolingErrorCode;\n }> = [];\n for (const name of toolsetNames) {\n try {\n const res = await this.enableToolset(name);\n results.push({ name, ...res });\n } catch (err) {\n results.push({\n name,\n success: false,\n message: err instanceof Error ? err.message : \"Unknown error\",\n code: \"E_INTERNAL\",\n });\n }\n }\n const successAll = results.every((r) => r.success);\n const message = successAll\n ? \"All toolsets enabled\"\n : \"Some toolsets failed to enable\";\n if (results.length > 0) {\n try {\n await this.onToolsListChanged?.();\n } catch {}\n }\n return { success: successAll, results, message };\n }\n\n private registerDirectTools(\n tools: McpToolDefinition[],\n toolsetKey?: string\n ): void {\n for (const tool of tools) {\n try {\n this.server.tool(\n tool.name,\n tool.description,\n tool.inputSchema as any,\n async (args: any) => {\n return await tool.handler(args);\n }\n );\n if (toolsetKey) this.toolRegistry.addForToolset(toolsetKey, tool.name);\n else this.toolRegistry.add(tool.name);\n } catch (err) {\n console.error(`Failed to register direct tool '${tool.name}':`, err);\n throw err;\n }\n }\n }\n\n public async enableAllToolsets(): Promise<{\n success: boolean;\n results: Array<{\n name: string;\n success: boolean;\n message: string;\n code?: ToolingErrorCode;\n }>;\n message: string;\n }> {\n const all = this.getAvailableToolsets();\n return this.enableToolsets(all);\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Mode } from \"../types/index.js\";\nimport { z } from \"zod\";\nimport { DynamicToolManager } from \"../core/DynamicToolManager.js\";\n\nexport function registerMetaTools(\n server: McpServer,\n manager: DynamicToolManager,\n options?: { mode?: Exclude<Mode, \"ALL\"> }\n): void {\n const mode = options?.mode ?? \"DYNAMIC\";\n // list_tools is always available\n server.tool(\n \"enable_toolset\",\n \"Enable a toolset by name\",\n { name: z.string().describe(\"Toolset name\") },\n async (args: any) => {\n const { name } = args as { name: string };\n const result = await manager.enableToolset(name);\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n };\n }\n );\n\n server.tool(\n \"disable_toolset\",\n \"Disable a toolset by name (state only)\",\n { name: z.string().describe(\"Toolset name\") },\n async (args: any) => {\n const { name } = args as { name: string };\n const result = await manager.disableToolset(name);\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n };\n }\n );\n\n if (mode === \"DYNAMIC\") {\n server.tool(\n \"list_toolsets\",\n \"List available toolsets with active status and definitions\",\n {},\n async () => {\n const available = manager.getAvailableToolsets();\n const byToolset = manager.getStatus().toolsetToTools;\n const items = available.map((key) => {\n const def = manager.getToolsetDefinition(key);\n return {\n key,\n active: manager.isActive(key),\n definition: def\n ? {\n name: def.name,\n description: def.description,\n modules: def.modules ?? [],\n decisionCriteria: def.decisionCriteria ?? undefined,\n }\n : null,\n tools: byToolset[key] ?? [],\n };\n });\n return {\n content: [\n { type: \"text\", text: JSON.stringify({ toolsets: items }) },\n ],\n };\n }\n );\n\n server.tool(\n \"describe_toolset\",\n \"Describe a toolset with definition, active status and tools\",\n { name: z.string().describe(\"Toolset name\") },\n async (args: any) => {\n const { name } = args as { name: string };\n const def = manager.getToolsetDefinition(name);\n const byToolset = manager.getStatus().toolsetToTools;\n if (!def) {\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({ error: `Unknown toolset '${name}'` }),\n },\n ],\n };\n }\n const payload = {\n key: name,\n active: manager.isActive(name),\n definition: {\n name: def.name,\n description: def.description,\n modules: def.modules ?? [],\n decisionCriteria: def.decisionCriteria ?? undefined,\n },\n tools: byToolset[name] ?? [],\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(payload) }],\n };\n }\n );\n }\n\n server.tool(\n \"list_tools\",\n \"List currently registered tool names (best effort)\",\n {},\n async () => {\n const status = manager.getStatus();\n const payload = {\n tools: status.tools,\n toolsetToTools: status.toolsetToTools,\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(payload) }],\n };\n }\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { ToolsetValidator } from \"../mode/ToolsetValidator.js\";\nimport { ModuleResolver } from \"../mode/ModuleResolver.js\";\nimport { DynamicToolManager } from \"./DynamicToolManager.js\";\nimport { registerMetaTools } from \"../meta/registerMetaTools.js\";\nimport type { ExposurePolicy, Mode, ToolSetCatalog } from \"../types/index.js\";\nimport { ToolRegistry } from \"./ToolRegistry.js\";\n\nexport interface ServerOrchestratorOptions {\n server: McpServer;\n catalog: ToolSetCatalog;\n moduleLoaders?: Record<string, any>;\n exposurePolicy?: ExposurePolicy;\n context?: unknown;\n notifyToolsListChanged?: () => Promise<void> | void;\n startup?: { mode?: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" };\n registerMetaTools?: boolean;\n}\n\nexport class ServerOrchestrator {\n private readonly mode: Exclude<Mode, \"ALL\">;\n private readonly resolver: ModuleResolver;\n private readonly manager: DynamicToolManager;\n private readonly toolsetValidator: ToolsetValidator;\n\n constructor(options: ServerOrchestratorOptions) {\n this.toolsetValidator = new ToolsetValidator();\n const startup = options.startup ?? {};\n const resolved = this.resolveStartupConfig(startup, options.catalog);\n this.mode = resolved.mode;\n this.resolver = new ModuleResolver({\n catalog: options.catalog,\n moduleLoaders: options.moduleLoaders,\n });\n const toolRegistry = new ToolRegistry({\n namespaceWithToolset:\n options.exposurePolicy?.namespaceToolsWithSetKey ?? true,\n });\n this.manager = new DynamicToolManager({\n server: options.server,\n resolver: this.resolver,\n context: options.context,\n onToolsListChanged: options.notifyToolsListChanged,\n exposurePolicy: options.exposurePolicy,\n toolRegistry,\n });\n\n // Register meta-tools only if requested (default true)\n if (options.registerMetaTools !== false) {\n registerMetaTools(options.server, this.manager, { mode: this.mode });\n }\n\n // Startup behavior\n const initial = resolved.toolsets;\n if (initial === \"ALL\") {\n void this.manager.enableToolsets(this.resolver.getAvailableToolsets());\n } else if (Array.isArray(initial) && initial.length > 0) {\n void this.manager.enableToolsets(initial);\n }\n }\n\n private resolveStartupConfig(\n startup: { mode?: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" },\n catalog: ToolSetCatalog\n ): { mode: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" } {\n // Explicit mode dominates\n if (startup.mode) {\n if (startup.mode === \"DYNAMIC\" && startup.toolsets) {\n console.warn(\"startup.toolsets provided but ignored in DYNAMIC mode\");\n return { mode: \"DYNAMIC\" };\n }\n if (startup.mode === \"STATIC\") {\n if (startup.toolsets === \"ALL\")\n return { mode: \"STATIC\", toolsets: \"ALL\" };\n const names = Array.isArray(startup.toolsets) ? startup.toolsets : [];\n const valid: string[] = [];\n for (const name of names) {\n const { isValid, sanitized, error } =\n this.toolsetValidator.validateToolsetName(name, catalog);\n if (isValid && sanitized) valid.push(sanitized);\n else if (error) console.warn(error);\n }\n if (names.length > 0 && valid.length === 0) {\n throw new Error(\n \"STATIC mode requires valid toolsets or 'ALL'; none were valid\"\n );\n }\n return { mode: \"STATIC\", toolsets: valid };\n }\n return { mode: startup.mode };\n }\n\n // No explicit mode; infer from toolsets\n if (startup.toolsets === \"ALL\") return { mode: \"STATIC\", toolsets: \"ALL\" };\n if (Array.isArray(startup.toolsets) && startup.toolsets.length > 0) {\n const valid: string[] = [];\n for (const name of startup.toolsets) {\n const { isValid, sanitized, error } =\n this.toolsetValidator.validateToolsetName(name, catalog);\n if (isValid && sanitized) valid.push(sanitized);\n else if (error) console.warn(error);\n }\n if (valid.length === 0) {\n throw new Error(\n \"STATIC mode requires valid toolsets or 'ALL'; none were valid\"\n );\n }\n return { mode: \"STATIC\", toolsets: valid };\n }\n\n // Default\n return { mode: \"DYNAMIC\" };\n }\n\n public getMode(): Exclude<Mode, \"ALL\"> {\n return this.mode;\n }\n\n public getManager(): DynamicToolManager {\n return this.manager;\n }\n}\n","export interface ClientResourceCacheOptions {\n maxSize?: number;\n ttlMs?: number; // ms\n pruneIntervalMs?: number;\n}\n\ninterface Entry<T> {\n resource: T;\n lastAccessed: number;\n}\n\nexport class ClientResourceCache<T> {\n private storage = new Map<string, Entry<T>>();\n private maxSize: number;\n private ttlMs: number;\n // Use ReturnType<typeof setInterval> for cross-env typings without NodeJS namespace\n private pruneInterval?: ReturnType<typeof setInterval>;\n\n constructor(options: ClientResourceCacheOptions = {}) {\n this.maxSize = options.maxSize ?? 1000;\n this.ttlMs = options.ttlMs ?? 1000 * 60 * 60;\n const pruneEvery = options.pruneIntervalMs ?? 1000 * 60 * 10;\n this.pruneInterval = setInterval(() => this.pruneExpired(), pruneEvery);\n }\n\n public getEntryCount(): number {\n return this.storage.size;\n }\n\n public getMaxSize(): number {\n return this.maxSize;\n }\n\n public getTtl(): number {\n return this.ttlMs;\n }\n\n public get(key: string): T | null {\n const entry = this.storage.get(key);\n if (!entry) return null;\n if (Date.now() - entry.lastAccessed > this.ttlMs) {\n this.delete(key);\n return null;\n }\n entry.lastAccessed = Date.now();\n this.storage.delete(key);\n this.storage.set(key, entry);\n return entry.resource;\n }\n\n public set(key: string, resource: T): void {\n if (this.storage.size >= this.maxSize) {\n this.evictLeastRecentlyUsed();\n }\n const newEntry: Entry<T> = { resource, lastAccessed: Date.now() };\n this.storage.set(key, newEntry);\n }\n\n public delete(key: string): void {\n this.storage.delete(key);\n }\n\n public stop(): void {\n if (this.pruneInterval) {\n clearInterval(this.pruneInterval);\n this.pruneInterval = undefined;\n }\n }\n\n private evictLeastRecentlyUsed(): void {\n const lruKey = this.storage.keys().next().value as string | undefined;\n if (lruKey) {\n this.delete(lruKey);\n }\n }\n\n private pruneExpired(): void {\n const now = Date.now();\n for (const [key, entry] of this.storage.entries()) {\n if (now - entry.lastAccessed > this.ttlMs) {\n this.delete(key);\n }\n }\n }\n}\n","import Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport { randomUUID } from \"node:crypto\";\nimport type { DynamicToolManager } from \"../core/DynamicToolManager.js\";\nimport type { ServerOrchestrator } from \"../core/ServerOrchestrator.js\";\nimport { ClientResourceCache } from \"../session/ClientResourceCache.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { isInitializeRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nexport interface FastifyTransportOptions {\n host?: string;\n port?: number;\n basePath?: string; // e.g. \"/\" or \"/api\"\n cors?: boolean;\n logger?: boolean;\n // Optional DI: provide a Fastify instance (e.g., for tests). If provided, start() will not listen.\n app?: FastifyInstance;\n}\n\nexport class FastifyTransport {\n private readonly options: {\n host: string;\n port: number;\n basePath: string;\n cors: boolean;\n logger: boolean;\n app?: FastifyInstance;\n };\n private readonly defaultManager: DynamicToolManager;\n private readonly createBundle: () => {\n server: McpServer;\n orchestrator: ServerOrchestrator;\n };\n private app: FastifyInstance | null = null;\n private readonly configSchema?: object;\n\n // Per-client server bundles and per-client session transports\n private readonly clientCache = new ClientResourceCache<{\n server: McpServer;\n orchestrator: ServerOrchestrator;\n sessions: Map<string, StreamableHTTPServerTransport>;\n }>();\n\n constructor(\n defaultManager: DynamicToolManager,\n createBundle: () => { server: McpServer; orchestrator: ServerOrchestrator },\n options: FastifyTransportOptions = {},\n configSchema?: object\n ) {\n this.defaultManager = defaultManager;\n this.createBundle = createBundle;\n this.options = {\n host: options.host ?? \"0.0.0.0\",\n port: options.port ?? 3000,\n basePath: options.basePath ?? \"/\",\n cors: options.cors ?? true,\n logger: options.logger ?? false,\n app: options.app,\n };\n this.configSchema = configSchema;\n }\n\n public async start(): Promise<void> {\n if (this.app) return;\n const app = this.options.app ?? Fastify({ logger: this.options.logger });\n if (this.options.cors) {\n await app.register(cors, { origin: true });\n }\n\n const base = this.options.basePath.endsWith(\"/\")\n ? this.options.basePath.slice(0, -1)\n : this.options.basePath;\n\n app.get(`${base}/healthz`, async () => ({ ok: true }));\n\n app.get(`${base}/tools`, async () => this.defaultManager.getStatus());\n\n // Config discovery (placeholder schema)\n app.get(`${base}/.well-known/mcp-config`, async (_req, reply) => {\n reply.header(\"Content-Type\", \"application/schema+json; charset=utf-8\");\n const baseSchema = this.configSchema ?? {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n title: \"MCP Session Configuration\",\n description: \"Schema for the /mcp endpoint configuration\",\n type: \"object\",\n properties: {},\n required: [],\n \"x-mcp-version\": \"1.0\",\n \"x-query-style\": \"dot+bracket\",\n };\n return baseSchema;\n });\n\n // POST /mcp - JSON-RPC\n app.post(\n `${base}/mcp`,\n async (req: FastifyRequest, reply: FastifyReply) => {\n const clientIdHeader = (\n req.headers[\"mcp-client-id\"] as string | undefined\n )?.trim();\n const clientId =\n clientIdHeader && clientIdHeader.length > 0\n ? clientIdHeader\n : `anon-${randomUUID()}`;\n\n // When anon id, avoid caching (one-off)\n const useCache = !clientId.startsWith(\"anon-\");\n\n let bundle = useCache ? this.clientCache.get(clientId) : null;\n if (!bundle) {\n const created = this.createBundle();\n bundle = {\n server: created.server,\n orchestrator: created.orchestrator,\n sessions: new Map(),\n };\n if (useCache) this.clientCache.set(clientId, bundle);\n }\n\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n let transport: StreamableHTTPServerTransport | undefined;\n if (sessionId && bundle.sessions.get(sessionId)) {\n transport = bundle.sessions.get(sessionId)!;\n } else if (!sessionId && isInitializeRequest((req as any).body)) {\n const newSessionId = randomUUID();\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => newSessionId,\n onsessioninitialized: (sid: string) => {\n bundle!.sessions.set(sid, transport!);\n },\n });\n try {\n await bundle.server.connect(transport);\n } catch (error) {\n reply.code(500);\n return {\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Error initializing server.\" },\n id: null,\n };\n }\n transport.onclose = () => {\n if (transport?.sessionId)\n bundle!.sessions.delete(transport.sessionId);\n };\n } else {\n reply.code(400);\n return {\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Session not found or expired\" },\n id: null,\n };\n }\n\n // Delegate handling to SDK transport using raw Node req/res\n await transport.handleRequest(\n (req as any).raw,\n (reply as any).raw,\n (req as any).body\n );\n // Fastify will consider the response already sent by transport\n return reply;\n }\n );\n\n // GET /mcp - SSE notifications\n app.get(`${base}/mcp`, async (req: FastifyRequest, reply: FastifyReply) => {\n const clientIdHeader = (\n req.headers[\"mcp-client-id\"] as string | undefined\n )?.trim();\n const clientId =\n clientIdHeader && clientIdHeader.length > 0 ? clientIdHeader : \"\";\n if (!clientId) {\n reply.code(400);\n return \"Missing mcp-client-id\";\n }\n const bundle = this.clientCache.get(clientId);\n if (!bundle) {\n reply.code(400);\n return \"Invalid or expired client\";\n }\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n if (!sessionId) {\n reply.code(400);\n return \"Missing mcp-session-id\";\n }\n const transport = bundle.sessions.get(sessionId);\n if (!transport) {\n reply.code(400);\n return \"Invalid or expired session ID\";\n }\n await transport.handleRequest((req as any).raw, (reply as any).raw);\n return reply;\n });\n\n // DELETE /mcp - terminate session\n app.delete(\n `${base}/mcp`,\n async (req: FastifyRequest, reply: FastifyReply) => {\n const clientIdHeader = (\n req.headers[\"mcp-client-id\"] as string | undefined\n )?.trim();\n const clientId =\n clientIdHeader && clientIdHeader.length > 0 ? clientIdHeader : \"\";\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n if (!clientId || !sessionId) {\n reply.code(400);\n return {\n jsonrpc: \"2.0\",\n error: {\n code: -32600,\n message: \"Missing mcp-client-id or mcp-session-id header\",\n },\n id: null,\n };\n }\n const bundle = this.clientCache.get(clientId);\n const transport = bundle?.sessions.get(sessionId);\n if (!bundle || !transport) {\n reply.code(404);\n return {\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Session not found or expired\" },\n id: null,\n };\n }\n reply.code(204).send();\n return reply;\n }\n );\n\n // Only listen if we created the app\n if (!this.options.app) {\n await app.listen({ host: this.options.host, port: this.options.port });\n }\n this.app = app;\n }\n\n public async stop(): Promise<void> {\n if (!this.app) return;\n if (!this.options.app) {\n await this.app.close();\n }\n this.app = null;\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ExposurePolicy, Mode, ToolSetCatalog } from \"../types/index.js\";\nimport { ServerOrchestrator } from \"../core/ServerOrchestrator.js\";\nimport {\n FastifyTransport,\n type FastifyTransportOptions,\n} from \"../http/FastifyTransport.js\";\n\nexport interface CreateMcpServerOptions {\n catalog: ToolSetCatalog;\n moduleLoaders?: Record<string, any>;\n exposurePolicy?: ExposurePolicy;\n context?: unknown;\n startup?: { mode?: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" };\n registerMetaTools?: boolean;\n http?: FastifyTransportOptions;\n /** Factory to create an MCP server instance. Required.\n * In DYNAMIC mode, a new instance is created per client bundle.\n * In STATIC mode, a single instance is created and reused across bundles.\n */\n createServer: () => McpServer;\n configSchema?: object;\n}\n\nexport async function createMcpServer(options: CreateMcpServerOptions) {\n const mode: Exclude<Mode, \"ALL\"> = options.startup?.mode ?? \"DYNAMIC\";\n if (typeof options.createServer !== \"function\") {\n throw new Error(\"createMcpServer: `createServer` (factory) is required\");\n }\n const baseServer: McpServer = options.createServer();\n\n // Typed, guarded notifier\n type NotifierA = {\n server: { notification: (msg: { method: string }) => Promise<void> | void };\n };\n type NotifierB = { notifyToolsListChanged: () => Promise<void> | void };\n const hasNotifierA = (s: unknown): s is NotifierA =>\n typeof (s as any)?.server?.notification === \"function\";\n const hasNotifierB = (s: unknown): s is NotifierB =>\n typeof (s as any)?.notifyToolsListChanged === \"function\";\n const notifyToolsChanged = async (target: unknown) => {\n try {\n if (hasNotifierA(target)) {\n await target.server.notification({\n method: \"notifications/tools/list_changed\",\n });\n return;\n }\n if (hasNotifierB(target)) {\n await target.notifyToolsListChanged();\n }\n } catch {}\n };\n\n const orchestrator = new ServerOrchestrator({\n server: baseServer,\n catalog: options.catalog,\n moduleLoaders: options.moduleLoaders,\n exposurePolicy: options.exposurePolicy,\n context: options.context,\n notifyToolsListChanged: async () => notifyToolsChanged(baseServer),\n startup: options.startup,\n registerMetaTools:\n options.registerMetaTools !== undefined\n ? options.registerMetaTools\n : mode === \"DYNAMIC\",\n });\n\n const transport = new FastifyTransport(\n orchestrator.getManager(),\n () => {\n // Create a server + orchestrator bundle\n // for a new client when needed\n const createdServer: McpServer =\n mode === \"DYNAMIC\" ? options.createServer() : baseServer;\n const orchestrator = new ServerOrchestrator({\n server: createdServer,\n catalog: options.catalog,\n moduleLoaders: options.moduleLoaders,\n exposurePolicy: options.exposurePolicy,\n context: options.context,\n notifyToolsListChanged: async () => notifyToolsChanged(createdServer),\n startup: options.startup,\n registerMetaTools:\n options.registerMetaTools !== undefined\n ? options.registerMetaTools\n : mode === \"DYNAMIC\",\n });\n return { server: createdServer, orchestrator };\n },\n options.http,\n options.configSchema\n );\n\n return {\n server: baseServer,\n start: async () => {\n await transport.start();\n },\n close: async () => {\n await transport.stop();\n },\n };\n}\n"],"names":["DEFAULT_KEYS","ToolsetValidator","options","env","args","input","catalog","raw","s","valid","result","name","toolsets","modules","def","m","sanitized","toolsetNames","error","source","key","value","ModuleResolver","context","collected","modKey","loader","loaded","err","ToolingError","message","code","details","_options","ToolRegistry","toolsetKey","toolName","set","tools","safe","k","v","DynamicToolManager","toolsetName","validation","resolvedTools","mapped","activeToolsets","results","res","successAll","tool","all","registerMetaTools","server","manager","mode","z","available","byToolset","items","payload","status","ServerOrchestrator","startup","resolved","toolRegistry","initial","names","isValid","ClientResourceCache","pruneEvery","entry","resource","newEntry","lruKey","now","FastifyTransport","defaultManager","createBundle","configSchema","app","Fastify","cors","base","_req","reply","req","clientIdHeader","clientId","randomUUID","useCache","bundle","created","sessionId","transport","isInitializeRequest","newSessionId","StreamableHTTPServerTransport","sid","createMcpServer","baseServer","hasNotifierA","hasNotifierB","notifyToolsChanged","target","orchestrator","createdServer"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/mode/ModeResolver.ts","../src/mode/ModuleResolver.ts","../src/errors/ToolingError.ts","../src/core/ToolRegistry.ts","../src/core/DynamicToolManager.ts","../src/meta/registerMetaTools.ts","../src/core/ServerOrchestrator.ts","../src/session/ClientResourceCache.ts","../src/http/FastifyTransport.ts","../src/server/createMcpServer.ts"],"sourcesContent":["import type { Mode, ToolSetCatalog } from \"../types/index.js\";\n\ninterface ModeResolverKeys {\n dynamic?: string[]; // keys that, when present/true, enable dynamic mode\n toolsets?: string[]; // keys that carry comma-separated toolsets\n}\n\ninterface ModeResolverOptions {\n keys?: ModeResolverKeys;\n}\n\nconst DEFAULT_KEYS: Required<ModeResolverKeys> = {\n dynamic: [\n \"dynamic-tool-discovery\",\n \"dynamicToolDiscovery\",\n \"DYNAMIC_TOOL_DISCOVERY\",\n ],\n toolsets: [\"tool-sets\", \"toolSets\", \"FMP_TOOL_SETS\"],\n};\n\nexport class ToolsetValidator {\n private readonly keys: Required<ModeResolverKeys>;\n\n constructor(options: ModeResolverOptions = {}) {\n this.keys = {\n dynamic: options.keys?.dynamic ?? DEFAULT_KEYS.dynamic,\n toolsets: options.keys?.toolsets ?? DEFAULT_KEYS.toolsets,\n };\n }\n\n public resolveMode(\n env?: Record<string, string | undefined>,\n args?: Record<string, unknown>\n ): Mode | null {\n // Check args first\n if (this.isDynamicEnabled(args)) return \"DYNAMIC\";\n\n const toolsetsFromArgs = this.getToolsetsString(args);\n if (toolsetsFromArgs) return \"STATIC\";\n\n // Check env next\n if (this.isDynamicEnabled(env)) return \"DYNAMIC\";\n\n const toolsetsFromEnv = this.getToolsetsString(env);\n if (toolsetsFromEnv) return \"STATIC\";\n\n return null; // no override\n }\n\n public parseCommaSeparatedToolSets(\n input: string,\n catalog: ToolSetCatalog\n ): string[] {\n if (!input || typeof input !== \"string\") return [];\n const raw = input\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n\n const valid = new Set(Object.keys(catalog));\n const result: string[] = [];\n for (const name of raw) {\n if (valid.has(name)) result.push(name);\n else\n console.warn(\n `Invalid toolset '${name}' ignored. Available: ${Array.from(\n valid\n ).join(\", \")}`\n );\n }\n return result;\n }\n\n public getModulesForToolSets(\n toolsets: string[],\n catalog: ToolSetCatalog\n ): string[] {\n const modules = new Set<string>();\n for (const name of toolsets) {\n const def = catalog[name];\n if (!def) continue;\n (def.modules || []).forEach((m) => modules.add(m));\n }\n return Array.from(modules);\n }\n\n public validateToolsetName(\n name: unknown,\n catalog: ToolSetCatalog\n ): { isValid: boolean; sanitized?: string; error?: string } {\n if (!name || typeof name !== \"string\") {\n return {\n isValid: false,\n error: `Invalid toolset name provided. Must be a non-empty string. Available toolsets: ${Object.keys(\n catalog\n ).join(\", \")}`,\n };\n }\n const sanitized = name.trim();\n if (sanitized.length === 0) {\n return {\n isValid: false,\n error: `Empty toolset name provided. Available toolsets: ${Object.keys(\n catalog\n ).join(\", \")}`,\n };\n }\n if (!catalog[sanitized]) {\n return {\n isValid: false,\n error: `Toolset '${sanitized}' not found. Available toolsets: ${Object.keys(\n catalog\n ).join(\", \")}`,\n };\n }\n return { isValid: true, sanitized };\n }\n\n public validateToolsetModules(\n toolsetNames: string[],\n catalog: ToolSetCatalog\n ): { isValid: boolean; modules?: string[]; error?: string } {\n try {\n const modules = this.getModulesForToolSets(toolsetNames, catalog);\n if (!modules || modules.length === 0) {\n return {\n isValid: false,\n error: `No modules found for toolsets: ${toolsetNames.join(\", \")}`,\n };\n }\n return { isValid: true, modules };\n } catch (error) {\n return {\n isValid: false,\n error: `Error resolving modules for ${toolsetNames.join(\", \")}: ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n };\n }\n }\n\n private isDynamicEnabled(\n source?: Record<string, unknown> | Record<string, string | undefined>\n ): boolean {\n if (!source) return false;\n for (const key of this.keys.dynamic) {\n const value = (source as any)[key];\n if (value === true) return true;\n if (typeof value === \"string\") {\n const v = value.trim().toLowerCase();\n if (v === \"true\") return true;\n }\n }\n return false;\n }\n\n private getToolsetsString(\n source?: Record<string, unknown> | Record<string, string | undefined>\n ): string | undefined {\n if (!source) return undefined;\n for (const key of this.keys.toolsets) {\n const value = (source as any)[key];\n if (typeof value === \"string\" && value.trim().length > 0)\n return value as string;\n }\n return undefined;\n }\n}\n","import type {\n ToolSetCatalog,\n ToolSetDefinition,\n McpToolDefinition,\n ModuleLoader,\n} from \"../types/index.js\";\n\nexport interface ModuleResolverOptions {\n catalog: ToolSetCatalog;\n moduleLoaders?: Record<string, ModuleLoader>;\n}\n\nexport class ModuleResolver {\n private readonly catalog: ToolSetCatalog;\n private readonly moduleLoaders: Record<string, ModuleLoader>;\n\n constructor(options: ModuleResolverOptions) {\n this.catalog = options.catalog;\n this.moduleLoaders = options.moduleLoaders ?? {};\n }\n\n public getAvailableToolsets(): string[] {\n return Object.keys(this.catalog);\n }\n\n public getToolsetDefinition(name: string): ToolSetDefinition | undefined {\n return this.catalog[name];\n }\n\n public validateToolsetName(name: unknown): {\n isValid: boolean;\n sanitized?: string;\n error?: string;\n } {\n if (!name || typeof name !== \"string\") {\n return {\n isValid: false,\n error: `Invalid toolset name provided. Must be a non-empty string. Available toolsets: ${this.getAvailableToolsets().join(\n \", \"\n )}`,\n };\n }\n const sanitized = name.trim();\n if (sanitized.length === 0) {\n return {\n isValid: false,\n error: `Empty toolset name provided. Available toolsets: ${this.getAvailableToolsets().join(\n \", \"\n )}`,\n };\n }\n if (!this.catalog[sanitized]) {\n return {\n isValid: false,\n error: `Toolset '${sanitized}' not found. Available toolsets: ${this.getAvailableToolsets().join(\n \", \"\n )}`,\n };\n }\n return { isValid: true, sanitized };\n }\n\n public async resolveToolsForToolsets(\n toolsets: string[],\n context?: unknown\n ): Promise<McpToolDefinition[]> {\n const collected: McpToolDefinition[] = [];\n for (const name of toolsets) {\n const def = this.catalog[name];\n if (!def) continue;\n if (Array.isArray(def.tools) && def.tools.length > 0) {\n collected.push(...def.tools);\n }\n if (Array.isArray(def.modules) && def.modules.length > 0) {\n for (const modKey of def.modules) {\n const loader = this.moduleLoaders[modKey];\n if (!loader) continue;\n try {\n const loaded = await loader(context);\n if (Array.isArray(loaded) && loaded.length > 0) {\n collected.push(...loaded);\n }\n } catch (err) {\n console.warn(\n `Module loader '${modKey}' failed for toolset '${name}':`,\n err\n );\n }\n }\n }\n }\n return collected;\n }\n}\n","import type { ToolingErrorCode } from \"../types/index.js\";\n\nexport class ToolingError extends Error {\n public readonly code: ToolingErrorCode;\n public readonly details?: Record<string, unknown>;\n\n constructor(\n message: string,\n code: ToolingErrorCode,\n details?: Record<string, unknown>,\n _options?: unknown\n ) {\n super(message);\n this.name = \"ToolingError\";\n this.code = code;\n this.details = details;\n }\n}\n","import type { McpToolDefinition } from \"../types/index.js\";\nimport { ToolingError } from \"../errors/ToolingError.js\";\n\nexport interface ToolRegistryOptions {\n namespaceWithToolset?: boolean;\n}\n\nexport class ToolRegistry {\n private readonly options: Required<ToolRegistryOptions>;\n private readonly names = new Set<string>();\n private readonly toolsetToNames = new Map<string, Set<string>>();\n\n constructor(options: ToolRegistryOptions = {}) {\n this.options = {\n namespaceWithToolset: options.namespaceWithToolset ?? true,\n };\n }\n\n public getSafeName(toolsetKey: string, toolName: string): string {\n if (!this.options.namespaceWithToolset) return toolName;\n if (toolName.startsWith(`${toolsetKey}.`)) return toolName;\n return `${toolsetKey}.${toolName}`;\n }\n\n public has(name: string): boolean {\n return this.names.has(name);\n }\n\n public add(name: string): void {\n if (this.names.has(name)) {\n throw new ToolingError(\n `Tool name collision: '${name}' already registered`,\n \"E_TOOL_NAME_CONFLICT\"\n );\n }\n this.names.add(name);\n }\n\n public addForToolset(toolsetKey: string, name: string): void {\n this.add(name);\n const set = this.toolsetToNames.get(toolsetKey) ?? new Set<string>();\n set.add(name);\n this.toolsetToNames.set(toolsetKey, set);\n }\n\n public mapAndValidate(\n toolsetKey: string,\n tools: McpToolDefinition[]\n ): McpToolDefinition[] {\n return tools.map((t) => {\n const safe = this.getSafeName(toolsetKey, t.name);\n if (this.has(safe)) {\n throw new ToolingError(\n `Tool name collision for '${safe}'`,\n \"E_TOOL_NAME_CONFLICT\"\n );\n }\n return { ...t, name: safe };\n });\n }\n\n public list(): string[] {\n return Array.from(this.names);\n }\n\n public listByToolset(): Record<string, string[]> {\n const result: Record<string, string[]> = {};\n for (const [k, v] of this.toolsetToNames.entries()) {\n result[k] = Array.from(v);\n }\n return result;\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type {\n ExposurePolicy,\n McpToolDefinition,\n ToolSetDefinition,\n ToolingErrorCode,\n} from \"../types/index.js\";\nimport { ModuleResolver } from \"../mode/ModuleResolver.js\";\nimport { ToolRegistry } from \"./ToolRegistry.js\";\n\nexport interface DynamicToolManagerOptions {\n server: McpServer;\n resolver: ModuleResolver;\n context?: unknown;\n onToolsListChanged?: () => Promise<void> | void;\n exposurePolicy?: ExposurePolicy;\n toolRegistry?: ToolRegistry;\n}\n\nexport class DynamicToolManager {\n private readonly server: McpServer;\n private readonly resolver: ModuleResolver;\n private readonly context?: unknown;\n private readonly onToolsListChanged?: () => Promise<void> | void;\n private readonly exposurePolicy?: ExposurePolicy;\n private readonly toolRegistry: ToolRegistry;\n\n private readonly activeToolsets = new Set<string>();\n\n constructor(options: DynamicToolManagerOptions) {\n this.server = options.server;\n this.resolver = options.resolver;\n this.context = options.context;\n this.onToolsListChanged = options.onToolsListChanged;\n this.exposurePolicy = options.exposurePolicy;\n this.toolRegistry =\n options.toolRegistry ?? new ToolRegistry({ namespaceWithToolset: true });\n }\n\n public getAvailableToolsets(): string[] {\n return this.resolver.getAvailableToolsets();\n }\n\n public getActiveToolsets(): string[] {\n return Array.from(this.activeToolsets);\n }\n\n public getToolsetDefinition(name: string): ToolSetDefinition | undefined {\n return this.resolver.getToolsetDefinition(name);\n }\n\n public isActive(name: string): boolean {\n return this.activeToolsets.has(name);\n }\n\n public async enableToolset(\n toolsetName: string\n ): Promise<{ success: boolean; message: string }> {\n const validation = this.resolver.validateToolsetName(toolsetName);\n if (!validation.isValid || !validation.sanitized) {\n return {\n success: false,\n message: validation.error || \"Unknown validation error\",\n };\n }\n const sanitized = validation.sanitized;\n if (this.activeToolsets.has(sanitized)) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is already enabled.`,\n };\n }\n\n try {\n const resolvedTools = await this.resolver.resolveToolsForToolsets(\n [sanitized],\n this.context\n );\n\n // Exposure policy checks\n if (\n this.exposurePolicy?.allowlist &&\n !this.exposurePolicy.allowlist.includes(sanitized)\n ) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is not allowed by policy.`,\n };\n }\n if (\n this.exposurePolicy?.denylist &&\n this.exposurePolicy.denylist.includes(sanitized)\n ) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is denied by policy.`,\n };\n }\n if (this.exposurePolicy?.maxActiveToolsets !== undefined) {\n const next = this.activeToolsets.size + 1;\n if (next > this.exposurePolicy.maxActiveToolsets) {\n this.exposurePolicy.onLimitExceeded?.(\n [sanitized],\n Array.from(this.activeToolsets)\n );\n return {\n success: false,\n message: `Activation exceeds maxActiveToolsets (${this.exposurePolicy.maxActiveToolsets}).`,\n };\n }\n }\n\n // Register all resolved tools (direct + module-derived)\n if (resolvedTools && resolvedTools.length > 0) {\n const mapped = this.toolRegistry.mapAndValidate(\n sanitized,\n resolvedTools\n );\n this.registerDirectTools(mapped, sanitized);\n }\n\n // Track state (modules no longer tracked)\n this.activeToolsets.add(sanitized);\n\n // Notify list change\n try {\n await this.onToolsListChanged?.();\n } catch (err) {\n console.warn(`Failed to send tool list change notification:`, err);\n }\n\n return {\n success: true,\n message: `Toolset '${sanitized}' enabled successfully. Registered ${\n resolvedTools?.length ?? 0\n } tools.`,\n };\n } catch (error) {\n this.activeToolsets.delete(sanitized);\n return {\n success: false,\n message: `Failed to enable toolset '${sanitized}': ${\n error instanceof Error ? error.message : \"Unknown error\"\n }`,\n };\n }\n }\n\n public async disableToolset(\n toolsetName: string\n ): Promise<{ success: boolean; message: string }> {\n const validation = this.resolver.validateToolsetName(toolsetName);\n if (!validation.isValid || !validation.sanitized) {\n const activeToolsets =\n Array.from(this.activeToolsets).join(\", \") || \"none\";\n const base = validation.error || \"Unknown validation error\";\n return {\n success: false,\n message: `${base} Active toolsets: ${activeToolsets}`,\n };\n }\n const sanitized = validation.sanitized;\n if (!this.activeToolsets.has(sanitized)) {\n return {\n success: false,\n message: `Toolset '${sanitized}' is not currently active. Active toolsets: ${\n Array.from(this.activeToolsets).join(\", \") || \"none\"\n }`,\n };\n }\n\n // State-only disable; no unregistration support in MCP\n this.activeToolsets.delete(sanitized);\n\n try {\n await this.onToolsListChanged?.();\n } catch (err) {\n console.warn(`Failed to send tool list change notification:`, err);\n }\n\n return {\n success: true,\n message: `Toolset '${sanitized}' disabled successfully. Individual tools remain registered due to MCP limitations.`,\n };\n }\n\n public getStatus() {\n return {\n availableToolsets: this.getAvailableToolsets(),\n activeToolsets: this.getActiveToolsets(),\n registeredModules: [],\n totalToolsets: this.getAvailableToolsets().length,\n activeCount: this.activeToolsets.size,\n tools: this.toolRegistry.list(),\n toolsetToTools: this.toolRegistry.listByToolset(),\n };\n }\n\n public async enableToolsets(toolsetNames: string[]): Promise<{\n success: boolean;\n results: Array<{\n name: string;\n success: boolean;\n message: string;\n code?: ToolingErrorCode;\n }>;\n message: string;\n }> {\n const results: Array<{\n name: string;\n success: boolean;\n message: string;\n code?: ToolingErrorCode;\n }> = [];\n for (const name of toolsetNames) {\n try {\n const res = await this.enableToolset(name);\n results.push({ name, ...res });\n } catch (err) {\n results.push({\n name,\n success: false,\n message: err instanceof Error ? err.message : \"Unknown error\",\n code: \"E_INTERNAL\",\n });\n }\n }\n const successAll = results.every((r) => r.success);\n const message = successAll\n ? \"All toolsets enabled\"\n : \"Some toolsets failed to enable\";\n if (results.length > 0) {\n try {\n await this.onToolsListChanged?.();\n } catch {}\n }\n return { success: successAll, results, message };\n }\n\n private registerDirectTools(\n tools: McpToolDefinition[],\n toolsetKey?: string\n ): void {\n for (const tool of tools) {\n try {\n this.server.tool(\n tool.name,\n tool.description,\n tool.inputSchema as any,\n async (args: any) => {\n return await tool.handler(args);\n }\n );\n if (toolsetKey) this.toolRegistry.addForToolset(toolsetKey, tool.name);\n else this.toolRegistry.add(tool.name);\n } catch (err) {\n console.error(`Failed to register direct tool '${tool.name}':`, err);\n throw err;\n }\n }\n }\n\n public async enableAllToolsets(): Promise<{\n success: boolean;\n results: Array<{\n name: string;\n success: boolean;\n message: string;\n code?: ToolingErrorCode;\n }>;\n message: string;\n }> {\n const all = this.getAvailableToolsets();\n return this.enableToolsets(all);\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Mode } from \"../types/index.js\";\nimport { z } from \"zod\";\nimport { DynamicToolManager } from \"../core/DynamicToolManager.js\";\n\nexport function registerMetaTools(\n server: McpServer,\n manager: DynamicToolManager,\n options?: { mode?: Exclude<Mode, \"ALL\"> }\n): void {\n const mode = options?.mode ?? \"DYNAMIC\";\n // list_tools is always available\n server.tool(\n \"enable_toolset\",\n \"Enable a toolset by name\",\n { name: z.string().describe(\"Toolset name\") },\n async (args: any) => {\n const { name } = args as { name: string };\n const result = await manager.enableToolset(name);\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n };\n }\n );\n\n server.tool(\n \"disable_toolset\",\n \"Disable a toolset by name (state only)\",\n { name: z.string().describe(\"Toolset name\") },\n async (args: any) => {\n const { name } = args as { name: string };\n const result = await manager.disableToolset(name);\n return {\n content: [{ type: \"text\", text: JSON.stringify(result) }],\n };\n }\n );\n\n if (mode === \"DYNAMIC\") {\n server.tool(\n \"list_toolsets\",\n \"List available toolsets with active status and definitions\",\n {},\n async () => {\n const available = manager.getAvailableToolsets();\n const byToolset = manager.getStatus().toolsetToTools;\n const items = available.map((key) => {\n const def = manager.getToolsetDefinition(key);\n return {\n key,\n active: manager.isActive(key),\n definition: def\n ? {\n name: def.name,\n description: def.description,\n modules: def.modules ?? [],\n decisionCriteria: def.decisionCriteria ?? undefined,\n }\n : null,\n tools: byToolset[key] ?? [],\n };\n });\n return {\n content: [\n { type: \"text\", text: JSON.stringify({ toolsets: items }) },\n ],\n };\n }\n );\n\n server.tool(\n \"describe_toolset\",\n \"Describe a toolset with definition, active status and tools\",\n { name: z.string().describe(\"Toolset name\") },\n async (args: any) => {\n const { name } = args as { name: string };\n const def = manager.getToolsetDefinition(name);\n const byToolset = manager.getStatus().toolsetToTools;\n if (!def) {\n return {\n content: [\n {\n type: \"text\",\n text: JSON.stringify({ error: `Unknown toolset '${name}'` }),\n },\n ],\n };\n }\n const payload = {\n key: name,\n active: manager.isActive(name),\n definition: {\n name: def.name,\n description: def.description,\n modules: def.modules ?? [],\n decisionCriteria: def.decisionCriteria ?? undefined,\n },\n tools: byToolset[name] ?? [],\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(payload) }],\n };\n }\n );\n }\n\n server.tool(\n \"list_tools\",\n \"List currently registered tool names (best effort)\",\n {},\n async () => {\n const status = manager.getStatus();\n const payload = {\n tools: status.tools,\n toolsetToTools: status.toolsetToTools,\n };\n return {\n content: [{ type: \"text\", text: JSON.stringify(payload) }],\n };\n }\n );\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { ToolsetValidator } from \"../mode/ToolsetValidator.js\";\nimport { ModuleResolver } from \"../mode/ModuleResolver.js\";\nimport { DynamicToolManager } from \"./DynamicToolManager.js\";\nimport { registerMetaTools } from \"../meta/registerMetaTools.js\";\nimport type { ExposurePolicy, Mode, ToolSetCatalog } from \"../types/index.js\";\nimport { ToolRegistry } from \"./ToolRegistry.js\";\n\nexport interface ServerOrchestratorOptions {\n server: McpServer;\n catalog: ToolSetCatalog;\n moduleLoaders?: Record<string, any>;\n exposurePolicy?: ExposurePolicy;\n context?: unknown;\n notifyToolsListChanged?: () => Promise<void> | void;\n startup?: { mode?: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" };\n registerMetaTools?: boolean;\n}\n\nexport class ServerOrchestrator {\n private readonly mode: Exclude<Mode, \"ALL\">;\n private readonly resolver: ModuleResolver;\n private readonly manager: DynamicToolManager;\n private readonly toolsetValidator: ToolsetValidator;\n\n constructor(options: ServerOrchestratorOptions) {\n this.toolsetValidator = new ToolsetValidator();\n const startup = options.startup ?? {};\n const resolved = this.resolveStartupConfig(startup, options.catalog);\n this.mode = resolved.mode;\n this.resolver = new ModuleResolver({\n catalog: options.catalog,\n moduleLoaders: options.moduleLoaders,\n });\n const toolRegistry = new ToolRegistry({\n namespaceWithToolset:\n options.exposurePolicy?.namespaceToolsWithSetKey ?? true,\n });\n this.manager = new DynamicToolManager({\n server: options.server,\n resolver: this.resolver,\n context: options.context,\n onToolsListChanged: options.notifyToolsListChanged,\n exposurePolicy: options.exposurePolicy,\n toolRegistry,\n });\n\n // Register meta-tools only if requested (default true)\n if (options.registerMetaTools !== false) {\n registerMetaTools(options.server, this.manager, { mode: this.mode });\n }\n\n // Startup behavior\n const initial = resolved.toolsets;\n if (initial === \"ALL\") {\n void this.manager.enableToolsets(this.resolver.getAvailableToolsets());\n } else if (Array.isArray(initial) && initial.length > 0) {\n void this.manager.enableToolsets(initial);\n }\n }\n\n private resolveStartupConfig(\n startup: { mode?: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" },\n catalog: ToolSetCatalog\n ): { mode: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" } {\n // Explicit mode dominates\n if (startup.mode) {\n if (startup.mode === \"DYNAMIC\" && startup.toolsets) {\n console.warn(\"startup.toolsets provided but ignored in DYNAMIC mode\");\n return { mode: \"DYNAMIC\" };\n }\n if (startup.mode === \"STATIC\") {\n if (startup.toolsets === \"ALL\")\n return { mode: \"STATIC\", toolsets: \"ALL\" };\n const names = Array.isArray(startup.toolsets) ? startup.toolsets : [];\n const valid: string[] = [];\n for (const name of names) {\n const { isValid, sanitized, error } =\n this.toolsetValidator.validateToolsetName(name, catalog);\n if (isValid && sanitized) valid.push(sanitized);\n else if (error) console.warn(error);\n }\n if (names.length > 0 && valid.length === 0) {\n throw new Error(\n \"STATIC mode requires valid toolsets or 'ALL'; none were valid\"\n );\n }\n return { mode: \"STATIC\", toolsets: valid };\n }\n return { mode: startup.mode };\n }\n\n // No explicit mode; infer from toolsets\n if (startup.toolsets === \"ALL\") return { mode: \"STATIC\", toolsets: \"ALL\" };\n if (Array.isArray(startup.toolsets) && startup.toolsets.length > 0) {\n const valid: string[] = [];\n for (const name of startup.toolsets) {\n const { isValid, sanitized, error } =\n this.toolsetValidator.validateToolsetName(name, catalog);\n if (isValid && sanitized) valid.push(sanitized);\n else if (error) console.warn(error);\n }\n if (valid.length === 0) {\n throw new Error(\n \"STATIC mode requires valid toolsets or 'ALL'; none were valid\"\n );\n }\n return { mode: \"STATIC\", toolsets: valid };\n }\n\n // Default\n return { mode: \"DYNAMIC\" };\n }\n\n public getMode(): Exclude<Mode, \"ALL\"> {\n return this.mode;\n }\n\n public getManager(): DynamicToolManager {\n return this.manager;\n }\n}\n","export interface ClientResourceCacheOptions {\n maxSize?: number;\n ttlMs?: number; // ms\n pruneIntervalMs?: number;\n}\n\ninterface Entry<T> {\n resource: T;\n lastAccessed: number;\n}\n\nexport class ClientResourceCache<T> {\n private storage = new Map<string, Entry<T>>();\n private maxSize: number;\n private ttlMs: number;\n // Use ReturnType<typeof setInterval> for cross-env typings without NodeJS namespace\n private pruneInterval?: ReturnType<typeof setInterval>;\n\n constructor(options: ClientResourceCacheOptions = {}) {\n this.maxSize = options.maxSize ?? 1000;\n this.ttlMs = options.ttlMs ?? 1000 * 60 * 60;\n const pruneEvery = options.pruneIntervalMs ?? 1000 * 60 * 10;\n this.pruneInterval = setInterval(() => this.pruneExpired(), pruneEvery);\n }\n\n public getEntryCount(): number {\n return this.storage.size;\n }\n\n public getMaxSize(): number {\n return this.maxSize;\n }\n\n public getTtl(): number {\n return this.ttlMs;\n }\n\n public get(key: string): T | null {\n const entry = this.storage.get(key);\n if (!entry) return null;\n if (Date.now() - entry.lastAccessed > this.ttlMs) {\n this.delete(key);\n return null;\n }\n entry.lastAccessed = Date.now();\n this.storage.delete(key);\n this.storage.set(key, entry);\n return entry.resource;\n }\n\n public set(key: string, resource: T): void {\n if (this.storage.size >= this.maxSize) {\n this.evictLeastRecentlyUsed();\n }\n const newEntry: Entry<T> = { resource, lastAccessed: Date.now() };\n this.storage.set(key, newEntry);\n }\n\n public delete(key: string): void {\n this.storage.delete(key);\n }\n\n public stop(): void {\n if (this.pruneInterval) {\n clearInterval(this.pruneInterval);\n this.pruneInterval = undefined;\n }\n }\n\n private evictLeastRecentlyUsed(): void {\n const lruKey = this.storage.keys().next().value as string | undefined;\n if (lruKey) {\n this.delete(lruKey);\n }\n }\n\n private pruneExpired(): void {\n const now = Date.now();\n for (const [key, entry] of this.storage.entries()) {\n if (now - entry.lastAccessed > this.ttlMs) {\n this.delete(key);\n }\n }\n }\n}\n","import Fastify, {\n type FastifyInstance,\n type FastifyReply,\n type FastifyRequest,\n} from \"fastify\";\nimport cors from \"@fastify/cors\";\nimport { randomUUID } from \"node:crypto\";\nimport type { DynamicToolManager } from \"../core/DynamicToolManager.js\";\nimport type { ServerOrchestrator } from \"../core/ServerOrchestrator.js\";\nimport { ClientResourceCache } from \"../session/ClientResourceCache.js\";\nimport { StreamableHTTPServerTransport } from \"@modelcontextprotocol/sdk/server/streamableHttp.js\";\nimport { isInitializeRequest } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\n\nexport interface FastifyTransportOptions {\n host?: string;\n port?: number;\n basePath?: string; // e.g. \"/\" or \"/api\"\n cors?: boolean;\n logger?: boolean;\n // Optional DI: provide a Fastify instance (e.g., for tests). If provided, start() will not listen.\n app?: FastifyInstance;\n}\n\nexport class FastifyTransport {\n private readonly options: {\n host: string;\n port: number;\n basePath: string;\n cors: boolean;\n logger: boolean;\n app?: FastifyInstance;\n };\n private readonly defaultManager: DynamicToolManager;\n private readonly createBundle: () => {\n server: McpServer;\n orchestrator: ServerOrchestrator;\n };\n private app: FastifyInstance | null = null;\n private readonly configSchema?: object;\n\n // Per-client server bundles and per-client session transports\n private readonly clientCache = new ClientResourceCache<{\n server: McpServer;\n orchestrator: ServerOrchestrator;\n sessions: Map<string, StreamableHTTPServerTransport>;\n }>();\n\n constructor(\n defaultManager: DynamicToolManager,\n createBundle: () => { server: McpServer; orchestrator: ServerOrchestrator },\n options: FastifyTransportOptions = {},\n configSchema?: object\n ) {\n this.defaultManager = defaultManager;\n this.createBundle = createBundle;\n this.options = {\n host: options.host ?? \"0.0.0.0\",\n port: options.port ?? 3000,\n basePath: options.basePath ?? \"/\",\n cors: options.cors ?? true,\n logger: options.logger ?? false,\n app: options.app,\n };\n this.configSchema = configSchema;\n }\n\n public async start(): Promise<void> {\n if (this.app) return;\n const app = this.options.app ?? Fastify({ logger: this.options.logger });\n if (this.options.cors) {\n await app.register(cors, { origin: true });\n }\n\n const base = this.options.basePath.endsWith(\"/\")\n ? this.options.basePath.slice(0, -1)\n : this.options.basePath;\n\n app.get(`${base}/healthz`, async () => ({ ok: true }));\n\n app.get(`${base}/tools`, async () => this.defaultManager.getStatus());\n\n // Config discovery (placeholder schema)\n app.get(`${base}/.well-known/mcp-config`, async (_req, reply) => {\n reply.header(\"Content-Type\", \"application/schema+json; charset=utf-8\");\n const baseSchema = this.configSchema ?? {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n title: \"MCP Session Configuration\",\n description: \"Schema for the /mcp endpoint configuration\",\n type: \"object\",\n properties: {},\n required: [],\n \"x-mcp-version\": \"1.0\",\n \"x-query-style\": \"dot+bracket\",\n };\n return baseSchema;\n });\n\n // POST /mcp - JSON-RPC\n app.post(\n `${base}/mcp`,\n async (req: FastifyRequest, reply: FastifyReply) => {\n const clientIdHeader = (\n req.headers[\"mcp-client-id\"] as string | undefined\n )?.trim();\n const clientId =\n clientIdHeader && clientIdHeader.length > 0\n ? clientIdHeader\n : `anon-${randomUUID()}`;\n\n // When anon id, avoid caching (one-off)\n const useCache = !clientId.startsWith(\"anon-\");\n\n let bundle = useCache ? this.clientCache.get(clientId) : null;\n if (!bundle) {\n const created = this.createBundle();\n const providedSessions = (created as any).sessions;\n bundle = {\n server: created.server,\n orchestrator: created.orchestrator,\n sessions:\n providedSessions instanceof Map ? providedSessions : new Map(),\n };\n if (useCache) this.clientCache.set(clientId, bundle);\n }\n\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n\n let transport: StreamableHTTPServerTransport | undefined;\n if (sessionId && bundle.sessions.get(sessionId)) {\n transport = bundle.sessions.get(sessionId)!;\n } else if (!sessionId && isInitializeRequest((req as any).body)) {\n const newSessionId = randomUUID();\n transport = new StreamableHTTPServerTransport({\n sessionIdGenerator: () => newSessionId,\n onsessioninitialized: (sid: string) => {\n bundle!.sessions.set(sid, transport!);\n },\n });\n try {\n await bundle.server.connect(transport);\n } catch (error) {\n reply.code(500);\n return {\n jsonrpc: \"2.0\",\n error: { code: -32603, message: \"Error initializing server.\" },\n id: null,\n };\n }\n transport.onclose = () => {\n if (transport?.sessionId)\n bundle!.sessions.delete(transport.sessionId);\n };\n } else {\n reply.code(400);\n return {\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Session not found or expired\" },\n id: null,\n };\n }\n\n // Delegate handling to SDK transport using raw Node req/res\n await transport.handleRequest(\n (req as any).raw,\n (reply as any).raw,\n (req as any).body\n );\n // Fastify will consider the response already sent by transport\n return reply;\n }\n );\n\n // GET /mcp - SSE notifications\n app.get(`${base}/mcp`, async (req: FastifyRequest, reply: FastifyReply) => {\n const clientIdHeader = (\n req.headers[\"mcp-client-id\"] as string | undefined\n )?.trim();\n const clientId =\n clientIdHeader && clientIdHeader.length > 0 ? clientIdHeader : \"\";\n if (!clientId) {\n reply.code(400);\n return \"Missing mcp-client-id\";\n }\n const bundle = this.clientCache.get(clientId);\n if (!bundle) {\n reply.code(400);\n return \"Invalid or expired client\";\n }\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n if (!sessionId) {\n reply.code(400);\n return \"Missing mcp-session-id\";\n }\n const transport = bundle.sessions.get(sessionId);\n if (!transport) {\n reply.code(400);\n return \"Invalid or expired session ID\";\n }\n await transport.handleRequest((req as any).raw, (reply as any).raw);\n return reply;\n });\n\n // DELETE /mcp - terminate session\n app.delete(\n `${base}/mcp`,\n async (req: FastifyRequest, reply: FastifyReply) => {\n const clientIdHeader = (\n req.headers[\"mcp-client-id\"] as string | undefined\n )?.trim();\n const clientId =\n clientIdHeader && clientIdHeader.length > 0 ? clientIdHeader : \"\";\n const sessionId = req.headers[\"mcp-session-id\"] as string | undefined;\n if (!clientId || !sessionId) {\n reply.code(400);\n return {\n jsonrpc: \"2.0\",\n error: {\n code: -32600,\n message: \"Missing mcp-client-id or mcp-session-id header\",\n },\n id: null,\n };\n }\n const bundle = this.clientCache.get(clientId);\n const transport = bundle?.sessions.get(sessionId);\n if (!bundle || !transport) {\n reply.code(404);\n return {\n jsonrpc: \"2.0\",\n error: { code: -32000, message: \"Session not found or expired\" },\n id: null,\n };\n }\n try {\n // Best-effort close and evict\n if (typeof (transport as any).close === \"function\") {\n try {\n await (transport as any).close();\n } catch {}\n }\n } finally {\n if (transport?.sessionId) bundle.sessions.delete(transport.sessionId);\n else bundle.sessions.delete(sessionId);\n }\n reply.code(204).send();\n return reply;\n }\n );\n\n // Only listen if we created the app\n if (!this.options.app) {\n await app.listen({ host: this.options.host, port: this.options.port });\n }\n this.app = app;\n }\n\n public async stop(): Promise<void> {\n if (!this.app) return;\n if (!this.options.app) {\n await this.app.close();\n }\n this.app = null;\n }\n}\n","import type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { ExposurePolicy, Mode, ToolSetCatalog } from \"../types/index.js\";\nimport { ServerOrchestrator } from \"../core/ServerOrchestrator.js\";\nimport {\n FastifyTransport,\n type FastifyTransportOptions,\n} from \"../http/FastifyTransport.js\";\n\nexport interface CreateMcpServerOptions {\n catalog: ToolSetCatalog;\n moduleLoaders?: Record<string, any>;\n exposurePolicy?: ExposurePolicy;\n context?: unknown;\n startup?: { mode?: Exclude<Mode, \"ALL\">; toolsets?: string[] | \"ALL\" };\n registerMetaTools?: boolean;\n http?: FastifyTransportOptions;\n /** Factory to create an MCP server instance. Required.\n * In DYNAMIC mode, a new instance is created per client bundle.\n * In STATIC mode, a single instance is created and reused across bundles.\n */\n createServer: () => McpServer;\n configSchema?: object;\n}\n\nexport async function createMcpServer(options: CreateMcpServerOptions) {\n const mode: Exclude<Mode, \"ALL\"> = options.startup?.mode ?? \"DYNAMIC\";\n if (typeof options.createServer !== \"function\") {\n throw new Error(\"createMcpServer: `createServer` (factory) is required\");\n }\n const baseServer: McpServer = options.createServer();\n\n // Typed, guarded notifier\n type NotifierA = {\n server: { notification: (msg: { method: string }) => Promise<void> | void };\n };\n type NotifierB = { notifyToolsListChanged: () => Promise<void> | void };\n const hasNotifierA = (s: unknown): s is NotifierA =>\n typeof (s as any)?.server?.notification === \"function\";\n const hasNotifierB = (s: unknown): s is NotifierB =>\n typeof (s as any)?.notifyToolsListChanged === \"function\";\n const notifyToolsChanged = async (target: unknown) => {\n try {\n if (hasNotifierA(target)) {\n await target.server.notification({\n method: \"notifications/tools/list_changed\",\n });\n return;\n }\n if (hasNotifierB(target)) {\n await target.notifyToolsListChanged();\n }\n } catch {}\n };\n\n const orchestrator = new ServerOrchestrator({\n server: baseServer,\n catalog: options.catalog,\n moduleLoaders: options.moduleLoaders,\n exposurePolicy: options.exposurePolicy,\n context: options.context,\n notifyToolsListChanged: async () => notifyToolsChanged(baseServer),\n startup: options.startup,\n registerMetaTools:\n options.registerMetaTools !== undefined\n ? options.registerMetaTools\n : mode === \"DYNAMIC\",\n });\n\n const transport = new FastifyTransport(\n orchestrator.getManager(),\n () => {\n // Create a server + orchestrator bundle\n // for a new client when needed\n if (mode === \"STATIC\") {\n // Reuse the base server and orchestrator to avoid duplicate registrations\n return { server: baseServer, orchestrator };\n }\n const createdServer: McpServer = options.createServer();\n const createdOrchestrator = new ServerOrchestrator({\n server: createdServer,\n catalog: options.catalog,\n moduleLoaders: options.moduleLoaders,\n exposurePolicy: options.exposurePolicy,\n context: options.context,\n notifyToolsListChanged: async () => notifyToolsChanged(createdServer),\n startup: options.startup,\n registerMetaTools:\n options.registerMetaTools !== undefined\n ? options.registerMetaTools\n : mode === \"DYNAMIC\",\n });\n return { server: createdServer, orchestrator: createdOrchestrator };\n },\n options.http,\n options.configSchema\n );\n\n return {\n server: baseServer,\n start: async () => {\n await transport.start();\n },\n close: async () => {\n await transport.stop();\n },\n };\n}\n"],"names":["DEFAULT_KEYS","ToolsetValidator","options","env","args","input","catalog","raw","s","valid","result","name","toolsets","modules","def","m","sanitized","toolsetNames","error","source","key","value","ModuleResolver","context","collected","modKey","loader","loaded","err","ToolingError","message","code","details","_options","ToolRegistry","toolsetKey","toolName","set","tools","safe","k","v","DynamicToolManager","toolsetName","validation","resolvedTools","mapped","activeToolsets","results","res","successAll","tool","all","registerMetaTools","server","manager","mode","z","available","byToolset","items","payload","status","ServerOrchestrator","startup","resolved","toolRegistry","initial","names","isValid","ClientResourceCache","pruneEvery","entry","resource","newEntry","lruKey","now","FastifyTransport","defaultManager","createBundle","configSchema","app","Fastify","cors","base","_req","reply","req","clientIdHeader","clientId","randomUUID","useCache","bundle","created","providedSessions","sessionId","transport","isInitializeRequest","newSessionId","StreamableHTTPServerTransport","sid","createMcpServer","baseServer","hasNotifierA","hasNotifierB","notifyToolsChanged","target","orchestrator","createdServer","createdOrchestrator"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createMcpServer.d.ts","sourceRoot":"","sources":["../../src/server/createMcpServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE9E,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;KAAE,CAAC;IACvE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,uBAAuB,CAAC;IAC/B;;;OAGG;IACH,YAAY,EAAE,MAAM,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB;;;;
|
|
1
|
+
{"version":3,"file":"createMcpServer.d.ts","sourceRoot":"","sources":["../../src/server/createMcpServer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAE9E,OAAO,EAEL,KAAK,uBAAuB,EAC7B,MAAM,6BAA6B,CAAC;AAErC,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,cAAc,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACpC,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;KAAE,CAAC;IACvE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,IAAI,CAAC,EAAE,uBAAuB,CAAC;IAC/B;;;OAGG;IACH,YAAY,EAAE,MAAM,SAAS,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,eAAe,CAAC,OAAO,EAAE,sBAAsB;;;;GAkFpE"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "toolception",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"@types/node": "^20.11.5",
|
|
34
34
|
"@vitest/coverage-v8": "^3.2.4",
|
|
35
35
|
"tsx": "^4.19.0",
|
|
36
|
-
"typescript": "^5.
|
|
36
|
+
"typescript": "^5.9.2",
|
|
37
37
|
"vite": "^5.3.1",
|
|
38
38
|
"vite-plugin-dts": "^4.5.4",
|
|
39
39
|
"vitest": "^3.2.4"
|