@samanhappy/mcphub 1.0.30 → 1.0.32

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 (277) hide show
  1. package/dist/betterAuth.js +13 -5
  2. package/dist/betterAuth.js.map +1 -1
  3. package/dist/cli/commands/cache.js.map +1 -1
  4. package/dist/cli/commands/call.js +2 -2
  5. package/dist/cli/commands/call.js.map +1 -1
  6. package/dist/cli/commands/config.js.map +1 -1
  7. package/dist/cli/commands/discover.js.map +1 -1
  8. package/dist/cli/commands/export.js.map +1 -1
  9. package/dist/cli/commands/groups.js.map +1 -1
  10. package/dist/cli/commands/install.js +1 -1
  11. package/dist/cli/commands/install.js.map +1 -1
  12. package/dist/cli/commands/keys.js.map +1 -1
  13. package/dist/cli/commands/login.js.map +1 -1
  14. package/dist/cli/commands/servers.js.map +1 -1
  15. package/dist/cli/commands/tools.js +2 -2
  16. package/dist/cli/commands/tools.js.map +1 -1
  17. package/dist/cli/context.js +1 -1
  18. package/dist/cli/context.js.map +1 -1
  19. package/dist/cli/http.js +3 -1
  20. package/dist/cli/http.js.map +1 -1
  21. package/dist/clients/openapi.js +75 -7
  22. package/dist/clients/openapi.js.map +1 -1
  23. package/dist/config/DaoConfigService.js +3 -2
  24. package/dist/config/DaoConfigService.js.map +1 -1
  25. package/dist/config/configManager.js +11 -9
  26. package/dist/config/configManager.js.map +1 -1
  27. package/dist/config/index.js +32 -7
  28. package/dist/config/index.js.map +1 -1
  29. package/dist/config/jwt.js +2 -1
  30. package/dist/config/jwt.js.map +1 -1
  31. package/dist/config/migrationUtils.js +46 -45
  32. package/dist/config/migrationUtils.js.map +1 -1
  33. package/dist/constants/oauthServerDefaults.js.map +1 -1
  34. package/dist/controllers/activityController.js +6 -5
  35. package/dist/controllers/activityController.js.map +1 -1
  36. package/dist/controllers/authController.js +5 -4
  37. package/dist/controllers/authController.js.map +1 -1
  38. package/dist/controllers/bearerKeyController.js +7 -6
  39. package/dist/controllers/bearerKeyController.js.map +1 -1
  40. package/dist/controllers/betterAuthController.js +2 -1
  41. package/dist/controllers/betterAuthController.js.map +1 -1
  42. package/dist/controllers/builtinPromptController.js +13 -5
  43. package/dist/controllers/builtinPromptController.js.map +1 -1
  44. package/dist/controllers/builtinResourceController.js +14 -6
  45. package/dist/controllers/builtinResourceController.js.map +1 -1
  46. package/dist/controllers/changelogController.js +5 -2
  47. package/dist/controllers/changelogController.js.map +1 -1
  48. package/dist/controllers/cloudController.js +11 -10
  49. package/dist/controllers/cloudController.js.map +1 -1
  50. package/dist/controllers/configController.js +4 -3
  51. package/dist/controllers/configController.js.map +1 -1
  52. package/dist/controllers/contextCostController.js +3 -2
  53. package/dist/controllers/contextCostController.js.map +1 -1
  54. package/dist/controllers/groupController.js +2 -1
  55. package/dist/controllers/groupController.js.map +1 -1
  56. package/dist/controllers/healthController.js +2 -1
  57. package/dist/controllers/healthController.js.map +1 -1
  58. package/dist/controllers/hostedInternalController.js +2 -1
  59. package/dist/controllers/hostedInternalController.js.map +1 -1
  60. package/dist/controllers/logController.js +5 -4
  61. package/dist/controllers/logController.js.map +1 -1
  62. package/dist/controllers/mcpbController.js +17 -7
  63. package/dist/controllers/mcpbController.js.map +1 -1
  64. package/dist/controllers/oauthCallbackController.js +28 -27
  65. package/dist/controllers/oauthCallbackController.js.map +1 -1
  66. package/dist/controllers/oauthClientController.js +7 -6
  67. package/dist/controllers/oauthClientController.js.map +1 -1
  68. package/dist/controllers/oauthDynamicRegistrationController.js +22 -4
  69. package/dist/controllers/oauthDynamicRegistrationController.js.map +1 -1
  70. package/dist/controllers/oauthServerController.js +96 -10
  71. package/dist/controllers/oauthServerController.js.map +1 -1
  72. package/dist/controllers/openApiController.js +7 -6
  73. package/dist/controllers/openApiController.js.map +1 -1
  74. package/dist/controllers/promptController.js +2 -1
  75. package/dist/controllers/promptController.js.map +1 -1
  76. package/dist/controllers/registryController.js +4 -3
  77. package/dist/controllers/registryController.js.map +1 -1
  78. package/dist/controllers/serverController.js +46 -34
  79. package/dist/controllers/serverController.js.map +1 -1
  80. package/dist/controllers/templateController.js +2 -1
  81. package/dist/controllers/templateController.js.map +1 -1
  82. package/dist/controllers/toolController.js +2 -1
  83. package/dist/controllers/toolController.js.map +1 -1
  84. package/dist/dao/DaoFactory.js +3 -2
  85. package/dist/dao/DaoFactory.js.map +1 -1
  86. package/dist/dao/ServerDao.js.map +1 -1
  87. package/dist/dao/UserConfigDaoDbImpl.js.map +1 -1
  88. package/dist/dao/UserDao.js.map +1 -1
  89. package/dist/dao/base/JsonFileBaseDao.js +3 -2
  90. package/dist/dao/base/JsonFileBaseDao.js.map +1 -1
  91. package/dist/dao/examples.js +35 -34
  92. package/dist/dao/examples.js.map +1 -1
  93. package/dist/db/connection.js +59 -58
  94. package/dist/db/connection.js.map +1 -1
  95. package/dist/db/index.js +2 -1
  96. package/dist/db/index.js.map +1 -1
  97. package/dist/db/repositories/ServerRepository.js +3 -3
  98. package/dist/db/repositories/ServerRepository.js.map +1 -1
  99. package/dist/db/repositories/SystemConfigRepository.js +2 -1
  100. package/dist/db/repositories/SystemConfigRepository.js.map +1 -1
  101. package/dist/db/repositories/UserConfigRepository.js.map +1 -1
  102. package/dist/db/repositories/VectorEmbeddingRepository.js +6 -5
  103. package/dist/db/repositories/VectorEmbeddingRepository.js.map +1 -1
  104. package/dist/index.js +28 -19
  105. package/dist/index.js.map +1 -1
  106. package/dist/middlewares/auth.js +4 -3
  107. package/dist/middlewares/auth.js.map +1 -1
  108. package/dist/middlewares/index.js +2 -1
  109. package/dist/middlewares/index.js.map +1 -1
  110. package/dist/middlewares/userContext.js +7 -6
  111. package/dist/middlewares/userContext.js.map +1 -1
  112. package/dist/models/OAuth.js +7 -6
  113. package/dist/models/OAuth.js.map +1 -1
  114. package/dist/models/User.js +13 -12
  115. package/dist/models/User.js.map +1 -1
  116. package/dist/routes/index.js +9 -9
  117. package/dist/routes/index.js.map +1 -1
  118. package/dist/scripts/dao-demo.js +28 -27
  119. package/dist/scripts/dao-demo.js.map +1 -1
  120. package/dist/server.js +40 -30
  121. package/dist/server.js.map +1 -1
  122. package/dist/services/activityLoggingService.js +3 -2
  123. package/dist/services/activityLoggingService.js.map +1 -1
  124. package/dist/services/betterAuthConfig.js +1 -4
  125. package/dist/services/betterAuthConfig.js.map +1 -1
  126. package/dist/services/betterAuthSession.js +8 -7
  127. package/dist/services/betterAuthSession.js.map +1 -1
  128. package/dist/services/changelogService.js +5 -2
  129. package/dist/services/changelogService.js.map +1 -1
  130. package/dist/services/cloudService.js +10 -9
  131. package/dist/services/cloudService.js.map +1 -1
  132. package/dist/services/contextCostService.js +6 -2
  133. package/dist/services/contextCostService.js.map +1 -1
  134. package/dist/services/groupService.js +8 -7
  135. package/dist/services/groupService.js.map +1 -1
  136. package/dist/services/hostedAuthService.js +3 -2
  137. package/dist/services/hostedAuthService.js.map +1 -1
  138. package/dist/services/hostedControlPlaneClient.js.map +1 -1
  139. package/dist/services/hostedEventSubscriber.js +9 -8
  140. package/dist/services/hostedEventSubscriber.js.map +1 -1
  141. package/dist/services/hostedRuntimeCatalogNames.js +1 -3
  142. package/dist/services/hostedRuntimeCatalogNames.js.map +1 -1
  143. package/dist/services/keepAliveService.js +7 -6
  144. package/dist/services/keepAliveService.js.map +1 -1
  145. package/dist/services/marketService.js +2 -1
  146. package/dist/services/marketService.js.map +1 -1
  147. package/dist/services/mcpOAuthProvider.js +22 -21
  148. package/dist/services/mcpOAuthProvider.js.map +1 -1
  149. package/dist/services/mcpService.js +136 -123
  150. package/dist/services/mcpService.js.map +1 -1
  151. package/dist/services/oauthClientRegistration.js +30 -29
  152. package/dist/services/oauthClientRegistration.js.map +1 -1
  153. package/dist/services/oauthServerService.js +22 -17
  154. package/dist/services/oauthServerService.js.map +1 -1
  155. package/dist/services/oauthService.js +16 -15
  156. package/dist/services/oauthService.js.map +1 -1
  157. package/dist/services/oauthSettingsStore.js +4 -3
  158. package/dist/services/oauthSettingsStore.js.map +1 -1
  159. package/dist/services/openApiGeneratorService.js +1 -3
  160. package/dist/services/openApiGeneratorService.js.map +1 -1
  161. package/dist/services/registry.js +2 -1
  162. package/dist/services/registry.js.map +1 -1
  163. package/dist/services/requestContextService.js.map +1 -1
  164. package/dist/services/smartRoutingService.js +6 -5
  165. package/dist/services/smartRoutingService.js.map +1 -1
  166. package/dist/services/sseService.js +66 -55
  167. package/dist/services/sseService.js.map +1 -1
  168. package/dist/services/templateService.js +57 -12
  169. package/dist/services/templateService.js.map +1 -1
  170. package/dist/services/toolResultCompressionService.js +8 -5
  171. package/dist/services/toolResultCompressionService.js.map +1 -1
  172. package/dist/services/upstreamOAuthDisconnectService.js +9 -6
  173. package/dist/services/upstreamOAuthDisconnectService.js.map +1 -1
  174. package/dist/services/userService.js +5 -4
  175. package/dist/services/userService.js.map +1 -1
  176. package/dist/services/vectorSearchService.js +126 -112
  177. package/dist/services/vectorSearchService.js.map +1 -1
  178. package/dist/utils/abortIsolatingFetch.js +31 -0
  179. package/dist/utils/abortIsolatingFetch.js.map +1 -0
  180. package/dist/utils/basePath.js +13 -0
  181. package/dist/utils/basePath.js.map +1 -0
  182. package/dist/utils/cacheUtils.js +5 -4
  183. package/dist/utils/cacheUtils.js.map +1 -1
  184. package/dist/utils/corsOrigin.js +42 -0
  185. package/dist/utils/corsOrigin.js.map +1 -0
  186. package/dist/utils/dbRetry.js +2 -5
  187. package/dist/utils/dbRetry.js.map +1 -1
  188. package/dist/utils/frontendShell.js +89 -0
  189. package/dist/utils/frontendShell.js.map +1 -0
  190. package/dist/utils/i18n.js.map +1 -1
  191. package/dist/utils/logger.js +170 -0
  192. package/dist/utils/logger.js.map +1 -0
  193. package/dist/utils/migration.js +51 -50
  194. package/dist/utils/migration.js.map +1 -1
  195. package/dist/utils/oauthConsentResource.js +45 -0
  196. package/dist/utils/oauthConsentResource.js.map +1 -0
  197. package/dist/utils/parameterConversion.js +2 -1
  198. package/dist/utils/parameterConversion.js.map +1 -1
  199. package/dist/utils/path.js +9 -8
  200. package/dist/utils/path.js.map +1 -1
  201. package/dist/utils/proxyTrust.js.map +1 -1
  202. package/dist/utils/rateLimit.js +8 -0
  203. package/dist/utils/rateLimit.js.map +1 -1
  204. package/dist/utils/requireAdmin.js +15 -0
  205. package/dist/utils/requireAdmin.js.map +1 -0
  206. package/dist/utils/serverConfigPersistence.js.map +1 -1
  207. package/dist/utils/serverShutdown.js +3 -2
  208. package/dist/utils/serverShutdown.js.map +1 -1
  209. package/dist/utils/smartRouting.js +4 -3
  210. package/dist/utils/smartRouting.js.map +1 -1
  211. package/dist/utils/ssrf.js +19 -6
  212. package/dist/utils/ssrf.js.map +1 -1
  213. package/dist/utils/tokenCost.js.map +1 -1
  214. package/dist/utils/tokenTruncation.js +9 -4
  215. package/dist/utils/tokenTruncation.js.map +1 -1
  216. package/dist/utils/version.js +3 -2
  217. package/dist/utils/version.js.map +1 -1
  218. package/frontend/dist/assets/{ActivityPage-U9om5C9X.js → ActivityPage-C6m1hGLq.js} +2 -2
  219. package/frontend/dist/assets/{ActivityPage-U9om5C9X.js.map → ActivityPage-C6m1hGLq.js.map} +1 -1
  220. package/frontend/dist/assets/{ConfirmDialog-CYfXEuyU.js → ConfirmDialog-BCMNzi21.js} +2 -2
  221. package/frontend/dist/assets/{ConfirmDialog-CYfXEuyU.js.map → ConfirmDialog-BCMNzi21.js.map} +1 -1
  222. package/frontend/dist/assets/{Dashboard-DGqpU4bd.js → Dashboard-DFKfjPff.js} +2 -2
  223. package/frontend/dist/assets/{Dashboard-DGqpU4bd.js.map → Dashboard-DFKfjPff.js.map} +1 -1
  224. package/frontend/dist/assets/{DeleteDialog-DNe-zTEl.js → DeleteDialog-D9ycSRvn.js} +2 -2
  225. package/frontend/dist/assets/{DeleteDialog-DNe-zTEl.js.map → DeleteDialog-D9ycSRvn.js.map} +1 -1
  226. package/frontend/dist/assets/{EndpointCopy-DuGmhiMq.js → EndpointCopy-CP_Fb1To.js} +2 -2
  227. package/frontend/dist/assets/{EndpointCopy-DuGmhiMq.js.map → EndpointCopy-CP_Fb1To.js.map} +1 -1
  228. package/frontend/dist/assets/{GroupsPage-Dhqy02FY.js → GroupsPage-Cwfm5q-a.js} +3 -3
  229. package/frontend/dist/assets/{GroupsPage-Dhqy02FY.js.map → GroupsPage-Cwfm5q-a.js.map} +1 -1
  230. package/frontend/dist/assets/{LoginPage-BXRn47pC.js → LoginPage-CnF44h_n.js} +2 -2
  231. package/frontend/dist/assets/LoginPage-CnF44h_n.js.map +1 -0
  232. package/frontend/dist/assets/{LogsPage-CiO6LZEJ.js → LogsPage-BFIpICsM.js} +2 -2
  233. package/frontend/dist/assets/{LogsPage-CiO6LZEJ.js.map → LogsPage-BFIpICsM.js.map} +1 -1
  234. package/frontend/dist/assets/{MarketPage-BEdWfj0u.js → MarketPage-Du-NqiEl.js} +2 -2
  235. package/frontend/dist/assets/{MarketPage-BEdWfj0u.js.map → MarketPage-Du-NqiEl.js.map} +1 -1
  236. package/frontend/dist/assets/OAuthConsentPage-zqXUvKMF.js +2 -0
  237. package/frontend/dist/assets/OAuthConsentPage-zqXUvKMF.js.map +1 -0
  238. package/frontend/dist/assets/{Pagination-DLSuQ8hw.js → Pagination-Dwko3g48.js} +2 -2
  239. package/frontend/dist/assets/{Pagination-DLSuQ8hw.js.map → Pagination-Dwko3g48.js.map} +1 -1
  240. package/frontend/dist/assets/{PromptsPage-BG6oWgAk.js → PromptsPage-Cm8ykiI4.js} +2 -2
  241. package/frontend/dist/assets/{PromptsPage-BG6oWgAk.js.map → PromptsPage-Cm8ykiI4.js.map} +1 -1
  242. package/frontend/dist/assets/{ResourcesPage-BqJUKqnV.js → ResourcesPage-UMyO6mQ4.js} +2 -2
  243. package/frontend/dist/assets/{ResourcesPage-BqJUKqnV.js.map → ResourcesPage-UMyO6mQ4.js.map} +1 -1
  244. package/frontend/dist/assets/{ServersPage-CHbXHEcG.js → ServersPage-B0RoM8ez.js} +8 -8
  245. package/frontend/dist/assets/ServersPage-B0RoM8ez.js.map +1 -0
  246. package/frontend/dist/assets/{SettingsPage-B6yl-U9T.js → SettingsPage-BTB-36-n.js} +2 -2
  247. package/frontend/dist/assets/{SettingsPage-B6yl-U9T.js.map → SettingsPage-BTB-36-n.js.map} +1 -1
  248. package/frontend/dist/assets/{StatusDot-Bz7sBh0t.js → StatusDot-BAMXeT2x.js} +2 -2
  249. package/frontend/dist/assets/{StatusDot-Bz7sBh0t.js.map → StatusDot-BAMXeT2x.js.map} +1 -1
  250. package/frontend/dist/assets/{ToggleGroup-60voS_0U.js → ToggleGroup-Cfgt5lJo.js} +2 -2
  251. package/frontend/dist/assets/{ToggleGroup-60voS_0U.js.map → ToggleGroup-Cfgt5lJo.js.map} +1 -1
  252. package/frontend/dist/assets/{UsersPage-Dzzo9CC-.js → UsersPage-DlzYf7Su.js} +2 -2
  253. package/frontend/dist/assets/{UsersPage-Dzzo9CC-.js.map → UsersPage-DlzYf7Su.js.map} +1 -1
  254. package/frontend/dist/assets/{contextCost-CIOdvJNu.js → contextCost-kp2vZYp7.js} +2 -2
  255. package/frontend/dist/assets/{contextCost-CIOdvJNu.js.map → contextCost-kp2vZYp7.js.map} +1 -1
  256. package/frontend/dist/assets/{framework-vendor-I9Y6AgD5.js → framework-vendor-BHAQX05P.js} +3 -3
  257. package/frontend/dist/assets/{framework-vendor-I9Y6AgD5.js.map → framework-vendor-BHAQX05P.js.map} +1 -1
  258. package/frontend/dist/assets/{i18n-vendor-y9bLzIeh.js → i18n-vendor-CMcB7XUR.js} +2 -2
  259. package/frontend/dist/assets/{i18n-vendor-y9bLzIeh.js.map → i18n-vendor-CMcB7XUR.js.map} +1 -1
  260. package/frontend/dist/assets/{icons-vendor-hw0ScL8G.js → icons-vendor-HZHHWeTa.js} +65 -60
  261. package/frontend/dist/assets/icons-vendor-HZHHWeTa.js.map +1 -0
  262. package/frontend/dist/assets/index-CvXw771N.js +3 -0
  263. package/frontend/dist/assets/index-CvXw771N.js.map +1 -0
  264. package/frontend/dist/assets/{resourceService-DIIsi_li.js → resourceService-D2QmlFby.js} +2 -2
  265. package/frontend/dist/assets/{resourceService-DIIsi_li.js.map → resourceService-D2QmlFby.js.map} +1 -1
  266. package/frontend/dist/assets/useSettingsData-CeCvZ2nU.js +2 -0
  267. package/frontend/dist/assets/{useSettingsData-C84qj7ge.js.map → useSettingsData-CeCvZ2nU.js.map} +1 -1
  268. package/frontend/dist/assets/{variableDetection-Y9ymMI80.js → variableDetection-DKPiHkxr.js} +2 -2
  269. package/frontend/dist/assets/{variableDetection-Y9ymMI80.js.map → variableDetection-DKPiHkxr.js.map} +1 -1
  270. package/frontend/dist/index.html +4 -4
  271. package/package.json +2 -2
  272. package/frontend/dist/assets/LoginPage-BXRn47pC.js.map +0 -1
  273. package/frontend/dist/assets/ServersPage-CHbXHEcG.js.map +0 -1
  274. package/frontend/dist/assets/icons-vendor-hw0ScL8G.js.map +0 -1
  275. package/frontend/dist/assets/index-Ca9HKIrV.js +0 -3
  276. package/frontend/dist/assets/index-Ca9HKIrV.js.map +0 -1
  277. package/frontend/dist/assets/useSettingsData-C84qj7ge.js +0 -2
