@samanhappy/mcphub 1.1.15 → 1.2.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 (150) hide show
  1. package/README.fr.md +1 -0
  2. package/README.md +6 -0
  3. package/README.zh.md +1 -0
  4. package/dist/clients/openapi.js +3 -2
  5. package/dist/clients/openapi.js.map +1 -1
  6. package/dist/controllers/configController.js +2 -0
  7. package/dist/controllers/configController.js.map +1 -1
  8. package/dist/controllers/credentialBindingController.js +1 -1
  9. package/dist/controllers/credentialBindingController.js.map +1 -1
  10. package/dist/controllers/healthController.js +23 -1
  11. package/dist/controllers/healthController.js.map +1 -1
  12. package/dist/controllers/metricsController.js +9 -1
  13. package/dist/controllers/metricsController.js.map +1 -1
  14. package/dist/controllers/oauthDynamicRegistrationController.js +5 -5
  15. package/dist/controllers/oauthDynamicRegistrationController.js.map +1 -1
  16. package/dist/controllers/serverController.js +64 -26
  17. package/dist/controllers/serverController.js.map +1 -1
  18. package/dist/db/connection.js +6 -2
  19. package/dist/db/connection.js.map +1 -1
  20. package/dist/db/entities/OAuthState.js +43 -0
  21. package/dist/db/entities/OAuthState.js.map +1 -0
  22. package/dist/db/entities/SystemConfig.js.map +1 -1
  23. package/dist/db/entities/index.js +3 -1
  24. package/dist/db/entities/index.js.map +1 -1
  25. package/dist/db/replicaSchema.js +40 -0
  26. package/dist/db/replicaSchema.js.map +1 -0
  27. package/dist/db/setup.js +25 -0
  28. package/dist/db/setup.js.map +1 -0
  29. package/dist/db/transactionContext.js +21 -0
  30. package/dist/db/transactionContext.js.map +1 -0
  31. package/dist/index.js +2 -0
  32. package/dist/index.js.map +1 -1
  33. package/dist/middlewares/replicaConfig.js +134 -0
  34. package/dist/middlewares/replicaConfig.js.map +1 -0
  35. package/dist/middlewares/userContext.js +1 -1
  36. package/dist/middlewares/userContext.js.map +1 -1
  37. package/dist/models/OAuth.js +57 -7
  38. package/dist/models/OAuth.js.map +1 -1
  39. package/dist/routes/index.js +14 -1
  40. package/dist/routes/index.js.map +1 -1
  41. package/dist/server.js +13 -4
  42. package/dist/server.js.map +1 -1
  43. package/dist/services/credentialBindingService.js +5 -1
  44. package/dist/services/credentialBindingService.js.map +1 -1
  45. package/dist/services/mcpOAuthProvider.js +91 -5
  46. package/dist/services/mcpOAuthProvider.js.map +1 -1
  47. package/dist/services/mcpService.js +113 -10
  48. package/dist/services/mcpService.js.map +1 -1
  49. package/dist/services/metricsService.js +4 -0
  50. package/dist/services/metricsService.js.map +1 -1
  51. package/dist/services/oauthClientRegistration.js +21 -1
  52. package/dist/services/oauthClientRegistration.js.map +1 -1
  53. package/dist/services/oauthServerService.js +5 -6
  54. package/dist/services/oauthServerService.js.map +1 -1
  55. package/dist/services/oauthSettingsStore.js +21 -0
  56. package/dist/services/oauthSettingsStore.js.map +1 -1
  57. package/dist/services/openApiGeneratorService.js +10 -3
  58. package/dist/services/openApiGeneratorService.js.map +1 -1
  59. package/dist/services/personalOAuthService.js +40 -2
  60. package/dist/services/personalOAuthService.js.map +1 -1
  61. package/dist/services/replicaLock.js +30 -0
  62. package/dist/services/replicaLock.js.map +1 -0
  63. package/dist/services/replicaService.js +111 -0
  64. package/dist/services/replicaService.js.map +1 -0
  65. package/dist/services/sseService.js +3 -2
  66. package/dist/services/sseService.js.map +1 -1
  67. package/dist/types/network.js +2 -0
  68. package/dist/types/network.js.map +1 -0
  69. package/dist/utils/logger.js +7 -0
  70. package/dist/utils/logger.js.map +1 -1
  71. package/dist/utils/migration.js +3 -0
  72. package/dist/utils/migration.js.map +1 -1
  73. package/dist/utils/openApiSchema.js +148 -0
  74. package/dist/utils/openApiSchema.js.map +1 -0
  75. package/dist/utils/parameterConversion.js +38 -5
  76. package/dist/utils/parameterConversion.js.map +1 -1
  77. package/dist/utils/passthroughHeaders.js +7 -3
  78. package/dist/utils/passthroughHeaders.js.map +1 -1
  79. package/dist/utils/replicaLogContext.js +3 -0
  80. package/dist/utils/replicaLogContext.js.map +1 -0
  81. package/dist/utils/replicaMode.js +17 -0
  82. package/dist/utils/replicaMode.js.map +1 -0
  83. package/dist/utils/serverConfigPersistence.js +4 -0
  84. package/dist/utils/serverConfigPersistence.js.map +1 -1
  85. package/dist/utils/settingsSync.js +1 -0
  86. package/dist/utils/settingsSync.js.map +1 -1
  87. package/dist/utils/ssrf.js +46 -12
  88. package/dist/utils/ssrf.js.map +1 -1
  89. package/frontend/dist/assets/{ActivityPage-Bi-TjKez.js → ActivityPage-DZFLY-Um.js} +2 -2
  90. package/frontend/dist/assets/{ActivityPage-Bi-TjKez.js.map → ActivityPage-DZFLY-Um.js.map} +1 -1
  91. package/frontend/dist/assets/{ConfirmDialog-BJpzQmMw.js → ConfirmDialog-ByWCtrIw.js} +2 -2
  92. package/frontend/dist/assets/{ConfirmDialog-BJpzQmMw.js.map → ConfirmDialog-ByWCtrIw.js.map} +1 -1
  93. package/frontend/dist/assets/{CredentialsPage-C4Ucer3d.js → CredentialsPage-BqEsnkMx.js} +2 -2
  94. package/frontend/dist/assets/{CredentialsPage-C4Ucer3d.js.map → CredentialsPage-BqEsnkMx.js.map} +1 -1
  95. package/frontend/dist/assets/{Dashboard-C_2KkuoD.js → Dashboard-BRU2Gk9z.js} +2 -2
  96. package/frontend/dist/assets/{Dashboard-C_2KkuoD.js.map → Dashboard-BRU2Gk9z.js.map} +1 -1
  97. package/frontend/dist/assets/{DeleteDialog-BoMYLx3J.js → DeleteDialog-BkEKW9LB.js} +2 -2
  98. package/frontend/dist/assets/{DeleteDialog-BoMYLx3J.js.map → DeleteDialog-BkEKW9LB.js.map} +1 -1
  99. package/frontend/dist/assets/{EndpointCopy-DITVC2YQ.js → EndpointCopy-3f1Uw-gu.js} +2 -2
  100. package/frontend/dist/assets/{EndpointCopy-DITVC2YQ.js.map → EndpointCopy-3f1Uw-gu.js.map} +1 -1
  101. package/frontend/dist/assets/{GroupsPage-sE6YJyuK.js → GroupsPage-D_E7QL_o.js} +2 -2
  102. package/frontend/dist/assets/{GroupsPage-sE6YJyuK.js.map → GroupsPage-D_E7QL_o.js.map} +1 -1
  103. package/frontend/dist/assets/{LoginPage-CFsd_nY-.js → LoginPage-Bsfdp4yD.js} +2 -2
  104. package/frontend/dist/assets/{LoginPage-CFsd_nY-.js.map → LoginPage-Bsfdp4yD.js.map} +1 -1
  105. package/frontend/dist/assets/{LogsPage-BxZuGDuc.js → LogsPage-CCHmA5cZ.js} +2 -2
  106. package/frontend/dist/assets/{LogsPage-BxZuGDuc.js.map → LogsPage-CCHmA5cZ.js.map} +1 -1
  107. package/frontend/dist/assets/{MarketPage-CDBs4vMb.js → MarketPage-DrQQT14y.js} +2 -2
  108. package/frontend/dist/assets/{MarketPage-CDBs4vMb.js.map → MarketPage-DrQQT14y.js.map} +1 -1
  109. package/frontend/dist/assets/{OAuthConsentPage-BN_ucViM.js → OAuthConsentPage-934ieVvL.js} +2 -2
  110. package/frontend/dist/assets/{OAuthConsentPage-BN_ucViM.js.map → OAuthConsentPage-934ieVvL.js.map} +1 -1
  111. package/frontend/dist/assets/{Pagination-S-7lzy59.js → Pagination-B2WW4qn_.js} +2 -2
  112. package/frontend/dist/assets/{Pagination-S-7lzy59.js.map → Pagination-B2WW4qn_.js.map} +1 -1
  113. package/frontend/dist/assets/{PromptsPage-Bl3ySXGK.js → PromptsPage-QAI8kF63.js} +2 -2
  114. package/frontend/dist/assets/{PromptsPage-Bl3ySXGK.js.map → PromptsPage-QAI8kF63.js.map} +1 -1
  115. package/frontend/dist/assets/{ResourcesPage-BOzQkQ92.js → ResourcesPage-TclV1l2q.js} +2 -2
  116. package/frontend/dist/assets/{ResourcesPage-BOzQkQ92.js.map → ResourcesPage-TclV1l2q.js.map} +1 -1
  117. package/frontend/dist/assets/{ServersPage-DHYwQ5AM.js → ServersPage-Bc0tS2uo.js} +4 -4
  118. package/frontend/dist/assets/ServersPage-Bc0tS2uo.js.map +1 -0
  119. package/frontend/dist/assets/SettingsPage-Dfhl51E1.js +14 -0
  120. package/frontend/dist/assets/SettingsPage-Dfhl51E1.js.map +1 -0
  121. package/frontend/dist/assets/{StatusDot-NSjojGCy.js → StatusDot-C_UTW6B7.js} +2 -2
  122. package/frontend/dist/assets/{StatusDot-NSjojGCy.js.map → StatusDot-C_UTW6B7.js.map} +1 -1
  123. package/frontend/dist/assets/{ToggleGroup-BIZWpNzm.js → ToggleGroup-CUUsTJDm.js} +2 -2
  124. package/frontend/dist/assets/{ToggleGroup-BIZWpNzm.js.map → ToggleGroup-CUUsTJDm.js.map} +1 -1
  125. package/frontend/dist/assets/{UserGroupSelection-CN0weGXJ.js → UserGroupSelection-DionUENR.js} +2 -2
  126. package/frontend/dist/assets/{UserGroupSelection-CN0weGXJ.js.map → UserGroupSelection-DionUENR.js.map} +1 -1
  127. package/frontend/dist/assets/{UsersPage-DC51v2b8.js → UsersPage-MpTb3xJ-.js} +2 -2
  128. package/frontend/dist/assets/{UsersPage-DC51v2b8.js.map → UsersPage-MpTb3xJ-.js.map} +1 -1
  129. package/frontend/dist/assets/{clipboard-ik5YV95M.js → clipboard-DVbqnePj.js} +2 -2
  130. package/frontend/dist/assets/{clipboard-ik5YV95M.js.map → clipboard-DVbqnePj.js.map} +1 -1
  131. package/frontend/dist/assets/{costRevision-Bxov9_vH.js → costRevision-DXEYAFUy.js} +2 -2
  132. package/frontend/dist/assets/{costRevision-Bxov9_vH.js.map → costRevision-DXEYAFUy.js.map} +1 -1
  133. package/frontend/dist/assets/{i18n-vendor-COTriSc6.js → i18n-vendor-CPneThYa.js} +3 -3
  134. package/frontend/dist/assets/{i18n-vendor-COTriSc6.js.map → i18n-vendor-CPneThYa.js.map} +1 -1
  135. package/frontend/dist/assets/index-BNm-68Gn.js +3 -0
  136. package/frontend/dist/assets/index-BNm-68Gn.js.map +1 -0
  137. package/frontend/dist/assets/{index-DrHctFvx.css → index-C33aH9Y7.css} +1 -1
  138. package/frontend/dist/assets/{resourceService-DMzCAZ0B.js → resourceService-DPjgql8Z.js} +2 -2
  139. package/frontend/dist/assets/{resourceService-DMzCAZ0B.js.map → resourceService-DPjgql8Z.js.map} +1 -1
  140. package/frontend/dist/assets/{useCostData-CcFSYViI.js → useCostData-CDNXYHZf.js} +2 -2
  141. package/frontend/dist/assets/{useCostData-CcFSYViI.js.map → useCostData-CDNXYHZf.js.map} +1 -1
  142. package/frontend/dist/assets/{variableDetection-CbYSa1ka.js → variableDetection-DGr_LErx.js} +14 -14
  143. package/frontend/dist/assets/{variableDetection-CbYSa1ka.js.map → variableDetection-DGr_LErx.js.map} +1 -1
  144. package/frontend/dist/index.html +3 -3
  145. package/package.json +6 -4
  146. package/frontend/dist/assets/ServersPage-DHYwQ5AM.js.map +0 -1
  147. package/frontend/dist/assets/SettingsPage-CSJ35jlM.js +0 -14
  148. package/frontend/dist/assets/SettingsPage-CSJ35jlM.js.map +0 -1
  149. package/frontend/dist/assets/index-6AyPtx0A.js +0 -3
  150. package/frontend/dist/assets/index-6AyPtx0A.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  import { validateToolPolicies } from '../utils/toolPolicy.js';
