mcp-use 1.9.1-canary.0 → 1.9.1-canary.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.
Files changed (28) hide show
  1. package/dist/.tsbuildinfo +1 -1
  2. package/dist/{chunk-KHTTBIRP.js → chunk-33U4IA4N.js} +58 -1
  3. package/dist/{chunk-5URNFWCQ.js → chunk-LWVK6RXA.js} +8 -3
  4. package/dist/{context-storage-TXQ4DVSS.js → context-storage-NA4MHWOZ.js} +3 -1
  5. package/dist/src/server/context-storage.d.ts +8 -1
  6. package/dist/src/server/context-storage.d.ts.map +1 -1
  7. package/dist/src/server/endpoints/mount-mcp.d.ts.map +1 -1
  8. package/dist/src/server/index.cjs +447 -21
  9. package/dist/src/server/index.d.ts +1 -1
  10. package/dist/src/server/index.d.ts.map +1 -1
  11. package/dist/src/server/index.js +391 -25
  12. package/dist/src/server/mcp-server.d.ts +30 -0
  13. package/dist/src/server/mcp-server.d.ts.map +1 -1
  14. package/dist/src/server/prompts/index.d.ts.map +1 -1
  15. package/dist/src/server/resources/index.d.ts +1 -0
  16. package/dist/src/server/resources/index.d.ts.map +1 -1
  17. package/dist/src/server/resources/subscriptions.d.ts +54 -0
  18. package/dist/src/server/resources/subscriptions.d.ts.map +1 -0
  19. package/dist/src/server/sessions/session-manager.d.ts +7 -1
  20. package/dist/src/server/sessions/session-manager.d.ts.map +1 -1
  21. package/dist/src/server/tools/tool-execution-helpers.d.ts +30 -17
  22. package/dist/src/server/tools/tool-execution-helpers.d.ts.map +1 -1
  23. package/dist/src/server/types/tool-context.d.ts +16 -0
  24. package/dist/src/server/types/tool-context.d.ts.map +1 -1
  25. package/dist/src/server/utils/response-helpers.d.ts +48 -4
  26. package/dist/src/server/utils/response-helpers.d.ts.map +1 -1
  27. package/dist/{tool-execution-helpers-IVUDHXMK.js → tool-execution-helpers-BQJTPWPN.js} +7 -1
  28. package/package.json +3 -3
