@mcp-weave/nestjs 0.1.1 → 0.3.0

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
@@ -2,9 +2,16 @@
2
2
 
3
3
  require('reflect-metadata');
4
4
  var core = require('@mcp-weave/core');
5
+ var crypto = require('crypto');
6
+ var http = require('http');
5
7
  var index_js = require('@modelcontextprotocol/sdk/server/index.js');
8
+ var sse_js = require('@modelcontextprotocol/sdk/server/sse.js');
6
9
  var stdio_js = require('@modelcontextprotocol/sdk/server/stdio.js');
7
10
 
11
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
12
+
13
+ var crypto__default = /*#__PURE__*/_interopDefault(crypto);
14
+
8
15
  // src/index.ts
9
16
  function McpServer(options) {
10
17
  return (target) => {
@@ -126,16 +133,161 @@ function getParamsMetadata(target) {
126
133
  return Reflect.getMetadata(core.METADATA_KEYS.PARAMS, target) ?? [];
127
134
  }
128
135
 
136
+ // src/auth/index.ts
137
+ function normalizeApiKeys(keys) {
138
+ if (!keys) return [];
139
+ if (typeof keys === "string") {
140
+ return [{ key: keys, name: "default" }];
141
+ }
142
+ return keys.map((k, index) => {
143
+ if (typeof k === "string") {
144
+ return { key: k, name: `key-${index + 1}` };
145
+ }
146
+ return k;
147
+ });
148
+ }
149
+ function extractApiKey(req, headerName = "x-api-key", queryParamName = "api_key") {
150
+ const headerKey = req.headers[headerName.toLowerCase()];
151
+ if (headerKey) {
152
+ return Array.isArray(headerKey) ? headerKey[0] : headerKey;
153
+ }
154
+ const authHeader = req.headers["authorization"];
155
+ if (authHeader && authHeader.startsWith("Bearer ")) {
156
+ return authHeader.slice(7);
157
+ }
158
+ const url = req.url ?? "";
159
+ const queryIndex = url.indexOf("?");
160
+ if (queryIndex !== -1) {
161
+ const searchParams = new URLSearchParams(url.slice(queryIndex + 1));
162
+ const queryKey = searchParams.get(queryParamName);
163
+ if (queryKey) return queryKey;
164
+ }
165
+ return void 0;
166
+ }
167
+ function validateApiKey(token, apiKeys) {
168
+ if (!token) {
169
+ return {
170
+ success: false,
171
+ error: "No API key provided"
172
+ };
173
+ }
174
+ const matchedKey = apiKeys.find((k) => k.key === token);
175
+ if (!matchedKey) {
176
+ return {
177
+ success: false,
178
+ error: "Invalid API key"
179
+ };
180
+ }
181
+ return {
182
+ success: true,
183
+ clientId: hashToken(token),
184
+ clientName: matchedKey.name,
185
+ scopes: matchedKey.scopes,
186
+ metadata: matchedKey.metadata
187
+ };
188
+ }
189
+ function hashToken(token) {
190
+ if (token.length <= 8) {
191
+ return "****";
192
+ }
193
+ return `${token.slice(0, 4)}...${token.slice(-4)}`;
194
+ }
195
+ function generateRequestId() {
196
+ return `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
197
+ }
198
+ function createAuthMiddleware(options = {}) {
199
+ const {
200
+ enabled = false,
201
+ apiKeys,
202
+ headerName = "x-api-key",
203
+ queryParamName = "api_key",
204
+ authenticate,
205
+ onAuthFailure,
206
+ onAuthSuccess
207
+ } = options;
208
+ const normalizedKeys = normalizeApiKeys(apiKeys);
209
+ return async (req, res) => {
210
+ const requestId = generateRequestId();
211
+ const timestamp = /* @__PURE__ */ new Date();
212
+ if (!enabled) {
213
+ return {
214
+ request: req,
215
+ auth: { success: true, clientId: "anonymous" },
216
+ requestId,
217
+ timestamp
218
+ };
219
+ }
220
+ const token = extractApiKey(req, headerName, queryParamName);
221
+ let result;
222
+ if (authenticate) {
223
+ const authResult = await authenticate(token, req);
224
+ if (typeof authResult === "boolean") {
225
+ result = {
226
+ success: authResult,
227
+ clientId: authResult ? hashToken(token ?? "unknown") : void 0,
228
+ error: authResult ? void 0 : "Authentication failed"
229
+ };
230
+ } else {
231
+ result = authResult;
232
+ }
233
+ } else {
234
+ result = validateApiKey(token, normalizedKeys);
235
+ }
236
+ if (!result.success) {
237
+ onAuthFailure?.(req, result.error ?? "Unknown error");
238
+ res.writeHead(401, { "Content-Type": "application/json" });
239
+ res.end(
240
+ JSON.stringify({
241
+ error: "Unauthorized",
242
+ message: result.error ?? "Authentication required",
243
+ requestId
244
+ })
245
+ );
246
+ return null;
247
+ }
248
+ const authRequest = {
249
+ request: req,
250
+ auth: result,
251
+ requestId,
252
+ timestamp
253
+ };
254
+ onAuthSuccess?.(req, result);
255
+ return authRequest;
256
+ };
257
+ }
258
+ function sendUnauthorized(res, message = "Unauthorized", requestId) {
259
+ res.writeHead(401, { "Content-Type": "application/json" });
260
+ res.end(
261
+ JSON.stringify({
262
+ error: "Unauthorized",
263
+ message,
264
+ requestId
265
+ })
266
+ );
267
+ }
268
+ function generateApiKey(prefix = "mcp") {
269
+ const chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
270
+ let key = "";
271
+ for (let i = 0; i < 32; i++) {
272
+ key += chars.charAt(Math.floor(Math.random() * chars.length));
273
+ }
274
+ return `${prefix}_${key}`;
275
+ }
276
+
129
277
  // src/runtime/server.ts
130
278
  var McpRuntimeServer = class {
131
279
  server;
132
280
  instance;
133
281
  metadata;
134
- constructor(target, _options = {}) {
282
+ authOptions;
283
+ authMiddleware;
284
+ constructor(target, options = {}) {
135
285
  this.metadata = core.extractMetadata(target);
136
286
  if (!this.metadata.server) {
137
287
  throw new Error(`Class ${target.name} is not decorated with @McpServer`);
138
288
  }
289
+ this.authOptions = options.auth ?? {};
290
+ this.authMiddleware = createAuthMiddleware(this.authOptions);
139
291
  this.server = new index_js.Server(
140
292
  {
141
293
  name: this.metadata.server.name,
@@ -326,23 +478,455 @@ var McpRuntimeServer = class {
326
478
  return params;
327
479
  }
328
480
  /**
329
- * Start the MCP server
481
+ * Start the MCP server with stdio transport
330
482
  */
331
483
  async start() {
332
484
  const transport = new stdio_js.StdioServerTransport();
333
485
  await this.server.connect(transport);
334
486
  console.error(`MCP server '${this.metadata.server?.name}' started on stdio`);
335
487
  }
488
+ /**
489
+ * Start the MCP server with SSE transport
490
+ */
491
+ async startSSE(options = {}) {
492
+ const port = options.port ?? 3e3;
493
+ const endpoint = options.endpoint ?? "/sse";
494
+ const httpServer = http.createServer(async (req, res) => {
495
+ res.setHeader("Access-Control-Allow-Origin", "*");
496
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
497
+ res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization, X-Api-Key");
498
+ if (req.method === "OPTIONS") {
499
+ res.writeHead(200);
500
+ res.end();
501
+ return;
502
+ }
503
+ const authResult = await this.authMiddleware(req, res);
504
+ if (!authResult) return;
505
+ const url = new URL(req.url ?? "/", `http://localhost:${port}`);
506
+ if (this.authOptions.enabled) {
507
+ console.error(
508
+ `[${authResult.requestId}] ${authResult.auth.clientName ?? authResult.auth.clientId} - ${req.method} ${url.pathname}`
509
+ );
510
+ }
511
+ if (url.pathname === endpoint && req.method === "GET") {
512
+ const transport = new sse_js.SSEServerTransport(endpoint, res);
513
+ await this.server.connect(transport);
514
+ return;
515
+ }
516
+ if (url.pathname === `${endpoint}/message` && req.method === "POST") {
517
+ let _body = "";
518
+ req.on("data", (chunk) => {
519
+ _body += chunk.toString();
520
+ });
521
+ req.on("end", () => {
522
+ res.writeHead(200, { "Content-Type": "application/json" });
523
+ res.end(JSON.stringify({ received: true }));
524
+ });
525
+ return;
526
+ }
527
+ if (url.pathname === "/health") {
528
+ res.writeHead(200, { "Content-Type": "application/json" });
529
+ res.end(
530
+ JSON.stringify({
531
+ status: "ok",
532
+ server: this.metadata.server?.name,
533
+ version: this.metadata.server?.version
534
+ })
535
+ );
536
+ return;
537
+ }
538
+ res.writeHead(404, { "Content-Type": "application/json" });
539
+ res.end(JSON.stringify({ error: "Not found" }));
540
+ });
541
+ return new Promise((resolve, reject) => {
542
+ httpServer.on("error", reject);
543
+ httpServer.listen(port, () => {
544
+ console.error(
545
+ `MCP server '${this.metadata.server?.name}' started on http://localhost:${port}${endpoint}`
546
+ );
547
+ resolve(httpServer);
548
+ });
549
+ });
550
+ }
336
551
  /**
337
552
  * Get the underlying MCP server instance
338
553
  */