@@ -11,6 +11,7 @@ import { StreamableHTTPClientTransport, } from '@modelcontextprotocol/sdk/client
11
11
  import { normalizeHeaders } from '@modelcontextprotocol/sdk/shared/transport.js';
12
12
  import { createFetchWithProxy, getProxyConfigFromEnv } from './proxy.js';
13
13
  import { assertSafeUrl, createRedirectValidatingFetch } from '../utils/ssrf.js';
14
+ import { createAbortIsolatingFetch } from '../utils/abortIsolatingFetch.js';
14
15
  import { ResilientJsonSchemaValidator } from '../utils/jsonSchemaValidator.js';
15
16
  import { getUserDao } from '../dao/index.js';
16
17
  import { expandEnvVars, replaceEnvVars, getNameSeparator } from '../config/index.js';
@@ -34,6 +35,7 @@ import { MCP_APPS_CAPABILITIES, filterModelVisibleTools, hasMcpAppsCapability, i
34
35
  import { supportsCacheRefresh, injectRefreshFlag, clearRunnerCache } from '../utils/cacheUtils.js';
35
36
  const servers = {};
36
37
  import { setupClientKeepAlive } from './keepAliveService.js';
38
+ import { logger } from '../utils/logger.js';
37
39
  /**
38
40
  * Check if proxychains4 is available on the system (Linux/macOS only).
39
41
  * Returns the path to proxychains4 if found, null otherwise.
@@ -76,12 +78,12 @@ const generateProxychainsConfig = (serverName, proxyConfig) => {
76
78
  if (fs.existsSync(proxyConfig.configPath)) {
77
79
  return proxyConfig.configPath;
78
80
  }
79
- console.warn(`[${serverName}] Custom proxychains config not found: ${proxyConfig.configPath}`);
81
+ logger.warn(`[${serverName}] Custom proxychains config not found: ${proxyConfig.configPath}`);
80
82
  return null;
81
83
  }
82
84
  // Validate required fields
83
85
  if (!proxyConfig.host || !proxyConfig.port) {
84
- console.warn(`[${serverName}] Proxy host and port are required for proxychains4`);
86
+ logger.warn(`[${serverName}] Proxy host and port are required for proxychains4`);
85
87
  return null;
86
88
  }
87
89
  const proxyType = proxyConfig.type || 'socks5';
@@ -113,7 +115,7 @@ ${proxyLine}
113
115
  // Write config file
114
116
  const configPath = path.join(tempDir, `${serverName.replace(/[^a-zA-Z0-9-_]/g, '_')}.conf`);
115
117
  fs.writeFileSync(configPath, configContent, 'utf-8');
116
- console.log(`[${serverName}] Generated proxychains4 config: ${configPath}`);
118
+ logger.log(`[${serverName}] Generated proxychains4 config: ${configPath}`);
117
119
  return configPath;
118
120
  };
119
121
  /**
@@ -123,9 +125,20 @@ ${proxyLine}
123
125
  const isSafeCommand = (command) => {
124
126
  // Block shell builtins that could be used for command injection
125
127
  const blockedCommands = new Set([
126
- 'sh', 'bash', 'zsh', 'fish', 'csh', 'ksh', 'tcsh',
127
- 'cmd', 'powershell', 'pwsh',
128
- 'eval', 'exec', 'source', '.',
128
+ 'sh',
129
+ 'bash',
130
+ 'zsh',
131
+ 'fish',
132
+ 'csh',
133
+ 'ksh',
134
+ 'tcsh',
135
+ 'cmd',
136
+ 'powershell',
137
+ 'pwsh',
138
+ 'eval',
139
+ 'exec',
140
+ 'source',
141
+ '.',
129
142
  ]);
130
143
  const basename = command.split('/').pop()?.split('\\').pop()?.toLowerCase() || '';
131
144
  if (blockedCommands.has(basename)) {
@@ -142,7 +155,7 @@ const isSafeCommand = (command) => {
142
155
  * Removes shell metacharacters and dangerous patterns.
143
156
  */
144
157
  const sanitizeArgs = (args) => {
145
- return args.map(arg => {
158
+ return args.map((arg) => {
146
159
  // Remove shell metacharacters that could be used for injection
147
160
  // Allow common flags (-f, --flag, -vvv) and paths
148
161
  if (/^[a-zA-Z0-9._/\\:@=+,-]+$/.test(arg)) {
@@ -150,7 +163,7 @@ const sanitizeArgs = (args) => {
150
163
  }
151
164
  // For arguments with special characters, log a warning
152
165
  // Also block redirection operators (>, <, >>) and newlines
153
- console.warn(`[proxychains] Potentially unsafe argument blocked: ${arg}`);
166
+ logger.warn(`[proxychains] Potentially unsafe argument blocked: ${arg}`);
154
167
  return arg.replace(/[;&|`$(){}[\]!><\n\r]/g, '');
155
168
  });
156
169
  };
@@ -165,30 +178,30 @@ const wrapWithProxychains = (serverName, command, args, proxyConfig) => {
165
178
  }
166
179
  // Check platform - Windows is not supported
167
180
  if (process.platform === 'win32') {
168
- console.warn(`[${serverName}] proxychains4 proxy is not supported on Windows, ignoring proxy configuration`);
181
+ logger.warn(`[${serverName}] proxychains4 proxy is not supported on Windows, ignoring proxy configuration`);
169
182
  return { command, args };
170
183
  }
171
184
  // SECURITY: Validate command is safe
172
185
  if (!isSafeCommand(command)) {
173
- console.error(`[${serverName}] Blocked unsafe command for proxychains4 wrapping: ${command}`);
186
+ logger.error(`[${serverName}] Blocked unsafe command for proxychains4 wrapping: ${command}`);
174
187
  throw new Error(`[${serverName}] Unsafe command blocked: ${command}. Shell builtins and metacharacters are not allowed.`);
175
188
  }
176
189
  // Find proxychains4 binary
177
190
  const proxychains4Path = findProxychains4();
178
191
  if (!proxychains4Path) {
179
- console.warn(`[${serverName}] proxychains4 not found on system, install it with: apt install proxychains4 (Debian/Ubuntu) or brew install proxychains-ng (macOS)`);
192
+ logger.warn(`[${serverName}] proxychains4 not found on system, install it with: apt install proxychains4 (Debian/Ubuntu) or brew install proxychains-ng (macOS)`);
180
193
  return { command, args };
181
194
  }
182
195
  // Generate or get config file
183
196
  const configPath = generateProxychainsConfig(serverName, proxyConfig);
184
197
  if (!configPath) {
185
- console.warn(`[${serverName}] Failed to setup proxychains4 configuration, skipping proxy`);
198
+ logger.warn(`[${serverName}] Failed to setup proxychains4 configuration, skipping proxy`);
186
199
  return { command, args };
187
200
  }
188
201
  // SECURITY: Sanitize arguments
189
202
  const sanitizedArgs = sanitizeArgs(args);
190
203
  // Wrap command with proxychains4
191
- console.log(`[${serverName}] Using proxychains4 proxy: ${proxyConfig.type || 'socks5'}://${proxyConfig.host}:${proxyConfig.port}`);
204
+ logger.log(`[${serverName}] Using proxychains4 proxy: ${proxyConfig.type || 'socks5'}://${proxyConfig.host}:${proxyConfig.port}`);
192
205
  return {
193
206
  command: proxychains4Path,
194
207
  args: ['-f', configPath, command, ...sanitizedArgs],
@@ -236,7 +249,7 @@ export const getMcpServer = async (sessionId, group) => {
236
249
  servers[sessionId] = createMcpServer(descriptor.name, descriptor.version, descriptor);
237
250
  }
238
251
  else {
239
- console.log(`MCP server already exists for sessionId: ${sessionId}`);
252
+ logger.log(`MCP server already exists for sessionId: ${sessionId}`);
240
253
  }
241
254
  return servers[sessionId];
242
255
  };
@@ -254,7 +267,7 @@ const closeIsolatedClient = (serverName, client, transport) => {
254
267
  client.close();
255
268
  }
256
269
  catch (e) {
257
- console.warn(`[${serverName}] Error closing isolated client:`, e);
270
+ logger.warn(`[${serverName}] Error closing isolated client:`, e);
258
271
  }
259
272
  const candidateTransport = transport;
260
273
  const stdioPid = typeof candidateTransport.pid === 'number' ? candidateTransport.pid : null;
@@ -262,7 +275,7 @@ const closeIsolatedClient = (serverName, client, transport) => {
262
275
  transport.close();
263
276
  }
264
277
  catch (e) {
265
- console.warn(`[${serverName}] Error closing isolated transport:`, e);
278
+ logger.warn(`[${serverName}] Error closing isolated transport:`, e);
266
279
  }
267
280
  // For stdio transports, kill the whole process tree to avoid orphans
268
281
  if (stdioPid) {
@@ -286,7 +299,7 @@ const cleanupIsolatedSession = (sessionId) => {
286
299
  isolatedClientCreationLocks.delete(key);
287
300
  }
288
301
  }
289
- console.log(`Cleaned up isolated clients for session: ${sessionId}`);
302
+ logger.log(`Cleaned up isolated clients for session: ${sessionId}`);
290
303
  }
291
304
  // Drop per-session OpenAPI cookie jars so authenticated state does not
292
305
  // outlive the downstream session.
@@ -354,12 +367,12 @@ const getOrCreateIsolatedClient = async (sessionId, serverInfo) => {
354
367
  // Guard: the session was cleaned up during the async connect if its map was
355
368
  // deleted (identity no longer matches) — close the just-created connection.
356
369
  if (sessionIsolatedClients.get(sessionId) !== reservedClients) {
357
- console.warn(`Session ${sessionId} was deleted during isolated client creation for ${serverInfo.name}, closing new client`);
370
+ logger.warn(`Session ${sessionId} was deleted during isolated client creation for ${serverInfo.name}, closing new client`);
358
371
  closeIsolatedClient(serverInfo.name, client, transport);
359
372
  throw new Error(`Session ${sessionId} no longer exists`);
360
373
  }
361
374
  setSessionIsolatedClient(sessionId, serverInfo.name, client, transport);
362
- console.log(`Created isolated client for session ${sessionId} -> ${serverInfo.name}`);
375
+ logger.log(`Created isolated client for session ${sessionId} -> ${serverInfo.name}`);
363
376
  return { client, transport };
364
377
  })();
365
378
  isolatedClientCreationLocks.set(lockKey, createPromise);
@@ -381,10 +394,10 @@ const broadcastListChanged = (listType, sendNotification) => {
381
394
  Object.values(servers).forEach((server) => {
382
395
  sendNotification(server)
383
396
  .then(() => {
384
- console.log(`${listType} list changed notification sent successfully`);
397
+ logger.log(`${listType} list changed notification sent successfully`);
385
398
  })
386
399
  .catch((error) => {
387
- console.warn(`Failed to send ${listType} list changed notification:`, error.message);
400
+ logger.warn(`Failed to send ${listType} list changed notification:`, error.message);
388
401
  });
389
402
  });
390
403
  };
@@ -415,12 +428,12 @@ export const updateServerInfoVisibility = (serverName, visibility, sharedWithUse
415
428
  export const syncToolEmbedding = async (serverName, toolName) => {
416
429
  const serverInfo = getServerByName(serverName);
417
430
  if (!serverInfo) {
418
- console.warn(`Server not found: ${serverName}`);
431
+ logger.warn(`Server not found: ${serverName}`);
419
432
  return;
420
433
  }
421
434
  const tool = serverInfo.tools.find((t) => t.name === toolName);
422
435
  if (!tool) {
423
- console.warn(`Tool not found: ${toolName} on server: ${serverName}`);
436
+ logger.warn(`Tool not found: ${toolName} on server: ${serverName}`);
424
437
  return;
425
438
  }
426
439
  if (isAppOnlyTool(tool)) {
@@ -428,8 +441,8 @@ export const syncToolEmbedding = async (serverName, toolName) => {
428
441
  }
429
442
  // Save tool as vector embedding for search
430
443
  syncToolsAsVectorEmbeddings(serverName, [tool]).catch((error) => {
431
- console.warn(`[EMBED_SYNC_ERROR] Failed to sync embedding for tool "${toolName}" on server "${serverName}"`);
432
- console.error('Error syncing single tool embedding', { serverName, toolName, error });
444
+ logger.warn(`[EMBED_SYNC_ERROR] Failed to sync embedding for tool "${toolName}" on server "${serverName}"`);
445
+ logger.error('Error syncing single tool embedding', { serverName, toolName, error });
433
446
  });
434
447
  };
435
448
  // Helper function to clean $schema field from inputSchema
@@ -539,7 +552,7 @@ export const updateServerToolsCache = (serverInfo, tools, options) => {
539
552
  syncToolsAsVectorEmbeddings(serverInfo.name, serverInfo.tools, {
540
553
  reportProgress: options?.reportEmbeddingProgress === true,
541
554
  }).catch(() => {
542
- console.warn('[EMBED_SYNC_ERROR] Failed to sync tool embeddings');
555
+ logger.warn('[EMBED_SYNC_ERROR] Failed to sync tool embeddings');
543
556
  });
544
557
  };
545
558
  const updateServerPromptsCache = (serverInfo, prompts) => {
@@ -549,7 +562,7 @@ const updateServerResourcesCache = (serverInfo, resources) => {
549
562
  serverInfo.resources = resources.map(normalizeResourceForCache);
550
563
  };
551
564
  const logListChangedRefreshError = (listType) => {
552
- console.warn(`Failed to refresh ${listType} list after upstream notification`);
565
+ logger.warn(`Failed to refresh ${listType} list after upstream notification`);
553
566
  };
554
567
  const createUpstreamMcpClient = (name, getServerInfo) => {
555
568
  return new Client({
@@ -660,7 +673,7 @@ export const cleanupAllServers = () => {
660
673
  }
661
674
  }
662
675
  catch (error) {
663
- console.warn('Error closing server', { serverName: serverInfo.name, error });
676
+ logger.warn('Error closing server', { serverName: serverInfo.name, error });
664
677
  }
665
678
  }
666
679
  serverInfos = [];
@@ -919,9 +932,7 @@ export const createTransportFromConfig = async (name, conf) => {
919
932
  // Admin-owned servers may legitimately target internal services, so they
920
933
  // skip the internal-IP blocklist. allowInternal also governs per-hop
921
934
  // redirect validation in createRedirectValidatingFetch below.
922
- const ownerUser = conf.owner
923
- ? await getUserDao().findByUsername(conf.owner)
924
- : null;
935
+ const ownerUser = conf.owner ? await getUserDao().findByUsername(conf.owner) : null;
925
936
  const allowInternal = !!ownerUser?.isAdmin;
926
937
  if (conf.url) {
927
938
  await assertSafeUrl(conf.url, { allowInternal });
@@ -929,7 +940,7 @@ export const createTransportFromConfig = async (name, conf) => {
929
940
  if (conf.type === 'streamable-http') {
930
941
  const options = {};
931
942
  let headers = conf.headers ? replaceEnvVars(conf.headers, env) : {};
932
- const baseFetch = createFetchWithProxy(getProxyConfigFromEnv(env));
943
+ const baseFetch = createAbortIsolatingFetch(createFetchWithProxy(getProxyConfigFromEnv(env)));
933
944
  const requestAwareFetch = createRedirectValidatingFetch(createRequestContextAwareFetch(baseFetch, conf.passthroughHeaders), allowInternal);
934
945
  // Create OAuth provider if configured - SDK will handle authentication automatically
935
946
  const authProvider = await createOAuthProvider(name, conf);
@@ -942,7 +953,7 @@ export const createTransportFromConfig = async (name, conf) => {
942
953
  // Authorization value would override the valid access token and cause
943
954
  // 401 re-authorization loops.
944
955
  headers = stripAuthorizationHeader(headers);
945
- console.log(`OAuth provider configured for server: ${name}`);
956
+ logger.log(`OAuth provider configured for server: ${name}`);
946
957
  }
947
958
  if (Object.keys(headers).length > 0) {
948
959
  options.requestInit = {
@@ -956,7 +967,7 @@ export const createTransportFromConfig = async (name, conf) => {
956
967
  // SSE transport
957
968
  const options = {};
958
969
  let headers = conf.headers ? replaceEnvVars(conf.headers, env) : {};
959
- const baseFetch = createFetchWithProxy(getProxyConfigFromEnv(env));
970
+ const baseFetch = createAbortIsolatingFetch(createFetchWithProxy(getProxyConfigFromEnv(env)));
960
971
  const requestAwareFetch = createRedirectValidatingFetch(createRequestContextAwareFetch(baseFetch, conf.passthroughHeaders), allowInternal);
961
972
  // Create OAuth provider if configured - SDK will handle authentication automatically
962
973
  const authProvider = await createOAuthProvider(name, conf);
@@ -964,7 +975,7 @@ export const createTransportFromConfig = async (name, conf) => {
964
975
  options.authProvider = authProvider;
965
976
  // Drop static Authorization header when OAuth manages auth (see above).
966
977
  headers = stripAuthorizationHeader(headers);
967
- console.log(`OAuth provider configured for server: ${name}`);
978
+ logger.log(`OAuth provider configured for server: ${name}`);
968
979
  }
969
980
  if (Object.keys(headers).length > 0) {
970
981
  options.eventSourceInit = {
@@ -1008,7 +1019,7 @@ export const createTransportFromConfig = async (name, conf) => {
1008
1019
  if (pendingReinstalls.has(name)) {
1009
1020
  resolvedArgs = injectRefreshFlag(conf.command, resolvedArgs);
1010
1021
  pendingReinstalls.delete(name);
1011
- console.log(`[${name}] Injected cache refresh flags for reinstall`);
1022
+ logger.log(`[${name}] Injected cache refresh flags for reinstall`);
1012
1023
  }
1013
1024
  const { command: finalCommand, args: finalArgs } = wrapWithProxychains(name, conf.command, resolvedArgs, conf.proxy);
1014
1025
  // Create STDIO transport with potentially wrapped command
@@ -1021,10 +1032,10 @@ export const createTransportFromConfig = async (name, conf) => {
1021
1032
  });
1022
1033
  if (transport.stderr) {
1023
1034
  observeStdioStderr(transport, transport.stderr, (message) => {
1024
- console.log('Upstream server stderr', {
1035
+ logger.log('Upstream server stderr', JSON.stringify({
1025
1036
  serverName: name,
1026
1037
  message,
1027
- });
1038
+ }));
1028
1039
  });
1029
1040
  }
1030
1041
  }
@@ -1056,7 +1067,7 @@ const callToolWithReconnect = async (serverInfo, toolParams, options, maxRetries
1056
1067
  const isStreamableHttp = transport instanceof StreamableHTTPClientTransport;
1057
1068
  const isSSE = transport instanceof SSEClientTransport;
1058
1069
  if (attempt < maxRetries && transport && ((isStreamableHttp && isHttp40xError) || isSSE)) {
1059
- console.warn(`${isHttp40xError ? 'HTTP 40x error' : 'error'} detected for ${isStreamableHttp ? 'StreamableHTTP' : 'SSE'} server ${serverInfo.name}${isolated ? ` (isolated session ${isolated.sessionId})` : ''}, attempting reconnection (attempt ${attempt + 1}/${maxRetries + 1})`);
1070
+ logger.warn(`${isHttp40xError ? 'HTTP 40x error' : 'error'} detected for ${isStreamableHttp ? 'StreamableHTTP' : 'SSE'} server ${serverInfo.name}${isolated ? ` (isolated session ${isolated.sessionId})` : ''}, attempting reconnection (attempt ${attempt + 1}/${maxRetries + 1})`);
1060
1071
  try {
1061
1072
  const server = await getServerDao().findById(serverInfo.name);
1062
1073
  if (!server) {
@@ -1073,11 +1084,15 @@ const callToolWithReconnect = async (serverInfo, toolParams, options, maxRetries
1073
1084
  try {
1074
1085
  client.close();
1075
1086
  }
1076
- catch { /* empty */ }
1087
+ catch {
1088
+ /* empty */
1089
+ }
1077
1090
  try {
1078
1091
  transport.close();
1079
1092
  }
1080
- catch { /* empty */ }
1093
+ catch {
1094
+ /* empty */
1095
+ }
1081
1096
  setSessionIsolatedClient(isolated.sessionId, serverInfo.name, newClient, newTransport);
1082
1097
  }
1083
1098
  else {
@@ -1089,11 +1104,15 @@ const callToolWithReconnect = async (serverInfo, toolParams, options, maxRetries
1089
1104
  try {
1090
1105
  serverInfo.client?.close();
1091
1106
  }
1092
- catch { /* empty */ }
1107
+ catch {
1108
+ /* empty */
1109
+ }
1093
1110
  try {
1094
1111
  transport.close();
1095
1112
  }
1096
- catch { /* empty */ }
1113
+ catch {
1114
+ /* empty */
1115
+ }
1097
1116
  serverInfo.client = newClient;
1098
1117
  serverInfo.transport = newTransport;
1099
1118
  serverInfo.status = 'connected';
@@ -1107,18 +1126,18 @@ const callToolWithReconnect = async (serverInfo, toolParams, options, maxRetries
1107
1126
  updateServerToolsCache(serverInfo, tools.tools);
1108
1127
  }
1109
1128
  catch (listToolsError) {
1110
- console.warn('Failed to reload tools after reconnection', {
1129
+ logger.warn('Failed to reload tools after reconnection', {
1111
1130
  serverName: serverInfo.name,
1112
1131
  error: summarizeErrorForLogging(listToolsError),
1113
1132
  });
1114
1133
  // Continue anyway, as the connection might still work for the current tool
1115
1134
  }
1116
- console.log(`Successfully reconnected to server: ${serverInfo.name}`);
1135
+ logger.log(`Successfully reconnected to server: ${serverInfo.name}`);
1117
1136
  // Continue to next attempt
1118
1137
  continue;
1119
1138
  }
1120
1139
  catch (reconnectError) {
1121
- console.error('Failed to reconnect to server', {
1140
+ logger.error('Failed to reconnect to server', {
1122
1141
  serverName: serverInfo.name,
1123
1142
  error: summarizeErrorForLogging(reconnectError),
1124
1143
  });
@@ -1152,7 +1171,7 @@ const setupServerKeepAlive = (serverInfo, serverConfig) => {
1152
1171
  throw error;
1153
1172
  }
1154
1173
  },
1155
- }).catch((error) => console.warn('Keepalive setup failed', {
1174
+ }).catch((error) => logger.warn('Keepalive setup failed', {
1156
1175
  serverName: serverInfo.name,
1157
1176
  error: summarizeErrorForLogging(error),
1158
1177
  }));
@@ -1169,7 +1188,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1169
1188
  const expandedConf = replaceEnvVars(conf);
1170
1189
  // Skip disabled servers
1171
1190
  if (expandedConf.enabled === false) {
1172
- console.log(`Skipping disabled server: ${name}`);
1191
+ logger.log(`Skipping disabled server: ${name}`);
1173
1192
  nextServerInfos.push({
1174
1193
  name,
1175
1194
  owner: expandedConf.owner,
@@ -1209,7 +1228,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1209
1228
  enabled: true,
1210
1229
  config: expandedConf,
1211
1230
  });
1212
- console.log(`Skipping startup connect for on-demand server: ${name}`);
1231
+ logger.log(`Skipping startup connect for on-demand server: ${name}`);
1213
1232
  continue;
1214
1233
  }
1215
1234
  // Reuse this server's existing runtime state instead of reconnecting when:
@@ -1225,8 +1244,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1225
1244
  const existingServer = existingServerInfos.find((s) => s.name === name);
1226
1245
  const isDifferentServer = Boolean(serverName) && serverName !== name;
1227
1246
  const hasInflightOAuthAuthorization = existingServer?.status === 'oauth_required' &&
1228
- Boolean(expandedConf.oauth?.pendingAuthorization?.state ||
1229
- existingServer.oauth?.state);
1247
+ Boolean(expandedConf.oauth?.pendingAuthorization?.state || existingServer.oauth?.state);
1230
1248
  if (existingServer &&
1231
1249
  (isDifferentServer ||
1232
1250
  (!serverName && (existingServer.status === 'connected' || hasInflightOAuthAuthorization)))) {
@@ -1237,7 +1255,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1237
1255
  sharedWithUsers: expandedConf.sharedWithUsers,
1238
1256
  enabled: expandedConf.enabled === undefined ? true : expandedConf.enabled,
1239
1257
  });
1240
- console.log(hasInflightOAuthAuthorization
1258
+ logger.log(hasInflightOAuthAuthorization
1241
1259
  ? `Server '${name}' has an in-flight OAuth authorization; preserving existing state.`
1242
1260
  : `Server '${name}' is already connected.`);
1243
1261
  continue;
@@ -1247,7 +1265,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1247
1265
  if (expandedConf.type === 'openapi') {
1248
1266
  // Handle OpenAPI type servers
1249
1267
  if (!expandedConf.openapi?.url && !expandedConf.openapi?.schema) {
1250
- console.warn(`Skipping OpenAPI server '${name}': missing OpenAPI specification URL or schema`);
1268
+ logger.warn(`Skipping OpenAPI server '${name}': missing OpenAPI specification URL or schema`);
1251
1269
  nextServerInfos.push({
1252
1270
  name,
1253
1271
  owner: expandedConf.owner,
@@ -1300,7 +1318,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1300
1318
  });
1301
1319
  },
1302
1320
  });
1303
- console.log(`Initializing OpenAPI server: ${name}...`);
1321
+ logger.log(`Initializing OpenAPI server: ${name}...`);
1304
1322
  // Perform async initialization
1305
1323
  await openApiClient.initialize();
1306
1324
  // Convert OpenAPI tools to MCP tool format
@@ -1314,7 +1332,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1314
1332
  serverInfo.status = 'connected';
1315
1333
  serverInfo.tools = mcpTools;
1316
1334
  serverInfo.openApiClient = openApiClient;
1317
- console.log(`Successfully initialized OpenAPI server: ${name} with ${mcpTools.length} tools`);
1335
+ logger.log(`Successfully initialized OpenAPI server: ${name} with ${mcpTools.length} tools`);
1318
1336
  // Broadcast now that tools are loaded. OpenAPI servers expose tools
1319
1337
  // only (no prompts/resources). See the standard-path note above.
1320
1338
  broadcastToolListChanged();
@@ -1322,8 +1340,8 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1322
1340
  syncToolsAsVectorEmbeddings(name, mcpTools, {
1323
1341
  reportProgress: options?.reportEmbeddingProgress === true && serverName === name,
1324
1342
  }).catch((error) => {
1325
- console.warn(`[EMBED_SYNC_ERROR] Failed to sync OpenAPI embeddings for server "${name}"`);
1326
- console.error('Error syncing OpenAPI tool embeddings', {
1343
+ logger.warn(`[EMBED_SYNC_ERROR] Failed to sync OpenAPI embeddings for server "${name}"`);
1344
+ logger.error('Error syncing OpenAPI tool embeddings', {
1327
1345
  serverName: name,
1328
1346
  error: summarizeErrorForLogging(error),
1329
1347
  });
@@ -1331,7 +1349,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1331
1349
  continue;
1332
1350
  }
1333
1351
  catch (error) {
1334
- console.error('Failed to initialize OpenAPI server', {
1352
+ logger.error('Failed to initialize OpenAPI server', {
1335
1353
  serverName: name,
1336
1354
  error: summarizeErrorForLogging(error),
1337
1355
  });
@@ -1390,18 +1408,18 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1390
1408
  nextServerInfos.push(serverInfo);
1391
1409
  connectClientWithDiagnostics(client, transport, initRequestOptions || requestOptions)
1392
1410
  .then(() => {
1393
- console.log(`Successfully connected client for server: ${name}`);
1411
+ logger.log(`Successfully connected client for server: ${name}`);
1394
1412
  const serverVersion = client.getServerVersion?.();
1395
1413
  serverInfo.version = serverVersion?.version;
1396
1414
  serverInfo.instructions = client.getInstructions?.();
1397
1415
  const capabilities = client.getServerCapabilities();
1398
- console.log('Server capabilities', JSON.stringify(capabilities));
1416
+ logger.log('Server capabilities', JSON.stringify(capabilities));
1399
1417
  let dataError = null;
1400
1418
  if (capabilities?.tools) {
1401
1419
  client
1402
1420
  .listTools({}, initRequestOptions || requestOptions)
1403
1421
  .then((tools) => {
1404
- console.log(`Successfully listed ${tools.tools.length} tools for server: ${name}`);
1422
+ logger.log(`Successfully listed ${tools.tools.length} tools for server: ${name}`);
1405
1423
  updateServerToolsCache(serverInfo, tools.tools, {
1406
1424
  reportEmbeddingProgress: options?.reportEmbeddingProgress === true && serverName === name,
1407
1425
  });
@@ -1412,7 +1430,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1412
1430
  broadcastToolListChanged();
1413
1431
  })
1414
1432
  .catch((error) => {
1415
- console.error('Failed to list tools for server', {
1433
+ logger.error('Failed to list tools for server', {
1416
1434
  serverName: name,
1417
1435
  error: summarizeErrorForLogging(error),
1418
1436
  });
@@ -1423,12 +1441,12 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1423
1441
  client
1424
1442
  .listPrompts({}, initRequestOptions || requestOptions)
1425
1443
  .then((prompts) => {
1426
- console.log(`Successfully listed ${prompts.prompts.length} prompts for server: ${name}`);
1444
+ logger.log(`Successfully listed ${prompts.prompts.length} prompts for server: ${name}`);
1427
1445
  updateServerPromptsCache(serverInfo, prompts.prompts);
1428
1446
  broadcastPromptListChanged();
1429
1447
  })
1430
1448
  .catch((error) => {
1431
- console.error('Failed to list prompts for server', {
1449
+ logger.error('Failed to list prompts for server', {
1432
1450
  serverName: name,
1433
1451
  error: summarizeErrorForLogging(error),
1434
1452
  });
@@ -1439,12 +1457,12 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1439
1457
  client
1440
1458
  .listResources({}, initRequestOptions || requestOptions)
1441
1459
  .then((resources) => {
1442
- console.log(`Successfully listed ${resources.resources.length} resources for server: ${name}`);
1460
+ logger.log(`Successfully listed ${resources.resources.length} resources for server: ${name}`);
1443
1461
  updateServerResourcesCache(serverInfo, resources.resources);
1444
1462
  broadcastResourceListChanged();
1445
1463
  })
1446
1464
  .catch((error) => {
1447
- console.error('Failed to list resources for server', {
1465
+ logger.error('Failed to list resources for server', {
1448
1466
  serverName: name,
1449
1467
  error: summarizeErrorForLogging(error),
1450
1468
  });
@@ -1470,7 +1488,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1470
1488
  if (isOAuthError) {
1471
1489
  // OAuth provider should have already set the status to 'oauth_required'
1472
1490
  // and stored the authorization URL in serverInfo.oauth
1473
- console.log(`OAuth authorization required for server ${name}. Status should be set to 'oauth_required'.`);
1491
+ logger.log(`OAuth authorization required for server ${name}. Status should be set to 'oauth_required'.`);
1474
1492
  // Make sure status is set correctly
1475
1493
  if (serverInfo.status !== 'oauth_required') {
1476
1494
  serverInfo.status = 'oauth_required';
@@ -1478,7 +1496,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1478
1496
  serverInfo.error = null;
1479
1497
  }
1480
1498
  else {
1481
- console.error('Failed to connect client for server', {
1499
+ logger.error('Failed to connect client for server', {
1482
1500
  serverName: name,
1483
1501
  error: summarizeErrorForLogging(error),
1484
1502
  });
@@ -1488,7 +1506,7 @@ export const initializeClientsFromSettings = async (isInit, serverName, options)
1488
1506
  setupServerKeepAlive(serverInfo, expandedConf);
1489
1507
  }
1490
1508
  });
1491
- console.log(`Initialized client for server: ${name}`);
1509
+ logger.log(`Initialized client for server: ${name}`);
1492
1510
  }
1493
1511
  }
1494
1512
  catch (error) {
@@ -1649,14 +1667,14 @@ export const getServerByOAuthState = (state) => {
1649
1667
  * This will close the existing connection and reinitialize the server
1650
1668
  */
1651
1669
  export const reconnectServer = async (serverName) => {
1652
- console.log(`Reconnecting server: ${serverName}`);
1670
+ logger.log(`Reconnecting server: ${serverName}`);
1653
1671
  const serverInfo = getServerByName(serverName);
1654
1672
  if (!serverInfo) {
1655
1673
  throw new Error(`Server not found: ${serverName}`);
1656
1674
  }
1657
1675
  const serverConfig = await getServerDao().findById(serverName);
1658
1676
  if (serverConfig?.enabled === false) {
1659
- console.log(`Skipping reconnect for disabled server: ${serverName}`);
1677
+ logger.log(`Skipping reconnect for disabled server: ${serverName}`);
1660
1678
  return;
1661
1679
  }
1662
1680
  // Close existing connection if any
@@ -1665,7 +1683,7 @@ export const reconnectServer = async (serverName) => {
1665
1683
  serverInfo.client.close();
1666
1684
  }
1667
1685
  catch (error) {
1668
- console.warn('Error closing client for server', { serverName, error });
1686
+ logger.warn('Error closing client for server', { serverName, error });
1669
1687
  }
1670
1688
  }
1671
1689
  if (serverInfo.transport) {
@@ -1673,7 +1691,7 @@ export const reconnectServer = async (serverName) => {
1673
1691
  serverInfo.transport.close();
1674
1692
  }
1675
1693
  catch (error) {
1676
- console.warn('Error closing transport for server', { serverName, error });
1694
+ logger.warn('Error closing transport for server', { serverName, error });
1677
1695
  }
1678
1696
  }
1679
1697
  if (serverInfo.keepAliveIntervalId) {
@@ -1682,13 +1700,13 @@ export const reconnectServer = async (serverName) => {
1682
1700
  }
1683
1701
  // Reinitialize the server
1684
1702
  await initializeClientsFromSettings(false, serverName);
1685
- console.log(`Successfully reconnected server: ${serverName}`);
1703
+ logger.log(`Successfully reconnected server: ${serverName}`);
1686
1704
  };
1687
1705
  // Reinstall server: clear package cache and reconnect.
1688
1706
  // For npx: deletes ~/.npm/_npx before reconnect (--ignore-existing removed in npm 7+).
1689
1707
  // For uvx: schedules --refresh flag injection on next spawn via pendingReinstalls Set.
1690
1708
  export const reinstallServer = async (serverName) => {
1691
- console.log(`Reinstalling server: ${serverName}`);
1709
+ logger.log(`Reinstalling server: ${serverName}`);
1692
1710
  const serverInfo = getServerByName(serverName);
1693
1711
  if (!serverInfo) {
1694
1712
  throw new Error(`Server not found: ${serverName}`);
@@ -1712,7 +1730,7 @@ export const reinstallServer = async (serverName) => {
1712
1730
  await clearRunnerCache(command);
1713
1731
  // Close and reconnect (will pick up pendingReinstalls flag for uvx)
1714
1732
  await reconnectServer(serverName);
1715
- console.log(`Successfully initiated reinstall for server: ${serverName}`);
1733
+ logger.log(`Successfully initiated reinstall for server: ${serverName}`);
1716
1734
  }
1717
1735
  catch (error) {
1718
1736
  // Clean up pendingReinstalls on failure to avoid stale entries
@@ -1763,7 +1781,7 @@ export const removeServer = async (name) => {
1763
1781
  await removeServerToolEmbeddings(name);
1764
1782
  }
1765
1783
  catch (error) {
1766
- console.warn('Failed to remove embeddings for server', { serverName: name, error });
1784
+ logger.warn('Failed to remove embeddings for server', { serverName: name, error });
1767
1785
  }
1768
1786
  serverInfos = serverInfos.filter((serverInfo) => serverInfo.name !== name);
1769
1787
  return { success: true, message: 'Server removed successfully' };
@@ -1792,7 +1810,7 @@ export const addOrUpdateServer = async (name, config, allowOverride = false) =>
1792
1810
  return { success: true, message: `Server ${action} successfully` };
1793
1811
  }
1794
1812
  catch (error) {
1795
- console.error('Failed to add/update server', { serverName: name, error });
1813
+ logger.error('Failed to add/update server', { serverName: name, error });
1796
1814
  return { success: false, message: 'Failed to add/update server' };
1797
1815
  }
1798
1816
  };
@@ -1822,7 +1840,7 @@ const closeServerRuntime = (serverInfo) => {
1822
1840
  if (serverInfo.keepAliveIntervalId) {
1823
1841
  clearInterval(serverInfo.keepAliveIntervalId);
1824
1842
  serverInfo.keepAliveIntervalId = undefined;
1825
- console.log('Cleared MCP server keep-alive interval');
1843
+ logger.log('Cleared MCP server keep-alive interval');
1826
1844
  }
1827
1845
  const candidateTransport = serverInfo.transport;
1828
1846
  const stdioPid = typeof candidateTransport?.pid === 'number' ? candidateTransport.pid : null;
@@ -1831,7 +1849,7 @@ const closeServerRuntime = (serverInfo) => {
1831
1849
  serverInfo.client.close();
1832
1850
  }
1833
1851
  catch {
1834
- console.warn('Error closing MCP client during runtime shutdown');
1852
+ logger.warn('Error closing MCP client during runtime shutdown');
1835
1853
  }
1836
1854
  serverInfo.client = undefined;
1837
1855
  }
@@ -1840,14 +1858,14 @@ const closeServerRuntime = (serverInfo) => {
1840
1858
  serverInfo.transport.close();
1841
1859
  }
1842
1860
  catch {
1843
- console.warn('Error closing MCP transport during runtime shutdown');
1861
+ logger.warn('Error closing MCP transport during runtime shutdown');
1844
1862
  }
1845
1863
  serverInfo.transport = undefined;
1846
1864
  }
1847
1865
  if (stdioPid) {
1848
1866
  killStdioProcessTree(serverInfo.name, stdioPid);
1849
1867
  }
1850
- console.log('Closed MCP server client and transport');
1868
+ logger.log('Closed MCP server client and transport');
1851
1869
  };
1852
1870
  // Close server client and transport (keeps the entry in serverInfos; the next
1853
1871
  // initializeClientsFromSettings rebuild drops it if it is no longer configured).
@@ -1873,7 +1891,7 @@ const shutdownOnDemandServer = (serverInfo) => {
1873
1891
  // Close runtime (kills process) but intentionally keep tools/prompts/resources
1874
1892
  closeServerRuntime(serverInfo);
1875
1893
  serverInfo.status = 'disconnected';
1876
- console.log(`[${serverInfo.name}] On-demand server shut down after idle; ` +
1894
+ logger.log(`[${serverInfo.name}] On-demand server shut down after idle; ` +
1877
1895
  `${serverInfo.tools.length} tools cached for next wake-up`);
1878
1896
  };
1879
1897
  /**
@@ -1931,7 +1949,7 @@ const ensureServerReady = async (serverInfo) => {
1931
1949
  return;
1932
1950
  }
1933
1951
  const name = rawConfig.name;
1934
- console.log(`[${name}] Cold-starting on-demand server…`);
1952
+ logger.log(`[${name}] Cold-starting on-demand server…`);
1935
1953
  const transport = await createTransportFromConfig(name, expandedConf);
1936
1954
  const client = createUpstreamMcpClient(name, () => serverInfo);
1937
1955
  const serverRequestOptions = expandedConf.options || {};
@@ -1964,7 +1982,7 @@ const ensureServerReady = async (serverInfo) => {
1964
1982
  broadcastToolListChanged();
1965
1983
  }
1966
1984
  catch (error) {
1967
- console.warn(`[${name}] Failed to list tools during wake`, {
1985
+ logger.warn(`[${name}] Failed to list tools during wake`, {
1968
1986
  error: summarizeErrorForLogging(error),
1969
1987
  });
1970
1988
  }
@@ -1976,7 +1994,7 @@ const ensureServerReady = async (serverInfo) => {
1976
1994
  updateServerPromptsCache(serverInfo, prompts.prompts);
1977
1995
  }
1978
1996
  catch (error) {
1979
- console.warn(`[${name}] Failed to list prompts during wake`, {
1997
+ logger.warn(`[${name}] Failed to list prompts during wake`, {
1980
1998
  error: summarizeErrorForLogging(error),
1981
1999
  });
1982
2000
  }
@@ -1988,14 +2006,14 @@ const ensureServerReady = async (serverInfo) => {
1988
2006
  updateServerResourcesCache(serverInfo, resources.resources);
1989
2007
  }
1990
2008
  catch (error) {
1991
- console.warn(`[${name}] Failed to list resources during wake`, {
2009
+ logger.warn(`[${name}] Failed to list resources during wake`, {
1992
2010
  error: summarizeErrorForLogging(error),
1993
2011
  });
1994
2012
  }
1995
2013
  }
1996
2014
  // No-op for stdio transports; only SSE/streamable-http opt in via enableKeepAlive.
1997
2015
  setupServerKeepAlive(serverInfo, expandedConf);
1998
- console.log(`[${name}] On-demand server ready in ${Date.now() - spawnStart}ms` +
2016
+ logger.log(`[${name}] On-demand server ready in ${Date.now() - spawnStart}ms` +
1999
2017
  ` (${toolCount} tools, ${promptCount} prompts, ${resourceCount} resources)`);
2000
2018
  })();
2001
2019
  serverInfo.spawningPromise = spawnPromise;
@@ -2034,16 +2052,16 @@ const primeOnDemandServers = () => {
2034
2052
  si.enabled !== false);
2035
2053
  if (targets.length === 0)
2036
2054
  return Promise.resolve();
2037
- console.log(`Priming ${targets.length} on-demand server(s) for tool discovery…`);
2055
+ logger.log(`Priming ${targets.length} on-demand server(s) for tool discovery…`);
2038
2056
  return Promise.allSettled(targets.map(async (si) => {
2039
2057
  try {
2040
2058
  await ensureServerReady(si);
2041
2059
  // Sleep the child but keep the cached tool list visible to agents.
2042
2060
  shutdownOnDemandServer(si);
2043
- console.log('On-demand server primed and asleep');
2061
+ logger.log('On-demand server primed and asleep');
2044
2062
  }
2045
2063
  catch (error) {
2046
- console.warn('Failed to prime on-demand server', {
2064
+ logger.warn('Failed to prime on-demand server', {
2047
2065
  error: summarizeErrorForLogging(error),
2048
2066
  });
2049
2067
  }
@@ -2084,7 +2102,7 @@ function killStdioProcessTree(name, pid) {
2084
2102
  // Pass the user-controlled `name` as a separate argument so a
2085
2103
  // server named e.g. "%s" cannot inject format specifiers into the
2086
2104
  // log line (CodeQL: use-of-externally-controlled-format-string).
2087
- console.warn('Failed to send signal to process tree', {
2105
+ logger.warn('Failed to send signal to process tree', {
2088
2106
  serverName: name,
2089
2107
  pid,
2090
2108
  signal,
@@ -2095,7 +2113,7 @@ function killStdioProcessTree(name, pid) {
2095
2113
  });
2096
2114
  }
2097
2115
  catch (err) {
2098
- console.warn('Failed to send signal to process tree', {
2116
+ logger.warn('Failed to send signal to process tree', {
2099
2117
  serverName: name,
2100
2118
  pid,
2101
2119
  signal,
@@ -2142,10 +2160,10 @@ export const toggleServerStatus = async (name, enabled) => {
2142
2160
  // Remove tool embeddings when server is disabled (for smart routing consistency)
2143
2161
  try {
2144
2162
  await removeServerToolEmbeddings(name);
2145
- console.log(`Removed tool embeddings for disabled server: ${name}`);
2163
+ logger.log(`Removed tool embeddings for disabled server: ${name}`);
2146
2164
  }
2147
2165
  catch (embeddingError) {
2148
- console.warn('Failed to remove embeddings for server', {
2166
+ logger.warn('Failed to remove embeddings for server', {
2149
2167
  serverName: name,
2150
2168
  error: summarizeErrorForLogging(embeddingError),
2151
2169
  });
@@ -2155,10 +2173,10 @@ export const toggleServerStatus = async (name, enabled) => {
2155
2173
  // If enabling, reconnect the server to restore connection and sync tool embeddings
2156
2174
  try {
2157
2175
  await initializeClientsFromSettings(false, name);
2158
- console.log(`Re-enabled server ${name} and triggered tool embedding sync`);
2176
+ logger.log(`Re-enabled server ${name} and triggered tool embedding sync`);
2159
2177
  }
2160
2178
  catch (reconnectError) {
2161
- console.warn('Failed to reconnect server during enable', {
2179
+ logger.warn('Failed to reconnect server during enable', {
2162
2180
  serverName: name,
2163
2181
  error: summarizeErrorForLogging(reconnectError),
2164
2182
  });
@@ -2167,7 +2185,7 @@ export const toggleServerStatus = async (name, enabled) => {
2167
2185
  return { success: true, message: `Server ${enabled ? 'enabled' : 'disabled'} successfully` };
2168
2186
  }
2169
2187
  catch (error) {
2170
- console.error('Failed to toggle server status', { serverName: name, error });
2188
+ logger.error('Failed to toggle server status', { serverName: name, error });
2171
2189
  return { success: false, message: 'Failed to toggle server status' };
2172
2190
  }
2173
2191
  };
@@ -2309,7 +2327,7 @@ const projectToolForDownstream = (serverName, tool, appsRouteContext, serverConf
2309
2327
  export const handleListToolsRequest = async (_, extra) => {
2310
2328
  const sessionId = extra.sessionId || '';
2311
2329
  const group = getGroup(sessionId);
2312
- console.log(`Handling ListToolsRequest for group: ${group}`);
2330
+ logger.log(`Handling ListToolsRequest for group: ${group}`);
2313
2331
  // Special handling for $smart group to return smart routing tools
2314
2332
  // Support both $smart and $smart/{group} patterns
2315
2333
  if (isSmartRoutingGroup(group)) {
@@ -2321,9 +2339,7 @@ export const handleListToolsRequest = async (_, extra) => {
2321
2339
  // so this list reflects the freshly cached tools instead of returning empty.
2322
2340
  // No wake is triggered from list itself; the prime handles that. See #1029.
2323
2341
  await Promise.allSettled(filteredServerInfos
2324
- .filter((si) => si.config?.startOnDemand === true &&
2325
- si.tools.length === 0 &&
2326
- si.spawningPromise)
2342
+ .filter((si) => si.config?.startOnDemand === true && si.tools.length === 0 && si.spawningPromise)
2327
2343
  .map((si) => si.spawningPromise));
2328
2344
  const allTools = [];
2329
2345
  for (const serverInfo of filteredServerInfos) {
@@ -2353,7 +2369,7 @@ export const handleListToolsRequest = async (_, extra) => {
2353
2369
  };
2354
2370
  };
2355
2371
  export const handleCallToolRequest = async (request, extra) => {
2356
- console.log('Handling CallToolRequest for tool', summarizeToolRequestForLogging(request.params));
2372
+ logger.log('Handling CallToolRequest for tool', summarizeToolRequestForLogging(request.params));
2357
2373
  const startTime = Date.now();
2358
2374
  const activityLogger = getActivityLoggingService();
2359
2375
  // Get request context for activity logging
@@ -2475,7 +2491,7 @@ export const handleCallToolRequest = async (request, extra) => {
2475
2491
  const openApiClient = targetServerInfo.openApiClient;
2476
2492
  // Use toolArgs if it has properties, otherwise fallback to request.params.arguments
2477
2493
  const finalArgs = toolArgs && typeof toolArgs === 'object' ? toolArgs : {};
2478
- console.log('Invoking OpenAPI tool', {
2494
+ logger.log('Invoking OpenAPI tool', {
2479
2495
  toolName: targetToolName,
2480
2496
  serverName: targetServerInfo.name,
2481
2497
  arguments: summarizeArgumentsForLogging(finalArgs),
@@ -2513,7 +2529,7 @@ export const handleCallToolRequest = async (request, extra) => {
2513
2529
  requestContent: finalArgs,
2514
2530
  responseContent: result,
2515
2531
  });
2516
- console.log('OpenAPI tool invocation result', {
2532
+ logger.log('OpenAPI tool invocation result', {
2517
2533
  serverName: targetServerInfo.name,
2518
2534
  toolName: cleanToolName,
2519
2535
  result: summarizeToolResultForLogging(result),
@@ -2558,7 +2574,7 @@ export const handleCallToolRequest = async (request, extra) => {
2558
2574
  }
2559
2575
  // Use toolArgs if it has properties, otherwise fallback to request.params.arguments
2560
2576
  const finalArgs = toolArgs && typeof toolArgs === 'object' ? toolArgs : {};
2561
- console.log('Invoking tool', {
2577
+ logger.log('Invoking tool', {
2562
2578
  toolName: targetToolName,
2563
2579
  serverName: targetServerInfo.name,
2564
2580
  arguments: summarizeArgumentsForLogging(finalArgs),
@@ -2575,7 +2591,7 @@ export const handleCallToolRequest = async (request, extra) => {
2575
2591
  requestContent: finalArgs,
2576
2592
  responseContent: result,
2577
2593
  });
2578
- console.log('Tool invocation result', {
2594
+ logger.log('Tool invocation result', {
2579
2595
  serverName: targetServerInfo.name,
2580
2596
  toolName: cleanToolName,
2581
2597
  result: summarizeToolResultForLogging(result),
@@ -2618,13 +2634,10 @@ export const handleCallToolRequest = async (request, extra) => {
2618
2634
  : undefined;
2619
2635
  const serverInfo = singleServerAppsRoute
2620
2636
  ? appsRouteContext.serverInfo
2621
- : (groupTool?.serverInfo ??
2622
- (lookupGroup ? undefined : getServerByTool(request.params.name)));
2637
+ : (groupTool?.serverInfo ?? (lookupGroup ? undefined : getServerByTool(request.params.name)));
2623
2638
  const routeToolName = groupTool?.toolName ?? request.params.name;
2624
2639
  const tool = groupTool?.tool ??
2625
- (serverInfo
2626
- ? findToolOnServer(serverInfo, routeToolName, singleServerAppsRoute)
2627
- : undefined);
2640
+ (serverInfo ? findToolOnServer(serverInfo, routeToolName, singleServerAppsRoute) : undefined);
2628
2641
  if (!serverInfo || !tool) {
2629
2642
  throw new Error(`Server not found: ${request.params.name}`);
2630
2643
  }
@@ -2642,7 +2655,7 @@ export const handleCallToolRequest = async (request, extra) => {
2642
2655
  const openApiClient = serverInfo.openApiClient;
2643
2656
  // Remove server prefix from tool name if present
2644
2657
  const cleanToolName = normalizeToolNameForServer(serverInfo.name, routeToolName);
2645
- console.log('Invoking OpenAPI tool', {
2658
+ logger.log('Invoking OpenAPI tool', {
2646
2659
  toolName: cleanToolName,
2647
2660
  serverName: serverInfo.name,
2648
2661
  arguments: summarizeArgumentsForLogging(request.params.arguments),
@@ -2679,7 +2692,7 @@ export const handleCallToolRequest = async (request, extra) => {
2679
2692
  requestContent: finalArgs,
2680
2693
  responseContent: result,
2681
2694
  });
2682
- console.log('OpenAPI tool invocation result', {
2695
+ logger.log('OpenAPI tool invocation result', {
2683
2696
  serverName: serverInfo.name,
2684
2697
  toolName: cleanToolName,
2685
2698
  result: summarizeToolResultForLogging(result),
@@ -2730,7 +2743,7 @@ export const handleCallToolRequest = async (request, extra) => {
2730
2743
  requestContent: request.params.arguments,
2731
2744
  responseContent: result,
2732
2745
  });
2733
- console.log('Tool call result', {
2746
+ logger.log('Tool call result', {
2734
2747
  serverName: serverInfo.name,
2735
2748
  toolName: cleanToolName,
2736
2749
  result: summarizeToolResultForLogging(result),
@@ -2760,7 +2773,7 @@ export const handleCallToolRequest = async (request, extra) => {
2760
2773
  });
2761
2774
  }
2762
2775
  catch (error) {
2763
- console.error('Error handling CallToolRequest', summarizeErrorForLogging(error));
2776
+ logger.error('Error handling CallToolRequest', summarizeErrorForLogging(error));
2764
2777
  // Log error activity
2765
2778
  const duration = Date.now() - startTime;
2766
2779
  await settleHostedIfNeeded({
@@ -2854,19 +2867,19 @@ export const handleGetPromptRequest = async (request, extra) => {
2854
2867
  arguments: promptArgs,
2855
2868
  };
2856
2869
  // Log the final promptParams
2857
- console.log('Calling getPrompt with params', {
2870
+ logger.log('Calling getPrompt with params', {
2858
2871
  name: cleanPromptName || '',
2859
2872
  arguments: summarizeArgumentsForLogging(promptArgs),
2860
2873
  });
2861
2874
  const prompt = await server.client?.getPrompt(promptParams);
2862
- console.log('Received prompt', summarizePromptForLogging(prompt));
2875
+ logger.log('Received prompt', summarizePromptForLogging(prompt));
2863
2876
  if (!prompt) {
2864
2877
  throw new Error(`Prompt not found: ${cleanPromptName}`);
2865
2878
  }
2866
2879
  return prompt;
2867
2880
  }
2868
2881
  catch (error) {
2869
- console.error('Error handling GetPromptRequest', summarizeErrorForLogging(error));
2882
+ logger.error('Error handling GetPromptRequest', summarizeErrorForLogging(error));
2870
2883
  const safeErrorText = formatErrorForLogging(error);
2871
2884
  return {
2872
2885
  content: [
@@ -2883,7 +2896,7 @@ export const handleListPromptsRequest = async (_, extra) => {
2883
2896
  const sessionId = extra.sessionId || '';
2884
2897
  const group = getGroup(sessionId);
2885
2898
  const lookupGroup = getGroupLookupName(group);
2886
- console.log(`Handling ListPromptsRequest for group: ${group}`);
2899
+ logger.log(`Handling ListPromptsRequest for group: ${group}`);
2887
2900
  // Start with built-in prompts (only enabled ones)
2888
2901
  const builtinPrompts = await getBuiltinPromptDao().findEnabled();
2889
2902
  const allPrompts = builtinPrompts.map((bp) => normalizePromptForList({
@@ -2927,7 +2940,7 @@ export const handleListResourcesRequest = async (_, extra) => {
2927
2940
  const sessionId = extra.sessionId || '';
2928
2941
  const group = getGroup(sessionId);
2929
2942
  const lookupGroup = getGroupLookupName(group);
2930
- console.log(`Handling ListResourcesRequest for group: ${group}`);
2943
+ logger.log(`Handling ListResourcesRequest for group: ${group}`);
2931
2944
  const appsRouteContext = await getMcpAppsRouteContext(sessionId, group);
2932
2945
  // Start with built-in resources (only enabled ones)
2933
2946
  const builtinResources = await getBuiltinResourceDao().findEnabled();
@@ -2972,7 +2985,7 @@ export const handleListResourceTemplatesRequest = async (_, extra) => {
2972
2985
  const sessionId = extra.sessionId || '';
2973
2986
  const group = getGroup(sessionId);
2974
2987
  const lookupGroup = getGroupLookupName(group);
2975
- console.log(`Handling ListResourceTemplatesRequest for group: ${group}`);
2988
+ logger.log(`Handling ListResourceTemplatesRequest for group: ${group}`);
2976
2989
  const appsRouteContext = await getMcpAppsRouteContext(sessionId, group);
2977
2990
  const { filteredServerInfos, serverConfigsByName } = await getFilteredServerInfosForGroup(lookupGroup, {
2978
2991
  requireClient: true,
@@ -3075,7 +3088,7 @@ export const handleReadResourceRequest = async (request, extra) => {
3075
3088
  };
3076
3089
  }
3077
3090
  catch (error) {
3078
- console.error('Error handling ReadResourceRequest', summarizeErrorForLogging(error));
3091
+ logger.error('Error handling ReadResourceRequest', summarizeErrorForLogging(error));
3079
3092
  const safeErrorText = formatErrorForLogging(error);
3080
3093
  return {
3081
3094
  contents: [