@@ -126,14 +126,18 @@ var init_runtime = __esm({
126
126
  var context_storage_exports = {};
127
127
  __export(context_storage_exports, {
128
128
  getRequestContext: () => getRequestContext,
129
+ getSessionId: () => getSessionId,
129
130
  hasRequestContext: () => hasRequestContext,
130
131
  runWithContext: () => runWithContext
131
132
  });
132
- async function runWithContext(context, fn) {
133
- return requestContextStorage.run(context, fn);
133
+ async function runWithContext(context, fn, sessionId) {
134
+ return requestContextStorage.run({ honoContext: context, sessionId }, fn);
134
135
  }
135
136
  function getRequestContext() {
136
- return requestContextStorage.getStore();
137
+ return requestContextStorage.getStore()?.honoContext;
138
+ }
139
+ function getSessionId() {
140
+ return requestContextStorage.getStore()?.sessionId;
137
141
  }
138
142
  function hasRequestContext() {
139
143
  return requestContextStorage.getStore() !== void 0;
@@ -146,6 +150,7 @@ var init_context_storage = __esm({
146
150
  requestContextStorage = new import_node_async_hooks.AsyncLocalStorage();
147
151
  __name(runWithContext, "runWithContext");
148
152
  __name(getRequestContext, "getRequestContext");
153
+ __name(getSessionId, "getSessionId");
149
154
  __name(hasRequestContext, "hasRequestContext");
150
155
  }
151
156
  });
@@ -174,13 +179,16 @@ var init_errors = __esm({
174
179
  // src/server/tools/tool-execution-helpers.ts
175
180
  var tool_execution_helpers_exports = {};
176
181
  __export(tool_execution_helpers_exports, {
182
+ VALID_LOG_LEVELS: () => VALID_LOG_LEVELS,
177
183
  createElicitMethod: () => createElicitMethod,
178
184
  createEnhancedContext: () => createEnhancedContext,
179
185
  createReportProgressMethod: () => createReportProgressMethod,
180
186
  createSampleMethod: () => createSampleMethod,
181
187
  findSessionContext: () => findSessionContext,
188
+ isValidLogLevel: () => isValidLogLevel,
182
189
  parseElicitParams: () => parseElicitParams,
183
190
  sendProgressNotification: () => sendProgressNotification,
191
+ shouldLogMessage: () => shouldLogMessage,
184
192
  withTimeout: () => withTimeout
185
193
  });
186
194
  function findSessionContext(sessions, initialRequestContext, extraProgressToken, extraSendNotification) {
@@ -418,7 +426,37 @@ function createReportProgressMethod(progressToken, sendNotification2) {
418
426
  }
419
427
  return void 0;
420
428
  }
421
- function createEnhancedContext(baseContext, createMessage, elicitInput, progressToken, sendNotification2) {
429
+ function isValidLogLevel(level) {
430
+ return VALID_LOG_LEVELS.includes(level);
431
+ }
432
+ function shouldLogMessage(messageLevel, minLevel) {
433
+ if (!minLevel) {
434
+ return true;
435
+ }
436
+ if (!isValidLogLevel(messageLevel) || !isValidLogLevel(minLevel)) {
437
+ return true;
438
+ }
439
+ return LOG_LEVELS[messageLevel] >= LOG_LEVELS[minLevel];
440
+ }
441
+ function createLogMethod(sendNotification2, minLogLevel) {
442
+ if (!sendNotification2) {
443
+ return void 0;
444
+ }
445
+ return async (level, message, logger) => {
446
+ if (!shouldLogMessage(level, minLogLevel)) {
447
+ return;
448
+ }
449
+ await sendNotification2({
450
+ method: "notifications/message",
451
+ params: {
452
+ level,
453
+ data: message,
454
+ logger: logger || "tool"
455
+ }
456
+ });
457
+ };
458
+ }
459
+ function createEnhancedContext(baseContext, createMessage, elicitInput, progressToken, sendNotification2, minLogLevel) {
422
460
  const enhancedContext = baseContext ? Object.create(baseContext) : {};
423
461
  enhancedContext.sample = createSampleMethod(
424
462
  createMessage,
@@ -430,9 +468,10 @@ function createEnhancedContext(baseContext, createMessage, elicitInput, progress
430
468
  progressToken,
431
469
  sendNotification2
432
470
  );
471
+ enhancedContext.log = createLogMethod(sendNotification2, minLogLevel);
433
472
  return enhancedContext;
434
473
  }
435
- var import_zod_json_schema_compat;
474
+ var import_zod_json_schema_compat, LOG_LEVELS, VALID_LOG_LEVELS;
436
475
  var init_tool_execution_helpers = __esm({
437
476
  "src/server/tools/tool-execution-helpers.ts"() {
438
477
  "use strict";
@@ -446,6 +485,29 @@ var init_tool_execution_helpers = __esm({
446
485
  __name(createSampleMethod, "createSampleMethod");
447
486
  __name(createElicitMethod, "createElicitMethod");
448
487
  __name(createReportProgressMethod, "createReportProgressMethod");
488
+ LOG_LEVELS = {
489
+ debug: 0,
490
+ info: 1,
491
+ notice: 2,
492
+ warning: 3,
493
+ error: 4,
494
+ critical: 5,
495
+ alert: 6,
496
+ emergency: 7
497
+ };
498
+ VALID_LOG_LEVELS = [
499
+ "debug",
500
+ "info",
501
+ "notice",
502
+ "warning",
503
+ "error",
504
+ "critical",
505
+ "alert",
506
+ "emergency"
507
+ ];
508
+ __name(isValidLogLevel, "isValidLogLevel");
509
+ __name(shouldLogMessage, "shouldLogMessage");
510
+ __name(createLogMethod, "createLogMethod");
449
511
  __name(createEnhancedContext, "createEnhancedContext");
450
512
  }
451
513
  });
@@ -646,6 +708,7 @@ __export(server_exports, {
646
708
  adaptConnectMiddleware: () => adaptConnectMiddleware,
647
709
  adaptMiddleware: () => adaptMiddleware,
648
710
  array: () => array,
711
+ audio: () => audio,
649
712
  binary: () => binary,
650
713
  buildWidgetUrl: () => buildWidgetUrl,
651
714
  createExternalUrlResource: () => createExternalUrlResource,
@@ -684,11 +747,14 @@ module.exports = __toCommonJS(server_exports);
684
747
 
685
748
  // src/server/mcp-server.ts
686
749
  var import_mcp2 = require("@modelcontextprotocol/sdk/server/mcp.js");
750
+ var import_types2 = require("@modelcontextprotocol/sdk/types.js");
751
+ var import_zod2 = require("zod");
687
752
 
688
753
  // src/server/widgets/index.ts
689
754
  init_runtime();
690
755
 
691
756
  // src/server/utils/response-helpers.ts
757
+ init_runtime();
692
758
  function text(content) {
693
759
  return {
694
760
  content: [
@@ -719,7 +785,109 @@ function image(data, mimeType = "image/png") {
719
785
  };
720
786
  }
721
787
  __name(image, "image");
722
- function resource(uri, mimeType, text2) {
788
+ function getAudioMimeType(filename) {
789
+ const ext = filename.split(".").pop()?.toLowerCase();
790
+ switch (ext) {
791
+ case "wav":
792
+ return "audio/wav";
793
+ case "mp3":
794
+ return "audio/mpeg";
795
+ case "ogg":
796
+ return "audio/ogg";
797
+ case "m4a":
798
+ return "audio/mp4";
799
+ case "webm":
800
+ return "audio/webm";
801
+ case "flac":
802
+ return "audio/flac";
803
+ case "aac":
804
+ return "audio/aac";
805
+ default:
806
+ return "audio/wav";
807
+ }
808
+ }
809
+ __name(getAudioMimeType, "getAudioMimeType");
810
+ function arrayBufferToBase64(buffer) {
811
+ if (isDeno) {
812
+ const bytes = new Uint8Array(buffer);
813
+ let binary2 = "";
814
+ for (let i = 0; i < bytes.length; i++) {
815
+ binary2 += String.fromCharCode(bytes[i]);
816
+ }
817
+ return btoa(binary2);
818
+ } else {
819
+ return Buffer.from(buffer).toString("base64");
820
+ }
821
+ }
822
+ __name(arrayBufferToBase64, "arrayBufferToBase64");
823
+ function audio(dataOrPath, mimeType) {
824
+ const isFilePath = dataOrPath.includes("/") || dataOrPath.includes("\\") || dataOrPath.includes(".");
825
+ if (isFilePath && dataOrPath.length < 1e3) {
826
+ return (async () => {
827
+ const buffer = await fsHelpers.readFile(dataOrPath);
828
+ const base64Data = arrayBufferToBase64(buffer);
829
+ const inferredMimeType = mimeType || getAudioMimeType(dataOrPath);
830
+ return {
831
+ content: [
832
+ {
833
+ type: "audio",
834
+ data: base64Data,
835
+ mimeType: inferredMimeType
836
+ }
837
+ ],
838
+ _meta: {
839
+ mimeType: inferredMimeType,
840
+ isAudio: true
841
+ }
842
+ };
843
+ })();
844
+ }
845
+ const finalMimeType = mimeType || "audio/wav";
846
+ return {
847
+ content: [
848
+ {
849
+ type: "audio",
850
+ data: dataOrPath,
851
+ mimeType: finalMimeType
852
+ }
853
+ ],
854
+ _meta: {
855
+ mimeType: finalMimeType,
856
+ isAudio: true
857
+ }
858
+ };
859
+ }
860
+ __name(audio, "audio");
861
+ function resource(uri, mimeTypeOrContent, text2) {
862
+ if (typeof mimeTypeOrContent === "object" && mimeTypeOrContent !== null && "content" in mimeTypeOrContent) {
863
+ const contentResult = mimeTypeOrContent;
864
+ let extractedText;
865
+ let extractedMimeType;
866
+ if (contentResult._meta && typeof contentResult._meta === "object") {
867
+ const meta = contentResult._meta;
868
+ if (meta.mimeType && typeof meta.mimeType === "string") {
869
+ extractedMimeType = meta.mimeType;
870
+ }
871
+ }
872
+ if (contentResult.content && contentResult.content.length > 0) {
873
+ const firstContent = contentResult.content[0];
874
+ if (firstContent.type === "text" && "text" in firstContent) {
875
+ extractedText = firstContent.text;
876
+ }
877
+ }
878
+ const resourceContent2 = {
879
+ type: "resource",
880
+ resource: {
881
+ uri,
882
+ ...extractedMimeType && { mimeType: extractedMimeType },
883
+ ...extractedText && { text: extractedText }
884
+ }
885
+ };
886
+ return {
887
+ content: [resourceContent2]
888
+ };
889
+ }
890
+ const mimeType = mimeTypeOrContent;
723
891
  const resourceContent = {
724
892
  type: "resource",
725
893
  resource: {
@@ -998,7 +1166,7 @@ function parseTemplateUri(template, uri) {
998
1166
  const params = {};
999
1167
  let regexPattern = template.replace(/[.*+?^$()[\]\\|]/g, "\\$&");
1000
1168
  const paramNames = [];
1001
- regexPattern = regexPattern.replace(/\\\{([^}]+)\\\}/g, (_, paramName) => {
1169
+ regexPattern = regexPattern.replace(/\{([^}]+)\}/g, (_, paramName) => {
1002
1170
  paramNames.push(paramName);
1003
1171
  return "([^/]+)";
1004
1172
  });
@@ -2467,6 +2635,152 @@ init_tool_execution_helpers();
2467
2635
  // src/server/resources/index.ts
2468
2636
  var import_mcp = require("@modelcontextprotocol/sdk/server/mcp.js");
2469
2637
  init_conversion();
2638
+
2639
+ // src/server/resources/subscriptions.ts
2640
+ var import_types = require("@modelcontextprotocol/sdk/types.js");
2641
+ init_context_storage();
2642
+ var ResourceSubscriptionManager = class {
2643
+ static {
2644
+ __name(this, "ResourceSubscriptionManager");
2645
+ }
2646
+ /**
2647
+ * Tracks resource subscriptions per session
2648
+ * Map structure: uri -> Set<sessionId>
2649
+ */
2650
+ subscriptions = /* @__PURE__ */ new Map();
2651
+ /**
2652
+ * Register subscription handlers with an MCP server instance
2653
+ *
2654
+ * @param server - The native MCP server instance
2655
+ * @param sessions - Map of active sessions
2656
+ */
2657
+ registerHandlers(server, sessions) {
2658
+ server.server.setRequestHandler(
2659
+ import_types.SubscribeRequestSchema,
2660
+ async (request) => {
2661
+ const { uri } = request.params;
2662
+ const sessionId = this.getSessionIdFromContext(sessions, server);
2663
+ if (!sessionId) {
2664
+ console.warn(
2665
+ `[MCP] Could not determine session ID for resource subscription to ${uri}`
2666
+ );
2667
+ return {};
2668
+ }
2669
+ if (!this.subscriptions.has(uri)) {
2670
+ this.subscriptions.set(uri, /* @__PURE__ */ new Set());
2671
+ }
2672
+ this.subscriptions.get(uri).add(sessionId);
2673
+ console.log(
2674
+ `[MCP] Session ${sessionId} subscribed to resource: ${uri}`
2675
+ );
2676
+ return {};
2677
+ }
2678
+ );
2679
+ server.server.setRequestHandler(
2680
+ import_types.UnsubscribeRequestSchema,
2681
+ async (request) => {
2682
+ const { uri } = request.params;
2683
+ const sessionId = this.getSessionIdFromContext(sessions, server);
2684
+ if (!sessionId) {
2685
+ console.warn(
2686
+ `[MCP] Could not determine session ID for resource unsubscribe from ${uri}`
2687
+ );
2688
+ return {};
2689
+ }
2690
+ const subscribers = this.subscriptions.get(uri);
2691
+ if (subscribers) {
2692
+ subscribers.delete(sessionId);
2693
+ if (subscribers.size === 0) {
2694
+ this.subscriptions.delete(uri);
2695
+ }
2696
+ console.log(
2697
+ `[MCP] Session ${sessionId} unsubscribed from resource: ${uri}`
2698
+ );
2699
+ }
2700
+ return {};
2701
+ }
2702
+ );
2703
+ }
2704
+ /**
2705
+ * Get session ID from request context or sessions map
2706
+ *
2707
+ * @param sessions - Map of active sessions
2708
+ * @param server - The server instance to match against
2709
+ * @returns The session ID, or undefined if not found
2710
+ */
2711
+ getSessionIdFromContext(sessions, server) {
2712
+ const requestContext = getRequestContext();
2713
+ let sessionId;
2714
+ if (requestContext) {
2715
+ sessionId = requestContext.req.header("mcp-session-id");
2716
+ }
2717
+ if (!sessionId) {
2718
+ for (const [sid, session] of sessions.entries()) {
2719
+ if (session.server === server) {
2720
+ sessionId = sid;
2721
+ break;
2722
+ }
2723
+ }
2724
+ }
2725
+ return sessionId;
2726
+ }
2727
+ /**
2728
+ * Notify subscribed clients that a resource has been updated
2729
+ *
2730
+ * This method sends a `notifications/resources/updated` notification to all
2731
+ * sessions that have subscribed to the specified resource URI.
2732
+ *
2733
+ * @param uri - The URI of the resource that changed
2734
+ * @param sessions - Map of active sessions
2735
+ * @returns Promise that resolves when all notifications have been sent
2736
+ */
2737
+ async notifyResourceUpdated(uri, sessions) {
2738
+ const subscribers = this.subscriptions.get(uri);
2739
+ if (!subscribers || subscribers.size === 0) {
2740
+ return;
2741
+ }
2742
+ console.log(
2743
+ `[MCP] Notifying ${subscribers.size} subscriber(s) of resource update: ${uri}`
2744
+ );
2745
+ for (const sessionId of subscribers) {
2746
+ const session = sessions.get(sessionId);
2747
+ if (session?.server) {
2748
+ try {
2749
+ await session.server.server.sendResourceUpdated({ uri });
2750
+ console.log(
2751
+ `[MCP] Sent resource update notification to session ${sessionId}`
2752
+ );
2753
+ } catch (error2) {
2754
+ console.error(
2755
+ `[MCP] Failed to send resource update notification to session ${sessionId}:`,
2756
+ error2
2757
+ );
2758
+ }
2759
+ }
2760
+ }
2761
+ }
2762
+ /**
2763
+ * Clean up resource subscriptions for a closed session
2764
+ *
2765
+ * This method is called automatically when a session is closed to remove
2766
+ * all resource subscriptions associated with that session.
2767
+ *
2768
+ * @param sessionId - The session ID to clean up
2769
+ */
2770
+ cleanupSession(sessionId) {
2771
+ for (const [uri, subscribers] of this.subscriptions) {
2772
+ subscribers.delete(sessionId);
2773
+ if (subscribers.size === 0) {
2774
+ this.subscriptions.delete(uri);
2775
+ }
2776
+ }
2777
+ console.log(
2778
+ `[MCP] Cleaned up resource subscriptions for session ${sessionId}`
2779
+ );
2780
+ }
2781
+ };
2782
+
2783
+ // src/server/resources/index.ts
2470
2784
  function registerResource(resourceDefinition, callback) {
2471
2785
  const actualCallback = callback || resourceDefinition.readCallback;
2472
2786
  if (!actualCallback) {
@@ -2602,8 +2916,10 @@ function registerPrompt(promptDefinition, callback) {
2602
2916
  argsSchema = this.convertZodSchemaToParams(
2603
2917
  promptDefinition.schema
2604
2918
  );
2919
+ } else if (promptDefinition.args && promptDefinition.args.length > 0) {
2920
+ argsSchema = this.createParamsSchema(promptDefinition.args);
2605
2921
  } else {
2606
- argsSchema = this.createParamsSchema(promptDefinition.args || []);
2922
+ argsSchema = void 0;
2607
2923
  }
2608
2924
  const wrappedCallback = /* @__PURE__ */ __name(async (params, extra) => {
2609
2925
  const { getRequestContext: getRequestContext2, runWithContext: runWithContext2 } = await Promise.resolve().then(() => (init_context_storage(), context_storage_exports));
@@ -2886,7 +3202,7 @@ init_tool_execution_helpers();
2886
3202
  init_context_storage();
2887
3203
 
2888
3204
  // src/server/sessions/session-manager.ts
2889
- function startIdleCleanup(sessions, idleTimeoutMs) {
3205
+ function startIdleCleanup(sessions, idleTimeoutMs, mcpServerInstance) {
2890
3206
  if (idleTimeoutMs <= 0) {
2891
3207
  return void 0;
2892
3208
  }
@@ -2904,6 +3220,7 @@ function startIdleCleanup(sessions, idleTimeoutMs) {
2904
3220
  );
2905
3221
  for (const sessionId of expiredSessions) {
2906
3222
  sessions.delete(sessionId);
3223
+ mcpServerInstance?.cleanupSessionSubscriptions?.(sessionId);
2907
3224
  }
2908
3225
  }
2909
3226
  }, 6e4);
@@ -2918,7 +3235,11 @@ async function mountMcp(app, mcpServerInstance, sessions, config, isProductionMo
2918
3235
  const transports = /* @__PURE__ */ new Map();
2919
3236
  let idleCleanupInterval;
2920
3237
  if (idleTimeoutMs > 0) {
2921
- idleCleanupInterval = startIdleCleanup(sessions, idleTimeoutMs);
3238
+ idleCleanupInterval = startIdleCleanup(
3239
+ sessions,
3240
+ idleTimeoutMs,
3241
+ mcpServerInstance
3242
+ );
2922
3243
  }
2923
3244
  const handleRequest = /* @__PURE__ */ __name(async (c) => {
2924
3245
  const sessionId = c.req.header("mcp-session-id");
@@ -2950,6 +3271,7 @@ async function mountMcp(app, mcpServerInstance, sessions, config, isProductionMo
2950
3271
  console.log(`[MCP] Session closed: ${sid}`);
2951
3272
  transports.delete(sid);
2952
3273
  sessions.delete(sid);
3274
+ mcpServerInstance.cleanupSessionSubscriptions?.(sid);
2953
3275
  }, "onsessionclosed")
2954
3276
  });
2955
3277
  await server.connect(transport);
@@ -3285,6 +3607,22 @@ var McpServer = class {
3285
3607
  resources: /* @__PURE__ */ new Map(),
3286
3608
  resourceTemplates: /* @__PURE__ */ new Map()
3287
3609
  };
3610
+ /**
3611
+ * Resource subscription manager for tracking and notifying resource updates
3612
+ */
3613
+ subscriptionManager = new ResourceSubscriptionManager();
3614
+ /**
3615
+ * Clean up resource subscriptions for a closed session
3616
+ *
3617
+ * This method is called automatically when a session is closed to remove
3618
+ * all resource subscriptions associated with that session.
3619
+ *
3620
+ * @param sessionId - The session ID to clean up
3621
+ * @internal
3622
+ */
3623
+ cleanupSessionSubscriptions(sessionId) {
3624
+ this.subscriptionManager.cleanupSession(sessionId);
3625
+ }
3288
3626
  /**
3289
3627
  * Creates a new MCP server instance with Hono integration
3290
3628
  *
@@ -3299,10 +3637,21 @@ var McpServer = class {
3299
3637
  this.config = config;
3300
3638
  this.serverHost = config.host || "localhost";
3301
3639
  this.serverBaseUrl = config.baseUrl;
3302
- this.nativeServer = new import_mcp2.McpServer({
3303
- name: config.name,
3304
- version: config.version
3305
- });
3640
+ this.nativeServer = new import_mcp2.McpServer(
3641
+ {
3642
+ name: config.name,
3643
+ version: config.version
3644
+ },
3645
+ {
3646
+ capabilities: {
3647
+ logging: {},
3648
+ resources: {
3649
+ subscribe: true,
3650
+ listChanged: true
3651
+ }
3652
+ }
3653
+ }
3654
+ );
3306
3655
  this.app = createHonoApp(requestLogger);
3307
3656
  this.oauthConfig = config.oauth;
3308
3657
  this.wrapRegistrationMethods();
@@ -3357,10 +3706,17 @@ var McpServer = class {
3357
3706
  * This is called for each initialize request to create an isolated server.
3358
3707
  */
3359
3708
  getServerForSession() {
3360
- const newServer = new import_mcp2.McpServer({
3361
- name: this.config.name,
3362
- version: this.config.version
3363
- });
3709
+ const newServer = new import_mcp2.McpServer(
3710
+ {
3711
+ name: this.config.name,
3712
+ version: this.config.version
3713
+ },
3714
+ {
3715
+ capabilities: {
3716
+ logging: {}
3717
+ }
3718
+ }
3719
+ );
3364
3720
  for (const [name, recipe] of this.registrationRecipes.tools) {
3365
3721
  const { config, handler: actualCallback } = recipe;
3366
3722
  let inputSchema;
@@ -3375,7 +3731,7 @@ var McpServer = class {
3375
3731
  const initialRequestContext = getRequestContext();
3376
3732
  const extraProgressToken = extra?._meta?.progressToken;
3377
3733
  const extraSendNotification = extra?.sendNotification;
3378
- const { requestContext, progressToken, sendNotification: sendNotification2 } = findSessionContext(
3734
+ const { requestContext, session, progressToken, sendNotification: sendNotification2 } = findSessionContext(
3379
3735
  this.sessions,
3380
3736
  initialRequestContext,
3381
3737
  extraProgressToken,
@@ -3406,7 +3762,8 @@ var McpServer = class {
3406
3762
  createMessageWithLogging,
3407
3763
  newServer.server.elicitInput.bind(newServer.server),
3408
3764
  progressToken,
3409
- sendNotification2
3765
+ sendNotification2,
3766
+ session?.logLevel
3410
3767
  );
3411
3768
  const executeCallback = /* @__PURE__ */ __name(async () => {
3412
3769
  if (actualCallback.length >= 2) {
@@ -3436,8 +3793,10 @@ var McpServer = class {
3436
3793
  let argsSchema;
3437
3794
  if (config.schema) {
3438
3795
  argsSchema = this.convertZodSchemaToParams(config.schema);
3796
+ } else if (config.args && config.args.length > 0) {
3797
+ argsSchema = this.createParamsSchema(config.args);
3439
3798
  } else {
3440
- argsSchema = this.createParamsSchema(config.args || []);
3799
+ argsSchema = void 0;
3441
3800
  }
3442
3801
  const wrappedHandler = /* @__PURE__ */ __name(async (params) => {
3443
3802
  const result = await handler(params);
@@ -3518,6 +3877,50 @@ var McpServer = class {
3518
3877
  }
3519
3878
  );
3520
3879
  }
3880
+ newServer.server.setRequestHandler(
3881
+ import_zod2.z.object({ method: import_zod2.z.literal("logging/setLevel") }).passthrough(),
3882
+ async (request) => {
3883
+ const level = request.params?.level;
3884
+ if (!level) {
3885
+ throw new import_types2.McpError(
3886
+ import_types2.ErrorCode.InvalidParams,
3887
+ "Missing 'level' parameter"
3888
+ );
3889
+ }
3890
+ if (!isValidLogLevel(level)) {
3891
+ throw new import_types2.McpError(
3892
+ import_types2.ErrorCode.InvalidParams,
3893
+ `Invalid log level '${level}'. Must be one of: debug, info, notice, warning, error, critical, alert, emergency`
3894
+ );
3895
+ }
3896
+ const requestContext = getRequestContext();
3897
+ if (requestContext) {
3898
+ const sessionId = requestContext.req.header("mcp-session-id");
3899
+ if (sessionId && this.sessions.has(sessionId)) {
3900
+ const session = this.sessions.get(sessionId);
3901
+ session.logLevel = level;
3902
+ console.log(
3903
+ `[MCP] Set log level to '${level}' for session ${sessionId}`
3904
+ );
3905
+ return {};
3906
+ }
3907
+ }
3908
+ for (const [sessionId, session] of this.sessions.entries()) {
3909
+ if (session.server === newServer) {
3910
+ session.logLevel = level;
3911
+ console.log(
3912
+ `[MCP] Set log level to '${level}' for session ${sessionId}`
3913
+ );
3914
+ return {};
3915
+ }
3916
+ }
3917
+ console.warn(
3918
+ "[MCP] Could not find session for logging/setLevel request"
3919
+ );
3920
+ throw new import_types2.McpError(import_types2.ErrorCode.InternalError, "Could not find session");
3921
+ }
3922
+ );
3923
+ this.subscriptionManager.registerHandlers(newServer, this.sessions);
3521
3924
  return newServer;
3522
3925
  }
3523
3926
  /**
@@ -3547,6 +3950,24 @@ var McpServer = class {
3547
3950
  getActiveSessions = getActiveSessions;
3548
3951
  sendNotification = sendNotification;
3549
3952
  sendNotificationToSession = sendNotificationToSession2;
3953
+ /**
3954
+ * Notify subscribed clients that a resource has been updated
3955
+ *
3956
+ * This method sends a `notifications/resources/updated` notification to all
3957
+ * sessions that have subscribed to the specified resource URI.
3958
+ *
3959
+ * @param uri - The URI of the resource that changed
3960
+ * @returns Promise that resolves when all notifications have been sent
3961
+ *
3962
+ * @example
3963
+ * ```typescript
3964
+ * // After updating a resource, notify subscribers
3965
+ * await server.notifyResourceUpdated("file:///path/to/resource.txt");
3966
+ * ```
3967
+ */
3968
+ async notifyResourceUpdated(uri) {
3969
+ return this.subscriptionManager.notifyResourceUpdated(uri, this.sessions);
3970
+ }
3550
3971
  uiResource = uiResourceRegistration;
3551
3972
  /**
3552
3973
  * Mount MCP server endpoints at /mcp and /sse
@@ -3630,6 +4051,11 @@ var McpServer = class {
3630
4051
  if (hostEnv) {
3631
4052
  this.serverHost = hostEnv;
3632
4053
  }
4054
+ this.serverBaseUrl = getServerBaseUrl(
4055
+ this.serverBaseUrl,
4056
+ this.serverHost,
4057
+ this.serverPort
4058
+ );
3633
4059
  if (this.oauthConfig && !this.oauthSetupState.complete) {
3634
4060
  await setupOAuthForServer(
3635
4061
  this.app,
@@ -2,7 +2,7 @@ export { createMCPServer, type McpServerInstance } from "./mcp-server.js";
2
2
  export type { ToolContext, SampleOptions, ElicitOptions, ElicitFormParams, ElicitUrlParams, } from "./types/tool-context.js";
3
3
  export * from "./types/index.js";
4
4
  export { getRequestContext, runWithContext, hasRequestContext, } from "./context-storage.js";
5
- export { text, image, resource, error, object, array, widget, mix, html, markdown, xml, css, javascript, binary, type WidgetResponseConfig, type TypedCallToolResult, } from "./utils/response-helpers.js";
5
+ export { text, image, resource, error, object, array, widget, mix, audio, html, markdown, xml, css, javascript, binary, type WidgetResponseConfig, type TypedCallToolResult, } from "./utils/response-helpers.js";
6
6
  export { getAuth, hasScope, hasAnyScope, requireScope, requireAnyScope, oauthSupabaseProvider, oauthAuth0Provider, oauthKeycloakProvider, oauthWorkOSProvider, oauthCustomProvider, type AuthInfo, type OAuthProvider, type UserInfo, type SupabaseProviderConfig, type Auth0ProviderConfig, type KeycloakProviderConfig, type WorkOSProviderConfig, type CustomProviderConfig, } from "./oauth/index.js";
7
7
  export { buildWidgetUrl, createExternalUrlResource, createRawHtmlResource, createRemoteDomResource, createUIResourceFromDefinition, type UrlConfig, } from "./widgets/mcp-ui-adapter.js";
8
8
  export { adaptConnectMiddleware, adaptMiddleware, isExpressMiddleware, } from "./connect-adapter.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAG1E,YAAY,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAEjC,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,KAAK,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,GAAG,EAEH,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,GAAG,EACH,UAAU,EACV,MAAM,EACN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,OAAO,EACP,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,KAAK,SAAS,GACf,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,cAAc,EAEd,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAG1E,YAAY,EACV,WAAW,EACX,aAAa,EACb,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,MAAM,yBAAyB,CAAC;AAEjC,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EACL,iBAAiB,EACjB,cAAc,EACd,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAG9B,OAAO,EACL,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,KAAK,EACL,MAAM,EACN,KAAK,EACL,MAAM,EACN,GAAG,EACH,KAAK,EAEL,IAAI,EACJ,QAAQ,EACR,GAAG,EACH,GAAG,EACH,UAAU,EACV,MAAM,EACN,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,OAAO,EACP,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,kBAAkB,EAClB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,QAAQ,EACb,KAAK,sBAAsB,EAC3B,KAAK,mBAAmB,EACxB,KAAK,sBAAsB,EAC3B,KAAK,oBAAoB,EACzB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAC;AAG1B,OAAO,EACL,cAAc,EACd,yBAAyB,EACzB,qBAAqB,EACrB,uBAAuB,EACvB,8BAA8B,EAC9B,KAAK,SAAS,GACf,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,mBAAmB,GACpB,MAAM,sBAAsB,CAAC;AAE9B,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,eAAe,EACf,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,oBAAoB,EACpB,4BAA4B,EAC5B,mBAAmB,EACnB,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,cAAc,EAEd,oBAAoB,EACpB,YAAY,EACZ,cAAc,EACd,WAAW,GACZ,MAAM,kBAAkB,CAAC"}