339
554
  getServer() {
340
555
  return this.server;
341
556
  }
557
+ /**
558
+ * Start the MCP server with WebSocket transport
559
+ */
560
+ async startWebSocket(options = {}) {
561
+ const port = options.port ?? 8080;
562
+ const endpoint = options.endpoint ?? "/ws";
563
+ const httpServer = http.createServer(async (req, res) => {
564
+ res.setHeader("Access-Control-Allow-Origin", "*");
565
+ res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
566
+ res.setHeader(
567
+ "Access-Control-Allow-Headers",
568
+ "Content-Type, Upgrade, Connection, Authorization, X-Api-Key"
569
+ );
570
+ if (req.method === "OPTIONS") {
571
+ res.writeHead(200);
572
+ res.end();
573
+ return;
574
+ }
575
+ if (req.url === "/health") {
576
+ res.writeHead(200, { "Content-Type": "application/json" });
577
+ res.end(
578
+ JSON.stringify({
579
+ status: "ok",
580
+ server: this.metadata.server?.name,
581
+ version: this.metadata.server?.version,
582
+ transport: "websocket",
583
+ authEnabled: this.authOptions.enabled ?? false
584
+ })
585
+ );
586
+ return;
587
+ }
588
+ const authResult = await this.authMiddleware(req, res);
589
+ if (!authResult) return;
590
+ if (req.url === "/" || req.url?.startsWith("/?")) {
591
+ res.writeHead(200, { "Content-Type": "application/json" });
592
+ res.end(
593
+ JSON.stringify({
594
+ name: this.metadata.server?.name,
595
+ version: this.metadata.server?.version,
596
+ websocket: `ws://localhost:${port}${endpoint}`,
597
+ tools: this.metadata.tools.length,
598
+ resources: this.metadata.resources.length,
599
+ prompts: this.metadata.prompts.length,
600
+ client: authResult.auth.clientName,
601
+ requestId: authResult.requestId
602
+ })
603
+ );
604
+ return;
605
+ }
606
+ res.writeHead(426, { "Content-Type": "application/json" });
607
+ res.end(
608
+ JSON.stringify({
609
+ error: "Upgrade Required",
610
+ message: `Connect via WebSocket at ${endpoint}`
611
+ })
612
+ );
613
+ });
614
+ httpServer.on("upgrade", async (req, socket, _head) => {
615
+ const url = new URL(req.url ?? "/", `http://localhost:${port}`);
616
+ if (url.pathname !== endpoint) {
617
+ socket.write("HTTP/1.1 404 Not Found\r\n\r\n");
618
+ socket.destroy();
619
+ return;
620
+ }
621
+ if (this.authOptions.enabled) {
622
+ const apiKeys = normalizeApiKeys(this.authOptions.apiKeys);
623
+ const token = extractApiKey(
624
+ req,
625
+ this.authOptions.headerName,
626
+ this.authOptions.queryParamName
627
+ );
628
+ const authResult = validateApiKey(token, apiKeys);
629
+ if (!authResult.success) {
630
+ socket.write("HTTP/1.1 401 Unauthorized\r\n\r\n");
631
+ socket.destroy();
632
+ this.authOptions.onAuthFailure?.(req, authResult.error ?? "Auth failed");
633
+ return;
634
+ }
635
+ console.error(
636
+ `[WebSocket] Client connected: ${authResult.clientName ?? authResult.clientId}`
637
+ );
638
+ }
639
+ const key = req.headers["sec-websocket-key"];
640
+ if (!key) {
641
+ socket.write("HTTP/1.1 400 Bad Request\r\n\r\n");
642
+ socket.destroy();
643
+ return;
644
+ }
645
+ const acceptKey = crypto__default.default.createHash("sha1").update(key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64");
646
+ socket.write(
647
+ `HTTP/1.1 101 Switching Protocols\r
648
+ Upgrade: websocket\r
649
+ Connection: Upgrade\r
650
+ Sec-WebSocket-Accept: ${acceptKey}\r
651
+ \r
652
+ `
653
+ );
654
+ const sessions = /* @__PURE__ */ new Map();
655
+ const sessionId = crypto__default.default.randomUUID();
656
+ const encodeFrame = (data) => {
657
+ const payload = Buffer.from(data, "utf8");
658
+ const length = payload.length;
659
+ let frame;
660
+ if (length < 126) {
661
+ frame = Buffer.alloc(2 + length);
662
+ frame[0] = 129;
663
+ frame[1] = length;
664
+ payload.copy(frame, 2);
665
+ } else if (length < 65536) {
666
+ frame = Buffer.alloc(4 + length);
667
+ frame[0] = 129;
668
+ frame[1] = 126;
669
+ frame.writeUInt16BE(length, 2);
670
+ payload.copy(frame, 4);
671
+ } else {
672
+ frame = Buffer.alloc(10 + length);
673
+ frame[0] = 129;
674
+ frame[1] = 127;
675
+ frame.writeBigUInt64BE(BigInt(length), 2);
676
+ payload.copy(frame, 10);
677
+ }
678
+ return frame;
679
+ };
680
+ const decodeFrame = (buffer) => {
681
+ if (buffer.length < 2) return null;
682
+ const byte0 = buffer[0];
683
+ const byte1 = buffer[1];
684
+ const opcode = byte0 & 15;
685
+ const masked = (byte1 & 128) !== 0;
686
+ let payloadLength = byte1 & 127;
687
+ let offset = 2;
688
+ if (payloadLength === 126) {
689
+ if (buffer.length < 4) return null;
690
+ payloadLength = buffer.readUInt16BE(2);
691
+ offset = 4;
692
+ } else if (payloadLength === 127) {
693
+ if (buffer.length < 10) return null;
694
+ payloadLength = Number(buffer.readBigUInt64BE(2));
695
+ offset = 10;
696
+ }
697
+ if (masked) {
698
+ if (buffer.length < offset + 4 + payloadLength) return null;
699
+ const mask = buffer.slice(offset, offset + 4);
700
+ offset += 4;
701
+ const payload = buffer.slice(offset, offset + payloadLength);
702
+ for (let i = 0; i < payload.length; i++) {
703
+ const maskByte = mask[i % 4] ?? 0;
704
+ payload[i] = (payload[i] ?? 0) ^ maskByte;
705
+ }
706
+ return { opcode, payload: payload.toString("utf8") };
707
+ } else {
708
+ if (buffer.length < offset + payloadLength) return null;
709
+ return { opcode, payload: buffer.slice(offset, offset + payloadLength).toString("utf8") };
710
+ }
711
+ };
712
+ const send = (data) => {
713
+ try {
714
+ socket.write(encodeFrame(data));
715
+ } catch {
716
+ }
717
+ };
718
+ sessions.set(sessionId, { send });
719
+ send(
720
+ JSON.stringify({
721
+ jsonrpc: "2.0",
722
+ method: "connection/established",
723
+ params: { sessionId, server: this.metadata.server?.name }
724
+ })
725
+ );
726
+ let messageBuffer = Buffer.alloc(0);
727
+ socket.on("data", async (chunk) => {
728
+ messageBuffer = Buffer.concat([messageBuffer, chunk]);
729
+ while (messageBuffer.length > 0) {
730
+ const frame = decodeFrame(messageBuffer);
731
+ if (!frame) break;
732
+ let frameSize = 2;
733
+ const byte1 = messageBuffer[1] ?? 0;
734
+ const payloadLength = byte1 & 127;
735
+ if (payloadLength === 126) frameSize = 4;
736
+ else if (payloadLength === 127) frameSize = 10;
737
+ if ((byte1 & 128) !== 0) frameSize += 4;
738
+ frameSize += frame.payload.length;
739
+ messageBuffer = messageBuffer.slice(frameSize);
740
+ if (frame.opcode === 8) {
741
+ socket.end();
742
+ return;
743
+ }
744
+ if (frame.opcode === 9) {
745
+ socket.write(Buffer.from([138, 0]));
746
+ continue;
747
+ }
748
+ if (frame.opcode === 1) {
749
+ try {
750
+ const message = JSON.parse(frame.payload);
751
+ const response = await this.handleWebSocketMessage(message);
752
+ if (response) {
753
+ send(JSON.stringify(response));
754
+ }
755
+ } catch (error) {
756
+ send(
757
+ JSON.stringify({
758
+ jsonrpc: "2.0",
759
+ error: { code: -32700, message: "Parse error" },
760
+ id: null
761
+ })
762
+ );
763
+ }
764
+ }
765
+ }
766
+ });
767
+ socket.on("close", () => {
768
+ sessions.delete(sessionId);
769
+ });
770
+ socket.on("error", () => {
771
+ sessions.delete(sessionId);
772
+ });
773
+ });
774
+ return new Promise((resolve, reject) => {
775
+ httpServer.on("error", reject);
776
+ httpServer.listen(port, () => {
777
+ console.error(
778
+ `MCP server '${this.metadata.server?.name}' started on ws://localhost:${port}${endpoint}`
779
+ );
780
+ resolve(httpServer);
781
+ });
782
+ });
783
+ }
784
+ /**
785
+ * Handle WebSocket JSON-RPC messages
786
+ */
787
+ async handleWebSocketMessage(message) {
788
+ if (!message || typeof message !== "object") {
789
+ return { jsonrpc: "2.0", error: { code: -32600, message: "Invalid Request" }, id: null };
790
+ }
791
+ const req = message;
792
+ if (req.jsonrpc !== "2.0" || !req.method) {
793
+ return {
794
+ jsonrpc: "2.0",
795
+ error: { code: -32600, message: "Invalid Request" },
796
+ id: req.id ?? null
797
+ };
798
+ }
799
+ try {
800
+ let result;
801
+ switch (req.method) {
802
+ case "initialize":
803
+ result = {
804
+ protocolVersion: "2024-11-05",
805
+ serverInfo: {
806
+ name: this.metadata.server?.name,
807
+ version: this.metadata.server?.version ?? "1.0.0"
808
+ },
809
+ capabilities: {
810
+ tools: this.metadata.tools.length > 0 ? {} : void 0,
811
+ resources: this.metadata.resources.length > 0 ? {} : void 0,
812
+ prompts: this.metadata.prompts.length > 0 ? {} : void 0
813
+ }
814
+ };
815
+ break;
816
+ case "tools/list":
817
+ result = {
818
+ tools: this.metadata.tools.map((t) => ({
819
+ name: t.name,
820
+ description: t.description,
821
+ inputSchema: t.inputSchema ?? { type: "object", properties: {} }
822
+ }))
823
+ };
824
+ break;
825
+ case "tools/call": {
826
+ const toolParams = req.params;
827
+ const tool = this.metadata.tools.find((t) => t.name === toolParams.name);
828
+ if (!tool) {
829
+ return {
830
+ jsonrpc: "2.0",
831
+ error: { code: -32602, message: `Unknown tool: ${toolParams.name}` },
832
+ id: req.id
833
+ };
834
+ }
835
+ const method = Reflect.get(this.instance, tool.propertyKey);
836
+ const toolResult = await method.apply(this.instance, [toolParams.arguments ?? {}]);
837
+ result = {
838
+ content: [
839
+ {
840
+ type: "text",
841
+ text: typeof toolResult === "string" ? toolResult : JSON.stringify(toolResult)
842
+ }
843
+ ]
844
+ };
845
+ break;
846
+ }
847
+ case "resources/list":
848
+ result = {
849
+ resources: this.metadata.resources.map((r) => ({
850
+ uri: r.uri,
851
+ name: r.name,
852
+ description: r.description,
853
+ mimeType: r.mimeType
854
+ }))
855
+ };
856
+ break;
857
+ case "resources/read": {
858
+ const resParams = req.params;
859
+ for (const resource of this.metadata.resources) {
860
+ const uriParams = this.extractUriParams(resource.uri, resParams.uri);
861
+ if (uriParams) {
862
+ const resMethod = Reflect.get(this.instance, resource.propertyKey);
863
+ const args = this.resolveResourceArgs(resource.propertyKey, uriParams);
864
+ result = await resMethod.apply(this.instance, args);
865
+ break;
866
+ }
867
+ }
868
+ if (!result) {
869
+ return {
870
+ jsonrpc: "2.0",
871
+ error: { code: -32602, message: `Resource not found: ${resParams.uri}` },
872
+ id: req.id
873
+ };
874
+ }
875
+ break;
876
+ }
877
+ case "prompts/list":
878
+ result = {
879
+ prompts: this.metadata.prompts.map((p) => ({
880
+ name: p.name,
881
+ description: p.description,
882
+ arguments: p.arguments ?? []
883
+ }))
884
+ };
885
+ break;
886
+ case "prompts/get": {
887
+ const promptParams = req.params;
888
+ const prompt = this.metadata.prompts.find((p) => p.name === promptParams.name);
889
+ if (!prompt) {
890
+ return {
891
+ jsonrpc: "2.0",
892
+ error: { code: -32602, message: `Unknown prompt: ${promptParams.name}` },
893
+ id: req.id
894
+ };
895
+ }
896
+ const promptMethod = Reflect.get(this.instance, prompt.propertyKey);
897
+ const promptArgs = this.resolvePromptArgs(
898
+ prompt.propertyKey,
899
+ promptParams.arguments ?? {}
900
+ );
901
+ result = await promptMethod.apply(this.instance, promptArgs);
902
+ break;
903
+ }
904
+ default:
905
+ return {
906
+ jsonrpc: "2.0",
907
+ error: { code: -32601, message: `Method not found: ${req.method}` },
908
+ id: req.id
909
+ };
910
+ }
911
+ return { jsonrpc: "2.0", result, id: req.id };
912
+ } catch (error) {
913
+ return {
914
+ jsonrpc: "2.0",
915
+ error: { code: -32e3, message: error instanceof Error ? error.message : "Internal error" },
916
+ id: req.id
917
+ };
918
+ }
919
+ }
342
920
  };