2
2
  import { hasPersonalAuthentication } from '../utils/credentialTemplate.js';
3
3
  import { matchesNamePattern } from '../utils/namePattern.js';
4
- import { validateAllowedCidrs } from '../utils/ssrf.js';
4
+ import { validateAllowedCidrs, validateFakeIpExceptions } from '../utils/ssrf.js';
5
5
  import { copyCredentialBindings, deleteCredentialBindings, } from '../services/credentialBindingService.js';
6
6
  import { StdioOptionsError } from '../utils/stdioOptions.js';
7
7
  import { CredentialBindingError } from '../utils/credentialTemplate.js';
@@ -62,6 +62,18 @@ const loadAuthorizedServer = async (req, res, serverName) => {
62
62
  }
63
63
  return server;
64
64
  };
65
+ // Tool, prompt and resource settings change what is exposed, not how upstream
66
+ // servers connect, so their handlers only broadcast. The unscoped
67
+ // notifyToolChanged() would re-initialize every enabled server that is not
68
+ // connected and re-spawn its stdio process. See #938 and #1426.
69
+ const broadcastPromptSettingsChanged = () => {
70
+ broadcastToolListChanged();
71
+ broadcastPromptListChanged();
72
+ };
73
+ const broadcastResourceSettingsChanged = () => {
74
+ broadcastToolListChanged();
75
+ broadcastResourceListChanged();
76
+ };
65
77
  const ensureNonAdminCanManageConfig = (req, res, config) => {
66
78
  const currentUser = getRequestUser(req);
67
79
  if (currentUser?.isAdmin) {
@@ -750,7 +762,12 @@ export const deleteServer = async (req, res) => {
750
762
  }
751
763
  const result = await removeServer(existingServer.name);
752
764
  if (result.success) {
753
- notifyToolChanged();
765
+ // removeServer already closed the server and dropped it from serverInfos.
766
+ // Only broadcast: a full re-init would reconnect every other server that
767
+ // is not connected (see #938).
768
+ broadcastToolListChanged();
769
+ broadcastPromptListChanged();
770
+ broadcastResourceListChanged();
754
771
  res.json({
755
772
  success: true,
756
773
  message: 'Server removed successfully',
@@ -1391,7 +1408,7 @@ export const batchToggleTools = async (req, res) => {
1391
1408
  }
1392
1409
  if (liveServer?.config)
1393
1410
  liveServer.config = { ...liveServer.config, tools };
1394
- notifyToolChanged();
1411
+ broadcastToolListChanged();
1395
1412
  }
1396
1413
  const data = { matchedTools, enabled };
1397
1414
  res.json({ success: true, data });
@@ -1440,19 +1457,15 @@ export const toggleTool = async (req, res) => {
1440
1457
  });
1441
1458
  return;
1442
1459
  }
1443
- // For an already-connected server, notifyToolChanged()'s full re-init pass
1444
- // takes the "already connected" shortcut and preserves the in-memory
1445
- // serverInfo verbatim (see registerAllTools) instead of applying the
1446
- // freshly-persisted tools config — so findToolOnServer's enabled check
1447
- // would keep seeing the pre-toggle state until the server reconnects for
1448
- // an unrelated reason. Patch the live config in place so the toggle takes
1449
- // effect immediately, without waiting for (or forcing) a reconnect.
1460
+ // findToolOnServer's enabled check reads the in-memory serverInfo.config,
1461
+ // which nothing reloads from settings while the server stays connected.
1462
+ // Patch the live config in place so the toggle takes effect immediately,
1463
+ // without waiting for (or forcing) a reconnect.
1450
1464
  const liveServer = getServerByName(serverName);
1451
1465
  if (liveServer?.config) {
1452
1466
  liveServer.config = { ...liveServer.config, tools };
1453
1467
  }
1454
- // Notify that tools have changed
1455
- notifyToolChanged();
1468
+ broadcastToolListChanged();
1456
1469
  res.json({
1457
1470
  success: true,
1458
1471
  message: `Tool ${toolName} ${enabled ? 'enabled' : 'disabled'} successfully`,
@@ -1516,7 +1529,7 @@ export const updateToolDescription = async (req, res) => {
1516
1529
  liveServerForDescription.config = { ...liveServerForDescription.config, tools };
1517
1530
  }
1518
1531
  // Notify that tools have changed
1519
- notifyToolChanged();
1532
+ broadcastToolListChanged();
1520
1533
  syncToolEmbedding(serverName, toolName);
1521
1534
  res.json({
1522
1535
  success: true,
@@ -1603,7 +1616,7 @@ export const updateToolHiddenParams = async (req, res) => {
1603
1616
  if (liveServer?.config) {
1604
1617
  liveServer.config = { ...liveServer.config, tools };
1605
1618
  }
1606
- notifyToolChanged();
1619
+ broadcastToolListChanged();
1607
1620
  syncToolEmbedding(serverName, toolName);
1608
1621
  res.json({
1609
1622
  success: true,
@@ -1644,7 +1657,7 @@ export const resetToolDescription = async (req, res) => {
1644
1657
  });
1645
1658
  return;
1646
1659
  }
1647
- notifyToolChanged();
1660
+ broadcastToolListChanged();
1648
1661
  syncToolEmbedding(serverName, toolName);
1649
1662
  const defaultDescription = getServerByName(serverName)?.tools.find((tool) => tool.name === toolName)?.description || '';
1650
1663
  res.json({
@@ -1692,11 +1705,24 @@ export const updateSystemConfig = async (req, res) => {
1692
1705
  });
1693
1706
  return;
1694
1707
  }
1708
+ if (routing?.allowAuthorizationPassthrough !== undefined &&
1709
+ typeof routing.allowAuthorizationPassthrough !== 'boolean') {
1710
+ res.status(400).json({
1711
+ success: false,
1712
+ message: 'routing.allowAuthorizationPassthrough must be a boolean',
1713
+ });
1714
+ return;
1715
+ }
1695
1716
  const hasNetworkUpdate = network !== undefined;
1696
- if (hasNetworkUpdate && (!network || !validateAllowedCidrs(network.allowedCidrs))) {
1717
+ if (hasNetworkUpdate &&
1718
+ (!network ||
1719
+ (network.allowedCidrs === undefined && network.fakeIpExceptions === undefined) ||
1720
+ (network.allowedCidrs !== undefined && !validateAllowedCidrs(network.allowedCidrs)) ||
1721
+ (network.fakeIpExceptions !== undefined &&
1722
+ !validateFakeIpExceptions(network.fakeIpExceptions)))) {
1697
1723
  res.status(400).json({
1698
1724
  success: false,
1699
- message: 'network.allowedCidrs must be an array of valid IPv4 or IPv6 CIDRs',
1725
+ message: 'Invalid network allowedCidrs or fakeIpExceptions',
1700
1726
  });
1701
1727
  return;
1702
1728
  }
@@ -1707,6 +1733,7 @@ export const updateSystemConfig = async (req, res) => {
1707
1733
  typeof routing.enableBearerAuth === 'boolean' ||
1708
1734
  typeof routing.bearerAuthKey === 'string' ||
1709
1735
  typeof routing.bearerAuthHeaderName === 'string' ||
1736
+ typeof routing.allowAuthorizationPassthrough === 'boolean' ||
1710
1737
  typeof routing.jsonBodyLimit === 'string' ||
1711
1738
  typeof routing.skipAuth === 'boolean');
1712
1739
  const hasInstallUpdate = install &&
@@ -1946,6 +1973,9 @@ export const updateSystemConfig = async (req, res) => {
1946
1973
  if (typeof routing.bearerAuthHeaderName === 'string') {
1947
1974
  systemConfig.routing.bearerAuthHeaderName = routing.bearerAuthHeaderName.trim();
1948
1975
  }
1976
+ if (typeof routing.allowAuthorizationPassthrough === 'boolean') {
1977
+ systemConfig.routing.allowAuthorizationPassthrough = routing.allowAuthorizationPassthrough;
1978
+ }
1949
1979
  if (typeof routing.jsonBodyLimit === 'string') {
1950
1980
  systemConfig.routing.jsonBodyLimit = routing.jsonBodyLimit.trim();
1951
1981
  }
@@ -2358,7 +2388,15 @@ export const updateSystemConfig = async (req, res) => {
2358
2388
  };
2359
2389
  }
2360
2390
  if (hasNetworkUpdate) {
2361
- systemConfig.network = { allowedCidrs: [...new Set(network.allowedCidrs)] };
2391
+ systemConfig.network = {
2392
+ ...systemConfig.network,
2393
+ ...(network.allowedCidrs !== undefined
2394
+ ? { allowedCidrs: [...new Set(network.allowedCidrs)] }
2395
+ : {}),
2396
+ ...(network.fakeIpExceptions !== undefined
2397
+ ? { fakeIpExceptions: network.fakeIpExceptions }
2398
+ : {}),
2399
+ };
2362
2400
  }
2363
2401
  if (toolPolicies !== undefined)
2364
2402
  systemConfig.toolPolicies = toolPolicies;
@@ -2436,8 +2474,8 @@ export const togglePrompt = async (req, res) => {
2436
2474
  });
2437
2475
  return;
2438
2476
  }
2439
- // Notify that tools have changed (as prompts are part of the tool listing)
2440
- notifyToolChanged();
2477
+ // Notify that prompts have changed
2478
+ broadcastPromptSettingsChanged();
2441
2479
  res.json({
2442
2480
  success: true,
2443
2481
  message: `Prompt ${promptName} ${enabled ? 'enabled' : 'disabled'} successfully`,
@@ -2494,8 +2532,8 @@ export const updatePromptDescription = async (req, res) => {
2494
2532
  });
2495
2533
  return;
2496
2534
  }
2497
- // Notify that tools have changed (as prompts are part of the tool listing)
2498
- notifyToolChanged();
2535
+ // Notify that prompts have changed
2536
+ broadcastPromptSettingsChanged();
2499
2537
  res.json({
2500
2538
  success: true,
2501
2539
  message: `Prompt ${promptName} description updated successfully`,
@@ -2535,7 +2573,7 @@ export const resetPromptDescription = async (req, res) => {
2535
2573
  });
2536
2574
  return;
2537
2575
  }
2538
- notifyToolChanged();
2576
+ broadcastPromptSettingsChanged();
2539
2577
  const defaultDescription = getServerByName(serverName)?.prompts.find((prompt) => prompt.name === promptName)
2540
2578
  ?.description || '';
2541
2579
  res.json({
@@ -2595,7 +2633,7 @@ export const toggleResource = async (req, res) => {
2595
2633
  return;
2596
2634
  }
2597
2635
  // Notify that tools/resources metadata has changed
2598
- notifyToolChanged();
2636
+ broadcastResourceSettingsChanged();
2599
2637
  res.json({
2600
2638
  success: true,
2601
2639
  message: `Resource ${resourceUri} ${enabled ? 'enabled' : 'disabled'} successfully`,
@@ -2653,7 +2691,7 @@ export const updateResourceDescription = async (req, res) => {
2653
2691
  return;
2654
2692
  }
2655
2693
  // Notify that tools/resources metadata has changed
2656
- notifyToolChanged();
2694
+ broadcastResourceSettingsChanged();
2657
2695
  res.json({
2658
2696
  success: true,
2659
2697
  message: `Resource ${resourceUri} description updated successfully`,
@@ -2693,7 +2731,7 @@ export const resetResourceDescription = async (req, res) => {
2693
2731
  });
2694
2732
  return;
2695
2733
  }
2696
- notifyToolChanged();
2734
+ broadcastResourceSettingsChanged();
2697
2735
  const defaultDescription = getServerByName(serverName)?.resources.find((resource) => resource.uri === resourceUri)
2698
2736
  ?.description || '';
2699
2737
  res.json({