toolception 0.5.5 → 0.6.1

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;
2
- var L = (r) => {
3
- throw TypeError(r);
1
+ var re = Object.defineProperty;
2
+ var j = (o) => {
3
+ throw TypeError(o);
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);
9
- import { z as y } from "zod";
10
- import j from "fastify";
11
- import k from "@fastify/cors";
12
- import { randomUUID as T } from "node:crypto";
13
- import { StreamableHTTPServerTransport as O } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
14
- import { isInitializeRequest as D } from "@modelcontextprotocol/sdk/types.js";
5
+ var ie = (o, e, t) => e in o ? re(o, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : o[e] = t;
6
+ var d = (o, e, t) => ie(o, typeof e != "symbol" ? e + "" : e, t), ne = (o, e, t) => e.has(o) || j("Cannot " + t);
7
+ var A = (o, e, t) => e.has(o) ? j("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(o) : e.set(o, t);
8
+ var m = (o, e, t) => (ne(o, e, "access private method"), t);
9
+ import { z as v } from "zod";
10
+ import N from "fastify";
11
+ import D from "@fastify/cors";
12
+ import { randomUUID as S, createHash as ae } from "node:crypto";
13
+ import { StreamableHTTPServerTransport as z } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
14
+ import { isInitializeRequest as _ } from "@modelcontextprotocol/sdk/types.js";
15
15
  const R = {
16
16
  dynamic: [
17
17
  "dynamic-tool-discovery",
@@ -20,7 +20,7 @@ const R = {
20
20
  ],
21
21
  toolsets: ["tool-sets", "toolSets", "FMP_TOOL_SETS"]
22
22
  };
23
- class re {
23
+ class le {
24
24
  constructor(e = {}) {
25
25
  d(this, "keys");
26
26
  this.keys = {
@@ -28,46 +28,46 @@ 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)
38
- o.has(n) ? i.push(n) : console.warn(
36
+ const s = e.split(",").map((n) => n.trim()).filter((n) => n.length > 0), r = new Set(Object.keys(t)), i = [];
37
+ for (const n of s)
38
+ r.has(n) ? i.push(n) : console.warn(
39
39
  `Invalid toolset '${n}' ignored. Available: ${Array.from(
40
- o
40
+ r
41
41
  ).join(", ")}`
42
42
  );
43
43
  return i;
44
44
  }
45
- getModulesForToolSets(e, s) {
46
- const t = /* @__PURE__ */ new Set();
47
- for (const o of e) {
48
- const i = s[o];
49
- i && (i.modules || []).forEach((n) => t.add(n));
45
+ getModulesForToolSets(e, t) {
46
+ const s = /* @__PURE__ */ new Set();
47
+ for (const r of e) {
48
+ const i = t[r];
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,44 +78,50 @@ 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
- for (const o of e)
84
- if (!s[o])
83
+ for (const r of e)
84
+ if (!t[r])
85
85
  return {
86
86
  isValid: !1,
87
- error: `Toolset '${o}' not found in catalog`
87
+ error: `Toolset '${r}' 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
  }
115
- class ie {
115
+ const k = ["_meta"];
116
+ class ce {
116
117
  constructor(e) {
117
118
  d(this, "catalog");
118
119
  d(this, "moduleLoaders");
120
+ for (const t of k)
121
+ if (t in e.catalog)
122
+ throw new Error(
123
+ `Toolset key '${t}' is reserved for internal use and cannot be used in the catalog`
124
+ );
119
125
  this.catalog = e.catalog, this.moduleLoaders = e.moduleLoaders ?? {};
120
126
  }
121
127
  getAvailableToolsets() {
@@ -132,50 +138,53 @@ class ie {
132
138
  ", "
133
139
  )}`
134
140
  };
135
- const s = e.trim();
136
- return s.length === 0 ? {
141
+ const t = e.trim();
142
+ return t.length === 0 ? {
137
143
  isValid: !1,
138
144
  error: `Empty toolset name provided. Available toolsets: ${this.getAvailableToolsets().join(
139
145
  ", "
140
146
  )}`
141
- } : this.catalog[s] ? { isValid: !0, sanitized: s } : {
147
+ } : k.includes(t) ? {
148
+ isValid: !1,
149
+ error: `Toolset key '${t}' is reserved for internal use`
150
+ } : this.catalog[t] ? { isValid: !0, sanitized: t } : {
142
151
  isValid: !1,
143
- error: `Toolset '${s}' not found. Available toolsets: ${this.getAvailableToolsets().join(
152
+ error: `Toolset '${t}' not found. Available toolsets: ${this.getAvailableToolsets().join(
144
153
  ", "
145
154
  )}`
146
155
  };
147
156
  }
148
- async resolveToolsForToolsets(e, s) {
149
- const t = [];
150
- for (const o of e) {
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))
157
+ async resolveToolsForToolsets(e, t) {
158
+ const s = [];
159
+ for (const r of e) {
160
+ const i = this.catalog[r];
161
+ if (i && (Array.isArray(i.tools) && i.tools.length > 0 && s.push(...i.tools), Array.isArray(i.modules) && i.modules.length > 0))
153
162
  for (const n of i.modules) {
154
163
  const l = this.moduleLoaders[n];
155
164
  if (l)
156
165
  try {
157
- const a = await l(s);
158
- Array.isArray(a) && a.length > 0 && t.push(...a);
159
- } catch (a) {
166
+ const c = await l(t);
167
+ Array.isArray(c) && c.length > 0 && s.push(...c);
168
+ } catch (c) {
160
169
  console.warn(
161
- `Module loader '${n}' failed for toolset '${o}':`,
162
- a
170
+ `Module loader '${n}' failed for toolset '${r}':`,
171
+ c
163
172
  );
164
173
  }
165
174
  }
166
175
  }
167
- return t;
176
+ return s;
168
177
  }
169
178
  }
170
- class N extends Error {
171
- constructor(s, t, o, i) {
172
- super(s);
179
+ class O extends Error {
180
+ constructor(t, s, r, i) {
181
+ super(t);
173
182
  d(this, "code");
174
183
  d(this, "details");
175
- this.name = "ToolingError", this.code = t, this.details = o;
184
+ this.name = "ToolingError", this.code = s, this.details = r;
176
185
  }
177
186
  }
178
- class z {
187
+ class q {
179
188
  constructor(e = {}) {
180
189
  d(this, "options");
181
190
  d(this, "names", /* @__PURE__ */ new Set());
@@ -184,34 +193,34 @@ class z {
184
193
  namespaceWithToolset: e.namespaceWithToolset ?? !0
185
194
  };
186
195
  }
187
- getSafeName(e, s) {
188
- return !this.options.namespaceWithToolset || s.startsWith(`${e}.`) ? s : `${e}.${s}`;
196
+ getSafeName(e, t) {
197
+ return !this.options.namespaceWithToolset || t.startsWith(`${e}.`) ? t : `${e}.${t}`;
189
198
  }
190
199
  has(e) {
191
200
  return this.names.has(e);
192
201
  }
193
202
  add(e) {
194
203
  if (this.names.has(e))
195
- throw new N(
204
+ throw new O(
196
205
  `Tool name collision: '${e}' already registered`,
197
206
  "E_TOOL_NAME_CONFLICT"
198
207
  );
199
208
  this.names.add(e);
200
209
  }
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);
205
- }
206
- mapAndValidate(e, s) {
207
- return s.map((t) => {
208
- const o = this.getSafeName(e, t.name);
209
- if (this.has(o))
210
- throw new N(
211
- `Tool name collision for '${o}'`,
210
+ addForToolset(e, t) {
211
+ this.add(t);
212
+ const s = this.toolsetToNames.get(e) ?? /* @__PURE__ */ new Set();
213
+ s.add(t), this.toolsetToNames.set(e, s);
214
+ }
215
+ mapAndValidate(e, t) {
216
+ return t.map((s) => {
217
+ const r = this.getSafeName(e, s.name);
218
+ if (this.has(r))
219
+ throw new O(
220
+ `Tool name collision for '${r}'`,
212
221
  "E_TOOL_NAME_CONFLICT"
213
222
  );
214
- return { ...t, name: o };
223
+ return { ...s, name: r };
215
224
  });
216
225
  }
217
226
  list() {
@@ -219,12 +228,12 @@ class z {
219
228
  }
220
229
  listByToolset() {
221
230
  const e = {};
222
- for (const [s, t] of this.toolsetToNames.entries())
223
- e[s] = Array.from(t);
231
+ for (const [t, s] of this.toolsetToNames.entries())
232
+ e[t] = Array.from(s);
224
233
  return e;
225
234
  }
226
235
  }
227
- class ne {
236
+ class de {
228
237
  constructor(e) {
229
238
  d(this, "server");
230
239
  d(this, "resolver");
@@ -233,7 +242,7 @@ class ne {
233
242
  d(this, "exposurePolicy");
234
243
  d(this, "toolRegistry");
235
244
  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 z({ namespaceWithToolset: !0 });
245
+ 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 q({ namespaceWithToolset: !0 });
237
246
  }
238
247
  /**
239
248
  * Sends a tool list change notification if configured.
@@ -268,46 +277,46 @@ class ne {
268
277
  * @param skipNotification - If true, skips the tool list change notification (for batch operations)
269
278
  * @returns Result object with success status and message
270
279
  */
271
- async enableToolset(e, s = !1) {
272
- const t = this.resolver.validateToolsetName(e);
273
- if (!t.isValid || !t.sanitized)
280
+ async enableToolset(e, t = !1) {
281
+ const s = this.resolver.validateToolsetName(e);
282
+ if (!s.isValid || !s.sanitized)
274
283
  return {
275
284
  success: !1,
276
- message: t.error || "Unknown validation error"
285
+ message: s.error || "Unknown validation error"
277
286
  };
278
- const o = t.sanitized;
279
- if (this.activeToolsets.has(o))
287
+ const r = s.sanitized;
288
+ if (this.activeToolsets.has(r))
280
289
  return {
281
290
  success: !1,
282
- message: `Toolset '${o}' is already enabled.`
291
+ message: `Toolset '${r}' is already enabled.`
283
292
  };
284
- const i = this.checkExposurePolicy(o);
293
+ const i = this.checkExposurePolicy(r);
285
294
  if (!i.allowed)
286
295
  return { success: !1, message: i.message };
287
296
  const n = [];
288
297
  try {
289
298
  const l = await this.resolver.resolveToolsForToolsets(
290
- [o],
299
+ [r],
291
300
  this.context
292
301
  );
293
302
  if (l && l.length > 0) {
294
- const a = this.toolRegistry.mapAndValidate(
295
- o,
303
+ const c = this.toolRegistry.mapAndValidate(
304
+ r,
296
305
  l
297
306
  );
298
- for (const c of a)
299
- this.registerSingleTool(c, o), n.push(c.name);
307
+ for (const a of c)
308
+ this.registerSingleTool(a, r), n.push(a.name);
300
309
  }
301
- return this.activeToolsets.add(o), s || await this.notifyToolsChanged(), {
310
+ return this.activeToolsets.add(r), t || await this.notifyToolsChanged(), {
302
311
  success: !0,
303
- message: `Toolset '${o}' enabled successfully. Registered ${l?.length ?? 0} tools.`
312
+ message: `Toolset '${r}' enabled successfully. Registered ${l?.length ?? 0} tools.`
304
313
  };
305
314
  } catch (l) {
306
315
  return n.length > 0 && console.warn(
307
- `Partial failure enabling toolset '${o}'. ${n.length} tools were registered but toolset activation failed. Tools remain registered due to MCP limitations: ${n.join(", ")}`
316
+ `Partial failure enabling toolset '${r}'. ${n.length} tools were registered but toolset activation failed. Tools remain registered due to MCP limitations: ${n.join(", ")}`
308
317
  ), {
309
318
  success: !1,
310
- message: `Failed to enable toolset '${o}': ${l instanceof Error ? l.message : "Unknown error"}`
319
+ message: `Failed to enable toolset '${r}': ${l instanceof Error ? l.message : "Unknown error"}`
311
320
  };
312
321
  }
313
322
  }
@@ -338,19 +347,19 @@ class ne {
338
347
  * @param toolsetKey - The toolset key for tracking
339
348
  * @private
340
349
  */
341
- registerSingleTool(e, s) {
350
+ registerSingleTool(e, t) {
342
351
  e.annotations && Object.keys(e.annotations).length > 0 && e.annotations ? this.server.tool(
343
352
  e.name,
344
353
  e.description,
345
354
  e.inputSchema,
346
355
  e.annotations,
347
- async (o) => await e.handler(o)
356
+ async (r) => await e.handler(r)
348
357
  ) : this.server.tool(
349
358
  e.name,
350
359
  e.description,
351
360
  e.inputSchema,
352
- async (o) => await e.handler(o)
353
- ), this.toolRegistry.addForToolset(s, e.name);
361
+ async (r) => await e.handler(r)
362
+ ), this.toolRegistry.addForToolset(t, e.name);
354
363
  }
355
364
  /**
356
365
  * Disables a toolset by name.
@@ -359,21 +368,21 @@ class ne {
359
368
  * @returns Result object with success status and message
360
369
  */
361
370
  async disableToolset(e) {
362
- const s = this.resolver.validateToolsetName(e);
363
- if (!s.isValid || !s.sanitized) {
364
- const o = Array.from(this.activeToolsets).join(", ") || "none";
371
+ const t = this.resolver.validateToolsetName(e);
372
+ if (!t.isValid || !t.sanitized) {
373
+ const r = Array.from(this.activeToolsets).join(", ") || "none";
365
374
  return {
366
375
  success: !1,
367
- message: `${s.error || "Unknown validation error"} Active toolsets: ${o}`
376
+ message: `${t.error || "Unknown validation error"} Active toolsets: ${r}`
368
377
  };
369
378
  }
370
- const t = s.sanitized;
371
- return this.activeToolsets.has(t) ? (this.activeToolsets.delete(t), await this.notifyToolsChanged(), {
379
+ const s = t.sanitized;
380
+ return this.activeToolsets.has(s) ? (this.activeToolsets.delete(s), await this.notifyToolsChanged(), {
372
381
  success: !0,
373
- message: `Toolset '${t}' disabled successfully. Individual tools remain registered due to MCP limitations.`
382
+ message: `Toolset '${s}' disabled successfully. Individual tools remain registered due to MCP limitations.`
374
383
  }) : {
375
384
  success: !1,
376
- message: `Toolset '${t}' is not currently active. Active toolsets: ${Array.from(this.activeToolsets).join(", ") || "none"}`
385
+ message: `Toolset '${s}' is not currently active. Active toolsets: ${Array.from(this.activeToolsets).join(", ") || "none"}`
377
386
  };
378
387
  }
379
388
  getStatus() {
@@ -394,21 +403,21 @@ class ne {
394
403
  * @returns Result object with overall success status and individual results
395
404
  */
396
405
  async enableToolsets(e) {
397
- const s = [];
406
+ const t = [];
398
407
  for (const n of e)
399
408
  try {
400
409
  const l = await this.enableToolset(n, !0);
401
- s.push({ name: n, ...l });
410
+ t.push({ name: n, ...l });
402
411
  } catch (l) {
403
- s.push({
412
+ t.push({
404
413
  name: n,
405
414
  success: !1,
406
415
  message: l instanceof Error ? l.message : "Unknown error",
407
416
  code: "E_INTERNAL"
408
417
  });
409
418
  }
410
- 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";
411
- return o && await this.notifyToolsChanged(), { success: t, results: s, message: i };
419
+ const s = t.every((n) => n.success), r = t.some((n) => n.success), i = s ? "All toolsets enabled" : r ? "Some toolsets failed to enable" : "All toolsets failed to enable";
420
+ return r && await this.notifyToolsChanged(), { success: s, results: t, message: i };
412
421
  }
413
422
  /**
414
423
  * Enables all available toolsets in a batch operation.
@@ -419,103 +428,104 @@ class ne {
419
428
  return this.enableToolsets(e);
420
429
  }
421
430
  }
422
- function ae(r, e, s) {
423
- (s?.mode ?? "DYNAMIC") === "DYNAMIC" && (r.tool(
431
+ const b = "_meta";
432
+ function ue(o, e, t, s) {
433
+ (s?.mode ?? "DYNAMIC") === "DYNAMIC" && (t.addForToolset(b, "enable_toolset"), o.tool(
424
434
  "enable_toolset",
425
435
  "Enable a toolset by name",
426
- { name: y.string().describe("Toolset name") },
436
+ { name: v.string().describe("Toolset name") },
427
437
  { destructiveHint: !0, idempotentHint: !0 },
428
- async (o) => {
429
- const i = await e.enableToolset(o.name);
438
+ async (i) => {
439
+ const n = await e.enableToolset(i.name);
430
440
  return {
431
- content: [{ type: "text", text: JSON.stringify(i) }]
441
+ content: [{ type: "text", text: JSON.stringify(n) }]
432
442
  };
433
443
  }
434
- ), r.tool(
444
+ ), t.addForToolset(b, "disable_toolset"), o.tool(
435
445
  "disable_toolset",
436
446
  "Disable a toolset by name (state only)",
437
- { name: y.string().describe("Toolset name") },
447
+ { name: v.string().describe("Toolset name") },
438
448
  { destructiveHint: !0, idempotentHint: !0 },
439
- async (o) => {
440
- const i = await e.disableToolset(o.name);
449
+ async (i) => {
450
+ const n = await e.disableToolset(i.name);
441
451
  return {
442
- content: [{ type: "text", text: JSON.stringify(i) }]
452
+ content: [{ type: "text", text: JSON.stringify(n) }]
443
453
  };
444
454
  }
445
- ), r.tool(
455
+ ), t.addForToolset(b, "list_toolsets"), o.tool(
446
456
  "list_toolsets",
447
457
  "List available toolsets with active status and definitions",
448
458
  {},
449
459
  { readOnlyHint: !0, idempotentHint: !0 },
450
460
  async () => {
451
- const o = e.getAvailableToolsets(), i = e.getStatus().toolsetToTools, n = o.map((l) => {
452
- const a = e.getToolsetDefinition(l);
461
+ const i = e.getAvailableToolsets(), n = e.getStatus().toolsetToTools, l = i.map((c) => {
462
+ const a = e.getToolsetDefinition(c);
453
463
  return {
454
- key: l,
455
- active: e.isActive(l),
464
+ key: c,
465
+ active: e.isActive(c),
456
466
  definition: a ? {
457
467
  name: a.name,
458
468
  description: a.description,
459
469
  modules: a.modules ?? [],
460
470
  decisionCriteria: a.decisionCriteria ?? void 0
461
471
  } : null,
462
- tools: i[l] ?? []
472
+ tools: n[c] ?? []
463
473
  };
464
474
  });
465
475
  return {
466
476
  content: [
467
- { type: "text", text: JSON.stringify({ toolsets: n }) }
477
+ { type: "text", text: JSON.stringify({ toolsets: l }) }
468
478
  ]
469
479
  };
470
480
  }
471
- ), r.tool(
481
+ ), t.addForToolset(b, "describe_toolset"), o.tool(
472
482
  "describe_toolset",
473
483
  "Describe a toolset with definition, active status and tools",
474
- { name: y.string().describe("Toolset name") },
484
+ { name: v.string().describe("Toolset name") },
475
485
  { readOnlyHint: !0, idempotentHint: !0 },
476
- async (o) => {
477
- const i = e.getToolsetDefinition(o.name), n = e.getStatus().toolsetToTools;
478
- if (!i)
486
+ async (i) => {
487
+ const n = e.getToolsetDefinition(i.name), l = e.getStatus().toolsetToTools;
488
+ if (!n)
479
489
  return {
480
490
  content: [
481
491
  {
482
492
  type: "text",
483
- text: JSON.stringify({ error: `Unknown toolset '${o.name}'` })
493
+ text: JSON.stringify({ error: `Unknown toolset '${i.name}'` })
484
494
  }
485
495
  ]
486
496
  };
487
- const l = {
488
- key: o.name,
489
- active: e.isActive(o.name),
497
+ const c = {
498
+ key: i.name,
499
+ active: e.isActive(i.name),
490
500
  definition: {
491
- name: i.name,
492
- description: i.description,
493
- modules: i.modules ?? [],
494
- decisionCriteria: i.decisionCriteria ?? void 0
501
+ name: n.name,
502
+ description: n.description,
503
+ modules: n.modules ?? [],
504
+ decisionCriteria: n.decisionCriteria ?? void 0
495
505
  },
496
- tools: n[o.name] ?? []
506
+ tools: l[i.name] ?? []
497
507
  };
498
508
  return {
499
- content: [{ type: "text", text: JSON.stringify(l) }]
509
+ content: [{ type: "text", text: JSON.stringify(c) }]
500
510
  };
501
511
  }
502
- )), r.tool(
512
+ )), t.addForToolset(b, "list_tools"), o.tool(
503
513
  "list_tools",
504
514
  "List currently registered tool names (best effort)",
505
515
  {},
506
516
  { readOnlyHint: !0, idempotentHint: !0 },
507
517
  async () => {
508
- const o = e.getStatus(), i = {
509
- tools: o.tools,
510
- toolsetToTools: o.toolsetToTools
518
+ const i = e.getStatus(), n = {
519
+ tools: i.tools,
520
+ toolsetToTools: i.toolsetToTools
511
521
  };
512
522
  return {
513
- content: [{ type: "text", text: JSON.stringify(i) }]
523
+ content: [{ type: "text", text: JSON.stringify(n) }]
514
524
  };
515
525
  }
516
526
  );
517
527
  }
518
- class A {
528
+ class C {
519
529
  constructor(e) {
520
530
  d(this, "mode");
521
531
  d(this, "resolver");
@@ -523,24 +533,24 @@ class A {
523
533
  d(this, "toolsetValidator");
524
534
  d(this, "initPromise");
525
535
  d(this, "initError", null);
526
- this.toolsetValidator = new re();
527
- const s = e.startup ?? {}, t = this.resolveStartupConfig(s, e.catalog);
528
- this.mode = t.mode, this.resolver = new ie({
536
+ this.toolsetValidator = new le();
537
+ const t = e.startup ?? {}, s = this.resolveStartupConfig(t, e.catalog);
538
+ this.mode = s.mode, this.resolver = new ce({
529
539
  catalog: e.catalog,
530
540
  moduleLoaders: e.moduleLoaders
531
541
  });
532
- const o = new z({
542
+ const r = new q({
533
543
  namespaceWithToolset: e.exposurePolicy?.namespaceToolsWithSetKey ?? !0
534
544
  });
535
- this.manager = new ne({
545
+ this.manager = new de({
536
546
  server: e.server,
537
547
  resolver: this.resolver,
538
548
  context: e.context,
539
549
  onToolsListChanged: e.notifyToolsListChanged,
540
550
  exposurePolicy: e.exposurePolicy,
541
- toolRegistry: o
542
- }), e.registerMetaTools !== !1 && ae(e.server, this.manager, { mode: this.mode });
543
- const i = t.toolsets;
551
+ toolRegistry: r
552
+ }), e.registerMetaTools !== !1 && ue(e.server, this.manager, r, { mode: this.mode });
553
+ const i = s.toolsets;
544
554
  this.initPromise = this.initializeToolsets(i);
545
555
  }
546
556
  /**
@@ -553,8 +563,8 @@ class A {
553
563
  async initializeToolsets(e) {
554
564
  try {
555
565
  e === "ALL" ? await this.manager.enableToolsets(this.resolver.getAvailableToolsets()) : Array.isArray(e) && e.length > 0 && await this.manager.enableToolsets(e);
556
- } catch (s) {
557
- this.initError = s instanceof Error ? s : new Error(String(s)), console.error("Failed to initialize toolsets:", this.initError);
566
+ } catch (t) {
567
+ this.initError = t instanceof Error ? t : new Error(String(t)), console.error("Failed to initialize toolsets:", this.initError);
558
568
  }
559
569
  }
560
570
  /**
@@ -574,38 +584,38 @@ class A {
574
584
  async isReady() {
575
585
  return await this.initPromise, this.initError === null;
576
586
  }
577
- resolveStartupConfig(e, s) {
587
+ resolveStartupConfig(e, t) {
578
588
  if (e.mode) {
579
589
  if (e.mode === "DYNAMIC" && e.toolsets)
580
590
  return console.warn("startup.toolsets provided but ignored in DYNAMIC mode"), { mode: "DYNAMIC" };
581
591
  if (e.mode === "STATIC") {
582
592
  if (e.toolsets === "ALL")
583
593
  return { mode: "STATIC", toolsets: "ALL" };
584
- const t = Array.isArray(e.toolsets) ? e.toolsets : [], o = [];
585
- for (const i of t) {
586
- const { isValid: n, sanitized: l, error: a } = this.toolsetValidator.validateToolsetName(i, s);
587
- n && l ? o.push(l) : a && console.warn(a);
594
+ const s = Array.isArray(e.toolsets) ? e.toolsets : [], r = [];
595
+ for (const i of s) {
596
+ const { isValid: n, sanitized: l, error: c } = this.toolsetValidator.validateToolsetName(i, t);
597
+ n && l ? r.push(l) : c && console.warn(c);
588
598
  }
589
- if (t.length > 0 && o.length === 0)
599
+ if (s.length > 0 && r.length === 0)
590
600
  throw new Error(
591
601
  "STATIC mode requires valid toolsets or 'ALL'; none were valid"
592
602
  );
593
- return { mode: "STATIC", toolsets: o };
603
+ return { mode: "STATIC", toolsets: r };
594
604
  }
595
605
  return { mode: e.mode };
596
606
  }
597
607
  if (e.toolsets === "ALL") return { mode: "STATIC", toolsets: "ALL" };
598
608
  if (Array.isArray(e.toolsets) && e.toolsets.length > 0) {
599
- const t = [];
600
- for (const o of e.toolsets) {
601
- const { isValid: i, sanitized: n, error: l } = this.toolsetValidator.validateToolsetName(o, s);
602
- i && n ? t.push(n) : l && console.warn(l);
609
+ const s = [];
610
+ for (const r of e.toolsets) {
611
+ const { isValid: i, sanitized: n, error: l } = this.toolsetValidator.validateToolsetName(r, t);
612
+ i && n ? s.push(n) : l && console.warn(l);
603
613
  }
604
- if (t.length === 0)
614
+ if (s.length === 0)
605
615
  throw new Error(
606
616
  "STATIC mode requires valid toolsets or 'ALL'; none were valid"
607
617
  );
608
- return { mode: "STATIC", toolsets: t };
618
+ return { mode: "STATIC", toolsets: s };
609
619
  }
610
620
  return { mode: "DYNAMIC" };
611
621
  }
@@ -616,10 +626,10 @@ class A {
616
626
  return this.manager;
617
627
  }
618
628
  }
619
- var w, E;
620
- class V {
629
+ var x, P;
630
+ class F {
621
631
  constructor(e = {}) {
622
- b(this, w);
632
+ A(this, x);
623
633
  d(this, "storage", /* @__PURE__ */ new Map());
624
634
  d(this, "maxSize");
625
635
  d(this, "ttlMs");
@@ -627,8 +637,8 @@ class V {
627
637
  // Use ReturnType<typeof setInterval> for cross-env typings without NodeJS namespace
628
638
  d(this, "pruneInterval");
629
639
  this.maxSize = e.maxSize ?? 1e3, this.ttlMs = e.ttlMs ?? 1e3 * 60 * 60, this.onEvict = e.onEvict;
630
- const s = e.pruneIntervalMs ?? 1e3 * 60 * 10;
631
- this.pruneInterval = setInterval(() => this.pruneExpired(), s);
640
+ const t = e.pruneIntervalMs ?? 1e3 * 60 * 10;
641
+ this.pruneInterval = setInterval(() => this.pruneExpired(), t);
632
642
  }
633
643
  getEntryCount() {
634
644
  return this.storage.size;
@@ -640,13 +650,13 @@ class V {
640
650
  return this.ttlMs;
641
651
  }
642
652
  get(e) {
643
- const s = this.storage.get(e);
644
- 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;
653
+ const t = this.storage.get(e);
654
+ 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;
645
655
  }
646
- set(e, s) {
656
+ set(e, t) {
647
657
  this.storage.size >= this.maxSize && this.evictLeastRecentlyUsed();
648
- const t = { resource: s, lastAccessed: Date.now() };
649
- this.storage.set(e, t);
658
+ const s = { resource: t, lastAccessed: Date.now() };
659
+ this.storage.set(e, s);
650
660
  }
651
661
  /**
652
662
  * Removes an entry from the cache.
@@ -654,8 +664,8 @@ class V {
654
664
  * @param key - The key to remove
655
665
  */
656
666
  delete(e) {
657
- const s = this.storage.get(e);
658
- s && (this.storage.delete(e), m(this, w, E).call(this, e, s.resource));
667
+ const t = this.storage.get(e);
668
+ t && (this.storage.delete(e), m(this, x, P).call(this, e, t.resource));
659
669
  }
660
670
  /**
661
671
  * Stops the background pruning interval and optionally clears all entries.
@@ -671,8 +681,8 @@ class V {
671
681
  clear() {
672
682
  const e = Array.from(this.storage.entries());
673
683
  this.storage.clear();
674
- for (const [s, t] of e)
675
- m(this, w, E).call(this, s, t.resource);
684
+ for (const [t, s] of e)
685
+ m(this, x, P).call(this, t, s.resource);
676
686
  }
677
687
  /**
678
688
  * Evicts the least recently used entry from the cache.
@@ -687,84 +697,84 @@ class V {
687
697
  * @private
688
698
  */
689
699
  pruneExpired() {
690
- const e = Date.now(), s = [];
691
- for (const [t, o] of this.storage.entries())
692
- e - o.lastAccessed > this.ttlMs && s.push(t);
693
- for (const t of s)
694
- this.delete(t);
700
+ const e = Date.now(), t = [];
701
+ for (const [s, r] of this.storage.entries())
702
+ e - r.lastAccessed > this.ttlMs && t.push(s);
703
+ for (const s of t)
704
+ this.delete(s);
695
705
  }
696
706
  }
697
- w = new WeakSet(), /**
707
+ x = new WeakSet(), /**
698
708
  * Safely calls the evict callback, catching and logging any errors.
699
709
  * @param key - The key being evicted
700
710
  * @param resource - The resource being evicted
701
711
  * @private
702
712
  */
703
- E = function(e, s) {
713
+ P = function(e, t) {
704
714
  if (this.onEvict)
705
715
  try {
706
- const t = this.onEvict(e, s);
707
- t instanceof Promise && t.catch((o) => {
708
- console.warn(`Error in cache eviction callback for key '${e}':`, o);
716
+ const s = this.onEvict(e, t);
717
+ s instanceof Promise && s.catch((r) => {
718
+ console.warn(`Error in cache eviction callback for key '${e}':`, r);
709
719
  });
710
- } catch (t) {
711
- console.warn(`Error in cache eviction callback for key '${e}':`, t);
720
+ } catch (s) {
721
+ console.warn(`Error in cache eviction callback for key '${e}':`, s);
712
722
  }
713
723
  };
714
- function F(r, e, s, t) {
715
- const o = ["/mcp", "/healthz", "/tools", "/.well-known/mcp-config"];
716
- for (const i of s) {
724
+ function V(o, e, t, s) {
725
+ const r = ["/mcp", "/healthz", "/tools", "/.well-known/mcp-config"];
726
+ for (const i of t) {
717
727
  const n = `${e}${i.path}`;
718
- if (o.some(
719
- (c) => n.startsWith(`${e}${c}`)
728
+ if (r.some(
729
+ (a) => n.startsWith(`${e}${a}`)
720
730
  )) {
721
731
  console.warn(
722
732
  `Custom endpoint ${i.method} ${i.path} conflicts with built-in MCP endpoint. Skipping registration.`
723
733
  );
724
734
  continue;
725
735
  }
726
- const a = i.method.toLowerCase();
727
- r[a](n, async (c, u) => {
736
+ const c = i.method.toLowerCase();
737
+ o[c](n, async (a, u) => {
728
738
  try {
729
- const f = c.headers["mcp-client-id"]?.trim(), v = f && f.length > 0 ? f : `anon-${T()}`;
730
- let x;
739
+ const h = a.headers["mcp-client-id"]?.trim(), g = h && h.length > 0 ? h : `anon-${S()}`;
740
+ let w;
731
741
  if (i.bodySchema) {
732
- const g = i.bodySchema.safeParse(c.body);
733
- if (!g.success)
734
- return S(u, "body", g.error);
735
- x = g.data;
742
+ const y = i.bodySchema.safeParse(a.body);
743
+ if (!y.success)
744
+ return E(u, "body", y.error);
745
+ w = y.data;
736
746
  }
737
- let I = {};
747
+ let T = {};
738
748
  if (i.querySchema) {
739
- const g = i.querySchema.safeParse(c.query);
740
- if (!g.success)
741
- return S(u, "query", g.error);
742
- I = g.data;
749
+ const y = i.querySchema.safeParse(a.query);
750
+ if (!y.success)
751
+ return E(u, "query", y.error);
752
+ T = y.data;
743
753
  }
744
- let M = {};
754
+ let I = {};
745
755
  if (i.paramsSchema) {
746
- const g = i.paramsSchema.safeParse(c.params);
747
- if (!g.success)
748
- return S(u, "params", g.error);
749
- M = g.data;
756
+ const y = i.paramsSchema.safeParse(a.params);
757
+ if (!y.success)
758
+ return E(u, "params", y.error);
759
+ I = y.data;
750
760
  }
751
- const P = {
752
- body: x,
753
- query: I,
754
- params: M,
755
- headers: c.headers,
756
- clientId: v
761
+ const $ = {
762
+ body: w,
763
+ query: T,
764
+ params: I,
765
+ headers: a.headers,
766
+ clientId: g
757
767
  };
758
- if (t?.contextExtractor) {
759
- const g = await t.contextExtractor(c);
760
- Object.assign(P, g);
768
+ if (s?.contextExtractor) {
769
+ const y = await s.contextExtractor(a);
770
+ Object.assign($, y);
761
771
  }
762
- const $ = await i.handler(P);
772
+ const L = await i.handler($);
763
773
  if (i.responseSchema) {
764
- const g = i.responseSchema.safeParse($);
765
- return g.success ? g.data : (console.error(
774
+ const y = i.responseSchema.safeParse(L);
775
+ return y.success ? y.data : (console.error(
766
776
  `Response validation failed for ${i.method} ${i.path}:`,
767
- g.error
777
+ y.error
768
778
  ), u.code(500), {
769
779
  error: {
770
780
  code: "RESPONSE_VALIDATION_ERROR",
@@ -772,59 +782,61 @@ function F(r, e, s, t) {
772
782
  }
773
783
  });
774
784
  }
775
- return $;
776
- } catch (f) {
785
+ return L;
786
+ } catch (h) {
777
787
  return console.error(
778
788
  `Error in custom endpoint ${i.method} ${i.path}:`,
779
- f
789
+ h
780
790
  ), u.code(500), {
781
791
  error: {
782
792
  code: "INTERNAL_ERROR",
783
- message: f instanceof Error ? f.message : "Internal server error"
793
+ message: h instanceof Error ? h.message : "Internal server error"
784
794
  }
785
795
  };
786
796
  }
787
797
  });
788
798
  }
789
799
  }
790
- function S(r, e, s) {
791
- return r.code(400), {
800
+ function E(o, e, t) {
801
+ return o.code(400), {
792
802
  error: {
793
803
  code: "VALIDATION_ERROR",
794
804
  message: `Validation failed for ${e}`,
795
- details: s.errors
805
+ details: t.errors
796
806
  }
797
807
  };
798
808
  }
799
- class le {
800
- constructor(e, s, t = {}, o) {
809
+ class he {
810
+ constructor(e, t, s = {}, r, i, n) {
801
811
  d(this, "options");
802
812
  d(this, "defaultManager");
803
813
  d(this, "createBundle");
814
+ d(this, "sessionContextResolver");
815
+ d(this, "baseContext");
804
816
  d(this, "app", null);
805
817
  d(this, "configSchema");
806
818
  // Per-client server bundles and per-client session transports
807
- d(this, "clientCache", new V({
808
- onEvict: (e, s) => {
809
- this.cleanupBundle(s);
819
+ d(this, "clientCache", new F({
820
+ onEvict: (e, t) => {
821
+ this.cleanupBundle(t);
810
822
  }
811
823
  }));
812
- this.defaultManager = e, this.createBundle = s, this.options = {
813
- host: t.host ?? "0.0.0.0",
814
- port: t.port ?? 3e3,
815
- basePath: t.basePath ?? "/",
816
- cors: t.cors ?? !0,
817
- logger: t.logger ?? !1,
818
- app: t.app,
819
- customEndpoints: t.customEndpoints
820
- }, this.configSchema = o;
824
+ this.defaultManager = e, this.createBundle = t, this.sessionContextResolver = i, this.baseContext = n, this.options = {
825
+ host: s.host ?? "0.0.0.0",
826
+ port: s.port ?? 3e3,
827
+ basePath: s.basePath ?? "/",
828
+ cors: s.cors ?? !0,
829
+ logger: s.logger ?? !1,
830
+ app: s.app,
831
+ customEndpoints: s.customEndpoints
832
+ }, this.configSchema = r;
821
833
  }
822
834
  async start() {
823
835
  if (this.app) return;
824
- const e = this.options.app ?? j({ logger: this.options.logger });
825
- this.options.cors && await e.register(k, { origin: !0 });
826
- const s = this.options.basePath.endsWith("/") ? this.options.basePath.slice(0, -1) : this.options.basePath;
827
- 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 ?? {
836
+ const e = this.options.app ?? N({ logger: this.options.logger });
837
+ this.options.cors && await e.register(D, { origin: !0 });
838
+ const t = this.options.basePath.endsWith("/") ? this.options.basePath.slice(0, -1) : this.options.basePath;
839
+ e.get(`${t}/healthz`, async () => ({ ok: !0 })), e.get(`${t}/tools`, async () => this.defaultManager.getStatus()), e.get(`${t}/.well-known/mcp-config`, async (s, r) => (r.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
828
840
  $schema: "https://json-schema.org/draft/2020-12/schema",
829
841
  title: "MCP Session Configuration",
830
842
  description: "Schema for the /mcp endpoint configuration",
@@ -834,72 +846,75 @@ class le {
834
846
  "x-mcp-version": "1.0",
835
847
  "x-query-style": "dot+bracket"
836
848
  })), e.post(
837
- `${s}/mcp`,
838
- async (t, o) => {
839
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : `anon-${T()}`, l = !n.startsWith("anon-");
840
- let a = l ? this.clientCache.get(n) : null;
841
- if (!a) {
842
- const f = this.createBundle(), v = f.sessions;
843
- a = {
844
- server: f.server,
845
- orchestrator: f.orchestrator,
846
- sessions: v instanceof Map ? v : /* @__PURE__ */ new Map()
847
- }, l && this.clientCache.set(n, a);
849
+ `${t}/mcp`,
850
+ async (s, r) => {
851
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : `anon-${S()}`, l = !n.startsWith("anon-"), { cacheKey: c, mergedContext: a } = this.resolveSessionContext(
852
+ s,
853
+ n
854
+ );
855
+ let u = l ? this.clientCache.get(c) : null;
856
+ if (!u) {
857
+ const w = this.createBundle(a);
858
+ u = {
859
+ server: w.server,
860
+ orchestrator: w.orchestrator,
861
+ sessions: /* @__PURE__ */ new Map()
862
+ }, l && this.clientCache.set(c, u);
848
863
  }
849
- const c = t.headers["mcp-session-id"];
850
- let u;
851
- if (c && a.sessions.get(c))
852
- u = a.sessions.get(c);
853
- else if (!c && D(t.body)) {
854
- const f = T();
855
- u = new O({
856
- sessionIdGenerator: () => f,
857
- onsessioninitialized: (v) => {
858
- a.sessions.set(v, u);
864
+ const h = s.headers["mcp-session-id"];
865
+ let g;
866
+ if (h && u.sessions.get(h))
867
+ g = u.sessions.get(h);
868
+ else if (!h && _(s.body)) {
869
+ const w = S();
870
+ g = new z({
871
+ sessionIdGenerator: () => w,
872
+ onsessioninitialized: (T) => {
873
+ u.sessions.set(T, g);
859
874
  }
860
875
  });
861
876
  try {
862
- await a.server.connect(u);
877
+ await u.server.connect(g);
863
878
  } catch {
864
- return o.code(500), {
879
+ return r.code(500), {
865
880
  jsonrpc: "2.0",
866
881
  error: { code: -32603, message: "Error initializing server." },
867
882
  id: null
868
883
  };
869
884
  }
870
- u.onclose = () => {
871
- u?.sessionId && a.sessions.delete(u.sessionId);
885
+ g.onclose = () => {
886
+ g?.sessionId && u.sessions.delete(g.sessionId);
872
887
  };
873
888
  } else
874
- return o.code(400), {
889
+ return r.code(400), {
875
890
  jsonrpc: "2.0",
876
891
  error: { code: -32e3, message: "Session not found or expired" },
877
892
  id: null
878
893
  };
879
- return await u.handleRequest(
880
- t.raw,
881
- o.raw,
882
- t.body
883
- ), o;
894
+ return await g.handleRequest(
895
+ s.raw,
896
+ r.raw,
897
+ s.body
898
+ ), r;
884
899
  }
885
- ), e.get(`${s}/mcp`, async (t, o) => {
886
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
900
+ ), e.get(`${t}/mcp`, async (s, r) => {
901
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
887
902
  if (!n)
888
- return o.code(400), "Missing mcp-client-id";
903
+ return r.code(400), "Missing mcp-client-id";
889
904
  const l = this.clientCache.get(n);
890
905
  if (!l)
891
- return o.code(400), "Invalid or expired client";
892
- const a = t.headers["mcp-session-id"];
893
- if (!a)
894
- return o.code(400), "Missing mcp-session-id";
895
- const c = l.sessions.get(a);
896
- return c ? (await c.handleRequest(t.raw, o.raw), o) : (o.code(400), "Invalid or expired session ID");
906
+ return r.code(400), "Invalid or expired client";
907
+ const c = s.headers["mcp-session-id"];
908
+ if (!c)
909
+ return r.code(400), "Missing mcp-session-id";
910
+ const a = l.sessions.get(c);
911
+ return a ? (await a.handleRequest(s.raw, r.raw), r) : (r.code(400), "Invalid or expired session ID");
897
912
  }), e.delete(
898
- `${s}/mcp`,
899
- async (t, o) => {
900
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = t.headers["mcp-session-id"];
913
+ `${t}/mcp`,
914
+ async (s, r) => {
915
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = s.headers["mcp-session-id"];
901
916
  if (!n || !l)
902
- return o.code(400), {
917
+ return r.code(400), {
903
918
  jsonrpc: "2.0",
904
919
  error: {
905
920
  code: -32600,
@@ -907,25 +922,25 @@ class le {
907
922
  },
908
923
  id: null
909
924
  };
910
- const a = this.clientCache.get(n), c = a?.sessions.get(l);
911
- if (!a || !c)
912
- return o.code(404), {
925
+ const c = this.clientCache.get(n), a = c?.sessions.get(l);
926
+ if (!c || !a)
927
+ return r.code(404), {
913
928
  jsonrpc: "2.0",
914
929
  error: { code: -32e3, message: "Session not found or expired" },
915
930
  id: null
916
931
  };
917
932
  try {
918
- if (typeof c.close == "function")
933
+ if (typeof a.close == "function")
919
934
  try {
920
- await c.close();
935
+ await a.close();
921
936
  } catch {
922
937
  }
923
938
  } finally {
924
- c?.sessionId ? a.sessions.delete(c.sessionId) : a.sessions.delete(l);
939
+ a?.sessionId ? c.sessions.delete(a.sessionId) : c.sessions.delete(l);
925
940
  }
926
- return o.code(204).send(), o;
941
+ return r.code(204).send(), r;
927
942
  }
928
- ), 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;
943
+ ), this.options.customEndpoints && this.options.customEndpoints.length > 0 && V(e, t, this.options.customEndpoints), this.options.app || await e.listen({ host: this.options.host, port: this.options.port }), this.app = e;
929
944
  }
930
945
  /**
931
946
  * Stops the Fastify server and cleans up all resources.
@@ -941,150 +956,399 @@ class le {
941
956
  * @private
942
957
  */
943
958
  cleanupBundle(e) {
944
- for (const [s, t] of e.sessions.entries())
959
+ for (const [t, s] of e.sessions.entries())
945
960
  try {
946
- typeof t.close == "function" && t.close().catch((o) => {
947
- console.warn(`Error closing session ${s}:`, o);
961
+ typeof s.close == "function" && s.close().catch((r) => {
962
+ console.warn(`Error closing session ${t}:`, r);
948
963
  });
949
- } catch (o) {
950
- console.warn(`Error closing session ${s}:`, o);
964
+ } catch (r) {
965
+ console.warn(`Error closing session ${t}:`, r);
951
966
  }
952
967
  e.sessions.clear();
953
968
  }
969
+ /**
970
+ * Resolves the session context and generates a cache key for the request.
971
+ * If a session context resolver is configured, it extracts query parameters
972
+ * and merges session-specific context with the base context.
973
+ *
974
+ * @param req - The Fastify request
975
+ * @param clientId - The client identifier
976
+ * @returns Object with cache key and merged context
977
+ * @private
978
+ */
979
+ resolveSessionContext(e, t) {
980
+ if (!this.sessionContextResolver)
981
+ return {
982
+ cacheKey: t,
983
+ mergedContext: this.baseContext
984
+ };
985
+ const s = {
986
+ clientId: t,
987
+ headers: this.extractHeaders(e),
988
+ query: this.extractQuery(e)
989
+ }, r = this.sessionContextResolver.resolve(
990
+ s,
991
+ this.baseContext
992
+ );
993
+ return {
994
+ cacheKey: r.cacheKeySuffix === "default" ? t : `${t}:${r.cacheKeySuffix}`,
995
+ mergedContext: r.context
996
+ };
997
+ }
998
+ /**
999
+ * Extracts headers from a Fastify request as a Record.
1000
+ * Normalizes header names to lowercase.
1001
+ *
1002
+ * @param req - The Fastify request
1003
+ * @returns Headers as a string record
1004
+ * @private
1005
+ */
1006
+ extractHeaders(e) {
1007
+ const t = {};
1008
+ for (const [s, r] of Object.entries(e.headers))
1009
+ typeof r == "string" ? t[s.toLowerCase()] = r : Array.isArray(r) && r.length > 0 && (t[s.toLowerCase()] = r[0]);
1010
+ return t;
1011
+ }
1012
+ /**
1013
+ * Extracts query parameters from a Fastify request as a Record.
1014
+ *
1015
+ * @param req - The Fastify request
1016
+ * @returns Query parameters as a string record
1017
+ * @private
1018
+ */
1019
+ extractQuery(e) {
1020
+ const t = {}, s = e.query;
1021
+ if (s && typeof s == "object")
1022
+ for (const [r, i] of Object.entries(s))
1023
+ typeof i == "string" && (t[r] = i);
1024
+ return t;
1025
+ }
954
1026
  }
955
- const ce = y.object({
956
- mode: y.enum(["DYNAMIC", "STATIC"]).optional(),
957
- toolsets: y.union([y.array(y.string()), y.literal("ALL")]).optional()
1027
+ class fe {
1028
+ constructor(e) {
1029
+ d(this, "config");
1030
+ d(this, "queryParamName");
1031
+ d(this, "encoding");
1032
+ d(this, "allowedKeys");
1033
+ d(this, "mergeStrategy");
1034
+ this.config = e, this.queryParamName = e.queryParam?.name ?? "config", this.encoding = e.queryParam?.encoding ?? "base64", this.allowedKeys = e.queryParam?.allowedKeys ? new Set(e.queryParam.allowedKeys) : null, this.mergeStrategy = e.merge ?? "shallow";
1035
+ }
1036
+ /**
1037
+ * Resolves the session context for a request.
1038
+ *
1039
+ * @param request - The request context (clientId, headers, query)
1040
+ * @param baseContext - The base context from server configuration
1041
+ * @returns The resolved context and cache key suffix
1042
+ */
1043
+ resolve(e, t) {
1044
+ if (this.config.enabled === !1)
1045
+ return {
1046
+ context: t,
1047
+ cacheKeySuffix: "default"
1048
+ };
1049
+ const s = this.parseQueryConfig(e.query);
1050
+ if (this.config.contextResolver)
1051
+ try {
1052
+ return {
1053
+ context: this.config.contextResolver(
1054
+ e,
1055
+ t,
1056
+ s
1057
+ ),
1058
+ cacheKeySuffix: this.generateCacheKeySuffix(s)
1059
+ };
1060
+ } catch {
1061
+ return {
1062
+ context: t,
1063
+ cacheKeySuffix: "default"
1064
+ };
1065
+ }
1066
+ return {
1067
+ context: this.mergeContexts(t, s),
1068
+ cacheKeySuffix: this.generateCacheKeySuffix(s)
1069
+ };
1070
+ }
1071
+ /**
1072
+ * Parses the session config from query parameters.
1073
+ * Returns empty object on parse failure (fail secure).
1074
+ *
1075
+ * @param query - Query parameters from the request
1076
+ * @returns Parsed and filtered config object
1077
+ * @private
1078
+ */
1079
+ parseQueryConfig(e) {
1080
+ const t = e[this.queryParamName];
1081
+ if (!t)
1082
+ return {};
1083
+ try {
1084
+ let s;
1085
+ this.encoding === "base64" ? s = Buffer.from(t, "base64").toString("utf-8") : s = t;
1086
+ const r = JSON.parse(s);
1087
+ return typeof r != "object" || r === null || Array.isArray(r) ? {} : this.filterAllowedKeys(r);
1088
+ } catch {
1089
+ return {};
1090
+ }
1091
+ }
1092
+ /**
1093
+ * Filters the parsed config to only include allowed keys.
1094
+ * If no allowedKeys whitelist is configured, returns the full object.
1095
+ *
1096
+ * @param parsed - The parsed config object
1097
+ * @returns Filtered config with only allowed keys
1098
+ * @private
1099
+ */
1100
+ filterAllowedKeys(e) {
1101
+ if (!this.allowedKeys)
1102
+ return e;
1103
+ const t = {};
1104
+ for (const s of this.allowedKeys)
1105
+ s in e && (t[s] = e[s]);
1106
+ return t;
1107
+ }
1108
+ /**
1109
+ * Merges the base context with the session config.
1110
+ *
1111
+ * @param baseContext - The base context from server configuration
1112
+ * @param sessionConfig - The parsed session config
1113
+ * @returns Merged context
1114
+ * @private
1115
+ */
1116
+ mergeContexts(e, t) {
1117
+ return Object.keys(t).length === 0 ? e : typeof e != "object" || e === null || Array.isArray(e) ? t : this.mergeStrategy === "deep" ? this.deepMerge(
1118
+ e,
1119
+ t
1120
+ ) : {
1121
+ ...e,
1122
+ ...t
1123
+ };
1124
+ }
1125
+ /**
1126
+ * Performs a deep merge of two objects.
1127
+ * Session config values override base context values.
1128
+ *
1129
+ * @param base - The base object
1130
+ * @param override - The override object
1131
+ * @returns Deep merged object
1132
+ * @private
1133
+ */
1134
+ deepMerge(e, t) {
1135
+ const s = { ...e };
1136
+ for (const [r, i] of Object.entries(t)) {
1137
+ const n = s[r];
1138
+ typeof i == "object" && i !== null && !Array.isArray(i) && typeof n == "object" && n !== null && !Array.isArray(n) ? s[r] = this.deepMerge(
1139
+ n,
1140
+ i
1141
+ ) : s[r] = i;
1142
+ }
1143
+ return s;
1144
+ }
1145
+ /**
1146
+ * Generates a deterministic cache key suffix based on the session config.
1147
+ * Returns 'default' when no session config is present.
1148
+ *
1149
+ * @param sessionConfig - The parsed session config
1150
+ * @returns Hash string or 'default'
1151
+ * @private
1152
+ */
1153
+ generateCacheKeySuffix(e) {
1154
+ if (Object.keys(e).length === 0)
1155
+ return "default";
1156
+ const t = Object.keys(e).sort(), s = {};
1157
+ for (const i of t)
1158
+ s[i] = e[i];
1159
+ const r = JSON.stringify(s);
1160
+ return ae("sha256").update(r).digest("hex").slice(0, 16);
1161
+ }
1162
+ }
1163
+ function K(o) {
1164
+ me(o), ye(o), ge(o), pe(o), ve(o);
1165
+ }
1166
+ function me(o) {
1167
+ if (!o || typeof o != "object")
1168
+ throw new Error(
1169
+ "Session context configuration must be an object"
1170
+ );
1171
+ }
1172
+ function ye(o) {
1173
+ if (o.enabled !== void 0 && typeof o.enabled != "boolean")
1174
+ throw new Error(
1175
+ `enabled must be a boolean, got ${typeof o.enabled}`
1176
+ );
1177
+ }
1178
+ function ge(o) {
1179
+ if (o.queryParam !== void 0) {
1180
+ if (typeof o.queryParam != "object" || o.queryParam === null)
1181
+ throw new Error("queryParam must be an object");
1182
+ if (o.queryParam.name !== void 0 && (typeof o.queryParam.name != "string" || o.queryParam.name.length === 0))
1183
+ throw new Error("queryParam.name must be a non-empty string");
1184
+ if (o.queryParam.encoding !== void 0 && o.queryParam.encoding !== "base64" && o.queryParam.encoding !== "json")
1185
+ throw new Error(
1186
+ `Invalid queryParam.encoding: "${o.queryParam.encoding}". Must be "base64" or "json"`
1187
+ );
1188
+ if (o.queryParam.allowedKeys !== void 0) {
1189
+ if (!Array.isArray(o.queryParam.allowedKeys))
1190
+ throw new Error("queryParam.allowedKeys must be an array of strings");
1191
+ for (let e = 0; e < o.queryParam.allowedKeys.length; e++) {
1192
+ const t = o.queryParam.allowedKeys[e];
1193
+ if (typeof t != "string" || t.length === 0)
1194
+ throw new Error(
1195
+ `queryParam.allowedKeys[${e}] must be a non-empty string`
1196
+ );
1197
+ }
1198
+ }
1199
+ }
1200
+ }
1201
+ function pe(o) {
1202
+ if (o.contextResolver !== void 0 && typeof o.contextResolver != "function")
1203
+ throw new Error(
1204
+ "contextResolver must be a function: (request, baseContext, parsedQueryConfig?) => unknown"
1205
+ );
1206
+ }
1207
+ function ve(o) {
1208
+ if (o.merge !== void 0 && o.merge !== "shallow" && o.merge !== "deep")
1209
+ throw new Error(
1210
+ `Invalid merge strategy: "${o.merge}". Must be "shallow" or "deep"`
1211
+ );
1212
+ }
1213
+ const we = v.object({
1214
+ mode: v.enum(["DYNAMIC", "STATIC"]).optional(),
1215
+ toolsets: v.union([v.array(v.string()), v.literal("ALL")]).optional()
958
1216
  }).strict();
959
- async function Ie(r) {
960
- if (r.startup)
1217
+ async function De(o) {
1218
+ if (o.startup)
961
1219
  try {
962
- ce.parse(r.startup);
1220
+ we.parse(o.startup);
963
1221
  } catch (a) {
964
- if (a instanceof y.ZodError) {
965
- const c = a.format();
1222
+ if (a instanceof v.ZodError) {
1223
+ const u = a.format();
966
1224
  throw new Error(
967
1225
  `Invalid startup configuration:
968
- ${JSON.stringify(c, null, 2)}
1226
+ ${JSON.stringify(u, null, 2)}
969
1227
 
970
1228
  Hint: Common mistake - use "toolsets" not "initialToolsets"`
971
1229
  );
972
1230
  }
973
1231
  throw a;
974
1232
  }
975
- const e = r.startup?.mode ?? "DYNAMIC";
976
- if (typeof r.createServer != "function")
1233
+ const e = o.startup?.mode ?? "DYNAMIC";
1234
+ let t;
1235
+ if (o.sessionContext && (K(o.sessionContext), t = new fe(o.sessionContext), e === "STATIC" && o.sessionContext.enabled !== !1 && console.warn(
1236
+ "sessionContext has limited effect in STATIC mode: all clients share the same server instance with base context. Use DYNAMIC mode for per-session context isolation."
1237
+ )), typeof o.createServer != "function")
977
1238
  throw new Error("createMcpServer: `createServer` (factory) is required");
978
- const s = r.createServer(), t = (a) => typeof a?.server?.notification == "function", o = (a) => typeof a?.notifyToolsListChanged == "function", i = async (a) => {
1239
+ const s = o.createServer(), r = (a) => typeof a?.server?.notification == "function", i = (a) => typeof a?.notifyToolsListChanged == "function", n = async (a) => {
979
1240
  try {
980
- if (t(a)) {
1241
+ if (r(a)) {
981
1242
  await a.server.notification({
982
1243
  method: "notifications/tools/list_changed"
983
1244
  });
984
1245
  return;
985
1246
  }
986
- o(a) && await a.notifyToolsListChanged();
987
- } catch (c) {
988
- if ((c instanceof Error ? c.message : String(c)) === "Not connected")
1247
+ i(a) && await a.notifyToolsListChanged();
1248
+ } catch (u) {
1249
+ if ((u instanceof Error ? u.message : String(u)) === "Not connected")
989
1250
  return;
990
- console.warn("Failed to send tools list changed notification:", c);
1251
+ console.warn("Failed to send tools list changed notification:", u);
991
1252
  }
992
- }, n = new A({
1253
+ }, l = new C({
993
1254
  server: s,
994
- catalog: r.catalog,
995
- moduleLoaders: r.moduleLoaders,
996
- exposurePolicy: r.exposurePolicy,
997
- context: r.context,
998
- notifyToolsListChanged: async () => i(s),
999
- startup: r.startup,
1000
- registerMetaTools: r.registerMetaTools !== void 0 ? r.registerMetaTools : e === "DYNAMIC"
1255
+ catalog: o.catalog,
1256
+ moduleLoaders: o.moduleLoaders,
1257
+ exposurePolicy: o.exposurePolicy,
1258
+ context: o.context,
1259
+ notifyToolsListChanged: async () => n(s),
1260
+ startup: o.startup,
1261
+ registerMetaTools: o.registerMetaTools !== void 0 ? o.registerMetaTools : e === "DYNAMIC"
1001
1262
  });
1002
- e === "STATIC" && await n.ensureReady();
1003
- const l = new le(
1004
- n.getManager(),
1005
- () => {
1263
+ e === "STATIC" && await l.ensureReady();
1264
+ const c = new he(
1265
+ l.getManager(),
1266
+ (a) => {
1267
+ const u = a ?? o.context;
1006
1268
  if (e === "STATIC")
1007
- return { server: s, orchestrator: n };
1008
- const a = r.createServer(), c = new A({
1009
- server: a,
1010
- catalog: r.catalog,
1011
- moduleLoaders: r.moduleLoaders,
1012
- exposurePolicy: r.exposurePolicy,
1013
- context: r.context,
1014
- notifyToolsListChanged: async () => i(a),
1015
- startup: r.startup,
1016
- registerMetaTools: r.registerMetaTools !== void 0 ? r.registerMetaTools : e === "DYNAMIC"
1269
+ return { server: s, orchestrator: l };
1270
+ const h = o.createServer(), g = new C({
1271
+ server: h,
1272
+ catalog: o.catalog,
1273
+ moduleLoaders: o.moduleLoaders,
1274
+ exposurePolicy: o.exposurePolicy,
1275
+ context: u,
1276
+ notifyToolsListChanged: async () => n(h),
1277
+ startup: o.startup,
1278
+ registerMetaTools: o.registerMetaTools !== void 0 ? o.registerMetaTools : e === "DYNAMIC"
1017
1279
  });
1018
- return { server: a, orchestrator: c };
1280
+ return { server: h, orchestrator: g };
1019
1281
  },
1020
- r.http,
1021
- r.configSchema
1282
+ o.http,
1283
+ o.configSchema,
1284
+ t,
1285
+ o.context
1022
1286
  );
1023
1287
  return {
1024
1288
  server: s,
1025
1289
  start: async () => {
1026
- await l.start();
1290
+ await c.start();
1027
1291
  },
1028
1292
  close: async () => {
1029
- await l.stop();
1293
+ await c.stop();
1030
1294
  }
1031
1295
  };
1032
1296
  }
1033
- function de(r) {
1034
- ue(r), he(r), fe(r), me(r);
1297
+ function Te(o) {
1298
+ be(o), Se(o), xe(o), Ae(o);
1035
1299
  }
1036
- function ue(r) {
1037
- if (!r || typeof r != "object")
1300
+ function be(o) {
1301
+ if (!o || typeof o != "object")
1038
1302
  throw new Error(
1039
1303
  "Permission configuration is required for createPermissionBasedMcpServer"
1040
1304
  );
1041
1305
  }
1042
- function he(r) {
1043
- if (!r.source)
1306
+ function Se(o) {
1307
+ if (!o.source)
1044
1308
  throw new Error('Permission source must be either "headers" or "config"');
1045
- if (r.source !== "headers" && r.source !== "config")
1309
+ if (o.source !== "headers" && o.source !== "config")
1046
1310
  throw new Error(
1047
- `Invalid permission source: "${r.source}". Must be either "headers" or "config"`
1311
+ `Invalid permission source: "${o.source}". Must be either "headers" or "config"`
1048
1312
  );
1049
1313
  }
1050
- function fe(r) {
1051
- if (r.source === "config" && !r.staticMap && !r.resolver)
1314
+ function xe(o) {
1315
+ if (o.source === "config" && !o.staticMap && !o.resolver)
1052
1316
  throw new Error(
1053
1317
  "Config-based permissions require at least one of: staticMap or resolver function"
1054
1318
  );
1055
1319
  }
1056
- function me(r) {
1057
- if (r.staticMap !== void 0) {
1058
- if (typeof r.staticMap != "object" || r.staticMap === null)
1320
+ function Ae(o) {
1321
+ if (o.staticMap !== void 0) {
1322
+ if (typeof o.staticMap != "object" || o.staticMap === null)
1059
1323
  throw new Error(
1060
1324
  "staticMap must be an object mapping client IDs to toolset arrays"
1061
1325
  );
1062
- ge(r.staticMap);
1326
+ Ce(o.staticMap);
1063
1327
  }
1064
- if (r.resolver !== void 0 && typeof r.resolver != "function")
1328
+ if (o.resolver !== void 0 && typeof o.resolver != "function")
1065
1329
  throw new Error(
1066
1330
  "resolver must be a synchronous function: (clientId: string) => string[]"
1067
1331
  );
1068
- if (r.defaultPermissions !== void 0 && !Array.isArray(r.defaultPermissions))
1332
+ if (o.defaultPermissions !== void 0 && !Array.isArray(o.defaultPermissions))
1069
1333
  throw new Error("defaultPermissions must be an array of toolset names");
1070
- if (r.headerName !== void 0 && (typeof r.headerName != "string" || r.headerName.length === 0))
1334
+ if (o.headerName !== void 0 && (typeof o.headerName != "string" || o.headerName.length === 0))
1071
1335
  throw new Error("headerName must be a non-empty string");
1072
1336
  }
1073
- function ge(r) {
1074
- for (const [e, s] of Object.entries(r))
1075
- if (!Array.isArray(s))
1337
+ function Ce(o) {
1338
+ for (const [e, t] of Object.entries(o))
1339
+ if (!Array.isArray(t))
1076
1340
  throw new Error(
1077
1341
  `staticMap value for client "${e}" must be an array of toolset names`
1078
1342
  );
1079
1343
  }
1080
- var p, _, H, B, Y, W;
1081
- class pe {
1344
+ var p, H, B, Y, U, W;
1345
+ class Ee {
1082
1346
  /**
1083
1347
  * Creates a new PermissionResolver instance.
1084
1348
  * @param config - The permission configuration defining how permissions are resolved
1085
1349
  */
1086
1350
  constructor(e) {
1087
- b(this, p);
1351
+ A(this, p);
1088
1352
  d(this, "cache", /* @__PURE__ */ new Map());
1089
1353
  d(this, "normalizedHeaderName");
1090
1354
  this.config = e, this.normalizedHeaderName = (e.headerName || "mcp-toolset-permissions").toLowerCase();
@@ -1102,23 +1366,23 @@ class pe {
1102
1366
  * @param headers - Optional request headers (required for header-based permissions)
1103
1367
  * @returns Array of toolset names the client is allowed to access
1104
1368
  */
1105
- resolvePermissions(e, s) {
1369
+ resolvePermissions(e, t) {
1106
1370
  if (this.cache.has(e))
1107
1371
  return this.cache.get(e);
1108
- let t;
1372
+ let s;
1109
1373
  try {
1110
- this.config.source === "headers" ? t = m(this, p, _).call(this, s) : t = m(this, p, B).call(this, e), Array.isArray(t) || (console.warn(
1374
+ this.config.source === "headers" ? s = m(this, p, H).call(this, t) : s = m(this, p, Y).call(this, e), Array.isArray(s) || (console.warn(
1111
1375
  `Permission resolution returned non-array for client ${e}, using empty permissions`
1112
- ), t = []), t = t.filter(
1113
- (o) => typeof o == "string" && o.trim().length > 0
1376
+ ), s = []), s = s.filter(
1377
+ (r) => typeof r == "string" && r.trim().length > 0
1114
1378
  );
1115
- } catch (o) {
1379
+ } catch (r) {
1116
1380
  console.error(
1117
1381
  `Unexpected error resolving permissions for client ${e}:`,
1118
- o
1119
- ), t = [];
1382
+ r
1383
+ ), s = [];
1120
1384
  }
1121
- return this.cache.set(e, t), t;
1385
+ return this.cache.set(e, s), s;
1122
1386
  }
1123
1387
  /**
1124
1388
  * Invalidates cached permissions for a specific client.
@@ -1145,18 +1409,18 @@ p = new WeakSet(), /**
1145
1409
  * @returns Array of toolset names from headers, or empty array if header is missing/malformed
1146
1410
  * @private
1147
1411
  */
1148
- _ = function(e) {
1412
+ H = function(e) {
1149
1413
  if (!e)
1150
1414
  return [];
1151
- const s = m(this, p, H).call(this, e, this.normalizedHeaderName);
1152
- if (!s)
1415
+ const t = m(this, p, B).call(this, e, this.normalizedHeaderName);
1416
+ if (!t)
1153
1417
  return [];
1154
1418
  try {
1155
- return s.split(",").map((t) => t.trim()).filter((t) => t.length > 0);
1156
- } catch (t) {
1419
+ return t.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
1420
+ } catch (s) {
1157
1421
  return console.warn(
1158
1422
  `Failed to parse permission header '${this.normalizedHeaderName}':`,
1159
- t
1423
+ s
1160
1424
  ), [];
1161
1425
  }
1162
1426
  }, /**
@@ -1167,12 +1431,12 @@ _ = function(e) {
1167
1431
  * @returns The header value if found, undefined otherwise
1168
1432
  * @private
1169
1433
  */
1170
- H = function(e, s) {
1171
- if (e[s] !== void 0)
1172
- return e[s];
1173
- for (const [t, o] of Object.entries(e))
1174
- if (t.toLowerCase() === s)
1175
- return o;
1434
+ B = function(e, t) {
1435
+ if (e[t] !== void 0)
1436
+ return e[t];
1437
+ for (const [s, r] of Object.entries(e))
1438
+ if (s.toLowerCase() === t)
1439
+ return r;
1176
1440
  }, /**
1177
1441
  * Resolves permissions from server-side configuration.
1178
1442
  * Tries resolver function first (if provided), then falls back to static map,
@@ -1181,16 +1445,16 @@ H = function(e, s) {
1181
1445
  * @returns Array of toolset names from configuration
1182
1446
  * @private
1183
1447
  */
1184
- B = function(e) {
1448
+ Y = function(e) {
1185
1449
  if (this.config.resolver) {
1186
- const s = m(this, p, Y).call(this, e);
1187
- if (s !== null)
1188
- return s;
1450
+ const t = m(this, p, U).call(this, e);
1451
+ if (t !== null)
1452
+ return t;
1189
1453
  }
1190
1454
  if (this.config.staticMap) {
1191
- const s = m(this, p, W).call(this, e);
1192
- if (s !== null)
1193
- return s;
1455
+ const t = m(this, p, W).call(this, e);
1456
+ if (t !== null)
1457
+ return t;
1194
1458
  }
1195
1459
  return this.config.defaultPermissions || [];
1196
1460
  }, /**
@@ -1200,16 +1464,16 @@ B = function(e) {
1200
1464
  * @returns Array of toolset names if successful, null if resolver fails or returns invalid data
1201
1465
  * @private
1202
1466
  */
1203
- Y = function(e) {
1467
+ U = function(e) {
1204
1468
  try {
1205
- const s = this.config.resolver(e);
1206
- return Array.isArray(s) ? s : (console.warn(
1469
+ const t = this.config.resolver(e);
1470
+ return Array.isArray(t) ? t : (console.warn(
1207
1471
  `Permission resolver returned non-array for client ${e}, using fallback`
1208
1472
  ), null);
1209
- } catch (s) {
1210
- const t = s instanceof Error ? s.message : String(s);
1473
+ } catch (t) {
1474
+ const s = t instanceof Error ? t.message : String(t);
1211
1475
  return console.warn(
1212
- `Permission resolver declined client ${e} (${t}), trying fallback`
1476
+ `Permission resolver declined client ${e} (${s}), trying fallback`
1213
1477
  ), null;
1214
1478
  }
1215
1479
  }, /**
@@ -1220,36 +1484,36 @@ Y = function(e) {
1220
1484
  * @private
1221
1485
  */
1222
1486
  W = function(e) {
1223
- const s = this.config.staticMap[e];
1224
- return s !== void 0 ? Array.isArray(s) ? s : [] : null;
1487
+ const t = this.config.staticMap[e];
1488
+ return t !== void 0 ? Array.isArray(t) ? t : [] : null;
1225
1489
  };
1226
- function ye(r, e) {
1227
- return async (s) => {
1228
- const t = e.resolvePermissions(
1229
- s.clientId,
1230
- s.headers
1231
- ), o = r(t), i = o.orchestrator.getManager(), n = [], l = [];
1232
- if (t.length > 0) {
1233
- const a = await i.enableToolsets(t);
1234
- for (const c of a.results)
1235
- c.success ? n.push(c.name) : (l.push(c.name), console.warn(
1236
- `Failed to enable toolset '${c.name}' for client '${s.clientId}': ${c.message}`
1490
+ function Pe(o, e) {
1491
+ return async (t) => {
1492
+ const s = e.resolvePermissions(
1493
+ t.clientId,
1494
+ t.headers
1495
+ ), r = o(s), i = r.orchestrator.getManager(), n = [], l = [];
1496
+ if (s.length > 0) {
1497
+ const c = await i.enableToolsets(s);
1498
+ for (const a of c.results)
1499
+ a.success ? n.push(a.name) : (l.push(a.name), console.warn(
1500
+ `Failed to enable toolset '${a.name}' for client '${t.clientId}': ${a.message}`
1237
1501
  ));
1238
1502
  if (n.length === 0 && l.length > 0)
1239
1503
  throw new Error(
1240
- `All requested toolsets failed to enable for client '${s.clientId}'. Requested: [${t.join(", ")}]. Check that toolset names in permissions match the catalog.`
1504
+ `All requested toolsets failed to enable for client '${t.clientId}'. Requested: [${s.join(", ")}]. Check that toolset names in permissions match the catalog.`
1241
1505
  );
1242
1506
  }
1243
1507
  return {
1244
- server: o.server,
1245
- orchestrator: o.orchestrator,
1508
+ server: r.server,
1509
+ orchestrator: r.orchestrator,
1246
1510
  allowedToolsets: n,
1247
1511
  failedToolsets: l
1248
1512
  };
1249
1513
  };
1250
1514
  }
1251
- var h, U, q, J, G, K, Z, Q, X, C, ee;
1252
- class ve {
1515
+ var f, J, Q, G, Z, X, ee, te, se, M, oe;
1516
+ class Me {
1253
1517
  /**
1254
1518
  * Creates a new PermissionAwareFastifyTransport instance.
1255
1519
  * @param defaultManager - Default tool manager for status endpoints
@@ -1257,28 +1521,28 @@ class ve {
1257
1521
  * @param options - Transport configuration options
1258
1522
  * @param configSchema - Optional JSON schema for configuration discovery
1259
1523
  */
1260
- constructor(e, s, t = {}, o) {
1261
- b(this, h);
1524
+ constructor(e, t, s = {}, r) {
1525
+ A(this, f);
1262
1526
  d(this, "options");
1263
1527
  d(this, "defaultManager");
1264
1528
  d(this, "createPermissionAwareBundle");
1265
1529
  d(this, "app", null);
1266
1530
  d(this, "configSchema");
1267
1531
  // Per-client server bundles and per-client session transports
1268
- d(this, "clientCache", new V({
1269
- onEvict: (e, s) => {
1270
- m(this, h, U).call(this, s);
1532
+ d(this, "clientCache", new F({
1533
+ onEvict: (e, t) => {
1534
+ m(this, f, J).call(this, t);
1271
1535
  }
1272
1536
  }));
1273
- this.defaultManager = e, this.createPermissionAwareBundle = s, this.options = {
1274
- host: t.host ?? "0.0.0.0",
1275
- port: t.port ?? 3e3,
1276
- basePath: t.basePath ?? "/",
1277
- cors: t.cors ?? !0,
1278
- logger: t.logger ?? !1,
1279
- app: t.app,
1280
- customEndpoints: t.customEndpoints
1281
- }, this.configSchema = o;
1537
+ this.defaultManager = e, this.createPermissionAwareBundle = t, this.options = {
1538
+ host: s.host ?? "0.0.0.0",
1539
+ port: s.port ?? 3e3,
1540
+ basePath: s.basePath ?? "/",
1541
+ cors: s.cors ?? !0,
1542
+ logger: s.logger ?? !1,
1543
+ app: s.app,
1544
+ customEndpoints: s.customEndpoints
1545
+ }, this.configSchema = r;
1282
1546
  }
1283
1547
  /**
1284
1548
  * Starts the Fastify server and registers all MCP endpoints.
@@ -1286,14 +1550,14 @@ class ve {
1286
1550
  */
1287
1551
  async start() {
1288
1552
  if (this.app) return;
1289
- const e = this.options.app ?? j({ logger: this.options.logger });
1290
- this.options.cors && await e.register(k, { origin: !0 });
1291
- const s = m(this, h, q).call(this, this.options.basePath);
1292
- m(this, h, J).call(this, e, s), m(this, h, G).call(this, e, s), m(this, h, K).call(this, e, s), m(this, h, Z).call(this, e, s), m(this, h, Q).call(this, e, s), m(this, h, X).call(this, e, s), this.options.customEndpoints && this.options.customEndpoints.length > 0 && F(e, s, this.options.customEndpoints, {
1293
- contextExtractor: async (t) => {
1294
- const o = m(this, h, C).call(this, t);
1553
+ const e = this.options.app ?? N({ logger: this.options.logger });
1554
+ this.options.cors && await e.register(D, { origin: !0 });
1555
+ const t = m(this, f, Q).call(this, this.options.basePath);
1556
+ m(this, f, G).call(this, e, t), m(this, f, Z).call(this, e, t), m(this, f, X).call(this, e, t), m(this, f, ee).call(this, e, t), m(this, f, te).call(this, e, t), m(this, f, se).call(this, e, t), this.options.customEndpoints && this.options.customEndpoints.length > 0 && V(e, t, this.options.customEndpoints, {
1557
+ contextExtractor: async (s) => {
1558
+ const r = m(this, f, M).call(this, s);
1295
1559
  try {
1296
- const i = await this.createPermissionAwareBundle(o);
1560
+ const i = await this.createPermissionAwareBundle(r);
1297
1561
  return {
1298
1562
  allowedToolsets: i.allowedToolsets,
1299
1563
  failedToolsets: i.failedToolsets
@@ -1317,20 +1581,20 @@ class ve {
1317
1581
  this.app && (this.clientCache.stop(!0), this.options.app || await this.app.close(), this.app = null);
1318
1582
  }
1319
1583
  }
1320
- h = new WeakSet(), /**
1584
+ f = new WeakSet(), /**
1321
1585
  * Cleans up resources associated with a client bundle.
1322
1586
  * Closes all sessions within the bundle.
1323
1587
  * @param bundle - The client bundle to clean up
1324
1588
  * @private
1325
1589
  */
1326
- U = function(e) {
1327
- for (const [s, t] of e.sessions.entries())
1590
+ J = function(e) {
1591
+ for (const [t, s] of e.sessions.entries())
1328
1592
  try {
1329
- typeof t.close == "function" && t.close().catch((o) => {
1330
- console.warn(`Error closing session ${s}:`, o);
1593
+ typeof s.close == "function" && s.close().catch((r) => {
1594
+ console.warn(`Error closing session ${t}:`, r);
1331
1595
  });
1332
- } catch (o) {
1333
- console.warn(`Error closing session ${s}:`, o);
1596
+ } catch (r) {
1597
+ console.warn(`Error closing session ${t}:`, r);
1334
1598
  }
1335
1599
  e.sessions.clear();
1336
1600
  }, /**
@@ -1339,7 +1603,7 @@ U = function(e) {
1339
1603
  * @returns Normalized base path without trailing slash
1340
1604
  * @private
1341
1605
  */
1342
- q = function(e) {
1606
+ Q = function(e) {
1343
1607
  return e.endsWith("/") ? e.slice(0, -1) : e;
1344
1608
  }, /**
1345
1609
  * Registers the health check endpoint.
@@ -1347,24 +1611,24 @@ q = function(e) {
1347
1611
  * @param base - Base path for routes
1348
1612
  * @private
1349
1613
  */
1350
- J = function(e, s) {
1351
- e.get(`${s}/healthz`, async () => ({ ok: !0 }));
1614
+ G = function(e, t) {
1615
+ e.get(`${t}/healthz`, async () => ({ ok: !0 }));
1352
1616
  }, /**
1353
1617
  * Registers the tools status endpoint.
1354
1618
  * @param app - Fastify instance
1355
1619
  * @param base - Base path for routes
1356
1620
  * @private
1357
1621
  */
1358
- G = function(e, s) {
1359
- e.get(`${s}/tools`, async () => this.defaultManager.getStatus());
1622
+ Z = function(e, t) {
1623
+ e.get(`${t}/tools`, async () => this.defaultManager.getStatus());
1360
1624
  }, /**
1361
1625
  * Registers the MCP configuration discovery endpoint.
1362
1626
  * @param app - Fastify instance
1363
1627
  * @param base - Base path for routes
1364
1628
  * @private
1365
1629
  */
1366
- K = function(e, s) {
1367
- e.get(`${s}/.well-known/mcp-config`, async (t, o) => (o.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
1630
+ X = function(e, t) {
1631
+ e.get(`${t}/.well-known/mcp-config`, async (s, r) => (r.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
1368
1632
  $schema: "https://json-schema.org/draft/2020-12/schema",
1369
1633
  title: "MCP Session Configuration",
1370
1634
  description: "Schema for the /mcp endpoint configuration",
@@ -1381,11 +1645,11 @@ K = function(e, s) {
1381
1645
  * @param base - Base path for routes
1382
1646
  * @private
1383
1647
  */
1384
- Z = function(e, s) {
1648
+ ee = function(e, t) {
1385
1649
  e.post(
1386
- `${s}/mcp`,
1387
- async (t, o) => {
1388
- const i = m(this, h, C).call(this, t), n = !i.clientId.startsWith("anon-");
1650
+ `${t}/mcp`,
1651
+ async (s, r) => {
1652
+ const i = m(this, f, M).call(this, s), n = !i.clientId.startsWith("anon-");
1389
1653
  let l = n ? this.clientCache.get(i.clientId) : null;
1390
1654
  if (!l)
1391
1655
  try {
@@ -1393,55 +1657,55 @@ Z = function(e, s) {
1393
1657
  u.failedToolsets.length > 0 && console.warn(
1394
1658
  `Client ${i.clientId} had ${u.failedToolsets.length} toolsets fail to enable: [${u.failedToolsets.join(", ")}]. Successfully enabled: [${u.allowedToolsets.join(", ")}]`
1395
1659
  );
1396
- const f = u.sessions;
1660
+ const h = u.sessions;
1397
1661
  l = {
1398
1662
  server: u.server,
1399
1663
  orchestrator: u.orchestrator,
1400
1664
  allowedToolsets: u.allowedToolsets,
1401
1665
  failedToolsets: u.failedToolsets,
1402
- sessions: f instanceof Map ? f : /* @__PURE__ */ new Map()
1666
+ sessions: h instanceof Map ? h : /* @__PURE__ */ new Map()
1403
1667
  }, n && this.clientCache.set(i.clientId, l);
1404
1668
  } catch (u) {
1405
1669
  return console.error(
1406
1670
  `Failed to create permission-aware bundle for client ${i.clientId}:`,
1407
1671
  u
1408
- ), o.code(403), m(this, h, ee).call(this, "Access denied");
1672
+ ), r.code(403), m(this, f, oe).call(this, "Access denied");
1409
1673
  }
1410
- const a = t.headers["mcp-session-id"];
1411
- let c;
1412
- if (a && l.sessions.get(a))
1413
- c = l.sessions.get(a);
1414
- else if (!a && D(t.body)) {
1415
- const u = T();
1416
- c = new O({
1674
+ const c = s.headers["mcp-session-id"];
1675
+ let a;
1676
+ if (c && l.sessions.get(c))
1677
+ a = l.sessions.get(c);
1678
+ else if (!c && _(s.body)) {
1679
+ const u = S();
1680
+ a = new z({
1417
1681
  sessionIdGenerator: () => u,
1418
- onsessioninitialized: (f) => {
1419
- l.sessions.set(f, c);
1682
+ onsessioninitialized: (h) => {
1683
+ l.sessions.set(h, a);
1420
1684
  }
1421
1685
  });
1422
1686
  try {
1423
- await l.server.connect(c);
1687
+ await l.server.connect(a);
1424
1688
  } catch {
1425
- return o.code(500), {
1689
+ return r.code(500), {
1426
1690
  jsonrpc: "2.0",
1427
1691
  error: { code: -32603, message: "Error initializing server." },
1428
1692
  id: null
1429
1693
  };
1430
1694
  }
1431
- c.onclose = () => {
1432
- c?.sessionId && l.sessions.delete(c.sessionId);
1695
+ a.onclose = () => {
1696
+ a?.sessionId && l.sessions.delete(a.sessionId);
1433
1697
  };
1434
1698
  } else
1435
- return o.code(400), {
1699
+ return r.code(400), {
1436
1700
  jsonrpc: "2.0",
1437
1701
  error: { code: -32e3, message: "Session not found or expired" },
1438
1702
  id: null
1439
1703
  };
1440
- return await c.handleRequest(
1441
- t.raw,
1442
- o.raw,
1443
- t.body
1444
- ), o;
1704
+ return await a.handleRequest(
1705
+ s.raw,
1706
+ r.raw,
1707
+ s.body
1708
+ ), r;
1445
1709
  }
1446
1710
  );
1447
1711
  }, /**
@@ -1450,19 +1714,19 @@ Z = function(e, s) {
1450
1714
  * @param base - Base path for routes
1451
1715
  * @private
1452
1716
  */
1453
- Q = function(e, s) {
1454
- e.get(`${s}/mcp`, async (t, o) => {
1455
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
1717
+ te = function(e, t) {
1718
+ e.get(`${t}/mcp`, async (s, r) => {
1719
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
1456
1720
  if (!n)
1457
- return o.code(400), "Missing mcp-client-id";
1721
+ return r.code(400), "Missing mcp-client-id";
1458
1722
  const l = this.clientCache.get(n);
1459
1723
  if (!l)
1460
- return o.code(400), "Invalid or expired client";
1461
- const a = t.headers["mcp-session-id"];
1462
- if (!a)
1463
- return o.code(400), "Missing mcp-session-id";
1464
- const c = l.sessions.get(a);
1465
- return c ? (await c.handleRequest(t.raw, o.raw), o) : (o.code(400), "Invalid or expired session ID");
1724
+ return r.code(400), "Invalid or expired client";
1725
+ const c = s.headers["mcp-session-id"];
1726
+ if (!c)
1727
+ return r.code(400), "Missing mcp-session-id";
1728
+ const a = l.sessions.get(c);
1729
+ return a ? (await a.handleRequest(s.raw, r.raw), r) : (r.code(400), "Invalid or expired session ID");
1466
1730
  });
1467
1731
  }, /**
1468
1732
  * Registers the DELETE /mcp endpoint for session termination.
@@ -1470,13 +1734,13 @@ Q = function(e, s) {
1470
1734
  * @param base - Base path for routes
1471
1735
  * @private
1472
1736
  */
1473
- X = function(e, s) {
1737
+ se = function(e, t) {
1474
1738
  e.delete(
1475
- `${s}/mcp`,
1476
- async (t, o) => {
1477
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = t.headers["mcp-session-id"];
1739
+ `${t}/mcp`,
1740
+ async (s, r) => {
1741
+ const i = s.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "", l = s.headers["mcp-session-id"];
1478
1742
  if (!n || !l)
1479
- return o.code(400), {
1743
+ return r.code(400), {
1480
1744
  jsonrpc: "2.0",
1481
1745
  error: {
1482
1746
  code: -32600,
@@ -1484,23 +1748,23 @@ X = function(e, s) {
1484
1748
  },
1485
1749
  id: null
1486
1750
  };
1487
- const a = this.clientCache.get(n), c = a?.sessions.get(l);
1488
- if (!a || !c)
1489
- return o.code(404), {
1751
+ const c = this.clientCache.get(n), a = c?.sessions.get(l);
1752
+ if (!c || !a)
1753
+ return r.code(404), {
1490
1754
  jsonrpc: "2.0",
1491
1755
  error: { code: -32e3, message: "Session not found or expired" },
1492
1756
  id: null
1493
1757
  };
1494
1758
  try {
1495
- if (typeof c.close == "function")
1759
+ if (typeof a.close == "function")
1496
1760
  try {
1497
- await c.close();
1761
+ await a.close();
1498
1762
  } catch {
1499
1763
  }
1500
1764
  } finally {
1501
- c?.sessionId ? a.sessions.delete(c.sessionId) : a.sessions.delete(l);
1765
+ a?.sessionId ? c.sessions.delete(a.sessionId) : c.sessions.delete(l);
1502
1766
  }
1503
- return o.code(204).send(), o;
1767
+ return r.code(204).send(), r;
1504
1768
  }
1505
1769
  );
1506
1770
  }, /**
@@ -1510,11 +1774,11 @@ X = function(e, s) {
1510
1774
  * @returns Client request context with ID and headers
1511
1775
  * @private
1512
1776
  */
1513
- C = function(e) {
1514
- const s = e.headers["mcp-client-id"]?.trim(), t = s && s.length > 0 ? s : `anon-${T()}`, o = {};
1777
+ M = function(e) {
1778
+ const t = e.headers["mcp-client-id"]?.trim(), s = t && t.length > 0 ? t : `anon-${S()}`, r = {};
1515
1779
  for (const [i, n] of Object.entries(e.headers))
1516
- typeof n == "string" && (o[i] = n);
1517
- return { clientId: t, headers: o };
1780
+ typeof n == "string" && (r[i] = n);
1781
+ return { clientId: s, headers: r };
1518
1782
  }, /**
1519
1783
  * Creates a safe error response that doesn't expose unauthorized toolset information.
1520
1784
  * Used for permission-related errors to prevent information leakage.
@@ -1523,64 +1787,66 @@ C = function(e) {
1523
1787
  * @returns JSON-RPC error response object
1524
1788
  * @private
1525
1789
  */
1526
- ee = function(e = "Access denied", s = -32e3) {
1790
+ oe = function(e = "Access denied", t = -32e3) {
1527
1791
  return {
1528
1792
  jsonrpc: "2.0",
1529
1793
  error: {
1530
- code: s,
1794
+ code: t,
1531
1795
  message: e
1532
1796
  },
1533
1797
  id: null
1534
1798
  };
1535
1799
  };
1536
- function Te(r) {
1537
- if (!r) return;
1800
+ function Ie(o) {
1801
+ if (!o) return;
1538
1802
  const e = {
1539
- namespaceToolsWithSetKey: r.namespaceToolsWithSetKey
1803
+ namespaceToolsWithSetKey: o.namespaceToolsWithSetKey
1540
1804
  };
1541
- return r.allowlist !== void 0 && console.warn(
1805
+ return o.allowlist !== void 0 && console.warn(
1542
1806
  "Permission-based servers: exposurePolicy.allowlist is ignored. Allowed toolsets are determined by client permissions."
1543
- ), r.denylist !== void 0 && console.warn(
1807
+ ), o.denylist !== void 0 && console.warn(
1544
1808
  "Permission-based servers: exposurePolicy.denylist is ignored. Use permission configuration to control toolset access."
1545
- ), r.maxActiveToolsets !== void 0 && console.warn(
1809
+ ), o.maxActiveToolsets !== void 0 && console.warn(
1546
1810
  "Permission-based servers: exposurePolicy.maxActiveToolsets is ignored. Toolset count is determined by client permissions."
1547
- ), r.onLimitExceeded !== void 0 && console.warn(
1811
+ ), o.onLimitExceeded !== void 0 && console.warn(
1548
1812
  "Permission-based servers: exposurePolicy.onLimitExceeded is ignored. No toolset limits are enforced."
1549
1813
  ), e;
1550
1814
  }
1551
- async function Me(r) {
1552
- if (!r.permissions)
1815
+ async function ze(o) {
1816
+ if (!o.permissions)
1553
1817
  throw new Error(
1554
1818
  "Permission configuration is required for createPermissionBasedMcpServer. Please provide a 'permissions' field in the options."
1555
1819
  );
1556
- if (de(r.permissions), r.startup)
1820
+ if (Te(o.permissions), o.sessionContext && (K(o.sessionContext), console.warn(
1821
+ "Session context support for permission-based servers is limited. The base context will be used for module loaders."
1822
+ )), o.startup)
1557
1823
  throw new Error(
1558
1824
  "Permission-based servers determine toolsets from client permissions. The 'startup' option is not allowed. Remove it from your configuration."
1559
1825
  );
1560
- if (typeof r.createServer != "function")
1826
+ if (typeof o.createServer != "function")
1561
1827
  throw new Error(
1562
1828
  "createPermissionBasedMcpServer: `createServer` (factory) is required"
1563
1829
  );
1564
- const e = Te(
1565
- r.exposurePolicy
1566
- ), s = new pe(r.permissions), t = r.createServer(), o = new A({
1567
- server: t,
1568
- catalog: r.catalog,
1569
- moduleLoaders: r.moduleLoaders,
1830
+ const e = Ie(
1831
+ o.exposurePolicy
1832
+ ), t = new Ee(o.permissions), s = o.createServer(), r = new C({
1833
+ server: s,
1834
+ catalog: o.catalog,
1835
+ moduleLoaders: o.moduleLoaders,
1570
1836
  exposurePolicy: e,
1571
- context: r.context,
1837
+ context: o.context,
1572
1838
  notifyToolsListChanged: void 0,
1573
1839
  // No notifications in STATIC mode
1574
1840
  startup: { mode: "STATIC", toolsets: [] },
1575
1841
  registerMetaTools: !1
1576
- }), i = ye(
1842
+ }), i = Pe(
1577
1843
  (l) => {
1578
- const a = r.createServer(), c = new A({
1579
- server: a,
1580
- catalog: r.catalog,
1581
- moduleLoaders: r.moduleLoaders,
1844
+ const c = o.createServer(), a = new C({
1845
+ server: c,
1846
+ catalog: o.catalog,
1847
+ moduleLoaders: o.moduleLoaders,
1582
1848
  exposurePolicy: e,
1583
- context: r.context,
1849
+ context: o.context,
1584
1850
  notifyToolsListChanged: void 0,
1585
1851
  // No notifications in STATIC mode
1586
1852
  startup: { mode: "STATIC", toolsets: [] },
@@ -1588,17 +1854,17 @@ async function Me(r) {
1588
1854
  registerMetaTools: !1
1589
1855
  // No meta-tools - toolsets are fixed per client
1590
1856
  });
1591
- return { server: a, orchestrator: c };
1857
+ return { server: c, orchestrator: a };
1592
1858
  },
1593
- s
1594
- ), n = new ve(
1595
- o.getManager(),
1859
+ t
1860
+ ), n = new Me(
1861
+ r.getManager(),
1596
1862
  i,
1597
- r.http,
1598
- r.configSchema
1863
+ o.http,
1864
+ o.configSchema
1599
1865
  );
1600
1866
  return {
1601
- server: t,
1867
+ server: s,
1602
1868
  start: async () => {
1603
1869
  await n.start();
1604
1870
  },
@@ -1606,21 +1872,22 @@ async function Me(r) {
1606
1872
  try {
1607
1873
  await n.stop();
1608
1874
  } finally {
1609
- s.clearCache();
1875
+ t.clearCache();
1610
1876
  }
1611
1877
  }
1612
1878
  };
1613
1879
  }
1614
- function Pe(r) {
1615
- return r;
1880
+ function _e(o) {
1881
+ return o;
1616
1882
  }
1617
- function $e(r) {
1618
- return r;
1883
+ function qe(o) {
1884
+ return o;
1619
1885
  }
1620
1886
  export {
1621
- Ie as createMcpServer,
1622
- Me as createPermissionBasedMcpServer,
1623
- Pe as defineEndpoint,
1624
- $e as definePermissionAwareEndpoint
1887
+ fe as SessionContextResolver,
1888
+ De as createMcpServer,
1889
+ ze as createPermissionBasedMcpServer,
1890
+ _e as defineEndpoint,
1891
+ qe as definePermissionAwareEndpoint
1625
1892
  };
1626
1893
  //# sourceMappingURL=index.js.map