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