toolception 0.5.2 → 0.5.3

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,16 +1,18 @@
1
- var P = (r) => {
1
+ var se = Object.defineProperty;
2
+ var L = (r) => {
2
3
  throw TypeError(r);
3
4
  };
4
- var ee = (r, e, s) => e.has(r) || P("Cannot " + s);
5
- var w = (r, e, s) => e.has(r) ? P("Cannot add the same private member more than once") : e instanceof WeakSet ? e.add(r) : e.set(r, s);
6
- var f = (r, e, s) => (ee(r, e, "access private method"), s);
7
- import { z as p } from "zod";
8
- import N from "fastify";
9
- import j from "@fastify/cors";
10
- import { randomUUID as v } from "node:crypto";
11
- import { StreamableHTTPServerTransport as k } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
12
- import { isInitializeRequest as D } from "@modelcontextprotocol/sdk/types.js";
13
- const L = {
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 D } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
14
+ import { isInitializeRequest as z } from "@modelcontextprotocol/sdk/types.js";
15
+ const R = {
14
16
  dynamic: [
15
17
  "dynamic-tool-discovery",
16
18
  "dynamicToolDiscovery",
@@ -18,11 +20,12 @@ const L = {
18
20
  ],
19
21
  toolsets: ["tool-sets", "toolSets", "FMP_TOOL_SETS"]
20
22
  };
21
- class se {
23
+ class re {
22
24
  constructor(e = {}) {
25
+ d(this, "keys");
23
26
  this.keys = {
24
- dynamic: e.keys?.dynamic ?? L.dynamic,
25
- toolsets: e.keys?.toolsets ?? L.toolsets
27
+ dynamic: e.keys?.dynamic ?? R.dynamic,
28
+ toolsets: e.keys?.toolsets ?? R.toolsets
26
29
  };
27
30
  }
28
31
  resolveMode(e, s) {
@@ -109,8 +112,10 @@ class se {
109
112
  }
110
113
  }
111
114
  }
112
- class te {
115
+ class ie {
113
116
  constructor(e) {
117
+ d(this, "catalog");
118
+ d(this, "moduleLoaders");
114
119
  this.catalog = e.catalog, this.moduleLoaders = e.moduleLoaders ?? {};
115
120
  }
116
121
  getAvailableToolsets() {
@@ -162,14 +167,20 @@ class te {
162
167
  return t;
163
168
  }
164
169
  }
165
- class R extends Error {
166
- constructor(e, s, t, o) {
167
- super(e), this.name = "ToolingError", this.code = s, this.details = t;
170
+ class N extends Error {
171
+ constructor(s, t, o, i) {
172
+ super(s);
173
+ d(this, "code");
174
+ d(this, "details");
175
+ this.name = "ToolingError", this.code = t, this.details = o;
168
176
  }
169
177
  }
170
178
  class O {
171
179
  constructor(e = {}) {
172
- this.names = /* @__PURE__ */ new Set(), this.toolsetToNames = /* @__PURE__ */ new Map(), this.options = {
180
+ d(this, "options");
181
+ d(this, "names", /* @__PURE__ */ new Set());
182
+ d(this, "toolsetToNames", /* @__PURE__ */ new Map());
183
+ this.options = {
173
184
  namespaceWithToolset: e.namespaceWithToolset ?? !0
174
185
  };
175
186
  }
@@ -181,7 +192,7 @@ class O {
181
192
  }
182
193
  add(e) {
183
194
  if (this.names.has(e))
184
- throw new R(
195
+ throw new N(
185
196
  `Tool name collision: '${e}' already registered`,
186
197
  "E_TOOL_NAME_CONFLICT"
187
198
  );
@@ -196,7 +207,7 @@ class O {
196
207
  return s.map((t) => {
197
208
  const o = this.getSafeName(e, t.name);
198
209
  if (this.has(o))
199
- throw new R(
210
+ throw new N(
200
211
  `Tool name collision for '${o}'`,
201
212
  "E_TOOL_NAME_CONFLICT"
202
213
  );
@@ -213,9 +224,16 @@ class O {
213
224
  return e;
214
225
  }
215
226
  }
216
- class oe {
227
+ class ne {
217
228
  constructor(e) {
218
- this.activeToolsets = /* @__PURE__ */ new Set(), 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 });
229
+ d(this, "server");
230
+ d(this, "resolver");
231
+ d(this, "context");
232
+ d(this, "onToolsListChanged");
233
+ d(this, "exposurePolicy");
234
+ d(this, "toolRegistry");
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 });
219
237
  }
220
238
  /**
221
239
  * Sends a tool list change notification if configured.
@@ -395,11 +413,11 @@ class oe {
395
413
  return this.enableToolsets(e);
396
414
  }
397
415
  }
398
- function re(r, e, s) {
416
+ function ae(r, e, s) {
399
417
  (s?.mode ?? "DYNAMIC") === "DYNAMIC" && (r.tool(
400
418
  "enable_toolset",
401
419
  "Enable a toolset by name",
402
- { name: p.string().describe("Toolset name") },
420
+ { name: y.string().describe("Toolset name") },
403
421
  async (o) => {
404
422
  const i = await e.enableToolset(o.name);
405
423
  return {
@@ -409,7 +427,7 @@ function re(r, e, s) {
409
427
  ), r.tool(
410
428
  "disable_toolset",
411
429
  "Disable a toolset by name (state only)",
412
- { name: p.string().describe("Toolset name") },
430
+ { name: y.string().describe("Toolset name") },
413
431
  async (o) => {
414
432
  const i = await e.disableToolset(o.name);
415
433
  return {
@@ -444,7 +462,7 @@ function re(r, e, s) {
444
462
  ), r.tool(
445
463
  "describe_toolset",
446
464
  "Describe a toolset with definition, active status and tools",
447
- { name: p.string().describe("Toolset name") },
465
+ { name: y.string().describe("Toolset name") },
448
466
  async (o) => {
449
467
  const i = e.getToolsetDefinition(o.name), n = e.getStatus().toolsetToTools;
450
468
  if (!i)
@@ -486,25 +504,31 @@ function re(r, e, s) {
486
504
  }
487
505
  );
488
506
  }
489
- class b {
507
+ class A {
490
508
  constructor(e) {
491
- this.initError = null, this.toolsetValidator = new se();
509
+ d(this, "mode");
510
+ d(this, "resolver");
511
+ d(this, "manager");
512
+ d(this, "toolsetValidator");
513
+ d(this, "initPromise");
514
+ d(this, "initError", null);
515
+ this.toolsetValidator = new re();
492
516
  const s = e.startup ?? {}, t = this.resolveStartupConfig(s, e.catalog);
493
- this.mode = t.mode, this.resolver = new te({
517
+ this.mode = t.mode, this.resolver = new ie({
494
518
  catalog: e.catalog,
495
519
  moduleLoaders: e.moduleLoaders
496
520
  });
497
521
  const o = new O({
498
522
  namespaceWithToolset: e.exposurePolicy?.namespaceToolsWithSetKey ?? !0
499
523
  });
500
- this.manager = new oe({
524
+ this.manager = new ne({
501
525
  server: e.server,
502
526
  resolver: this.resolver,
503
527
  context: e.context,
504
528
  onToolsListChanged: e.notifyToolsListChanged,
505
529
  exposurePolicy: e.exposurePolicy,
506
530
  toolRegistry: o
507
- }), e.registerMetaTools !== !1 && re(e.server, this.manager, { mode: this.mode });
531
+ }), e.registerMetaTools !== !1 && ae(e.server, this.manager, { mode: this.mode });
508
532
  const i = t.toolsets;
509
533
  this.initPromise = this.initializeToolsets(i);
510
534
  }
@@ -581,11 +605,17 @@ class b {
581
605
  return this.manager;
582
606
  }
583
607
  }
584
- var T, S;
585
- class z {
608
+ var w, E;
609
+ class V {
586
610
  constructor(e = {}) {
587
- w(this, T);
588
- this.storage = /* @__PURE__ */ new Map(), this.maxSize = e.maxSize ?? 1e3, this.ttlMs = e.ttlMs ?? 1e3 * 60 * 60, this.onEvict = e.onEvict;
611
+ b(this, w);
612
+ d(this, "storage", /* @__PURE__ */ new Map());
613
+ d(this, "maxSize");
614
+ d(this, "ttlMs");
615
+ d(this, "onEvict");
616
+ // Use ReturnType<typeof setInterval> for cross-env typings without NodeJS namespace
617
+ d(this, "pruneInterval");
618
+ this.maxSize = e.maxSize ?? 1e3, this.ttlMs = e.ttlMs ?? 1e3 * 60 * 60, this.onEvict = e.onEvict;
589
619
  const s = e.pruneIntervalMs ?? 1e3 * 60 * 10;
590
620
  this.pruneInterval = setInterval(() => this.pruneExpired(), s);
591
621
  }
@@ -614,7 +644,7 @@ class z {
614
644
  */
615
645
  delete(e) {
616
646
  const s = this.storage.get(e);
617
- s && (this.storage.delete(e), f(this, T, S).call(this, e, s.resource));
647
+ s && (this.storage.delete(e), m(this, w, E).call(this, e, s.resource));
618
648
  }
619
649
  /**
620
650
  * Stops the background pruning interval and optionally clears all entries.
@@ -631,7 +661,7 @@ class z {
631
661
  const e = Array.from(this.storage.entries());
632
662
  this.storage.clear();
633
663
  for (const [s, t] of e)
634
- f(this, T, S).call(this, s, t.resource);
664
+ m(this, w, E).call(this, s, t.resource);
635
665
  }
636
666
  /**
637
667
  * Evicts the least recently used entry from the cache.
@@ -653,13 +683,13 @@ class z {
653
683
  this.delete(t);
654
684
  }
655
685
  }
656
- T = new WeakSet(), /**
686
+ w = new WeakSet(), /**
657
687
  * Safely calls the evict callback, catching and logging any errors.
658
688
  * @param key - The key being evicted
659
689
  * @param resource - The resource being evicted
660
690
  * @private
661
691
  */
662
- S = function(e, s) {
692
+ E = function(e, s) {
663
693
  if (this.onEvict)
664
694
  try {
665
695
  const t = this.onEvict(e, s);
@@ -670,7 +700,7 @@ S = function(e, s) {
670
700
  console.warn(`Error in cache eviction callback for key '${e}':`, t);
671
701
  }
672
702
  };
673
- function V(r, e, s, t) {
703
+ function F(r, e, s, t) {
674
704
  const o = ["/mcp", "/healthz", "/tools", "/.well-known/mcp-config"];
675
705
  for (const i of s) {
676
706
  const n = `${e}${i.path}`;
@@ -683,48 +713,48 @@ function V(r, e, s, t) {
683
713
  continue;
684
714
  }
685
715
  const a = i.method.toLowerCase();
686
- r[a](n, async (c, d) => {
716
+ r[a](n, async (c, h) => {
687
717
  try {
688
- const u = c.headers["mcp-client-id"]?.trim(), y = u && u.length > 0 ? u : `anon-${v()}`;
689
- let C;
718
+ const f = c.headers["mcp-client-id"]?.trim(), v = f && f.length > 0 ? f : `anon-${T()}`;
719
+ let x;
690
720
  if (i.bodySchema) {
691
- const m = i.bodySchema.safeParse(c.body);
692
- if (!m.success)
693
- return A(d, "body", m.error);
694
- C = m.data;
721
+ const g = i.bodySchema.safeParse(c.body);
722
+ if (!g.success)
723
+ return S(h, "body", g.error);
724
+ x = g.data;
695
725
  }
696
726
  let I = {};
697
727
  if (i.querySchema) {
698
- const m = i.querySchema.safeParse(c.query);
699
- if (!m.success)
700
- return A(d, "query", m.error);
701
- I = m.data;
728
+ const g = i.querySchema.safeParse(c.query);
729
+ if (!g.success)
730
+ return S(h, "query", g.error);
731
+ I = g.data;
702
732
  }
703
- let x = {};
733
+ let M = {};
704
734
  if (i.paramsSchema) {
705
- const m = i.paramsSchema.safeParse(c.params);
706
- if (!m.success)
707
- return A(d, "params", m.error);
708
- x = m.data;
735
+ const g = i.paramsSchema.safeParse(c.params);
736
+ if (!g.success)
737
+ return S(h, "params", g.error);
738
+ M = g.data;
709
739
  }
710
- const M = {
711
- body: C,
740
+ const P = {
741
+ body: x,
712
742
  query: I,
713
- params: x,
743
+ params: M,
714
744
  headers: c.headers,
715
- clientId: y
745
+ clientId: v
716
746
  };
717
747
  if (t?.contextExtractor) {
718
- const m = await t.contextExtractor(c);
719
- Object.assign(M, m);
748
+ const g = await t.contextExtractor(c);
749
+ Object.assign(P, g);
720
750
  }
721
- const $ = await i.handler(M);
751
+ const $ = await i.handler(P);
722
752
  if (i.responseSchema) {
723
- const m = i.responseSchema.safeParse($);
724
- return m.success ? m.data : (console.error(
753
+ const g = i.responseSchema.safeParse($);
754
+ return g.success ? g.data : (console.error(
725
755
  `Response validation failed for ${i.method} ${i.path}:`,
726
- m.error
727
- ), d.code(500), {
756
+ g.error
757
+ ), h.code(500), {
728
758
  error: {
729
759
  code: "RESPONSE_VALIDATION_ERROR",
730
760
  message: "Internal server error: invalid response format"
@@ -732,21 +762,21 @@ function V(r, e, s, t) {
732
762
  });
733
763
  }
734
764
  return $;
735
- } catch (u) {
765
+ } catch (f) {
736
766
  return console.error(
737
767
  `Error in custom endpoint ${i.method} ${i.path}:`,
738
- u
739
- ), d.code(500), {
768
+ f
769
+ ), h.code(500), {
740
770
  error: {
741
771
  code: "INTERNAL_ERROR",
742
- message: u instanceof Error ? u.message : "Internal server error"
772
+ message: f instanceof Error ? f.message : "Internal server error"
743
773
  }
744
774
  };
745
775
  }
746
776
  });
747
777
  }
748
778
  }
749
- function A(r, e, s) {
779
+ function S(r, e, s) {
750
780
  return r.code(400), {
751
781
  error: {
752
782
  code: "VALIDATION_ERROR",
@@ -755,13 +785,20 @@ function A(r, e, s) {
755
785
  }
756
786
  };
757
787
  }
758
- class ie {
788
+ class le {
759
789
  constructor(e, s, t = {}, o) {
760
- this.app = null, this.clientCache = new z({
761
- onEvict: (i, n) => {
762
- this.cleanupBundle(n);
790
+ d(this, "options");
791
+ d(this, "defaultManager");
792
+ d(this, "createBundle");
793
+ d(this, "app", null);
794
+ d(this, "configSchema");
795
+ // Per-client server bundles and per-client session transports
796
+ d(this, "clientCache", new V({
797
+ onEvict: (e, s) => {
798
+ this.cleanupBundle(s);
763
799
  }
764
- }), this.defaultManager = e, this.createBundle = s, this.options = {
800
+ }));
801
+ this.defaultManager = e, this.createBundle = s, this.options = {
765
802
  host: t.host ?? "0.0.0.0",
766
803
  port: t.port ?? 3e3,
767
804
  basePath: t.basePath ?? "/",
@@ -773,8 +810,8 @@ class ie {
773
810
  }
774
811
  async start() {
775
812
  if (this.app) return;
776
- const e = this.options.app ?? N({ logger: this.options.logger });
777
- this.options.cors && await e.register(j, { origin: !0 });
813
+ const e = this.options.app ?? j({ logger: this.options.logger });
814
+ this.options.cors && await e.register(k, { origin: !0 });
778
815
  const s = this.options.basePath.endsWith("/") ? this.options.basePath.slice(0, -1) : this.options.basePath;
779
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 ?? {
780
817
  $schema: "https://json-schema.org/draft/2020-12/schema",
@@ -788,30 +825,30 @@ class ie {
788
825
  })), e.post(
789
826
  `${s}/mcp`,
790
827
  async (t, o) => {
791
- const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : `anon-${v()}`, l = !n.startsWith("anon-");
828
+ const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : `anon-${T()}`, l = !n.startsWith("anon-");
792
829
  let a = l ? this.clientCache.get(n) : null;
793
830
  if (!a) {
794
- const u = this.createBundle(), y = u.sessions;
831
+ const f = this.createBundle(), v = f.sessions;
795
832
  a = {
796
- server: u.server,
797
- orchestrator: u.orchestrator,
798
- sessions: y instanceof Map ? y : /* @__PURE__ */ new Map()
833
+ server: f.server,
834
+ orchestrator: f.orchestrator,
835
+ sessions: v instanceof Map ? v : /* @__PURE__ */ new Map()
799
836
  }, l && this.clientCache.set(n, a);
800
837
  }
801
838
  const c = t.headers["mcp-session-id"];
802
- let d;
839
+ let h;
803
840
  if (c && a.sessions.get(c))
804
- d = a.sessions.get(c);
805
- else if (!c && D(t.body)) {
806
- const u = v();
807
- d = new k({
808
- sessionIdGenerator: () => u,
809
- onsessioninitialized: (y) => {
810
- a.sessions.set(y, d);
841
+ h = a.sessions.get(c);
842
+ else if (!c && z(t.body)) {
843
+ const f = T();
844
+ h = new D({
845
+ sessionIdGenerator: () => f,
846
+ onsessioninitialized: (v) => {
847
+ a.sessions.set(v, h);
811
848
  }
812
849
  });
813
850
  try {
814
- await a.server.connect(d);
851
+ await a.server.connect(h);
815
852
  } catch {
816
853
  return o.code(500), {
817
854
  jsonrpc: "2.0",
@@ -819,8 +856,8 @@ class ie {
819
856
  id: null
820
857
  };
821
858
  }
822
- d.onclose = () => {
823
- d?.sessionId && a.sessions.delete(d.sessionId);
859
+ h.onclose = () => {
860
+ h?.sessionId && a.sessions.delete(h.sessionId);
824
861
  };
825
862
  } else
826
863
  return o.code(400), {
@@ -828,7 +865,7 @@ class ie {
828
865
  error: { code: -32e3, message: "Session not found or expired" },
829
866
  id: null
830
867
  };
831
- return await d.handleRequest(
868
+ return await h.handleRequest(
832
869
  t.raw,
833
870
  o.raw,
834
871
  t.body
@@ -877,7 +914,7 @@ class ie {
877
914
  }
878
915
  return o.code(204).send(), o;
879
916
  }
880
- ), this.options.customEndpoints && this.options.customEndpoints.length > 0 && V(e, s, this.options.customEndpoints), this.options.app || await e.listen({ host: this.options.host, port: this.options.port }), this.app = e;
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;
881
918
  }
882
919
  /**
883
920
  * Stops the Fastify server and cleans up all resources.
@@ -904,16 +941,16 @@ class ie {
904
941
  e.sessions.clear();
905
942
  }
906
943
  }
907
- const ne = p.object({
908
- mode: p.enum(["DYNAMIC", "STATIC"]).optional(),
909
- toolsets: p.union([p.array(p.string()), p.literal("ALL")]).optional()
944
+ const ce = y.object({
945
+ mode: y.enum(["DYNAMIC", "STATIC"]).optional(),
946
+ toolsets: y.union([y.array(y.string()), y.literal("ALL")]).optional()
910
947
  }).strict();
911
- async function Ee(r) {
948
+ async function Ie(r) {
912
949
  if (r.startup)
913
950
  try {
914
- ne.parse(r.startup);
951
+ ce.parse(r.startup);
915
952
  } catch (a) {
916
- if (a instanceof p.ZodError) {
953
+ if (a instanceof y.ZodError) {
917
954
  const c = a.format();
918
955
  throw new Error(
919
956
  `Invalid startup configuration:
@@ -941,7 +978,7 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
941
978
  return;
942
979
  console.warn("Failed to send tools list changed notification:", c);
943
980
  }
944
- }, n = new b({
981
+ }, n = new A({
945
982
  server: s,
946
983
  catalog: r.catalog,
947
984
  moduleLoaders: r.moduleLoaders,
@@ -952,12 +989,12 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
952
989
  registerMetaTools: r.registerMetaTools !== void 0 ? r.registerMetaTools : e === "DYNAMIC"
953
990
  });
954
991
  e === "STATIC" && await n.ensureReady();
955
- const l = new ie(
992
+ const l = new le(
956
993
  n.getManager(),
957
994
  () => {
958
995
  if (e === "STATIC")
959
996
  return { server: s, orchestrator: n };
960
- const a = r.createServer(), c = new b({
997
+ const a = r.createServer(), c = new A({
961
998
  server: a,
962
999
  catalog: r.catalog,
963
1000
  moduleLoaders: r.moduleLoaders,
@@ -982,16 +1019,16 @@ Hint: Common mistake - use "toolsets" not "initialToolsets"`
982
1019
  }
983
1020
  };
984
1021
  }
985
- function ae(r) {
986
- le(r), ce(r), de(r), he(r);
1022
+ function de(r) {
1023
+ he(r), ue(r), fe(r), me(r);
987
1024
  }
988
- function le(r) {
1025
+ function he(r) {
989
1026
  if (!r || typeof r != "object")
990
1027
  throw new Error(
991
1028
  "Permission configuration is required for createPermissionBasedMcpServer"
992
1029
  );
993
1030
  }
994
- function ce(r) {
1031
+ function ue(r) {
995
1032
  if (!r.source)
996
1033
  throw new Error('Permission source must be either "headers" or "config"');
997
1034
  if (r.source !== "headers" && r.source !== "config")
@@ -999,19 +1036,19 @@ function ce(r) {
999
1036
  `Invalid permission source: "${r.source}". Must be either "headers" or "config"`
1000
1037
  );
1001
1038
  }
1002
- function de(r) {
1039
+ function fe(r) {
1003
1040
  if (r.source === "config" && !r.staticMap && !r.resolver)
1004
1041
  throw new Error(
1005
1042
  "Config-based permissions require at least one of: staticMap or resolver function"
1006
1043
  );
1007
1044
  }
1008
- function he(r) {
1045
+ function me(r) {
1009
1046
  if (r.staticMap !== void 0) {
1010
1047
  if (typeof r.staticMap != "object" || r.staticMap === null)
1011
1048
  throw new Error(
1012
1049
  "staticMap must be an object mapping client IDs to toolset arrays"
1013
1050
  );
1014
- ue(r.staticMap);
1051
+ ge(r.staticMap);
1015
1052
  }
1016
1053
  if (r.resolver !== void 0 && typeof r.resolver != "function")
1017
1054
  throw new Error(
@@ -1022,22 +1059,24 @@ function he(r) {
1022
1059
  if (r.headerName !== void 0 && (typeof r.headerName != "string" || r.headerName.length === 0))
1023
1060
  throw new Error("headerName must be a non-empty string");
1024
1061
  }
1025
- function ue(r) {
1062
+ function ge(r) {
1026
1063
  for (const [e, s] of Object.entries(r))
1027
1064
  if (!Array.isArray(s))
1028
1065
  throw new Error(
1029
1066
  `staticMap value for client "${e}" must be an array of toolset names`
1030
1067
  );
1031
1068
  }
1032
- var g, F, _, B, H, Y;
1033
- class fe {
1069
+ var p, _, B, H, Y, W;
1070
+ class pe {
1034
1071
  /**
1035
1072
  * Creates a new PermissionResolver instance.
1036
1073
  * @param config - The permission configuration defining how permissions are resolved
1037
1074
  */
1038
1075
  constructor(e) {
1039
- w(this, g);
1040
- this.config = e, this.cache = /* @__PURE__ */ new Map(), this.normalizedHeaderName = (e.headerName || "mcp-toolset-permissions").toLowerCase();
1076
+ b(this, p);
1077
+ d(this, "cache", /* @__PURE__ */ new Map());
1078
+ d(this, "normalizedHeaderName");
1079
+ this.config = e, this.normalizedHeaderName = (e.headerName || "mcp-toolset-permissions").toLowerCase();
1041
1080
  }
1042
1081
  /**
1043
1082
  * Resolves permissions for a client based on the configured source.
@@ -1057,7 +1096,7 @@ class fe {
1057
1096
  return this.cache.get(e);
1058
1097
  let t;
1059
1098
  try {
1060
- this.config.source === "headers" ? t = f(this, g, F).call(this, s) : t = f(this, g, B).call(this, e), Array.isArray(t) || (console.warn(
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(
1061
1100
  `Permission resolution returned non-array for client ${e}, using empty permissions`
1062
1101
  ), t = []), t = t.filter(
1063
1102
  (o) => typeof o == "string" && o.trim().length > 0
@@ -1086,7 +1125,7 @@ class fe {
1086
1125
  this.cache.clear();
1087
1126
  }
1088
1127
  }
1089
- g = new WeakSet(), /**
1128
+ p = new WeakSet(), /**
1090
1129
  * Parses permissions from request headers.
1091
1130
  * Extracts comma-separated toolset names from the configured header.
1092
1131
  * Handles malformed headers gracefully by returning empty permissions.
@@ -1095,10 +1134,10 @@ g = new WeakSet(), /**
1095
1134
  * @returns Array of toolset names from headers, or empty array if header is missing/malformed
1096
1135
  * @private
1097
1136
  */
1098
- F = function(e) {
1137
+ _ = function(e) {
1099
1138
  if (!e)
1100
1139
  return [];
1101
- const s = f(this, g, _).call(this, e, this.normalizedHeaderName);
1140
+ const s = m(this, p, B).call(this, e, this.normalizedHeaderName);
1102
1141
  if (!s)
1103
1142
  return [];
1104
1143
  try {
@@ -1117,7 +1156,7 @@ F = function(e) {
1117
1156
  * @returns The header value if found, undefined otherwise
1118
1157
  * @private
1119
1158
  */
1120
- _ = function(e, s) {
1159
+ B = function(e, s) {
1121
1160
  if (e[s] !== void 0)
1122
1161
  return e[s];
1123
1162
  for (const [t, o] of Object.entries(e))
@@ -1131,14 +1170,14 @@ _ = function(e, s) {
1131
1170
  * @returns Array of toolset names from configuration
1132
1171
  * @private
1133
1172
  */
1134
- B = function(e) {
1173
+ H = function(e) {
1135
1174
  if (this.config.resolver) {
1136
- const s = f(this, g, H).call(this, e);
1175
+ const s = m(this, p, Y).call(this, e);
1137
1176
  if (s !== null)
1138
1177
  return s;
1139
1178
  }
1140
1179
  if (this.config.staticMap) {
1141
- const s = f(this, g, Y).call(this, e);
1180
+ const s = m(this, p, W).call(this, e);
1142
1181
  if (s !== null)
1143
1182
  return s;
1144
1183
  }
@@ -1150,7 +1189,7 @@ B = function(e) {
1150
1189
  * @returns Array of toolset names if successful, null if resolver fails or returns invalid data
1151
1190
  * @private
1152
1191
  */
1153
- H = function(e) {
1192
+ Y = function(e) {
1154
1193
  try {
1155
1194
  const s = this.config.resolver(e);
1156
1195
  return Array.isArray(s) ? s : (console.warn(
@@ -1169,11 +1208,11 @@ H = function(e) {
1169
1208
  * @returns Array of toolset names if found, null if client not in map
1170
1209
  * @private
1171
1210
  */
1172
- Y = function(e) {
1211
+ W = function(e) {
1173
1212
  const s = this.config.staticMap[e];
1174
1213
  return s !== void 0 ? Array.isArray(s) ? s : [] : null;
1175
1214
  };
1176
- function me(r, e) {
1215
+ function ye(r, e) {
1177
1216
  return async (s) => {
1178
1217
  const t = e.resolvePermissions(
1179
1218
  s.clientId,
@@ -1198,8 +1237,8 @@ function me(r, e) {
1198
1237
  };
1199
1238
  };
1200
1239
  }
1201
- var h, W, U, q, J, G, K, Z, Q, E, X;
1202
- class ge {
1240
+ var u, U, q, J, G, K, Z, Q, X, C, ee;
1241
+ class ve {
1203
1242
  /**
1204
1243
  * Creates a new PermissionAwareFastifyTransport instance.
1205
1244
  * @param defaultManager - Default tool manager for status endpoints
@@ -1208,12 +1247,19 @@ class ge {
1208
1247
  * @param configSchema - Optional JSON schema for configuration discovery
1209
1248
  */
1210
1249
  constructor(e, s, t = {}, o) {
1211
- w(this, h);
1212
- this.app = null, this.clientCache = new z({
1213
- onEvict: (i, n) => {
1214
- f(this, h, W).call(this, n);
1250
+ b(this, u);
1251
+ d(this, "options");
1252
+ d(this, "defaultManager");
1253
+ d(this, "createPermissionAwareBundle");
1254
+ d(this, "app", null);
1255
+ d(this, "configSchema");
1256
+ // Per-client server bundles and per-client session transports
1257
+ d(this, "clientCache", new V({
1258
+ onEvict: (e, s) => {
1259
+ m(this, u, U).call(this, s);
1215
1260
  }
1216
- }), this.defaultManager = e, this.createPermissionAwareBundle = s, this.options = {
1261
+ }));
1262
+ this.defaultManager = e, this.createPermissionAwareBundle = s, this.options = {
1217
1263
  host: t.host ?? "0.0.0.0",
1218
1264
  port: t.port ?? 3e3,
1219
1265
  basePath: t.basePath ?? "/",
@@ -1229,12 +1275,12 @@ class ge {
1229
1275
  */
1230
1276
  async start() {
1231
1277
  if (this.app) return;
1232
- const e = this.options.app ?? N({ logger: this.options.logger });
1233
- this.options.cors && await e.register(j, { origin: !0 });
1234
- const s = f(this, h, U).call(this, this.options.basePath);
1235
- f(this, h, q).call(this, e, s), f(this, h, J).call(this, e, s), f(this, h, G).call(this, e, s), f(this, h, K).call(this, e, s), f(this, h, Z).call(this, e, s), f(this, h, Q).call(this, e, s), this.options.customEndpoints && this.options.customEndpoints.length > 0 && V(e, s, this.options.customEndpoints, {
1278
+ const e = this.options.app ?? j({ logger: this.options.logger });
1279
+ 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, {
1236
1282
  contextExtractor: async (t) => {
1237
- const o = f(this, h, E).call(this, t);
1283
+ const o = m(this, u, C).call(this, t);
1238
1284
  try {
1239
1285
  const i = await this.createPermissionAwareBundle(o);
1240
1286
  return {
@@ -1260,13 +1306,13 @@ class ge {
1260
1306
  this.app && (this.clientCache.stop(!0), this.options.app || await this.app.close(), this.app = null);
1261
1307
  }
1262
1308
  }
1263
- h = new WeakSet(), /**
1309
+ u = new WeakSet(), /**
1264
1310
  * Cleans up resources associated with a client bundle.
1265
1311
  * Closes all sessions within the bundle.
1266
1312
  * @param bundle - The client bundle to clean up
1267
1313
  * @private
1268
1314
  */
1269
- W = function(e) {
1315
+ U = function(e) {
1270
1316
  for (const [s, t] of e.sessions.entries())
1271
1317
  try {
1272
1318
  typeof t.close == "function" && t.close().catch((o) => {
@@ -1282,7 +1328,7 @@ W = function(e) {
1282
1328
  * @returns Normalized base path without trailing slash
1283
1329
  * @private
1284
1330
  */
1285
- U = function(e) {
1331
+ q = function(e) {
1286
1332
  return e.endsWith("/") ? e.slice(0, -1) : e;
1287
1333
  }, /**
1288
1334
  * Registers the health check endpoint.
@@ -1290,7 +1336,7 @@ U = function(e) {
1290
1336
  * @param base - Base path for routes
1291
1337
  * @private
1292
1338
  */
1293
- q = function(e, s) {
1339
+ J = function(e, s) {
1294
1340
  e.get(`${s}/healthz`, async () => ({ ok: !0 }));
1295
1341
  }, /**
1296
1342
  * Registers the tools status endpoint.
@@ -1298,7 +1344,7 @@ q = function(e, s) {
1298
1344
  * @param base - Base path for routes
1299
1345
  * @private
1300
1346
  */
1301
- J = function(e, s) {
1347
+ G = function(e, s) {
1302
1348
  e.get(`${s}/tools`, async () => this.defaultManager.getStatus());
1303
1349
  }, /**
1304
1350
  * Registers the MCP configuration discovery endpoint.
@@ -1306,7 +1352,7 @@ J = function(e, s) {
1306
1352
  * @param base - Base path for routes
1307
1353
  * @private
1308
1354
  */
1309
- G = function(e, s) {
1355
+ K = function(e, s) {
1310
1356
  e.get(`${s}/.well-known/mcp-config`, async (t, o) => (o.header("Content-Type", "application/schema+json; charset=utf-8"), this.configSchema ?? {
1311
1357
  $schema: "https://json-schema.org/draft/2020-12/schema",
1312
1358
  title: "MCP Session Configuration",
@@ -1324,42 +1370,42 @@ G = function(e, s) {
1324
1370
  * @param base - Base path for routes
1325
1371
  * @private
1326
1372
  */
1327
- K = function(e, s) {
1373
+ Z = function(e, s) {
1328
1374
  e.post(
1329
1375
  `${s}/mcp`,
1330
1376
  async (t, o) => {
1331
- const i = f(this, h, E).call(this, t), n = !i.clientId.startsWith("anon-");
1377
+ const i = m(this, u, C).call(this, t), n = !i.clientId.startsWith("anon-");
1332
1378
  let l = n ? this.clientCache.get(i.clientId) : null;
1333
1379
  if (!l)
1334
1380
  try {
1335
- const d = await this.createPermissionAwareBundle(i);
1336
- d.failedToolsets.length > 0 && console.warn(
1337
- `Client ${i.clientId} had ${d.failedToolsets.length} toolsets fail to enable: [${d.failedToolsets.join(", ")}]. Successfully enabled: [${d.allowedToolsets.join(", ")}]`
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(", ")}]`
1338
1384
  );
1339
- const u = d.sessions;
1385
+ const f = h.sessions;
1340
1386
  l = {
1341
- server: d.server,
1342
- orchestrator: d.orchestrator,
1343
- allowedToolsets: d.allowedToolsets,
1344
- failedToolsets: d.failedToolsets,
1345
- sessions: u instanceof Map ? u : /* @__PURE__ */ new Map()
1387
+ server: h.server,
1388
+ orchestrator: h.orchestrator,
1389
+ allowedToolsets: h.allowedToolsets,
1390
+ failedToolsets: h.failedToolsets,
1391
+ sessions: f instanceof Map ? f : /* @__PURE__ */ new Map()
1346
1392
  }, n && this.clientCache.set(i.clientId, l);
1347
- } catch (d) {
1393
+ } catch (h) {
1348
1394
  return console.error(
1349
1395
  `Failed to create permission-aware bundle for client ${i.clientId}:`,
1350
- d
1351
- ), o.code(403), f(this, h, X).call(this, "Access denied");
1396
+ h
1397
+ ), o.code(403), m(this, u, ee).call(this, "Access denied");
1352
1398
  }
1353
1399
  const a = t.headers["mcp-session-id"];
1354
1400
  let c;
1355
1401
  if (a && l.sessions.get(a))
1356
1402
  c = l.sessions.get(a);
1357
- else if (!a && D(t.body)) {
1358
- const d = v();
1359
- c = new k({
1360
- sessionIdGenerator: () => d,
1361
- onsessioninitialized: (u) => {
1362
- l.sessions.set(u, c);
1403
+ else if (!a && z(t.body)) {
1404
+ const h = T();
1405
+ c = new D({
1406
+ sessionIdGenerator: () => h,
1407
+ onsessioninitialized: (f) => {
1408
+ l.sessions.set(f, c);
1363
1409
  }
1364
1410
  });
1365
1411
  try {
@@ -1393,7 +1439,7 @@ K = function(e, s) {
1393
1439
  * @param base - Base path for routes
1394
1440
  * @private
1395
1441
  */
1396
- Z = function(e, s) {
1442
+ Q = function(e, s) {
1397
1443
  e.get(`${s}/mcp`, async (t, o) => {
1398
1444
  const i = t.headers["mcp-client-id"]?.trim(), n = i && i.length > 0 ? i : "";
1399
1445
  if (!n)
@@ -1413,7 +1459,7 @@ Z = function(e, s) {
1413
1459
  * @param base - Base path for routes
1414
1460
  * @private
1415
1461
  */
1416
- Q = function(e, s) {
1462
+ X = function(e, s) {
1417
1463
  e.delete(
1418
1464
  `${s}/mcp`,
1419
1465
  async (t, o) => {
@@ -1453,8 +1499,8 @@ Q = function(e, s) {
1453
1499
  * @returns Client request context with ID and headers
1454
1500
  * @private
1455
1501
  */
1456
- E = function(e) {
1457
- const s = e.headers["mcp-client-id"]?.trim(), t = s && s.length > 0 ? s : `anon-${v()}`, o = {};
1502
+ C = function(e) {
1503
+ const s = e.headers["mcp-client-id"]?.trim(), t = s && s.length > 0 ? s : `anon-${T()}`, o = {};
1458
1504
  for (const [i, n] of Object.entries(e.headers))
1459
1505
  typeof n == "string" && (o[i] = n);
1460
1506
  return { clientId: t, headers: o };
@@ -1466,7 +1512,7 @@ E = function(e) {
1466
1512
  * @returns JSON-RPC error response object
1467
1513
  * @private
1468
1514
  */
1469
- X = function(e = "Access denied", s = -32e3) {
1515
+ ee = function(e = "Access denied", s = -32e3) {
1470
1516
  return {
1471
1517
  jsonrpc: "2.0",
1472
1518
  error: {
@@ -1476,7 +1522,7 @@ X = function(e = "Access denied", s = -32e3) {
1476
1522
  id: null
1477
1523
  };
1478
1524
  };
1479
- function pe(r) {
1525
+ function Te(r) {
1480
1526
  if (!r) return;
1481
1527
  const e = {
1482
1528
  namespaceToolsWithSetKey: r.namespaceToolsWithSetKey
@@ -1491,12 +1537,12 @@ function pe(r) {
1491
1537
  "Permission-based servers: exposurePolicy.onLimitExceeded is ignored. No toolset limits are enforced."
1492
1538
  ), e;
1493
1539
  }
1494
- async function Ce(r) {
1540
+ async function Me(r) {
1495
1541
  if (!r.permissions)
1496
1542
  throw new Error(
1497
1543
  "Permission configuration is required for createPermissionBasedMcpServer. Please provide a 'permissions' field in the options."
1498
1544
  );
1499
- if (ae(r.permissions), r.startup)
1545
+ if (de(r.permissions), r.startup)
1500
1546
  throw new Error(
1501
1547
  "Permission-based servers determine toolsets from client permissions. The 'startup' option is not allowed. Remove it from your configuration."
1502
1548
  );
@@ -1504,9 +1550,9 @@ async function Ce(r) {
1504
1550
  throw new Error(
1505
1551
  "createPermissionBasedMcpServer: `createServer` (factory) is required"
1506
1552
  );
1507
- const e = pe(
1553
+ const e = Te(
1508
1554
  r.exposurePolicy
1509
- ), s = new fe(r.permissions), t = r.createServer(), o = new b({
1555
+ ), s = new pe(r.permissions), t = r.createServer(), o = new A({
1510
1556
  server: t,
1511
1557
  catalog: r.catalog,
1512
1558
  moduleLoaders: r.moduleLoaders,
@@ -1516,9 +1562,9 @@ async function Ce(r) {
1516
1562
  // No notifications in STATIC mode
1517
1563
  startup: { mode: "STATIC", toolsets: [] },
1518
1564
  registerMetaTools: !1
1519
- }), i = me(
1565
+ }), i = ye(
1520
1566
  (l) => {
1521
- const a = r.createServer(), c = new b({
1567
+ const a = r.createServer(), c = new A({
1522
1568
  server: a,
1523
1569
  catalog: r.catalog,
1524
1570
  moduleLoaders: r.moduleLoaders,
@@ -1534,7 +1580,7 @@ async function Ce(r) {
1534
1580
  return { server: a, orchestrator: c };
1535
1581
  },
1536
1582
  s
1537
- ), n = new ge(
1583
+ ), n = new ve(
1538
1584
  o.getManager(),
1539
1585
  i,
1540
1586
  r.http,
@@ -1554,16 +1600,16 @@ async function Ce(r) {
1554
1600
  }
1555
1601
  };
1556
1602
  }
1557
- function Ie(r) {
1603
+ function Pe(r) {
1558
1604
  return r;
1559
1605
  }
1560
- function xe(r) {
1606
+ function $e(r) {
1561
1607
  return r;
1562
1608
  }
1563
1609
  export {
1564
- Ee as createMcpServer,
1565
- Ce as createPermissionBasedMcpServer,
1566
- Ie as defineEndpoint,
1567
- xe as definePermissionAwareEndpoint
1610
+ Ie as createMcpServer,
1611
+ Me as createPermissionBasedMcpServer,
1612
+ Pe as defineEndpoint,
1613
+ $e as definePermissionAwareEndpoint
1568
1614
  };
1569
1615
  //# sourceMappingURL=index.js.map