toolception 0.5.3 → 0.5.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/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
- var se = Object.defineProperty;
1
+ var te = Object.defineProperty;
2
2
  var L = (r) => {
3
3
  throw TypeError(r);
4
4
  };
5
- var te = (r, e, s) => e in r ? se(r, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : r[e] = s;
6
- var d = (r, e, s) => te(r, typeof e != "symbol" ? e + "" : e, s), oe = (r, e, s) => e.has(r) || L("Cannot " + s);
7
- var b = (r, e, s) => e.has(r) ? L("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(r) : e.set(r, s);
8
- var m = (r, e, s) => (oe(r, e, "access private method"), s);
5
+ var se = (r, e, t) => e in r ? te(r, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : r[e] = t;
6
+ var d = (r, e, t) => se(r, typeof e != "symbol" ? e + "" : e, t), oe = (r, e, t) => e.has(r) || L("Cannot " + t);
7
+ var b = (r, e, t) => e.has(r) ? L("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(r) : e.set(r, t);
8
+ var m = (r, e, t) => (oe(r, e, "access private method"), t);
9
9
  import { z as y } from "zod";
10
10
  import j from "fastify";
11
11
  import k from "@fastify/cors";
12
12
  import { randomUUID as T } from "node:crypto";
13
13
  import { StreamableHTTPServerTransport as D } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
14
- import { isInitializeRequest as z } from "@modelcontextprotocol/sdk/types.js";
14
+ import { isInitializeRequest as O } from "@modelcontextprotocol/sdk/types.js";
15
15
  const R = {
16
16
  dynamic: [
17
17
  "dynamic-tool-discovery",
@@ -28,13 +28,13 @@ class re {
28
28
  toolsets: e.keys?.toolsets ?? R.toolsets
29
29
  };
30
30
  }
31
- resolveMode(e, s) {
32
- return this.isDynamicEnabled(s) ? "DYNAMIC" : this.getToolsetsString(s) ? "STATIC" : this.isDynamicEnabled(e) ? "DYNAMIC" : this.getToolsetsString(e) ? "STATIC" : null;
31
+ resolveMode(e, t) {
32
+ return this.isDynamicEnabled(t) ? "DYNAMIC" : this.getToolsetsString(t) ? "STATIC" : this.isDynamicEnabled(e) ? "DYNAMIC" : this.getToolsetsString(e) ? "STATIC" : null;
33
33
  }
34
- parseCommaSeparatedToolSets(e, s) {
34
+ parseCommaSeparatedToolSets(e, t) {
35
35
  if (!e || typeof e != "string") return [];
36
- const t = e.split(",").map((n) => n.trim()).filter((n) => n.length > 0), o = new Set(Object.keys(s)), i = [];
37
- for (const n of t)
36
+ const s = e.split(",").map((n) => n.trim()).filter((n) => n.length > 0), o = new Set(Object.keys(t)), i = [];
37
+ for (const n of s)
38
38
  o.has(n) ? i.push(n) : console.warn(
39
39
  `Invalid toolset '${n}' ignored. Available: ${Array.from(
40
40
  o
@@ -42,32 +42,32 @@ class re {
42
42
  );
43
43
  return i;
44
44
  }
45
- getModulesForToolSets(e, s) {
46
- const t = /* @__PURE__ */ new Set();
45
+ getModulesForToolSets(e, t) {
46
+ const s = /* @__PURE__ */ new Set();
47
47
  for (const o of e) {
48
- const i = s[o];
49
- i && (i.modules || []).forEach((n) => t.add(n));
48
+ const i = t[o];
49
+ i && (i.modules || []).forEach((n) => s.add(n));
50
50
  }
51
- return Array.from(t);
51
+ return Array.from(s);
52
52
  }
53
- validateToolsetName(e, s) {
53
+ validateToolsetName(e, t) {
54
54
  if (!e || typeof e != "string")
55
55
  return {
56
56
  isValid: !1,
57
57
  error: `Invalid toolset name provided. Must be a non-empty string. Available toolsets: ${Object.keys(
58
- s
58
+ t
59
59
  ).join(", ")}`
60
60
  };
61
- const t = e.trim();
62
- return t.length === 0 ? {
61
+ const s = e.trim();
62
+ return s.length === 0 ? {
63
63
  isValid: !1,
64
64
  error: `Empty toolset name provided. Available toolsets: ${Object.keys(
65
- s
65
+ t
66
66
  ).join(", ")}`
67
- } : s[t] ? { isValid: !0, sanitized: t } : {
67
+ } : t[s] ? { isValid: !0, sanitized: s } : {
68
68
  isValid: !1,
69
- error: `Toolset '${t}' not found. Available toolsets: ${Object.keys(
70
- s
69
+ error: `Toolset '${s}' not found. Available toolsets: ${Object.keys(
70
+ t
71
71
  ).join(", ")}`
72
72
  };
73
73
  }
@@ -78,37 +78,37 @@ class re {
78
78
  * @param catalog - The toolset catalog to validate against
79
79
  * @returns Validation result with modules array if valid
80
80
  */
81
- validateToolsetModules(e, s) {
81
+ validateToolsetModules(e, t) {
82
82
  try {
83
83
  for (const o of e)
84
- if (!s[o])
84
+ if (!t[o])
85
85
  return {
86
86
  isValid: !1,
87
87
  error: `Toolset '${o}' not found in catalog`
88
88
  };
89
- return { isValid: !0, modules: this.getModulesForToolSets(e, s) };
90
- } catch (t) {
89
+ return { isValid: !0, modules: this.getModulesForToolSets(e, t) };
90
+ } catch (s) {
91
91
  return {
92
92
  isValid: !1,
93
- error: `Error resolving modules for ${e.join(", ")}: ${t instanceof Error ? t.message : "Unknown error"}`
93
+ error: `Error resolving modules for ${e.join(", ")}: ${s instanceof Error ? s.message : "Unknown error"}`
94
94
  };
95
95
  }
96
96
  }
97
97
  isDynamicEnabled(e) {
98
98
  if (!e) return !1;
99
- for (const s of this.keys.dynamic) {
100
- const t = e[s];
101
- if (t === !0 || typeof t == "string" && t.trim().toLowerCase() === "true")
99
+ for (const t of this.keys.dynamic) {
100
+ const s = e[t];
101
+ if (s === !0 || typeof s == "string" && s.trim().toLowerCase() === "true")
102
102
  return !0;
103
103
  }
104
104
  return !1;
105
105
  }
106
106
  getToolsetsString(e) {
107
107
  if (e)
108
- for (const s of this.keys.toolsets) {
109
- const t = e[s];
110
- if (typeof t == "string" && t.trim().length > 0)
111
- return t;
108
+ for (const t of this.keys.toolsets) {
109
+ const s = e[t];
110
+ if (typeof s == "string" && s.trim().length > 0)
111
+ return s;
112
112
  }
113
113
  }
114
114
  }
@@ -132,30 +132,30 @@ class ie {
132
132
  ", "
133
133
  )}`
134
134
  };
135
- const s = e.trim();
136
- return s.length === 0 ? {
135
+ const t = e.trim();
136
+ return t.length === 0 ? {
137
137
  isValid: !1,
138
138
  error: `Empty toolset name provided. Available toolsets: ${this.getAvailableToolsets().join(
139
139
  ", "
140
140
  )}`
141
- } : this.catalog[s] ? { isValid: !0, sanitized: s } : {
141
+ } : this.catalog[t] ? { isValid: !0, sanitized: t } : {
142
142
  isValid: !1,
143
- error: `Toolset '${s}' not found. Available toolsets: ${this.getAvailableToolsets().join(
143
+ error: `Toolset '${t}' not found. Available toolsets: ${this.getAvailableToolsets().join(
144
144
  ", "
145
145
  )}`
146
146
  };
147
147
  }
148
- async resolveToolsForToolsets(e, s) {
149
- const t = [];
148
+ async resolveToolsForToolsets(e, t) {
149
+ const s = [];
150
150
  for (const o of e) {
151
151
  const i = this.catalog[o];
152
- if (i && (Array.isArray(i.tools) && i.tools.length > 0 && t.push(...i.tools), Array.isArray(i.modules) && i.modules.length > 0))
152
+ if (i && (Array.isArray(i.tools) && i.tools.length > 0 && s.push(...i.tools), Array.isArray(i.modules) && i.modules.length > 0))
153
153
  for (const n of i.modules) {
154
154
  const l = this.moduleLoaders[n];
155
155
  if (l)
156
156
  try {
157
- const a = await l(s);
158
- Array.isArray(a) && a.length > 0 && t.push(...a);
157
+ const a = await l(t);
158
+ Array.isArray(a) && a.length > 0 && s.push(...a);
159
159
  } catch (a) {
160
160
  console.warn(
161
161
  `Module loader '${n}' failed for toolset '${o}':`,
@@ -164,18 +164,18 @@ class ie {
164
164
  }
165
165
  }
166
166
  }
167
- return t;
167
+ return s;
168
168
  }
169
169
  }
170
170
  class N extends Error {
171
- constructor(s, t, o, i) {
172
- super(s);
171
+ constructor(t, s, o, i) {
172
+ super(t);
173
173
  d(this, "code");
174
174
  d(this, "details");
175
- this.name = "ToolingError", this.code = t, this.details = o;
175
+ this.name = "ToolingError", this.code = s, this.details = o;
176
176
  }
177
177
  }
178
- class O {
178
+ class z {
179
179
  constructor(e = {}) {
180
180
  d(this, "options");
181
181
  d(this, "names", /* @__PURE__ */ new Set());
@@ -184,8 +184,8 @@ class O {
184
184
  namespaceWithToolset: e.namespaceWithToolset ?? !0
185
185
  };
186
186
  }
187
- getSafeName(e, s) {
188
- return !this.options.namespaceWithToolset || s.startsWith(`${e}.`) ? s : `${e}.${s}`;
187
+ getSafeName(e, t) {
188
+ return !this.options.namespaceWithToolset || t.startsWith(`${e}.`) ? t : `${e}.${t}`;
189
189
  }
190
190
  has(e) {
191
191
  return this.names.has(e);
@@ -198,20 +198,20 @@ class O {
198
198
  );
199
199
  this.names.add(e);
200
200
  }
201
- addForToolset(e, s) {
202
- this.add(s);
203
- const t = this.toolsetToNames.get(e) ?? /* @__PURE__ */ new Set();
204
- t.add(s), this.toolsetToNames.set(e, t);
201
+ addForToolset(e, t) {
202
+ this.add(t);
203
+ const s = this.toolsetToNames.get(e) ?? /* @__PURE__ */ new Set();
204
+ s.add(t), this.toolsetToNames.set(e, s);
205
205
  }
206
- mapAndValidate(e, s) {
207
- return s.map((t) => {
208
- const o = this.getSafeName(e, t.name);
206
+ mapAndValidate(e, t) {
207
+ return t.map((s) => {
208
+ const o = this.getSafeName(e, s.name);
209
209
  if (this.has(o))
210
210
  throw new N(
211
211
  `Tool name collision for '${o}'`,
212
212
  "E_TOOL_NAME_CONFLICT"
213
213
  );
214
- return { ...t, name: o };
214
+ return { ...s, name: o };
215
215
  });
216
216
  }
217
217
  list() {
@@ -219,8 +219,8 @@ class O {
219
219
  }
220
220
  listByToolset() {
221
221
  const e = {};
222
- for (const [s, t] of this.toolsetToNames.entries())
223
- e[s] = Array.from(t);
222
+ for (const [t, s] of this.toolsetToNames.entries())
223
+ e[t] = Array.from(s);
224
224
  return e;
225
225
  }
226
226
  }
@@ -233,7 +233,7 @@ class ne {
233
233
  d(this, "exposurePolicy");
234
234
  d(this, "toolRegistry");
235
235
  d(this, "activeToolsets", /* @__PURE__ */ new Set());
236
- this.server = e.server, this.resolver = e.resolver, this.context = e.context, this.onToolsListChanged = e.onToolsListChanged, this.exposurePolicy = e.exposurePolicy, this.toolRegistry = e.toolRegistry ?? new O({ namespaceWithToolset: !0 });
236
+ this.server = e.server, this.resolver = e.resolver, this.context = e.context, this.onToolsListChanged = e.onToolsListChanged, this.exposurePolicy = e.exposurePolicy, this.toolRegistry = e.toolRegistry ?? new z({ namespaceWithToolset: !0 });
237
237
  }
238
238
  /**
239
239
  * Sends a tool list change notification if configured.
@@ -268,14 +268,14 @@ class ne {
268
268
  * @param skipNotification - If true, skips the tool list change notification (for batch operations)
269
269
  * @returns Result object with success status and message
270
270
  */
271
- async enableToolset(e, s = !1) {
272
- const t = this.resolver.validateToolsetName(e);
273
- if (!t.isValid || !t.sanitized)
271
+ async enableToolset(e, t = !1) {
272
+ const s = this.resolver.validateToolsetName(e);
273
+ if (!s.isValid || !s.sanitized)
274
274
  return {
275
275
  success: !1,
276
- message: t.error || "Unknown validation error"
276
+ message: s.error || "Unknown validation error"
277
277
  };
278
- const o = t.sanitized;
278
+ const o = s.sanitized;
279
279
  if (this.activeToolsets.has(o))
280
280
  return {
281
281
  success: !1,
@@ -298,7 +298,7 @@ class ne {
298
298
  for (const c of a)
299
299
  this.registerSingleTool(c, o), n.push(c.name);
300
300
  }
301
- return this.activeToolsets.add(o), s || await this.notifyToolsChanged(), {
301
+ return this.activeToolsets.add(o), t || await this.notifyToolsChanged(), {
302
302
  success: !0,
303
303
  message: `Toolset '${o}' enabled successfully. Registered ${l?.length ?? 0} tools.`
304
304
  };
@@ -338,13 +338,13 @@ class ne {
338
338
  * @param toolsetKey - The toolset key for tracking
339
339
  * @private
340
340
  */
341
- registerSingleTool(e, s) {
341
+ registerSingleTool(e, t) {
342
342
  this.server.tool(
343
343
  e.name,
344
344
  e.description,
345
345
  e.inputSchema,
346
- async (t) => await e.handler(t)
347
- ), this.toolRegistry.addForToolset(s, e.name);
346
+ async (s) => await e.handler(s)
347
+ ), this.toolRegistry.addForToolset(t, e.name);
348
348
  }
349
349
  /**
350
350
  * Disables a toolset by name.
@@ -353,21 +353,21 @@ class ne {
353
353
  * @returns Result object with success status and message
354
354
  */
355
355
  async disableToolset(e) {
356
- const s = this.resolver.validateToolsetName(e);
357
- if (!s.isValid || !s.sanitized) {
356
+ const t = this.resolver.validateToolsetName(e);
357
+ if (!t.isValid || !t.sanitized) {
358
358
  const o = Array.from(this.activeToolsets).join(", ") || "none";
359
359
  return {
360
360
  success: !1,
361
- message: `${s.error || "Unknown validation error"} Active toolsets: ${o}`
361
+ message: `${t.error || "Unknown validation error"} Active toolsets: ${o}`
362
362
  };
363
363
  }
364
- const t = s.sanitized;
365
- return this.activeToolsets.has(t) ? (this.activeToolsets.delete(t), await this.notifyToolsChanged(), {
364
+ const s = t.sanitized;
365
+ return this.activeToolsets.has(s) ? (this.activeToolsets.delete(s), await this.notifyToolsChanged(), {
366
366
  success: !0,
367
- message: `Toolset '${t}' disabled successfully. Individual tools remain registered due to MCP limitations.`
367
+ message: `Toolset '${s}' disabled successfully. Individual tools remain registered due to MCP limitations.`
368
368
  }) : {
369
369
  success: !1,
370
- message: `Toolset '${t}' is not currently active. Active toolsets: ${Array.from(this.activeToolsets).join(", ") || "none"}`
370
+ message: `Toolset '${s}' is not currently active. Active toolsets: ${Array.from(this.activeToolsets).join(", ") || "none"}`
371
371
  };
372
372
  }
373
373
  getStatus() {
@@ -388,21 +388,21 @@ class ne {
388
388
  * @returns Result object with overall success status and individual results
389
389
  */
390
390
  async enableToolsets(e) {
391
- const s = [];
391
+ const t = [];
392
392
  for (const n of e)
393
393
  try {
394
394
  const l = await this.enableToolset(n, !0);
395
- s.push({ name: n, ...l });
395
+ t.push({ name: n, ...l });
396
396
  } catch (l) {
397
- s.push({
397
+ t.push({
398
398
  name: n,
399
399
  success: !1,
400
400
  message: l instanceof Error ? l.message : "Unknown error",
401
401
  code: "E_INTERNAL"
402
402
  });
403
403
  }
404
- const t = s.every((n) => n.success), o = s.some((n) => n.success), i = t ? "All toolsets enabled" : o ? "Some toolsets failed to enable" : "All toolsets failed to enable";
405
- return o && await this.notifyToolsChanged(), { success: t, results: s, message: i };
404
+ const s = t.every((n) => n.success), o = t.some((n) => n.success), i = s ? "All toolsets enabled" : o ? "Some toolsets failed to enable" : "All toolsets failed to enable";
405
+ return o && await this.notifyToolsChanged(), { success: s, results: t, message: i };
406
406
  }
407
407
  /**
408
408
  * Enables all available toolsets in a batch operation.
@@ -413,11 +413,12 @@ class ne {
413
413
  return this.enableToolsets(e);
414
414
  }
415
415
  }
416
- function ae(r, e, s) {
417
- (s?.mode ?? "DYNAMIC") === "DYNAMIC" && (r.tool(
416
+ function ae(r, e, t) {
417
+ (t?.mode ?? "DYNAMIC") === "DYNAMIC" && (r.tool(
418
418
  "enable_toolset",
419
419
  "Enable a toolset by name",
420
420
  { name: y.string().describe("Toolset name") },
421
+ { destructiveHint: !0, idempotentHint: !0 },
421
422
  async (o) => {
422
423
  const i = await e.enableToolset(o.name);
423
424
  return {
@@ -428,6 +429,7 @@ function ae(r, e, s) {
428
429
  "disable_toolset",
429
430
  "Disable a toolset by name (state only)",
430
431
  { name: y.string().describe("Toolset name") },
432
+ { destructiveHint: !0, idempotentHint: !0 },
431
433
  async (o) => {
432
434
  const i = await e.disableToolset(o.name);
433
435
  return {
@@ -438,6 +440,7 @@ function ae(r, e, s) {
438
440
  "list_toolsets",
439
441
  "List available toolsets with active status and definitions",
440
442
  {},
443
+ { readOnlyHint: !0, idempotentHint: !0 },
441
444
  async () => {
442
445
  const o = e.getAvailableToolsets(), i = e.getStatus().toolsetToTools, n = o.map((l) => {
443
446
  const a = e.getToolsetDefinition(l);
@@ -463,6 +466,7 @@ function ae(r, e, s) {
463
466
  "describe_toolset",
464
467
  "Describe a toolset with definition, active status and tools",
465
468
  { name: y.string().describe("Toolset name") },
469
+ { readOnlyHint: !0, idempotentHint: !0 },
466
470
  async (o) => {
467
471
  const i = e.getToolsetDefinition(o.name), n = e.getStatus().toolsetToTools;
468
472
  if (!i)
@@ -493,6 +497,7 @@ function ae(r, e, s) {
493
497
  "list_tools",
494
498
  "List currently registered tool names (best effort)",
495
499
  {},
500
+ { readOnlyHint: !0, idempotentHint: !0 },
496
501
  async () => {
497
502
  const o = e.getStatus(), i = {
498
503
  tools: o.tools,
@@ -513,12 +518,12 @@ class A {
513
518
  d(this, "initPromise");
514
519
  d(this, "initError", null);
515
520
  this.toolsetValidator = new re();
516
- const s = e.startup ?? {}, t = this.resolveStartupConfig(s, e.catalog);
517
- this.mode = t.mode, this.resolver = new ie({
521
+ const t = e.startup ?? {}, s = this.resolveStartupConfig(t, e.catalog);
522
+ this.mode = s.mode, this.resolver = new ie({
518
523
  catalog: e.catalog,
519
524
  moduleLoaders: e.moduleLoaders
520
525
  });
521
- const o = new O({
526
+ const o = new z({
522
527
  namespaceWithToolset: e.exposurePolicy?.namespaceToolsWithSetKey ?? !0
523
528
  });
524
529
  this.manager = new ne({
@@ -529,7 +534,7 @@ class A {
529
534
  exposurePolicy: e.exposurePolicy,
530
535
  toolRegistry: o
531
536
  }), e.registerMetaTools !== !1 && ae(e.server, this.manager, { mode: this.mode });
532
- const i = t.toolsets;
537
+ const i = s.toolsets;
533
538
  this.initPromise = this.initializeToolsets(i);
534
539
  }
535
540
  /**
@@ -542,8 +547,8 @@ class A {
542
547
  async initializeToolsets(e) {
543
548
  try {
544
549
  e === "ALL" ? await this.manager.enableToolsets(this.resolver.getAvailableToolsets()) : Array.isArray(e) && e.length > 0 && await this.manager.enableToolsets(e);
545
- } catch (s) {
546
- this.initError = s instanceof Error ? s : new Error(String(s)), console.error("Failed to initialize toolsets:", this.initError);
550
+ } catch (t) {
551
+ this.initError = t instanceof Error ? t : new Error(String(t)), console.error("Failed to initialize toolsets:", this.initError);
547
552
  }
548
553
  }
549
554
  /**
@@ -563,19 +568,19 @@ class A {
563
568
  async isReady() {
564
569
  return await this.initPromise, this.initError === null;
565
570
  }
566
- resolveStartupConfig(e, s) {
571
+ resolveStartupConfig(e, t) {
567
572
  if (e.mode) {
568
573
  if (e.mode === "DYNAMIC" && e.toolsets)
569
574
  return console.warn("startup.toolsets provided but ignored in DYNAMIC mode"), { mode: "DYNAMIC" };
570
575
  if (e.mode === "STATIC") {
571
576
  if (e.toolsets === "ALL")
572
577
  return { mode: "STATIC", toolsets: "ALL" };
573
- const t = Array.isArray(e.toolsets) ? e.toolsets : [], o = [];
574
- for (const i of t) {
575
- const { isValid: n, sanitized: l, error: a } = this.toolsetValidator.validateToolsetName(i, s);
578
+ const s = Array.isArray(e.toolsets) ? e.toolsets : [], o = [];
579
+ for (const i of s) {
580
+ const { isValid: n, sanitized: l, error: a } = this.toolsetValidator.validateToolsetName(i, t);
576
581
  n && l ? o.push(l) : a && console.warn(a);
577
582
  }
578
- if (t.length > 0 && o.length === 0)
583
+ if (s.length > 0 && o.length === 0)
579
584
  throw new Error(
580
585
  "STATIC mode requires valid toolsets or 'ALL'; none were valid"
581
586
  );
@@ -585,16 +590,16 @@ class A {
585
590
  }
586
591
  if (e.toolsets === "ALL") return { mode: "STATIC", toolsets: "ALL" };
587
592
  if (Array.isArray(e.toolsets) && e.toolsets.length > 0) {
588
- const t = [];
593
+ const s = [];
589
594
  for (const o of e.toolsets) {
590
- const { isValid: i, sanitized: n, error: l } = this.toolsetValidator.validateToolsetName(o, s);
591
- i && n ? t.push(n) : l && console.warn(l);
595
+ const { isValid: i, sanitized: n, error: l } = this.toolsetValidator.validateToolsetName(o, t);
596
+ i && n ? s.push(n) : l && console.warn(l);
592
597
  }
593
- if (t.length === 0)
598
+ if (s.length === 0)
594
599
  throw new Error(
595
600
  "STATIC mode requires valid toolsets or 'ALL'; none were valid"
596
601
  );
597
- return { mode: "STATIC", toolsets: t };
602
+ return { mode: "STATIC", toolsets: s };
598
603
  }
599
604
  return { mode: "DYNAMIC" };
600
605
  }
@@ -616,8 +621,8 @@ class V {
616
621
  // Use ReturnType<typeof setInterval> for cross-env typings without NodeJS namespace
617
622
  d(this, "pruneInterval");
618
623
  this.maxSize = e.maxSize ?? 1e3, this.ttlMs = e.ttlMs ?? 1e3 * 60 * 60, this.onEvict = e.onEvict;
619
- const s = e.pruneIntervalMs ?? 1e3 * 60 * 10;
620
- this.pruneInterval = setInterval(() => this.pruneExpired(), s);
624
+ const t = e.pruneIntervalMs ?? 1e3 * 60 * 10;
625
+ this.pruneInterval = setInterval(() => this.pruneExpired(), t);
621
626
  }
622
627
  getEntryCount() {
623
628
  return this.storage.size;
@@ -629,13 +634,13 @@ class V {
629
634
  return this.ttlMs;
630
635
  }
631
636
  get(e) {
632
- const s = this.storage.get(e);
633
- return s ? Date.now() - s.lastAccessed > this.ttlMs ? (this.delete(e), null) : (s.lastAccessed = Date.now(), this.storage.delete(e), this.storage.set(e, s), s.resource) : null;
637
+ const t = this.storage.get(e);
638
+ return t ? Date.now() - t.lastAccessed > this.ttlMs ? (this.delete(e), null) : (t.lastAccessed = Date.now(), this.storage.delete(e), this.storage.set(e, t), t.resource) : null;
634
639
  }
635
- set(e, s) {
640
+ set(e, t) {
636
641
  this.storage.size >= this.maxSize && this.evictLeastRecentlyUsed();
637
- const t = { resource: s, lastAccessed: Date.now() };
638
- this.storage.set(e, t);
642
+ const s = { resource: t, lastAccessed: Date.now() };
643
+ this.storage.set(e, s);
639
644
  }
640
645
  /**
641
646
  * Removes an entry from the cache.
@@ -643,8 +648,8 @@ class V {
643
648
  * @param key - The key to remove
644
649
  */
645
650
  delete(e) {
646
- const s = this.storage.get(e);
647
- s && (this.storage.delete(e), m(this, w, E).call(this, e, s.resource));
651
+ const t = this.storage.get(e);
652
+ t && (this.storage.delete(e), m(this, w, E).call(this, e, t.resource));
648
653
  }
649
654
  /**
650
655
  * Stops the background pruning interval and optionally clears all entries.
@@ -660,8 +665,8 @@ class V {
660
665
  clear() {
661
666
  const e = Array.from(this.storage.entries());
662
667
  this.storage.clear();
663
- for (const [s, t] of e)
664
- m(this, w, E).call(this, s, t.resource);
668
+ for (const [t, s] of e)
669
+ m(this, w, E).call(this, t, s.resource);
665
670
  }
666
671
  /**
667
672
  * Evicts the least recently used entry from the cache.
@@ -676,11 +681,11 @@ class V {
676
681
  * @private
677
682
  */
678
683
  pruneExpired() {
679
- const e = Date.now(), s = [];
680
- for (const [t, o] of this.storage.entries())
681
- e - o.lastAccessed > this.ttlMs && s.push(t);
682
- for (const t of s)
683
- this.delete(t);
684
+ const e = Date.now(), t = [];
685
+ for (const [s, o] of this.storage.entries())
686
+ e - o.lastAccessed > this.ttlMs && t.push(s);
687
+ for (const s of t)
688
+ this.delete(s);
684
689
  }
685
690
  }
686
691
  w = new WeakSet(), /**
@@ -689,20 +694,20 @@ w = new WeakSet(), /**
689
694
  * @param resource - The resource being evicted
690
695
  * @private
691
696
  */
692
- E = function(e, s) {
697
+ E = function(e, t) {
693
698
  if (this.onEvict)
694
699
  try {
695
- const t = this.onEvict(e, s);
696
- t instanceof Promise && t.catch((o) => {
700
+ const s = this.onEvict(e, t);
701
+ s instanceof Promise && s.catch((o) => {
697
702
  console.warn(`Error in cache eviction callback for key '${e}':`, o);
698
703
  });
699
- } catch (t) {
700
- console.warn(`Error in cache eviction callback for key '${e}':`, t);
704
+ } catch (s) {
705
+ console.warn(`Error in cache eviction callback for key '${e}':`, s);
701
706
  }
702
707
  };
703
- function F(r, e, s, t) {
708
+ function F(r, e, t, s) {
704
709
  const o = ["/mcp", "/healthz", "/tools", "/.well-known/mcp-config"];
705
- for (const i of s) {
710
+ for (const i of t) {
706
711
  const n = `${e}${i.path}`;
707
712
  if (o.some(
708
713
  (c) => n.startsWith(`${e}${c}`)
@@ -713,28 +718,28 @@ function F(r, e, s, t) {
713
718
  continue;
714
719
  }
715
720
  const a = i.method.toLowerCase();
716
- r[a](n, async (c, h) => {
721
+ r[a](n, async (c, u) => {
717
722
  try {
718
723
  const f = c.headers["mcp-client-id"]?.trim(), v = f && f.length > 0 ? f : `anon-${T()}`;
719
724
  let x;
720
725
  if (i.bodySchema) {
721
726
  const g = i.bodySchema.safeParse(c.body);
722
727
  if (!g.success)
723
- return S(h, "body", g.error);
728
+ return S(u, "body", g.error);
724
729
  x = g.data;
725
730
  }
726
731
  let I = {};
727
732
  if (i.querySchema) {
728
733
  const g = i.querySchema.safeParse(c.query);
729
734
  if (!g.success)
730
- return S(h, "query", g.error);
735
+ return S(u, "query", g.error);
731
736
  I = g.data;
732
737
  }
733
738
  let M = {};
734
739
  if (i.paramsSchema) {
735
740
  const g = i.paramsSchema.safeParse(c.params);
736
741
  if (!g.success)
737
- return S(h, "params", g.error);
742
+ return S(u, "params", g.error);
738
743
  M = g.data;
739
744
  }
740
745
  const P = {
@@ -744,8 +749,8 @@ function F(r, e, s, t) {
744
749
  headers: c.headers,
745
750
  clientId: v
746
751
  };
747
- if (t?.contextExtractor) {
748
- const g = await t.contextExtractor(c);
752
+ if (s?.contextExtractor) {
753
+ const g = await s.contextExtractor(c);
749
754
  Object.assign(P, g);
750
755
  }
751
756
  const $ = await i.handler(P);
@@ -754,7 +759,7 @@ function F(r, e, s, t) {
754
759
  return g.success ? g.data : (console.error(
755
760
  `Response validation failed for ${i.method} ${i.path}:`,
756
761
  g.error
757
- ), h.code(500), {
762
+ ), u.code(500), {
758
763
  error: {
759
764
  code: "RESPONSE_VALIDATION_ERROR",
760
765
  message: "Internal server error: invalid response format"
@@ -766,7 +771,7 @@ function F(r, e, s, t) {
766
771
  return console.error(
767
772
  `Error in custom endpoint ${i.method} ${i.path}:`,
768
773
  f
769
- ), h.code(500), {
774
+ ), u.code(500), {
770
775
  error: {
771
776
  code: "INTERNAL_ERROR",
772
777
  message: f instanceof Error ? f.message : "Internal server error"
@@ -776,17 +781,17 @@ function F(r, e, s, t) {
776
781
  });
777
782
  }
778
783
  }
779
- function S(r, e, s) {
784
+ function S(r, e, t) {
780
785
  return r.code(400), {
781
786
  error: {
782
787
  code: "VALIDATION_ERROR",
783
788
  message: `Validation failed for ${e}`,
784
- details: s.errors
789
+ details: t.errors
785
790
  }
786
791
  };
787
792
  }
788
793
  class le {
789
- constructor(e, s, t = {}, o) {
794
+ constructor(e, t, s = {}, o) {
790
795
  d(this, "options");
791
796
  d(this, "defaultManager");
792
797
  d(this, "createBundle");
@@ -794,26 +799,26 @@ class le {
794
799
  d(this, "configSchema");
795
800
  // Per-client server bundles and per-client session transports
796
801
  d(this, "clientCache", new V({
797
- onEvict: (e, s) => {
798
- this.cleanupBundle(s);
802
+ onEvict: (e, t) => {
803
+ this.cleanupBundle(t);
799
804
  }
800
805
  }));
801
- this.defaultManager = e, this.createBundle = s, this.options = {
802
- host: t.host ?? "0.0.0.0",
803
- port: t.port ?? 3e3,
804
- basePath: t.basePath ?? "/",
805
- cors: t.cors ?? !0,
806
- logger: t.logger ?? !1,
807
- app: t.app,
808
- customEndpoints: t.customEndpoints
806
+ this.defaultManager = e, this.createBundle = t, this.options = {
807
+ host: s.host ?? "0.0.0.0",
808
+ port: s.port ?? 3e3,
809
+ basePath: s.basePath ?? "/",
810
+ cors: s.cors ?? !0,
811
+ logger: s.logger ?? !1,
812
+ app: s.app,
813
+ customEndpoints: s.customEndpoints
809
814
  }, this.configSchema = o;
810
815
  }
811
816
  async start() {
812
817
  if (this.app) return;
813
818
  const e = this.options.app ?? j({ logger: this.options.logger });
814
819
  this.options.cors && await e.register(k, { origin: !0 });
815
- const s = this.options.basePath.endsWith("/") ? this.options.basePath.slice(0, -1) : this.options.basePath;
816
- e.get(`${s}/healthz`, async () => ({ ok: !0 })), e.get(`${s}/tools`, async () => this.defaultManager.getStatus()), e.get(`${s}/.well-known/mcp-config`, async (t, o) => (o.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
820
+ const t = this.options.basePath.endsWith("/") ? this.options.basePath.slice(0, -1) : this.options.basePath;
821
+ e.get(`${t}/healthz`, async () => ({ ok: !0 })), e.get(`${t}/tools`, async () => this.defaultManager.getStatus()), e.get(`${t}/.well-known/mcp-config`, async (s, o) => (o.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
817
822
  $schema: "https://json-schema.org/draft/2020-12/schema",
818
823
  title: "MCP Session Configuration",
819
824
  description: "Schema for the /mcp endpoint configuration",
@@ -823,9 +828,9 @@ class le {
823
828
  "x-mcp-version": "1.0",
824
829
  "x-query-style": "dot+bracket"
825
830
  })), e.post(
826
- `${s}/mcp`,
827
- async (t, o) => {
828
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : `anon-${T()}`, l = !n.startsWith("anon-");
831
+ `${t}/mcp`,
832
+ async (s, o) => {
833
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : `anon-${T()}`, l = !n.startsWith("anon-");
829
834
  let a = l ? this.clientCache.get(n) : null;
830
835
  if (!a) {
831
836
  const f = this.createBundle(), v = f.sessions;
@@ -835,20 +840,20 @@ class le {
835
840
  sessions: v instanceof Map ? v : /* @__PURE__ */ new Map()
836
841
  }, l && this.clientCache.set(n, a);
837
842
  }
838
- const c = t.headers["mcp-session-id"];
839
- let h;
843
+ const c = s.headers["mcp-session-id"];
844
+ let u;
840
845
  if (c && a.sessions.get(c))
841
- h = a.sessions.get(c);
842
- else if (!c && z(t.body)) {
846
+ u = a.sessions.get(c);
847
+ else if (!c && O(s.body)) {
843
848
  const f = T();
844
- h = new D({
849
+ u = new D({
845
850
  sessionIdGenerator: () => f,
846
851
  onsessioninitialized: (v) => {
847
- a.sessions.set(v, h);
852
+ a.sessions.set(v, u);
848
853
  }
849
854
  });
850
855
  try {
851
- await a.server.connect(h);
856
+ await a.server.connect(u);
852
857
  } catch {
853
858
  return o.code(500), {
854
859
  jsonrpc: "2.0",
@@ -856,8 +861,8 @@ class le {
856
861
  id: null
857
862
  };
858
863
  }
859
- h.onclose = () => {
860
- h?.sessionId && a.sessions.delete(h.sessionId);
864
+ u.onclose = () => {
865
+ u?.sessionId && a.sessions.delete(u.sessionId);
861
866
  };
862
867
  } else
863
868
  return o.code(400), {
@@ -865,28 +870,28 @@ class le {
865
870
  error: { code: -32e3, message: "Session not found or expired" },
866
871
  id: null
867
872
  };
868
- return await h.handleRequest(
869
- t.raw,
873
+ return await u.handleRequest(
874
+ s.raw,
870
875
  o.raw,
871
- t.body
876
+ s.body
872
877
  ), o;
873
878
  }
874
- ), e.get(`${s}/mcp`, async (t, o) => {
875
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
879
+ ), e.get(`${t}/mcp`, async (s, o) => {
880
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
876
881
  if (!n)
877
882
  return o.code(400), "Missing mcp-client-id";
878
883
  const l = this.clientCache.get(n);
879
884
  if (!l)
880
885
  return o.code(400), "Invalid or expired client";
881
- const a = t.headers["mcp-session-id"];
886
+ const a = s.headers["mcp-session-id"];
882
887
  if (!a)
883
888
  return o.code(400), "Missing mcp-session-id";
884
889
  const c = l.sessions.get(a);
885
- return c ? (await c.handleRequest(t.raw, o.raw), o) : (o.code(400), "Invalid or expired session ID");
890
+ return c ? (await c.handleRequest(s.raw, o.raw), o) : (o.code(400), "Invalid or expired session ID");
886
891
  }), e.delete(
887
- `${s}/mcp`,
888
- async (t, o) => {
889
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = t.headers["mcp-session-id"];
892
+ `${t}/mcp`,
893
+ async (s, o) => {
894
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = s.headers["mcp-session-id"];
890
895
  if (!n || !l)
891
896
  return o.code(400), {
892
897
  jsonrpc: "2.0",
@@ -914,7 +919,7 @@ class le {
914
919
  }
915
920
  return o.code(204).send(), o;
916
921
  }
917
- ), this.options.customEndpoints && this.options.customEndpoints.length > 0 && F(e, s, this.options.customEndpoints), this.options.app || await e.listen({ host: this.options.host, port: this.options.port }), this.app = e;
922
+ ), this.options.customEndpoints && this.options.customEndpoints.length > 0 && F(e, t, this.options.customEndpoints), this.options.app || await e.listen({ host: this.options.host, port: this.options.port }), this.app = e;
918
923
  }
919
924
  /**
920
925
  * Stops the Fastify server and cleans up all resources.
@@ -930,13 +935,13 @@ class le {
930
935
  * @private
931
936
  */
932
937
  cleanupBundle(e) {
933
- for (const [s, t] of e.sessions.entries())
938
+ for (const [t, s] of e.sessions.entries())
934
939
  try {
935
- typeof t.close == "function" && t.close().catch((o) => {
936
- console.warn(`Error closing session ${s}:`, o);
940
+ typeof s.close == "function" && s.close().catch((o) => {
941
+ console.warn(`Error closing session ${t}:`, o);
937
942
  });
938
943
  } catch (o) {
939
- console.warn(`Error closing session ${s}:`, o);
944
+ console.warn(`Error closing session ${t}:`, o);
940
945
  }
941
946
  e.sessions.clear();
942
947
  }
@@ -964,9 +969,9 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
964
969
  const e = r.startup?.mode ?? "DYNAMIC";
965
970
  if (typeof r.createServer != "function")
966
971
  throw new Error("createMcpServer: `createServer` (factory) is required");
967
- const s = r.createServer(), t = (a) => typeof a?.server?.notification == "function", o = (a) => typeof a?.notifyToolsListChanged == "function", i = async (a) => {
972
+ const t = r.createServer(), s = (a) => typeof a?.server?.notification == "function", o = (a) => typeof a?.notifyToolsListChanged == "function", i = async (a) => {
968
973
  try {
969
- if (t(a)) {
974
+ if (s(a)) {
970
975
  await a.server.notification({
971
976
  method: "notifications/tools/list_changed"
972
977
  });
@@ -979,12 +984,12 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
979
984
  console.warn("Failed to send tools list changed notification:", c);
980
985
  }
981
986
  }, n = new A({
982
- server: s,
987
+ server: t,
983
988
  catalog: r.catalog,
984
989
  moduleLoaders: r.moduleLoaders,
985
990
  exposurePolicy: r.exposurePolicy,
986
991
  context: r.context,
987
- notifyToolsListChanged: async () => i(s),
992
+ notifyToolsListChanged: async () => i(t),
988
993
  startup: r.startup,
989
994
  registerMetaTools: r.registerMetaTools !== void 0 ? r.registerMetaTools : e === "DYNAMIC"
990
995
  });
@@ -993,7 +998,7 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
993
998
  n.getManager(),
994
999
  () => {
995
1000
  if (e === "STATIC")
996
- return { server: s, orchestrator: n };
1001
+ return { server: t, orchestrator: n };
997
1002
  const a = r.createServer(), c = new A({
998
1003
  server: a,
999
1004
  catalog: r.catalog,
@@ -1010,7 +1015,7 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
1010
1015
  r.configSchema
1011
1016
  );
1012
1017
  return {
1013
- server: s,
1018
+ server: t,
1014
1019
  start: async () => {
1015
1020
  await l.start();
1016
1021
  },
@@ -1020,15 +1025,15 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
1020
1025
  };
1021
1026
  }
1022
1027
  function de(r) {
1023
- he(r), ue(r), fe(r), me(r);
1028
+ ue(r), he(r), fe(r), me(r);
1024
1029
  }
1025
- function he(r) {
1030
+ function ue(r) {
1026
1031
  if (!r || typeof r != "object")
1027
1032
  throw new Error(
1028
1033
  "Permission configuration is required for createPermissionBasedMcpServer"
1029
1034
  );
1030
1035
  }
1031
- function ue(r) {
1036
+ function he(r) {
1032
1037
  if (!r.source)
1033
1038
  throw new Error('Permission source must be either "headers" or "config"');
1034
1039
  if (r.source !== "headers" && r.source !== "config")
@@ -1060,13 +1065,13 @@ function me(r) {
1060
1065
  throw new Error("headerName must be a non-empty string");
1061
1066
  }
1062
1067
  function ge(r) {
1063
- for (const [e, s] of Object.entries(r))
1064
- if (!Array.isArray(s))
1068
+ for (const [e, t] of Object.entries(r))
1069
+ if (!Array.isArray(t))
1065
1070
  throw new Error(
1066
1071
  `staticMap value for client "${e}" must be an array of toolset names`
1067
1072
  );
1068
1073
  }
1069
- var p, _, B, H, Y, W;
1074
+ var p, _, H, B, Y, W;
1070
1075
  class pe {
1071
1076
  /**
1072
1077
  * Creates a new PermissionResolver instance.
@@ -1091,23 +1096,23 @@ class pe {
1091
1096
  * @param headers - Optional request headers (required for header-based permissions)
1092
1097
  * @returns Array of toolset names the client is allowed to access
1093
1098
  */
1094
- resolvePermissions(e, s) {
1099
+ resolvePermissions(e, t) {
1095
1100
  if (this.cache.has(e))
1096
1101
  return this.cache.get(e);
1097
- let t;
1102
+ let s;
1098
1103
  try {
1099
- this.config.source === "headers" ? t = m(this, p, _).call(this, s) : t = m(this, p, H).call(this, e), Array.isArray(t) || (console.warn(
1104
+ this.config.source === "headers" ? s = m(this, p, _).call(this, t) : s = m(this, p, B).call(this, e), Array.isArray(s) || (console.warn(
1100
1105
  `Permission resolution returned non-array for client ${e}, using empty permissions`
1101
- ), t = []), t = t.filter(
1106
+ ), s = []), s = s.filter(
1102
1107
  (o) => typeof o == "string" && o.trim().length > 0
1103
1108
  );
1104
1109
  } catch (o) {
1105
1110
  console.error(
1106
1111
  `Unexpected error resolving permissions for client ${e}:`,
1107
1112
  o
1108
- ), t = [];
1113
+ ), s = [];
1109
1114
  }
1110
- return this.cache.set(e, t), t;
1115
+ return this.cache.set(e, s), s;
1111
1116
  }
1112
1117
  /**
1113
1118
  * Invalidates cached permissions for a specific client.
@@ -1137,15 +1142,15 @@ p = new WeakSet(), /**
1137
1142
  _ = function(e) {
1138
1143
  if (!e)
1139
1144
  return [];
1140
- const s = m(this, p, B).call(this, e, this.normalizedHeaderName);
1141
- if (!s)
1145
+ const t = m(this, p, H).call(this, e, this.normalizedHeaderName);
1146
+ if (!t)
1142
1147
  return [];
1143
1148
  try {
1144
- return s.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
1145
- } catch (t) {
1149
+ return t.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
1150
+ } catch (s) {
1146
1151
  return console.warn(
1147
1152
  `Failed to parse permission header '${this.normalizedHeaderName}':`,
1148
- t
1153
+ s
1149
1154
  ), [];
1150
1155
  }
1151
1156
  }, /**
@@ -1156,11 +1161,11 @@ _ = function(e) {
1156
1161
  * @returns The header value if found, undefined otherwise
1157
1162
  * @private
1158
1163
  */
1159
- B = function(e, s) {
1160
- if (e[s] !== void 0)
1161
- return e[s];
1162
- for (const [t, o] of Object.entries(e))
1163
- if (t.toLowerCase() === s)
1164
+ H = function(e, t) {
1165
+ if (e[t] !== void 0)
1166
+ return e[t];
1167
+ for (const [s, o] of Object.entries(e))
1168
+ if (s.toLowerCase() === t)
1164
1169
  return o;
1165
1170
  }, /**
1166
1171
  * Resolves permissions from server-side configuration.
@@ -1170,16 +1175,16 @@ B = function(e, s) {
1170
1175
  * @returns Array of toolset names from configuration
1171
1176
  * @private
1172
1177
  */
1173
- H = function(e) {
1178
+ B = function(e) {
1174
1179
  if (this.config.resolver) {
1175
- const s = m(this, p, Y).call(this, e);
1176
- if (s !== null)
1177
- return s;
1180
+ const t = m(this, p, Y).call(this, e);
1181
+ if (t !== null)
1182
+ return t;
1178
1183
  }
1179
1184
  if (this.config.staticMap) {
1180
- const s = m(this, p, W).call(this, e);
1181
- if (s !== null)
1182
- return s;
1185
+ const t = m(this, p, W).call(this, e);
1186
+ if (t !== null)
1187
+ return t;
1183
1188
  }
1184
1189
  return this.config.defaultPermissions || [];
1185
1190
  }, /**
@@ -1191,14 +1196,14 @@ H = function(e) {
1191
1196
  */
1192
1197
  Y = function(e) {
1193
1198
  try {
1194
- const s = this.config.resolver(e);
1195
- return Array.isArray(s) ? s : (console.warn(
1199
+ const t = this.config.resolver(e);
1200
+ return Array.isArray(t) ? t : (console.warn(
1196
1201
  `Permission resolver returned non-array for client ${e}, using fallback`
1197
1202
  ), null);
1198
- } catch (s) {
1199
- const t = s instanceof Error ? s.message : String(s);
1203
+ } catch (t) {
1204
+ const s = t instanceof Error ? t.message : String(t);
1200
1205
  return console.warn(
1201
- `Permission resolver declined client ${e} (${t}), trying fallback`
1206
+ `Permission resolver declined client ${e} (${s}), trying fallback`
1202
1207
  ), null;
1203
1208
  }
1204
1209
  }, /**
@@ -1209,24 +1214,24 @@ Y = function(e) {
1209
1214
  * @private
1210
1215
  */
1211
1216
  W = function(e) {
1212
- const s = this.config.staticMap[e];
1213
- return s !== void 0 ? Array.isArray(s) ? s : [] : null;
1217
+ const t = this.config.staticMap[e];
1218
+ return t !== void 0 ? Array.isArray(t) ? t : [] : null;
1214
1219
  };
1215
1220
  function ye(r, e) {
1216
- return async (s) => {
1217
- const t = e.resolvePermissions(
1218
- s.clientId,
1219
- s.headers
1220
- ), o = r(t), i = o.orchestrator.getManager(), n = [], l = [];
1221
- if (t.length > 0) {
1222
- const a = await i.enableToolsets(t);
1221
+ return async (t) => {
1222
+ const s = e.resolvePermissions(
1223
+ t.clientId,
1224
+ t.headers
1225
+ ), o = r(s), i = o.orchestrator.getManager(), n = [], l = [];
1226
+ if (s.length > 0) {
1227
+ const a = await i.enableToolsets(s);
1223
1228
  for (const c of a.results)
1224
1229
  c.success ? n.push(c.name) : (l.push(c.name), console.warn(
1225
- `Failed to enable toolset '${c.name}' for client '${s.clientId}': ${c.message}`
1230
+ `Failed to enable toolset '${c.name}' for client '${t.clientId}': ${c.message}`
1226
1231
  ));
1227
1232
  if (n.length === 0 && l.length > 0)
1228
1233
  throw new Error(
1229
- `All requested toolsets failed to enable for client '${s.clientId}'. Requested: [${t.join(", ")}]. Check that toolset names in permissions match the catalog.`
1234
+ `All requested toolsets failed to enable for client '${t.clientId}'. Requested: [${s.join(", ")}]. Check that toolset names in permissions match the catalog.`
1230
1235
  );
1231
1236
  }
1232
1237
  return {
@@ -1237,7 +1242,7 @@ function ye(r, e) {
1237
1242
  };
1238
1243
  };
1239
1244
  }
1240
- var u, U, q, J, G, K, Z, Q, X, C, ee;
1245
+ var h, U, q, J, G, K, Z, Q, X, C, ee;
1241
1246
  class ve {
1242
1247
  /**
1243
1248
  * Creates a new PermissionAwareFastifyTransport instance.
@@ -1246,8 +1251,8 @@ class ve {
1246
1251
  * @param options - Transport configuration options
1247
1252
  * @param configSchema - Optional JSON schema for configuration discovery
1248
1253
  */
1249
- constructor(e, s, t = {}, o) {
1250
- b(this, u);
1254
+ constructor(e, t, s = {}, o) {
1255
+ b(this, h);
1251
1256
  d(this, "options");
1252
1257
  d(this, "defaultManager");
1253
1258
  d(this, "createPermissionAwareBundle");
@@ -1255,18 +1260,18 @@ class ve {
1255
1260
  d(this, "configSchema");
1256
1261
  // Per-client server bundles and per-client session transports
1257
1262
  d(this, "clientCache", new V({
1258
- onEvict: (e, s) => {
1259
- m(this, u, U).call(this, s);
1263
+ onEvict: (e, t) => {
1264
+ m(this, h, U).call(this, t);
1260
1265
  }
1261
1266
  }));
1262
- this.defaultManager = e, this.createPermissionAwareBundle = s, this.options = {
1263
- host: t.host ?? "0.0.0.0",
1264
- port: t.port ?? 3e3,
1265
- basePath: t.basePath ?? "/",
1266
- cors: t.cors ?? !0,
1267
- logger: t.logger ?? !1,
1268
- app: t.app,
1269
- customEndpoints: t.customEndpoints
1267
+ this.defaultManager = e, this.createPermissionAwareBundle = t, this.options = {
1268
+ host: s.host ?? "0.0.0.0",
1269
+ port: s.port ?? 3e3,
1270
+ basePath: s.basePath ?? "/",
1271
+ cors: s.cors ?? !0,
1272
+ logger: s.logger ?? !1,
1273
+ app: s.app,
1274
+ customEndpoints: s.customEndpoints
1270
1275
  }, this.configSchema = o;
1271
1276
  }
1272
1277
  /**
@@ -1277,10 +1282,10 @@ class ve {
1277
1282
  if (this.app) return;
1278
1283
  const e = this.options.app ?? j({ logger: this.options.logger });
1279
1284
  this.options.cors && await e.register(k, { origin: !0 });
1280
- const s = m(this, u, q).call(this, this.options.basePath);
1281
- m(this, u, J).call(this, e, s), m(this, u, G).call(this, e, s), m(this, u, K).call(this, e, s), m(this, u, Z).call(this, e, s), m(this, u, Q).call(this, e, s), m(this, u, X).call(this, e, s), this.options.customEndpoints && this.options.customEndpoints.length > 0 && F(e, s, this.options.customEndpoints, {
1282
- contextExtractor: async (t) => {
1283
- const o = m(this, u, C).call(this, t);
1285
+ const t = m(this, h, q).call(this, this.options.basePath);
1286
+ m(this, h, J).call(this, e, t), m(this, h, G).call(this, e, t), m(this, h, K).call(this, e, t), m(this, h, Z).call(this, e, t), m(this, h, Q).call(this, e, t), m(this, h, X).call(this, e, t), this.options.customEndpoints && this.options.customEndpoints.length > 0 && F(e, t, this.options.customEndpoints, {
1287
+ contextExtractor: async (s) => {
1288
+ const o = m(this, h, C).call(this, s);
1284
1289
  try {
1285
1290
  const i = await this.createPermissionAwareBundle(o);
1286
1291
  return {
@@ -1306,20 +1311,20 @@ class ve {
1306
1311
  this.app && (this.clientCache.stop(!0), this.options.app || await this.app.close(), this.app = null);
1307
1312
  }
1308
1313
  }
1309
- u = new WeakSet(), /**
1314
+ h = new WeakSet(), /**
1310
1315
  * Cleans up resources associated with a client bundle.
1311
1316
  * Closes all sessions within the bundle.
1312
1317
  * @param bundle - The client bundle to clean up
1313
1318
  * @private
1314
1319
  */
1315
1320
  U = function(e) {
1316
- for (const [s, t] of e.sessions.entries())
1321
+ for (const [t, s] of e.sessions.entries())
1317
1322
  try {
1318
- typeof t.close == "function" && t.close().catch((o) => {
1319
- console.warn(`Error closing session ${s}:`, o);
1323
+ typeof s.close == "function" && s.close().catch((o) => {
1324
+ console.warn(`Error closing session ${t}:`, o);
1320
1325
  });
1321
1326
  } catch (o) {
1322
- console.warn(`Error closing session ${s}:`, o);
1327
+ console.warn(`Error closing session ${t}:`, o);
1323
1328
  }
1324
1329
  e.sessions.clear();
1325
1330
  }, /**
@@ -1336,24 +1341,24 @@ q = function(e) {
1336
1341
  * @param base - Base path for routes
1337
1342
  * @private
1338
1343
  */
1339
- J = function(e, s) {
1340
- e.get(`${s}/healthz`, async () => ({ ok: !0 }));
1344
+ J = function(e, t) {
1345
+ e.get(`${t}/healthz`, async () => ({ ok: !0 }));
1341
1346
  }, /**
1342
1347
  * Registers the tools status endpoint.
1343
1348
  * @param app - Fastify instance
1344
1349
  * @param base - Base path for routes
1345
1350
  * @private
1346
1351
  */
1347
- G = function(e, s) {
1348
- e.get(`${s}/tools`, async () => this.defaultManager.getStatus());
1352
+ G = function(e, t) {
1353
+ e.get(`${t}/tools`, async () => this.defaultManager.getStatus());
1349
1354
  }, /**
1350
1355
  * Registers the MCP configuration discovery endpoint.
1351
1356
  * @param app - Fastify instance
1352
1357
  * @param base - Base path for routes
1353
1358
  * @private
1354
1359
  */
1355
- K = function(e, s) {
1356
- e.get(`${s}/.well-known/mcp-config`, async (t, o) => (o.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
1360
+ K = function(e, t) {
1361
+ e.get(`${t}/.well-known/mcp-config`, async (s, o) => (o.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
1357
1362
  $schema: "https://json-schema.org/draft/2020-12/schema",
1358
1363
  title: "MCP Session Configuration",
1359
1364
  description: "Schema for the /mcp endpoint configuration",
@@ -1370,40 +1375,40 @@ K = function(e, s) {
1370
1375
  * @param base - Base path for routes
1371
1376
  * @private
1372
1377
  */
1373
- Z = function(e, s) {
1378
+ Z = function(e, t) {
1374
1379
  e.post(
1375
- `${s}/mcp`,
1376
- async (t, o) => {
1377
- const i = m(this, u, C).call(this, t), n = !i.clientId.startsWith("anon-");
1380
+ `${t}/mcp`,
1381
+ async (s, o) => {
1382
+ const i = m(this, h, C).call(this, s), n = !i.clientId.startsWith("anon-");
1378
1383
  let l = n ? this.clientCache.get(i.clientId) : null;
1379
1384
  if (!l)
1380
1385
  try {
1381
- const h = await this.createPermissionAwareBundle(i);
1382
- h.failedToolsets.length > 0 && console.warn(
1383
- `Client ${i.clientId} had ${h.failedToolsets.length} toolsets fail to enable: [${h.failedToolsets.join(", ")}]. Successfully enabled: [${h.allowedToolsets.join(", ")}]`
1386
+ const u = await this.createPermissionAwareBundle(i);
1387
+ u.failedToolsets.length > 0 && console.warn(
1388
+ `Client ${i.clientId} had ${u.failedToolsets.length} toolsets fail to enable: [${u.failedToolsets.join(", ")}]. Successfully enabled: [${u.allowedToolsets.join(", ")}]`
1384
1389
  );
1385
- const f = h.sessions;
1390
+ const f = u.sessions;
1386
1391
  l = {
1387
- server: h.server,
1388
- orchestrator: h.orchestrator,
1389
- allowedToolsets: h.allowedToolsets,
1390
- failedToolsets: h.failedToolsets,
1392
+ server: u.server,
1393
+ orchestrator: u.orchestrator,
1394
+ allowedToolsets: u.allowedToolsets,
1395
+ failedToolsets: u.failedToolsets,
1391
1396
  sessions: f instanceof Map ? f : /* @__PURE__ */ new Map()
1392
1397
  }, n && this.clientCache.set(i.clientId, l);
1393
- } catch (h) {
1398
+ } catch (u) {
1394
1399
  return console.error(
1395
1400
  `Failed to create permission-aware bundle for client ${i.clientId}:`,
1396
- h
1397
- ), o.code(403), m(this, u, ee).call(this, "Access denied");
1401
+ u
1402
+ ), o.code(403), m(this, h, ee).call(this, "Access denied");
1398
1403
  }
1399
- const a = t.headers["mcp-session-id"];
1404
+ const a = s.headers["mcp-session-id"];
1400
1405
  let c;
1401
1406
  if (a && l.sessions.get(a))
1402
1407
  c = l.sessions.get(a);
1403
- else if (!a && z(t.body)) {
1404
- const h = T();
1408
+ else if (!a && O(s.body)) {
1409
+ const u = T();
1405
1410
  c = new D({
1406
- sessionIdGenerator: () => h,
1411
+ sessionIdGenerator: () => u,
1407
1412
  onsessioninitialized: (f) => {
1408
1413
  l.sessions.set(f, c);
1409
1414
  }
@@ -1427,9 +1432,9 @@ Z = function(e, s) {
1427
1432
  id: null
1428
1433
  };
1429
1434
  return await c.handleRequest(
1430
- t.raw,
1435
+ s.raw,
1431
1436
  o.raw,
1432
- t.body
1437
+ s.body
1433
1438
  ), o;
1434
1439
  }
1435
1440
  );
@@ -1439,19 +1444,19 @@ Z = function(e, s) {
1439
1444
  * @param base - Base path for routes
1440
1445
  * @private
1441
1446
  */
1442
- Q = function(e, s) {
1443
- e.get(`${s}/mcp`, async (t, o) => {
1444
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
1447
+ Q = function(e, t) {
1448
+ e.get(`${t}/mcp`, async (s, o) => {
1449
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
1445
1450
  if (!n)
1446
1451
  return o.code(400), "Missing mcp-client-id";
1447
1452
  const l = this.clientCache.get(n);
1448
1453
  if (!l)
1449
1454
  return o.code(400), "Invalid or expired client";
1450
- const a = t.headers["mcp-session-id"];
1455
+ const a = s.headers["mcp-session-id"];
1451
1456
  if (!a)
1452
1457
  return o.code(400), "Missing mcp-session-id";
1453
1458
  const c = l.sessions.get(a);
1454
- return c ? (await c.handleRequest(t.raw, o.raw), o) : (o.code(400), "Invalid or expired session ID");
1459
+ return c ? (await c.handleRequest(s.raw, o.raw), o) : (o.code(400), "Invalid or expired session ID");
1455
1460
  });
1456
1461
  }, /**
1457
1462
  * Registers the DELETE /mcp endpoint for session termination.
@@ -1459,11 +1464,11 @@ Q = function(e, s) {
1459
1464
  * @param base - Base path for routes
1460
1465
  * @private
1461
1466
  */
1462
- X = function(e, s) {
1467
+ X = function(e, t) {
1463
1468
  e.delete(
1464
- `${s}/mcp`,
1465
- async (t, o) => {
1466
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = t.headers["mcp-session-id"];
1469
+ `${t}/mcp`,
1470
+ async (s, o) => {
1471
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = s.headers["mcp-session-id"];
1467
1472
  if (!n || !l)
1468
1473
  return o.code(400), {
1469
1474
  jsonrpc: "2.0",
@@ -1500,10 +1505,10 @@ X = function(e, s) {
1500
1505
  * @private
1501
1506
  */
1502
1507
  C = function(e) {
1503
- const s = e.headers["mcp-client-id"]?.trim(), t = s && s.length > 0 ? s : `anon-${T()}`, o = {};
1508
+ const t = e.headers["mcp-client-id"]?.trim(), s = t && t.length > 0 ? t : `anon-${T()}`, o = {};
1504
1509
  for (const [i, n] of Object.entries(e.headers))
1505
1510
  typeof n == "string" && (o[i] = n);
1506
- return { clientId: t, headers: o };
1511
+ return { clientId: s, headers: o };
1507
1512
  }, /**
1508
1513
  * Creates a safe error response that doesn't expose unauthorized toolset information.
1509
1514
  * Used for permission-related errors to prevent information leakage.
@@ -1512,11 +1517,11 @@ C = function(e) {
1512
1517
  * @returns JSON-RPC error response object
1513
1518
  * @private
1514
1519
  */
1515
- ee = function(e = "Access denied", s = -32e3) {
1520
+ ee = function(e = "Access denied", t = -32e3) {
1516
1521
  return {
1517
1522
  jsonrpc: "2.0",
1518
1523
  error: {
1519
- code: s,
1524
+ code: t,
1520
1525
  message: e
1521
1526
  },
1522
1527
  id: null
@@ -1552,8 +1557,8 @@ async function Me(r) {
1552
1557
  );
1553
1558
  const e = Te(
1554
1559
  r.exposurePolicy
1555
- ), s = new pe(r.permissions), t = r.createServer(), o = new A({
1556
- server: t,
1560
+ ), t = new pe(r.permissions), s = r.createServer(), o = new A({
1561
+ server: s,
1557
1562
  catalog: r.catalog,
1558
1563
  moduleLoaders: r.moduleLoaders,
1559
1564
  exposurePolicy: e,
@@ -1579,7 +1584,7 @@ async function Me(r) {
1579
1584
  });
1580
1585
  return { server: a, orchestrator: c };
1581
1586
  },
1582
- s
1587
+ t
1583
1588
  ), n = new ve(
1584
1589
  o.getManager(),
1585
1590
  i,
@@ -1587,7 +1592,7 @@ async function Me(r) {
1587
1592
  r.configSchema
1588
1593
  );
1589
1594
  return {
1590
- server: t,
1595
+ server: s,
1591
1596
  start: async () => {
1592
1597
  await n.start();
1593
1598
  },
@@ -1595,7 +1600,7 @@ async function Me(r) {
1595
1600
  try {
1596
1601
  await n.stop();
1597
1602
  } finally {
1598
- s.clearCache();
1603
+ t.clearCache();
1599
1604
  }
1600
1605
  }
1601
1606
  };