343
- async function createMcpServer(target, options) {
921
+ async function createMcpServer(target, options = {}) {
344
922
  const server = new McpRuntimeServer(target, options);
345
- await server.start();
923
+ if (options.transport === "sse") {
924
+ await server.startSSE({ port: options.port, endpoint: options.endpoint });
925
+ } else if (options.transport === "websocket") {
926
+ await server.startWebSocket({ port: options.port, endpoint: options.endpoint });
927
+ } else {
928
+ await server.start();
929
+ }
346
930
  return server;
347
931
  }
348
932
 
@@ -366,13 +950,21 @@ exports.McpRuntimeServer = McpRuntimeServer;
366
950
  exports.McpServer = McpServer;
367
951
  exports.McpTool = McpTool;
368
952
  exports.VERSION = VERSION;
953
+ exports.createAuthMiddleware = createAuthMiddleware;
369
954
  exports.createMcpServer = createMcpServer;
955
+ exports.extractApiKey = extractApiKey;
956
+ exports.generateApiKey = generateApiKey;
957
+ exports.generateRequestId = generateRequestId;
370
958
  exports.getMcpServers = getMcpServers;
371
959
  exports.getParamsMetadata = getParamsMetadata;
372
960
  exports.getPromptsMetadata = getPromptsMetadata;
373
961
  exports.getResourcesMetadata = getResourcesMetadata;
374
962
  exports.getServerMetadata = getServerMetadata;
375
963
  exports.getToolsMetadata = getToolsMetadata;
964
+ exports.hashToken = hashToken;
376
965
  exports.isMcpServer = isMcpServer;
966
+ exports.normalizeApiKeys = normalizeApiKeys;
967
+ exports.sendUnauthorized = sendUnauthorized;
968
+ exports.validateApiKey = validateApiKey;
377
969
  //# sourceMappingURL=index.js.map
378
970
  //# sourceMappingURL=index.js.map