@machina.ai/cell-cli-core 1.19.4-rc3 → 1.22.5-rc1

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 (504) hide show
  1. package/dist/index.d.ts +1 -1
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +1 -1
  5. package/dist/src/agents/delegate-to-agent-tool.d.ts +19 -0
  6. package/dist/src/agents/delegate-to-agent-tool.js +111 -0
  7. package/dist/src/agents/delegate-to-agent-tool.js.map +1 -0
  8. package/dist/src/agents/delegate-to-agent-tool.test.d.ts +6 -0
  9. package/dist/src/agents/delegate-to-agent-tool.test.js +133 -0
  10. package/dist/src/agents/delegate-to-agent-tool.test.js.map +1 -0
  11. package/dist/src/agents/executor.js +12 -17
  12. package/dist/src/agents/executor.js.map +1 -1
  13. package/dist/src/agents/executor.test.js +8 -9
  14. package/dist/src/agents/executor.test.js.map +1 -1
  15. package/dist/src/agents/registry.d.ts +15 -0
  16. package/dist/src/agents/registry.js +58 -2
  17. package/dist/src/agents/registry.js.map +1 -1
  18. package/dist/src/agents/registry.test.js +61 -0
  19. package/dist/src/agents/registry.test.js.map +1 -1
  20. package/dist/src/availability/errorClassification.d.ts +7 -0
  21. package/dist/src/availability/errorClassification.js +20 -0
  22. package/dist/src/availability/errorClassification.js.map +1 -0
  23. package/dist/src/availability/modelAvailabilityService.d.ts +2 -1
  24. package/dist/src/availability/modelAvailabilityService.js +5 -2
  25. package/dist/src/availability/modelAvailabilityService.js.map +1 -1
  26. package/dist/src/availability/modelAvailabilityService.test.js +3 -3
  27. package/dist/src/availability/modelAvailabilityService.test.js.map +1 -1
  28. package/dist/src/availability/modelPolicy.d.ts +8 -1
  29. package/dist/src/availability/policyCatalog.d.ts +4 -1
  30. package/dist/src/availability/policyCatalog.js +8 -9
  31. package/dist/src/availability/policyCatalog.js.map +1 -1
  32. package/dist/src/availability/policyCatalog.test.js +2 -2
  33. package/dist/src/availability/policyCatalog.test.js.map +1 -1
  34. package/dist/src/availability/policyHelpers.d.ts +51 -0
  35. package/dist/src/availability/policyHelpers.js +145 -0
  36. package/dist/src/availability/policyHelpers.js.map +1 -0
  37. package/dist/src/availability/policyHelpers.test.d.ts +6 -0
  38. package/dist/src/availability/policyHelpers.test.js +172 -0
  39. package/dist/src/availability/policyHelpers.test.js.map +1 -0
  40. package/dist/src/availability/testUtils.d.ts +10 -0
  41. package/dist/src/availability/testUtils.js +22 -0
  42. package/dist/src/availability/testUtils.js.map +1 -0
  43. package/dist/src/code_assist/experiments/client_metadata.js +3 -2
  44. package/dist/src/code_assist/experiments/client_metadata.js.map +1 -1
  45. package/dist/src/code_assist/experiments/client_metadata.test.js +7 -10
  46. package/dist/src/code_assist/experiments/client_metadata.test.js.map +1 -1
  47. package/dist/src/code_assist/experiments/experiments.js +2 -2
  48. package/dist/src/code_assist/experiments/experiments.js.map +1 -1
  49. package/dist/src/code_assist/oauth2.d.ts +2 -0
  50. package/dist/src/code_assist/oauth2.js +41 -15
  51. package/dist/src/code_assist/oauth2.js.map +1 -1
  52. package/dist/src/code_assist/oauth2.test.js +114 -7
  53. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  54. package/dist/src/code_assist/server.d.ts +2 -1
  55. package/dist/src/code_assist/server.js +7 -4
  56. package/dist/src/code_assist/server.js.map +1 -1
  57. package/dist/src/code_assist/server.test.js +24 -0
  58. package/dist/src/code_assist/server.test.js.map +1 -1
  59. package/dist/src/code_assist/types.d.ts +14 -0
  60. package/dist/src/commands/init.d.ts +7 -0
  61. package/dist/src/commands/init.js +53 -0
  62. package/dist/src/commands/init.js.map +1 -0
  63. package/dist/src/commands/init.test.d.ts +6 -0
  64. package/dist/src/commands/init.test.js +25 -0
  65. package/dist/src/commands/init.test.js.map +1 -0
  66. package/dist/src/commands/restore.d.ts +9 -0
  67. package/dist/src/commands/restore.js +46 -0
  68. package/dist/src/commands/restore.js.map +1 -0
  69. package/dist/src/commands/restore.test.d.ts +6 -0
  70. package/dist/src/commands/restore.test.js +137 -0
  71. package/dist/src/commands/restore.test.js.map +1 -0
  72. package/dist/src/commands/types.d.ts +41 -0
  73. package/dist/src/commands/types.js +7 -0
  74. package/dist/src/commands/types.js.map +1 -0
  75. package/dist/src/config/config.d.ts +43 -3
  76. package/dist/src/config/config.js +182 -29
  77. package/dist/src/config/config.js.map +1 -1
  78. package/dist/src/config/config.test.js +217 -9
  79. package/dist/src/config/config.test.js.map +1 -1
  80. package/dist/src/config/defaultModelConfigs.js +21 -0
  81. package/dist/src/config/defaultModelConfigs.js.map +1 -1
  82. package/dist/src/config/models.d.ts +33 -11
  83. package/dist/src/config/models.js +82 -24
  84. package/dist/src/config/models.js.map +1 -1
  85. package/dist/src/config/models.test.js +70 -76
  86. package/dist/src/config/models.test.js.map +1 -1
  87. package/dist/src/confirmation-bus/message-bus.js +1 -0
  88. package/dist/src/confirmation-bus/message-bus.js.map +1 -1
  89. package/dist/src/confirmation-bus/types.d.ts +4 -0
  90. package/dist/src/core/AuthenticatedContentGenerator.js +4 -4
  91. package/dist/src/core/AuthenticatedContentGenerator.js.map +1 -1
  92. package/dist/src/core/baseLlmClient.d.ts +3 -1
  93. package/dist/src/core/baseLlmClient.js +40 -3
  94. package/dist/src/core/baseLlmClient.js.map +1 -1
  95. package/dist/src/core/baseLlmClient.test.js +184 -7
  96. package/dist/src/core/baseLlmClient.test.js.map +1 -1
  97. package/dist/src/core/client.js +52 -51
  98. package/dist/src/core/client.js.map +1 -1
  99. package/dist/src/core/client.test.js +178 -6
  100. package/dist/src/core/client.test.js.map +1 -1
  101. package/dist/src/core/contentGenerator.js +5 -3
  102. package/dist/src/core/contentGenerator.js.map +1 -1
  103. package/dist/src/core/contentGenerator.test.js +29 -22
  104. package/dist/src/core/contentGenerator.test.js.map +1 -1
  105. package/dist/src/core/coreToolHookTriggers.d.ts +55 -0
  106. package/dist/src/core/coreToolHookTriggers.js +244 -0
  107. package/dist/src/core/coreToolHookTriggers.js.map +1 -0
  108. package/dist/src/core/coreToolScheduler.d.ts +1 -1
  109. package/dist/src/core/coreToolScheduler.js +87 -36
  110. package/dist/src/core/coreToolScheduler.js.map +1 -1
  111. package/dist/src/core/coreToolScheduler.test.js +201 -38
  112. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  113. package/dist/src/core/geminiChat.js +144 -41
  114. package/dist/src/core/geminiChat.js.map +1 -1
  115. package/dist/src/core/geminiChat.test.js +251 -192
  116. package/dist/src/core/geminiChat.test.js.map +1 -1
  117. package/dist/src/core/geminiChatHookTriggers.d.ts +64 -0
  118. package/dist/src/core/geminiChatHookTriggers.js +136 -0
  119. package/dist/src/core/geminiChatHookTriggers.js.map +1 -0
  120. package/dist/src/core/geminiChat_network_retry.test.d.ts +6 -0
  121. package/dist/src/core/geminiChat_network_retry.test.js +198 -0
  122. package/dist/src/core/geminiChat_network_retry.test.js.map +1 -0
  123. package/dist/src/core/logger.js.map +1 -1
  124. package/dist/src/core/loggingContentGenerator.js +9 -4
  125. package/dist/src/core/loggingContentGenerator.js.map +1 -1
  126. package/dist/src/core/nonInteractiveToolExecutor.test.js +4 -5
  127. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  128. package/dist/src/core/prompts.js +50 -29
  129. package/dist/src/core/prompts.js.map +1 -1
  130. package/dist/src/core/prompts.test.js +19 -8
  131. package/dist/src/core/prompts.test.js.map +1 -1
  132. package/dist/src/core/sessionHookTriggers.d.ts +28 -0
  133. package/dist/src/core/sessionHookTriggers.js +68 -0
  134. package/dist/src/core/sessionHookTriggers.js.map +1 -0
  135. package/dist/src/core/turn.d.ts +1 -0
  136. package/dist/src/core/turn.js +1 -1
  137. package/dist/src/core/turn.js.map +1 -1
  138. package/dist/src/fallback/handler.js +82 -69
  139. package/dist/src/fallback/handler.js.map +1 -1
  140. package/dist/src/fallback/handler.test.js +186 -170
  141. package/dist/src/fallback/handler.test.js.map +1 -1
  142. package/dist/src/fallback/types.d.ts +8 -0
  143. package/dist/src/generated/git-commit.d.ts +2 -2
  144. package/dist/src/generated/git-commit.js +2 -2
  145. package/dist/src/hooks/hookEventHandler.js +70 -12
  146. package/dist/src/hooks/hookEventHandler.js.map +1 -1
  147. package/dist/src/hooks/hookEventHandler.test.js +8 -1
  148. package/dist/src/hooks/hookEventHandler.test.js.map +1 -1
  149. package/dist/src/hooks/hookRegistry.d.ts +0 -7
  150. package/dist/src/hooks/hookRegistry.js +8 -21
  151. package/dist/src/hooks/hookRegistry.js.map +1 -1
  152. package/dist/src/hooks/hookRegistry.test.js +2 -7
  153. package/dist/src/hooks/hookRegistry.test.js.map +1 -1
  154. package/dist/src/hooks/hookRunner.js +19 -3
  155. package/dist/src/hooks/hookRunner.js.map +1 -1
  156. package/dist/src/hooks/hookRunner.test.js +2 -1
  157. package/dist/src/hooks/hookRunner.test.js.map +1 -1
  158. package/dist/src/hooks/hookSystem.d.ts +0 -8
  159. package/dist/src/hooks/hookSystem.js +0 -18
  160. package/dist/src/hooks/hookSystem.js.map +1 -1
  161. package/dist/src/hooks/hookSystem.test.js +124 -18
  162. package/dist/src/hooks/hookSystem.test.js.map +1 -1
  163. package/dist/src/hooks/index.d.ts +3 -1
  164. package/dist/src/hooks/index.js +3 -0
  165. package/dist/src/hooks/index.js.map +1 -1
  166. package/dist/src/hooks/types.d.ts +1 -2
  167. package/dist/src/hooks/types.js +0 -1
  168. package/dist/src/hooks/types.js.map +1 -1
  169. package/dist/src/ide/detect-ide.test.js +32 -1
  170. package/dist/src/ide/detect-ide.test.js.map +1 -1
  171. package/dist/src/ide/ide-client.js +5 -3
  172. package/dist/src/ide/ide-client.js.map +1 -1
  173. package/dist/src/ide/ide-client.test.js +17 -0
  174. package/dist/src/ide/ide-client.test.js.map +1 -1
  175. package/dist/src/ide/ide-installer.test.js +1 -1
  176. package/dist/src/ide/ide-installer.test.js.map +1 -1
  177. package/dist/src/index.d.ts +10 -0
  178. package/dist/src/index.js +10 -0
  179. package/dist/src/index.js.map +1 -1
  180. package/dist/src/mcp/auth-provider.d.ts +16 -0
  181. package/dist/src/mcp/auth-provider.js +7 -0
  182. package/dist/src/mcp/auth-provider.js.map +1 -0
  183. package/dist/src/mcp/google-auth-provider.d.ts +10 -2
  184. package/dist/src/mcp/google-auth-provider.js +28 -0
  185. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  186. package/dist/src/mcp/google-auth-provider.test.js +45 -0
  187. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  188. package/dist/src/mcp/mcpLauncher.js +6 -3
  189. package/dist/src/mcp/mcpLauncher.js.map +1 -1
  190. package/dist/src/mcp/oauth-provider.js.map +1 -1
  191. package/dist/src/mcp/sa-impersonation-provider.d.ts +2 -2
  192. package/dist/src/mcp/sa-impersonation-provider.js.map +1 -1
  193. package/dist/src/mcp/token-storage/hybrid-token-storage.js +1 -1
  194. package/dist/src/mcp/token-storage/hybrid-token-storage.js.map +1 -1
  195. package/dist/src/output/json-formatter.d.ts +2 -2
  196. package/dist/src/output/json-formatter.js +6 -3
  197. package/dist/src/output/json-formatter.js.map +1 -1
  198. package/dist/src/output/json-formatter.test.js +37 -9
  199. package/dist/src/output/json-formatter.test.js.map +1 -1
  200. package/dist/src/output/stream-json-formatter.js +6 -0
  201. package/dist/src/output/stream-json-formatter.js.map +1 -1
  202. package/dist/src/output/stream-json-formatter.test.js +98 -100
  203. package/dist/src/output/stream-json-formatter.test.js.map +1 -1
  204. package/dist/src/output/types.d.ts +3 -0
  205. package/dist/src/output/types.js.map +1 -1
  206. package/dist/src/policy/config.js +97 -11
  207. package/dist/src/policy/config.js.map +1 -1
  208. package/dist/src/policy/persistence.test.d.ts +6 -0
  209. package/dist/src/policy/persistence.test.js +154 -0
  210. package/dist/src/policy/persistence.test.js.map +1 -0
  211. package/dist/src/policy/policies/agent.toml +31 -0
  212. package/dist/src/policy/policies/read-only.toml +5 -0
  213. package/dist/src/policy/policy-engine.d.ts +10 -1
  214. package/dist/src/policy/policy-engine.js +79 -5
  215. package/dist/src/policy/policy-engine.js.map +1 -1
  216. package/dist/src/policy/policy-engine.test.js +26 -2
  217. package/dist/src/policy/policy-engine.test.js.map +1 -1
  218. package/dist/src/policy/policy-updater.test.d.ts +6 -0
  219. package/dist/src/policy/policy-updater.test.js +116 -0
  220. package/dist/src/policy/policy-updater.test.js.map +1 -0
  221. package/dist/src/policy/shell-safety.test.d.ts +6 -0
  222. package/dist/src/policy/shell-safety.test.js +75 -0
  223. package/dist/src/policy/shell-safety.test.js.map +1 -0
  224. package/dist/src/policy/toml-loader.d.ts +11 -5
  225. package/dist/src/policy/toml-loader.js +38 -23
  226. package/dist/src/policy/toml-loader.js.map +1 -1
  227. package/dist/src/policy/toml-loader.test.js +28 -7
  228. package/dist/src/policy/toml-loader.test.js.map +1 -1
  229. package/dist/src/policy/types.d.ts +15 -0
  230. package/dist/src/resources/resource-registry.d.ts +30 -0
  231. package/dist/src/resources/resource-registry.js +57 -0
  232. package/dist/src/resources/resource-registry.js.map +1 -0
  233. package/dist/src/resources/resource-registry.test.d.ts +6 -0
  234. package/dist/src/resources/resource-registry.test.js +54 -0
  235. package/dist/src/resources/resource-registry.test.js.map +1 -0
  236. package/dist/src/routing/modelRouterService.js +0 -15
  237. package/dist/src/routing/modelRouterService.js.map +1 -1
  238. package/dist/src/routing/modelRouterService.test.js +0 -62
  239. package/dist/src/routing/modelRouterService.test.js.map +1 -1
  240. package/dist/src/routing/strategies/classifierStrategy.js +10 -21
  241. package/dist/src/routing/strategies/classifierStrategy.js.map +1 -1
  242. package/dist/src/routing/strategies/classifierStrategy.test.js +2 -1
  243. package/dist/src/routing/strategies/classifierStrategy.test.js.map +1 -1
  244. package/dist/src/routing/strategies/fallbackStrategy.js +23 -12
  245. package/dist/src/routing/strategies/fallbackStrategy.js.map +1 -1
  246. package/dist/src/routing/strategies/fallbackStrategy.test.js +69 -39
  247. package/dist/src/routing/strategies/fallbackStrategy.test.js.map +1 -1
  248. package/dist/src/routing/strategies/overrideStrategy.js +4 -3
  249. package/dist/src/routing/strategies/overrideStrategy.js.map +1 -1
  250. package/dist/src/safety/checker-runner.js +17 -6
  251. package/dist/src/safety/checker-runner.js.map +1 -1
  252. package/dist/src/services/chatCompressionService.js +17 -3
  253. package/dist/src/services/chatCompressionService.js.map +1 -1
  254. package/dist/src/services/chatCompressionService.test.js +9 -0
  255. package/dist/src/services/chatCompressionService.test.js.map +1 -1
  256. package/dist/src/services/chatRecordingService.d.ts +14 -0
  257. package/dist/src/services/chatRecordingService.js +37 -0
  258. package/dist/src/services/chatRecordingService.js.map +1 -1
  259. package/dist/src/services/contextManager.d.ts +35 -0
  260. package/dist/src/services/contextManager.js +68 -0
  261. package/dist/src/services/contextManager.js.map +1 -0
  262. package/dist/src/services/contextManager.test.d.ts +6 -0
  263. package/dist/src/services/contextManager.test.js +105 -0
  264. package/dist/src/services/contextManager.test.js.map +1 -0
  265. package/dist/src/services/fileSystemService.d.ts +0 -9
  266. package/dist/src/services/fileSystemService.js +0 -11
  267. package/dist/src/services/fileSystemService.js.map +1 -1
  268. package/dist/src/services/gitService.js +5 -0
  269. package/dist/src/services/gitService.js.map +1 -1
  270. package/dist/src/services/gitService.test.js +28 -0
  271. package/dist/src/services/gitService.test.js.map +1 -1
  272. package/dist/src/services/loopDetectionService.js +3 -3
  273. package/dist/src/services/loopDetectionService.js.map +1 -1
  274. package/dist/src/services/modelConfig.golden.test.js +32 -0
  275. package/dist/src/services/modelConfig.golden.test.js.map +1 -1
  276. package/dist/src/services/modelConfigService.d.ts +3 -0
  277. package/dist/src/services/modelConfigService.js +3 -2
  278. package/dist/src/services/modelConfigService.js.map +1 -1
  279. package/dist/src/services/modelConfigService.test.js +110 -0
  280. package/dist/src/services/modelConfigService.test.js.map +1 -1
  281. package/dist/src/services/modelConfigServiceTestUtils.d.ts +10 -0
  282. package/dist/src/services/modelConfigServiceTestUtils.js +17 -0
  283. package/dist/src/services/modelConfigServiceTestUtils.js.map +1 -0
  284. package/dist/src/services/sessionSummaryService.d.ts +28 -0
  285. package/dist/src/services/sessionSummaryService.js +131 -0
  286. package/dist/src/services/sessionSummaryService.js.map +1 -0
  287. package/dist/src/services/sessionSummaryService.test.d.ts +6 -0
  288. package/dist/src/services/sessionSummaryService.test.js +785 -0
  289. package/dist/src/services/sessionSummaryService.test.js.map +1 -0
  290. package/dist/src/services/sessionSummaryUtils.d.ts +16 -0
  291. package/dist/src/services/sessionSummaryUtils.js +129 -0
  292. package/dist/src/services/sessionSummaryUtils.js.map +1 -0
  293. package/dist/src/services/sessionSummaryUtils.test.d.ts +6 -0
  294. package/dist/src/services/sessionSummaryUtils.test.js +137 -0
  295. package/dist/src/services/sessionSummaryUtils.test.js.map +1 -0
  296. package/dist/src/services/shellExecutionService.js +56 -22
  297. package/dist/src/services/shellExecutionService.js.map +1 -1
  298. package/dist/src/services/shellExecutionService.test.js +137 -5
  299. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  300. package/dist/src/services/test-data/resolved-aliases-retry.golden.json +238 -0
  301. package/dist/src/services/test-data/resolved-aliases.golden.json +16 -0
  302. package/dist/src/telemetry/activity-detector.test.js.map +1 -1
  303. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +1 -0
  304. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +28 -5
  305. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  306. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +67 -1
  307. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -1
  308. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +1 -0
  309. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +3 -1
  310. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  311. package/dist/src/telemetry/config.js +2 -0
  312. package/dist/src/telemetry/config.js.map +1 -1
  313. package/dist/src/telemetry/config.test.js +25 -0
  314. package/dist/src/telemetry/config.test.js.map +1 -1
  315. package/dist/src/telemetry/gcp-exporters.d.ts +4 -3
  316. package/dist/src/telemetry/gcp-exporters.js +8 -4
  317. package/dist/src/telemetry/gcp-exporters.js.map +1 -1
  318. package/dist/src/telemetry/index.d.ts +2 -1
  319. package/dist/src/telemetry/index.js +2 -1
  320. package/dist/src/telemetry/index.js.map +1 -1
  321. package/dist/src/telemetry/loggers.d.ts +2 -1
  322. package/dist/src/telemetry/loggers.js +345 -338
  323. package/dist/src/telemetry/loggers.js.map +1 -1
  324. package/dist/src/telemetry/loggers.test.js +195 -18
  325. package/dist/src/telemetry/loggers.test.js.map +1 -1
  326. package/dist/src/telemetry/metrics.test.js.map +1 -1
  327. package/dist/src/telemetry/sdk.d.ts +9 -2
  328. package/dist/src/telemetry/sdk.js +143 -17
  329. package/dist/src/telemetry/sdk.js.map +1 -1
  330. package/dist/src/telemetry/sdk.test.js +130 -28
  331. package/dist/src/telemetry/sdk.test.js.map +1 -1
  332. package/dist/src/telemetry/startupProfiler.d.ts +51 -0
  333. package/dist/src/telemetry/startupProfiler.js +170 -0
  334. package/dist/src/telemetry/startupProfiler.js.map +1 -0
  335. package/dist/src/telemetry/startupProfiler.test.d.ts +6 -0
  336. package/dist/src/telemetry/startupProfiler.test.js +289 -0
  337. package/dist/src/telemetry/startupProfiler.test.js.map +1 -0
  338. package/dist/src/telemetry/telemetry.test.js +10 -3
  339. package/dist/src/telemetry/telemetry.test.js.map +1 -1
  340. package/dist/src/telemetry/trace.js +2 -2
  341. package/dist/src/telemetry/trace.js.map +1 -1
  342. package/dist/src/telemetry/types.d.ts +37 -10
  343. package/dist/src/telemetry/types.js +82 -17
  344. package/dist/src/telemetry/types.js.map +1 -1
  345. package/dist/src/telemetry/uiTelemetry.d.ts +1 -0
  346. package/dist/src/telemetry/uiTelemetry.js +2 -0
  347. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  348. package/dist/src/telemetry/uiTelemetry.test.js +4 -0
  349. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  350. package/dist/src/test-utils/mock-message-bus.js.map +1 -1
  351. package/dist/src/tools/confirmation-policy.test.d.ts +6 -0
  352. package/dist/src/tools/confirmation-policy.test.js +152 -0
  353. package/dist/src/tools/confirmation-policy.test.js.map +1 -0
  354. package/dist/src/tools/edit.js +5 -0
  355. package/dist/src/tools/edit.js.map +1 -1
  356. package/dist/src/tools/edit.test.js.map +1 -1
  357. package/dist/src/tools/grep.js.map +1 -1
  358. package/dist/src/tools/mcp-client-manager.d.ts +3 -1
  359. package/dist/src/tools/mcp-client-manager.js +30 -4
  360. package/dist/src/tools/mcp-client-manager.js.map +1 -1
  361. package/dist/src/tools/mcp-client-manager.test.js +38 -10
  362. package/dist/src/tools/mcp-client-manager.test.js.map +1 -1
  363. package/dist/src/tools/mcp-client.d.ts +40 -3
  364. package/dist/src/tools/mcp-client.js +437 -174
  365. package/dist/src/tools/mcp-client.js.map +1 -1
  366. package/dist/src/tools/mcp-client.test.js +695 -28
  367. package/dist/src/tools/mcp-client.test.js.map +1 -1
  368. package/dist/src/tools/mcp-tool.js +13 -0
  369. package/dist/src/tools/mcp-tool.js.map +1 -1
  370. package/dist/src/tools/mcp-tool.test.js +25 -0
  371. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  372. package/dist/src/tools/memoryTool.js +1 -0
  373. package/dist/src/tools/memoryTool.js.map +1 -1
  374. package/dist/src/tools/modifiable-tool.js.map +1 -1
  375. package/dist/src/tools/modifiable-tool.test.js +22 -13
  376. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  377. package/dist/src/tools/read-file.js +1 -1
  378. package/dist/src/tools/read-file.js.map +1 -1
  379. package/dist/src/tools/read-file.test.js.map +1 -1
  380. package/dist/src/tools/read-many-files.js +6 -4
  381. package/dist/src/tools/read-many-files.js.map +1 -1
  382. package/dist/src/tools/read-many-files.test.js +1 -1
  383. package/dist/src/tools/read-many-files.test.js.map +1 -1
  384. package/dist/src/tools/shell.d.ts +2 -1
  385. package/dist/src/tools/shell.js +58 -4
  386. package/dist/src/tools/shell.js.map +1 -1
  387. package/dist/src/tools/shell.test.js +25 -5
  388. package/dist/src/tools/shell.test.js.map +1 -1
  389. package/dist/src/tools/smart-edit.js +6 -1
  390. package/dist/src/tools/smart-edit.js.map +1 -1
  391. package/dist/src/tools/smart-edit.test.js.map +1 -1
  392. package/dist/src/tools/tool-names.d.ts +2 -0
  393. package/dist/src/tools/tool-names.js +2 -0
  394. package/dist/src/tools/tool-names.js.map +1 -1
  395. package/dist/src/tools/tools.d.ts +19 -0
  396. package/dist/src/tools/tools.js +29 -8
  397. package/dist/src/tools/tools.js.map +1 -1
  398. package/dist/src/tools/web-fetch.js +18 -5
  399. package/dist/src/tools/web-fetch.js.map +1 -1
  400. package/dist/src/tools/web-fetch.test.js +1 -0
  401. package/dist/src/tools/web-fetch.test.js.map +1 -1
  402. package/dist/src/tools/write-file.js +5 -0
  403. package/dist/src/tools/write-file.js.map +1 -1
  404. package/dist/src/tools/write-file.test.js.map +1 -1
  405. package/dist/src/utils/bfsFileSearch.d.ts +8 -0
  406. package/dist/src/utils/bfsFileSearch.js +63 -23
  407. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  408. package/dist/src/utils/bfsFileSearch.test.js +65 -1
  409. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  410. package/dist/src/utils/checkpointUtils.d.ts +82 -0
  411. package/dist/src/utils/checkpointUtils.js +117 -0
  412. package/dist/src/utils/checkpointUtils.js.map +1 -0
  413. package/dist/src/utils/checkpointUtils.test.d.ts +6 -0
  414. package/dist/src/utils/checkpointUtils.test.js +229 -0
  415. package/dist/src/utils/checkpointUtils.test.js.map +1 -0
  416. package/dist/src/utils/debugLogger.d.ts +3 -0
  417. package/dist/src/utils/debugLogger.js +27 -0
  418. package/dist/src/utils/debugLogger.js.map +1 -1
  419. package/dist/src/utils/editCorrector.test.js +4 -0
  420. package/dist/src/utils/editCorrector.test.js.map +1 -1
  421. package/dist/src/utils/editor.d.ts +9 -1
  422. package/dist/src/utils/editor.js +23 -14
  423. package/dist/src/utils/editor.js.map +1 -1
  424. package/dist/src/utils/errors.d.ts +8 -0
  425. package/dist/src/utils/errors.js +39 -2
  426. package/dist/src/utils/errors.js.map +1 -1
  427. package/dist/src/utils/errors.test.d.ts +6 -0
  428. package/dist/src/utils/errors.test.js +155 -0
  429. package/dist/src/utils/errors.test.js.map +1 -0
  430. package/dist/src/utils/exitCodes.d.ts +12 -0
  431. package/dist/src/utils/exitCodes.js +13 -0
  432. package/dist/src/utils/exitCodes.js.map +1 -0
  433. package/dist/src/utils/extensionLoader.d.ts +2 -2
  434. package/dist/src/utils/extensionLoader.js +5 -6
  435. package/dist/src/utils/extensionLoader.js.map +1 -1
  436. package/dist/src/utils/extensionLoader.test.js +11 -0
  437. package/dist/src/utils/extensionLoader.test.js.map +1 -1
  438. package/dist/src/utils/fetch.d.ts +1 -1
  439. package/dist/src/utils/fetch.js +3 -3
  440. package/dist/src/utils/fetch.js.map +1 -1
  441. package/dist/src/utils/fileUtils.test.js +15 -0
  442. package/dist/src/utils/fileUtils.test.js.map +1 -1
  443. package/dist/src/utils/filesearch/crawlCache.js.map +1 -1
  444. package/dist/src/utils/filesearch/fileSearch.js.map +1 -1
  445. package/dist/src/utils/flashFallback.test.js +1 -1
  446. package/dist/src/utils/flashFallback.test.js.map +1 -1
  447. package/dist/src/utils/googleErrors.js +31 -18
  448. package/dist/src/utils/googleErrors.js.map +1 -1
  449. package/dist/src/utils/googleErrors.test.js +10 -2
  450. package/dist/src/utils/googleErrors.test.js.map +1 -1
  451. package/dist/src/utils/googleQuotaErrors.d.ts +3 -3
  452. package/dist/src/utils/googleQuotaErrors.js +32 -6
  453. package/dist/src/utils/googleQuotaErrors.js.map +1 -1
  454. package/dist/src/utils/googleQuotaErrors.test.js +94 -2
  455. package/dist/src/utils/googleQuotaErrors.test.js.map +1 -1
  456. package/dist/src/utils/memoryDiscovery.d.ts +5 -0
  457. package/dist/src/utils/memoryDiscovery.js +7 -3
  458. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  459. package/dist/src/utils/memoryDiscovery.test.js +28 -0
  460. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  461. package/dist/src/utils/nextSpeakerChecker.test.js +4 -0
  462. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  463. package/dist/src/utils/pathCorrector.js +12 -2
  464. package/dist/src/utils/pathCorrector.js.map +1 -1
  465. package/dist/src/utils/pathCorrector.test.js +6 -2
  466. package/dist/src/utils/pathCorrector.test.js.map +1 -1
  467. package/dist/src/utils/retry.d.ts +11 -0
  468. package/dist/src/utils/retry.js +54 -13
  469. package/dist/src/utils/retry.js.map +1 -1
  470. package/dist/src/utils/retry.test.js +170 -10
  471. package/dist/src/utils/retry.test.js.map +1 -1
  472. package/dist/src/utils/shell-permissions.d.ts +52 -0
  473. package/dist/src/utils/shell-permissions.js +188 -0
  474. package/dist/src/utils/shell-permissions.js.map +1 -0
  475. package/dist/src/utils/shell-permissions.test.d.ts +6 -0
  476. package/dist/src/utils/shell-permissions.test.js +347 -0
  477. package/dist/src/utils/shell-permissions.test.js.map +1 -0
  478. package/dist/src/utils/shell-utils.d.ts +10 -47
  479. package/dist/src/utils/shell-utils.js +1 -182
  480. package/dist/src/utils/shell-utils.js.map +1 -1
  481. package/dist/src/utils/shell-utils.test.js +1 -288
  482. package/dist/src/utils/shell-utils.test.js.map +1 -1
  483. package/dist/src/utils/stdio.d.ts +2 -2
  484. package/dist/src/utils/stdio.js +2 -2
  485. package/dist/src/utils/stdio.js.map +1 -1
  486. package/dist/src/utils/stdio.test.js +5 -5
  487. package/dist/src/utils/stdio.test.js.map +1 -1
  488. package/dist/src/utils/terminalSerializer.test.js +17 -0
  489. package/dist/src/utils/terminalSerializer.test.js.map +1 -1
  490. package/dist/src/utils/tokenCalculation.d.ts +19 -0
  491. package/dist/src/utils/tokenCalculation.js +70 -0
  492. package/dist/src/utils/tokenCalculation.js.map +1 -0
  493. package/dist/src/utils/tokenCalculation.test.d.ts +6 -0
  494. package/dist/src/utils/tokenCalculation.test.js +78 -0
  495. package/dist/src/utils/tokenCalculation.test.js.map +1 -0
  496. package/dist/src/utils/tool-utils.js.map +1 -1
  497. package/dist/src/utils/version.d.ts +6 -0
  498. package/dist/src/utils/version.js +15 -0
  499. package/dist/src/utils/version.js.map +1 -0
  500. package/dist/src/utils/version.test.d.ts +6 -0
  501. package/dist/src/utils/version.test.js +39 -0
  502. package/dist/src/utils/version.test.js.map +1 -0
  503. package/dist/tsconfig.tsbuildinfo +1 -1
  504. package/package.json +1 -1
@@ -8,7 +8,7 @@ import { AjvJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/ajv
8
8
  import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
9
9
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
10
10
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
11
- import { ListRootsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
11
+ import { ListResourcesResultSchema, ListRootsRequestSchema, ReadResourceResultSchema, ResourceListChangedNotificationSchema, ToolListChangedNotificationSchema, } from '@modelcontextprotocol/sdk/types.js';
12
12
  import { parse } from 'shell-quote';
13
13
  import { AuthProviderType } from '../config/config.js';
14
14
  import { GoogleCredentialProvider } from '../mcp/google-auth-provider.js';
@@ -19,7 +19,7 @@ import { pathToFileURL } from 'node:url';
19
19
  import { MCPOAuthProvider } from '../mcp/oauth-provider.js';
20
20
  import { MCPOAuthTokenStorage } from '../mcp/oauth-token-storage.js';
21
21
  import { OAuthUtils } from '../mcp/oauth-utils.js';
22
- import { getErrorMessage } from '../utils/errors.js';
22
+ import { getErrorMessage, isAuthenticationError, UnauthorizedError, } from '../utils/errors.js';
23
23
  import { debugLogger } from '../utils/debugLogger.js';
24
24
  import { coreEvents } from '../utils/events.js';
25
25
  import { loadYamlConfig } from '@machina.ai/config-yaml';
@@ -95,18 +95,28 @@ export class McpClient {
95
95
  serverConfig;
96
96
  toolRegistry;
97
97
  promptRegistry;
98
+ resourceRegistry;
98
99
  workspaceContext;
100
+ cliConfig;
99
101
  debugMode;
102
+ onToolsUpdated;
100
103
  client;
101
104
  transport;
102
105
  status = MCPServerStatus.DISCONNECTED;
103
- constructor(serverName, serverConfig, toolRegistry, promptRegistry, workspaceContext, debugMode) {
106
+ isRefreshingTools = false;
107
+ pendingToolRefresh = false;
108
+ isRefreshingResources = false;
109
+ pendingResourceRefresh = false;
110
+ constructor(serverName, serverConfig, toolRegistry, promptRegistry, resourceRegistry, workspaceContext, cliConfig, debugMode, onToolsUpdated) {
104
111
  this.serverName = serverName;
105
112
  this.serverConfig = serverConfig;
106
113
  this.toolRegistry = toolRegistry;
107
114
  this.promptRegistry = promptRegistry;
115
+ this.resourceRegistry = resourceRegistry;
108
116
  this.workspaceContext = workspaceContext;
117
+ this.cliConfig = cliConfig;
109
118
  this.debugMode = debugMode;
119
+ this.onToolsUpdated = onToolsUpdated;
110
120
  }
111
121
  /**
112
122
  * Connects to the MCP server.
@@ -118,6 +128,7 @@ export class McpClient {
118
128
  this.updateStatus(MCPServerStatus.CONNECTING);
119
129
  try {
120
130
  this.client = await connectToMcpServer(this.serverName, this.serverConfig, this.debugMode, this.workspaceContext);
131
+ this.registerNotificationHandlers();
121
132
  const originalOnError = this.client.onerror;
122
133
  this.client.onerror = (error) => {
123
134
  if (this.status !== MCPServerStatus.CONNECTED) {
@@ -142,8 +153,10 @@ export class McpClient {
142
153
  this.assertConnected();
143
154
  const prompts = await this.discoverPrompts();
144
155
  const tools = await this.discoverTools(cliConfig);
145
- if (prompts.length === 0 && tools.length === 0) {
146
- throw new Error('No prompts or tools found on the server.');
156
+ const resources = await this.discoverResources();
157
+ this.updateResourceRegistry(resources);
158
+ if (prompts.length === 0 && tools.length === 0 && resources.length === 0) {
159
+ throw new Error('No prompts, tools, or resources found on the server.');
147
160
  }
148
161
  for (const tool of tools) {
149
162
  this.toolRegistry.registerTool(tool);
@@ -159,6 +172,7 @@ export class McpClient {
159
172
  }
160
173
  this.toolRegistry.removeMcpToolsByServer(this.serverName);
161
174
  this.promptRegistry.removePromptsByServer(this.serverName);
175
+ this.resourceRegistry.removeResourcesByServer(this.serverName);
162
176
  this.updateStatus(MCPServerStatus.DISCONNECTING);
163
177
  const client = this.client;
164
178
  this.client = undefined;
@@ -185,17 +199,157 @@ export class McpClient {
185
199
  throw new Error(`Client is not connected, must connect before interacting with the server. Current state is ${this.status}`);
186
200
  }
187
201
  }
188
- async discoverTools(cliConfig) {
202
+ async discoverTools(cliConfig, options) {
189
203
  this.assertConnected();
190
- return discoverTools(this.serverName, this.serverConfig, this.client, cliConfig, this.toolRegistry.getMessageBus());
204
+ return discoverTools(this.serverName, this.serverConfig, this.client, cliConfig, this.toolRegistry.getMessageBus(), options ?? {
205
+ timeout: this.serverConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
206
+ });
191
207
  }
192
208
  async discoverPrompts() {
193
209
  this.assertConnected();
194
210
  return discoverPrompts(this.serverName, this.client, this.promptRegistry);
195
211
  }
212
+ async discoverResources() {
213
+ this.assertConnected();
214
+ return discoverResources(this.serverName, this.client);
215
+ }
216
+ updateResourceRegistry(resources) {
217
+ this.resourceRegistry.setResourcesForServer(this.serverName, resources);
218
+ }
219
+ async readResource(uri) {
220
+ this.assertConnected();
221
+ return this.client.request({
222
+ method: 'resources/read',
223
+ params: { uri },
224
+ }, ReadResourceResultSchema);
225
+ }
226
+ /**
227
+ * Registers notification handlers for dynamic updates from the MCP server.
228
+ * This includes handlers for tool list changes and resource list changes.
229
+ */
230
+ registerNotificationHandlers() {
231
+ if (!this.client) {
232
+ return;
233
+ }
234
+ const capabilities = this.client.getServerCapabilities();
235
+ if (capabilities?.tools?.listChanged) {
236
+ debugLogger.log(`Server '${this.serverName}' supports tool updates. Listening for changes...`);
237
+ this.client.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
238
+ debugLogger.log(`🔔 Received tool update notification from '${this.serverName}'`);
239
+ await this.refreshTools();
240
+ });
241
+ }
242
+ if (capabilities?.resources?.listChanged) {
243
+ debugLogger.log(`Server '${this.serverName}' supports resource updates. Listening for changes...`);
244
+ this.client.setNotificationHandler(ResourceListChangedNotificationSchema, async () => {
245
+ debugLogger.log(`🔔 Received resource update notification from '${this.serverName}'`);
246
+ await this.refreshResources();
247
+ });
248
+ }
249
+ }
250
+ /**
251
+ * Refreshes the resources for this server by re-querying the MCP `resources/list` endpoint.
252
+ *
253
+ * This method implements a **Coalescing Pattern** to handle rapid bursts of notifications
254
+ * (e.g., during server startup or bulk updates) without overwhelming the server or
255
+ * creating race conditions in the ResourceRegistry.
256
+ */
257
+ async refreshResources() {
258
+ if (this.isRefreshingResources) {
259
+ debugLogger.log(`Resource refresh for '${this.serverName}' is already in progress. Pending update.`);
260
+ this.pendingResourceRefresh = true;
261
+ return;
262
+ }
263
+ this.isRefreshingResources = true;
264
+ try {
265
+ do {
266
+ this.pendingResourceRefresh = false;
267
+ if (this.status !== MCPServerStatus.CONNECTED || !this.client)
268
+ break;
269
+ const timeoutMs = this.serverConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC;
270
+ const abortController = new AbortController();
271
+ const timeoutId = setTimeout(() => abortController.abort(), timeoutMs);
272
+ let newResources;
273
+ try {
274
+ newResources = await this.discoverResources();
275
+ }
276
+ catch (err) {
277
+ debugLogger.error(`Resource discovery failed during refresh: ${getErrorMessage(err)}`);
278
+ clearTimeout(timeoutId);
279
+ break;
280
+ }
281
+ this.updateResourceRegistry(newResources);
282
+ clearTimeout(timeoutId);
283
+ coreEvents.emitFeedback('info', `Resources updated for server: ${this.serverName}`);
284
+ } while (this.pendingResourceRefresh);
285
+ }
286
+ catch (error) {
287
+ debugLogger.error(`Critical error in resource refresh loop for ${this.serverName}: ${getErrorMessage(error)}`);
288
+ }
289
+ finally {
290
+ this.isRefreshingResources = false;
291
+ this.pendingResourceRefresh = false;
292
+ }
293
+ }
196
294
  getServerConfig() {
197
295
  return this.serverConfig;
198
296
  }
297
+ getInstructions() {
298
+ return this.client?.getInstructions();
299
+ }
300
+ /**
301
+ * Refreshes the tools for this server by re-querying the MCP `tools/list` endpoint.
302
+ *
303
+ * This method implements a **Coalescing Pattern** to handle rapid bursts of notifications
304
+ * (e.g., during server startup or bulk updates) without overwhelming the server or
305
+ * creating race conditions in the global ToolRegistry.
306
+ */
307
+ async refreshTools() {
308
+ if (this.isRefreshingTools) {
309
+ debugLogger.log(`Tool refresh for '${this.serverName}' is already in progress. Pending update.`);
310
+ this.pendingToolRefresh = true;
311
+ return;
312
+ }
313
+ this.isRefreshingTools = true;
314
+ try {
315
+ do {
316
+ this.pendingToolRefresh = false;
317
+ if (this.status !== MCPServerStatus.CONNECTED || !this.client)
318
+ break;
319
+ const timeoutMs = this.serverConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC;
320
+ const abortController = new AbortController();
321
+ const timeoutId = setTimeout(() => abortController.abort(), timeoutMs);
322
+ let newTools;
323
+ try {
324
+ newTools = await this.discoverTools(this.cliConfig, {
325
+ signal: abortController.signal,
326
+ });
327
+ }
328
+ catch (err) {
329
+ debugLogger.error(`Discovery failed during refresh: ${getErrorMessage(err)}`);
330
+ clearTimeout(timeoutId);
331
+ break;
332
+ }
333
+ this.toolRegistry.removeMcpToolsByServer(this.serverName);
334
+ for (const tool of newTools) {
335
+ this.toolRegistry.registerTool(tool);
336
+ }
337
+ this.toolRegistry.sortTools();
338
+ if (this.onToolsUpdated) {
339
+ await this.onToolsUpdated(abortController.signal);
340
+ }
341
+ clearTimeout(timeoutId);
342
+ coreEvents.emitFeedback('info', `Tools updated for server: ${this.serverName}`);
343
+ } while (this.pendingToolRefresh);
344
+ }
345
+ catch (error) {
346
+ debugLogger.error(`Critical error in refresh loop for ${this.serverName}: ${getErrorMessage(error)}`);
347
+ }
348
+ finally {
349
+ this.isRefreshingTools = false;
350
+ this.pendingToolRefresh = false;
351
+ }
352
+ }
199
353
  }
200
354
  /**
201
355
  * Map to track the status of each MCP server within the core package
@@ -354,21 +508,6 @@ function createAuthProvider(mcpServerConfig) {
354
508
  }
355
509
  return undefined;
356
510
  }
357
- /**
358
- * Create a transport for URL based servers (remote servers).
359
- *
360
- * @param mcpServerConfig The MCP server configuration
361
- * @param transportOptions The transport options
362
- */
363
- function createUrlTransport(mcpServerConfig, transportOptions) {
364
- if (mcpServerConfig.httpUrl) {
365
- return new StreamableHTTPClientTransport(new URL(mcpServerConfig.httpUrl), transportOptions);
366
- }
367
- if (mcpServerConfig.url) {
368
- return new SSEClientTransport(new URL(mcpServerConfig.url), transportOptions);
369
- }
370
- throw new Error('No URL configured for MCP Server');
371
- }
372
511
  /**
373
512
  * Create a transport with OAuth token for the given server configuration.
374
513
  *
@@ -385,7 +524,7 @@ async function createTransportWithOAuth(mcpServerName, mcpServerConfig, accessTo
385
524
  const transportOptions = {
386
525
  requestInit: createTransportRequestInit(mcpServerConfig, headers),
387
526
  };
388
- return createUrlTransport(mcpServerConfig, transportOptions);
527
+ return createUrlTransport(mcpServerName, mcpServerConfig, transportOptions);
389
528
  }
390
529
  catch (error) {
391
530
  coreEvents.emitFeedback('error', `Failed to create OAuth transport for server '${mcpServerName}': ${getErrorMessage(error)}`, error);
@@ -477,7 +616,7 @@ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolReg
477
616
  };
478
617
  // Attempt to discover both prompts and tools
479
618
  const prompts = await discoverPrompts(mcpServerName, mcpClient, promptRegistry);
480
- const tools = await discoverTools(mcpServerName, mcpServerConfig, mcpClient, cliConfig, toolRegistry.getMessageBus());
619
+ const tools = await discoverTools(mcpServerName, mcpServerConfig, mcpClient, cliConfig, toolRegistry.getMessageBus(), { timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC });
481
620
  // If we have neither prompts nor tools, it's a failed discovery
482
621
  if (prompts.length === 0 && tools.length === 0) {
483
622
  throw new Error('No prompts or tools found on the server.');
@@ -492,6 +631,7 @@ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolReg
492
631
  }
493
632
  catch (error) {
494
633
  if (mcpClient) {
634
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
495
635
  mcpClient.close();
496
636
  }
497
637
  coreEvents.emitFeedback('error', `Error connecting to MCP server '${mcpServerName}': ${getErrorMessage(error)}`, error);
@@ -511,12 +651,12 @@ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolReg
511
651
  * @returns A promise that resolves to an array of discovered and enabled tools.
512
652
  * @throws An error if no enabled tools are found or if the server provides invalid function declarations.
513
653
  */
514
- export async function discoverTools(mcpServerName, mcpServerConfig, mcpClient, cliConfig, messageBus) {
654
+ export async function discoverTools(mcpServerName, mcpServerConfig, mcpClient, cliConfig, messageBus, options) {
515
655
  try {
516
656
  // Only request tools if the server supports them.
517
657
  if (mcpClient.getServerCapabilities()?.tools == null)
518
658
  return [];
519
- const response = await mcpClient.listTools({});
659
+ const response = await mcpClient.listTools({}, options);
520
660
  const discoveredTools = [];
521
661
  for (const toolDef of response.tools) {
522
662
  try {
@@ -631,6 +771,35 @@ export async function discoverPrompts(mcpServerName, mcpClient, promptRegistry)
631
771
  return [];
632
772
  }
633
773
  }
774
+ export async function discoverResources(mcpServerName, mcpClient) {
775
+ if (mcpClient.getServerCapabilities()?.resources == null) {
776
+ return [];
777
+ }
778
+ const resources = await listResources(mcpServerName, mcpClient);
779
+ return resources;
780
+ }
781
+ async function listResources(mcpServerName, mcpClient) {
782
+ const resources = [];
783
+ let cursor;
784
+ try {
785
+ do {
786
+ const response = await mcpClient.request({
787
+ method: 'resources/list',
788
+ params: cursor ? { cursor } : {},
789
+ }, ListResourcesResultSchema);
790
+ resources.push(...(response.resources ?? []));
791
+ cursor = response.nextCursor ?? undefined;
792
+ } while (cursor);
793
+ }
794
+ catch (error) {
795
+ if (error instanceof Error && error.message?.includes('Method not found')) {
796
+ return [];
797
+ }
798
+ coreEvents.emitFeedback('error', `Error discovering resources from ${mcpServerName}: ${getErrorMessage(error)}`, error);
799
+ throw error;
800
+ }
801
+ return resources;
802
+ }
634
803
  /**
635
804
  * Invokes a prompt on a connected MCP client.
636
805
  *
@@ -671,6 +840,116 @@ export async function invokeMcpPrompt(mcpServerName, mcpClient, promptName, prom
671
840
  export function hasNetworkTransport(config) {
672
841
  return !!(config.url || config.httpUrl);
673
842
  }
843
+ /**
844
+ * Helper function to retrieve a stored OAuth token for an MCP server.
845
+ * Handles token validation and refresh automatically.
846
+ *
847
+ * @param serverName The name of the MCP server
848
+ * @returns The valid access token, or null if no token is stored
849
+ */
850
+ async function getStoredOAuthToken(serverName) {
851
+ const tokenStorage = new MCPOAuthTokenStorage();
852
+ const credentials = await tokenStorage.getCredentials(serverName);
853
+ if (!credentials)
854
+ return null;
855
+ const authProvider = new MCPOAuthProvider(tokenStorage);
856
+ return authProvider.getValidToken(serverName, {
857
+ // Pass client ID if available
858
+ clientId: credentials.clientId,
859
+ });
860
+ }
861
+ /**
862
+ * Helper function to create an SSE transport with optional OAuth authentication.
863
+ *
864
+ * @param config The MCP server configuration
865
+ * @param accessToken Optional OAuth access token for authentication
866
+ * @returns A configured SSE transport ready for connection
867
+ */
868
+ function createSSETransportWithAuth(config, accessToken) {
869
+ const headers = {
870
+ ...config.headers,
871
+ ...(accessToken ? { Authorization: `Bearer ${accessToken}` } : {}),
872
+ };
873
+ const options = {};
874
+ if (Object.keys(headers).length > 0) {
875
+ options.requestInit = { headers };
876
+ }
877
+ return new SSEClientTransport(new URL(config.url), options);
878
+ }
879
+ /**
880
+ * Helper function to connect a client using SSE transport with optional OAuth.
881
+ *
882
+ * @param client The MCP client to connect
883
+ * @param config The MCP server configuration
884
+ * @param accessToken Optional OAuth access token for authentication
885
+ */
886
+ async function connectWithSSETransport(client, config, accessToken) {
887
+ const transport = createSSETransportWithAuth(config, accessToken);
888
+ await client.connect(transport, {
889
+ timeout: config.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
890
+ });
891
+ }
892
+ /**
893
+ * Helper function to show authentication required message and throw error.
894
+ * Checks if there's a stored token that was rejected (requires re-auth).
895
+ *
896
+ * @param serverName The name of the MCP server
897
+ * @throws Always throws an error with authentication instructions
898
+ */
899
+ async function showAuthRequiredMessage(serverName) {
900
+ const hasRejectedToken = !!(await getStoredOAuthToken(serverName));
901
+ const message = hasRejectedToken
902
+ ? `MCP server '${serverName}' rejected stored OAuth token. Please re-authenticate using: /mcp auth ${serverName}`
903
+ : `MCP server '${serverName}' requires authentication using: /mcp auth ${serverName}`;
904
+ coreEvents.emitFeedback('info', message);
905
+ throw new UnauthorizedError(message);
906
+ }
907
+ /**
908
+ * Helper function to retry connection with OAuth token after authentication.
909
+ * Handles both HTTP and SSE transports based on what previously failed.
910
+ *
911
+ * @param client The MCP client to connect
912
+ * @param serverName The name of the MCP server
913
+ * @param config The MCP server configuration
914
+ * @param accessToken The OAuth access token to use
915
+ * @param httpReturned404 Whether the HTTP transport returned 404 (indicating SSE-only server)
916
+ */
917
+ async function retryWithOAuth(client, serverName, config, accessToken, httpReturned404) {
918
+ if (httpReturned404) {
919
+ // HTTP returned 404, only try SSE
920
+ debugLogger.log(`Retrying SSE connection to '${serverName}' with OAuth token...`);
921
+ await connectWithSSETransport(client, config, accessToken);
922
+ debugLogger.log(`Successfully connected to '${serverName}' using SSE with OAuth.`);
923
+ return;
924
+ }
925
+ // HTTP returned 401, try HTTP with OAuth first
926
+ debugLogger.log(`Retrying connection to '${serverName}' with OAuth token...`);
927
+ const httpTransport = await createTransportWithOAuth(serverName, config, accessToken);
928
+ if (!httpTransport) {
929
+ throw new Error(`Failed to create OAuth transport for server '${serverName}'`);
930
+ }
931
+ try {
932
+ await client.connect(httpTransport, {
933
+ timeout: config.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
934
+ });
935
+ debugLogger.log(`Successfully connected to '${serverName}' using HTTP with OAuth.`);
936
+ }
937
+ catch (httpError) {
938
+ await httpTransport.close();
939
+ // If HTTP+OAuth returns 404 and auto-detection enabled, try SSE+OAuth
940
+ if (String(httpError).includes('404') &&
941
+ config.url &&
942
+ !config.type &&
943
+ !config.httpUrl) {
944
+ debugLogger.log(`HTTP with OAuth returned 404, trying SSE with OAuth...`);
945
+ await connectWithSSETransport(client, config, accessToken);
946
+ debugLogger.log(`Successfully connected to '${serverName}' using SSE with OAuth.`);
947
+ }
948
+ else {
949
+ throw httpError;
950
+ }
951
+ }
952
+ }
674
953
  /**
675
954
  * Creates and connects an MCP client to a server based on the provided configuration.
676
955
  * It determines the appropriate transport (Stdio, SSE, or Streamable HTTP) and
@@ -730,6 +1009,9 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
730
1009
  unlistenDirectories?.();
731
1010
  unlistenDirectories = undefined;
732
1011
  };
1012
+ let firstAttemptError = null;
1013
+ let httpReturned404 = false; // Track if HTTP returned 404 to skip it in OAuth retry
1014
+ let sseError = null; // Track SSE fallback error
733
1015
  try {
734
1016
  const transport = await createTransport(mcpServerName, mcpServerConfig, debugMode);
735
1017
  try {
@@ -740,52 +1022,92 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
740
1022
  }
741
1023
  catch (error) {
742
1024
  await transport.close();
1025
+ firstAttemptError = error;
743
1026
  throw error;
744
1027
  }
745
1028
  }
746
- catch (error) {
1029
+ catch (initialError) {
1030
+ let error = initialError;
1031
+ // Check if this is a 401 error FIRST (before attempting SSE fallback)
1032
+ // This ensures OAuth flow happens before we try SSE
1033
+ if (isAuthenticationError(error) && hasNetworkTransport(mcpServerConfig)) {
1034
+ // Continue to OAuth handling below (after SSE fallback section)
1035
+ }
1036
+ else if (
1037
+ // If not 401, and HTTP failed with url without explicit type, try SSE fallback
1038
+ firstAttemptError &&
1039
+ mcpServerConfig.url &&
1040
+ !mcpServerConfig.type &&
1041
+ !mcpServerConfig.httpUrl) {
1042
+ // Check if HTTP returned 404 - if so, we know it's not an HTTP server
1043
+ httpReturned404 = String(firstAttemptError).includes('404');
1044
+ const logMessage = httpReturned404
1045
+ ? `HTTP returned 404, trying SSE transport...`
1046
+ : `HTTP connection failed, attempting SSE fallback...`;
1047
+ debugLogger.log(`MCP server '${mcpServerName}': ${logMessage}`);
1048
+ try {
1049
+ // Try SSE with stored OAuth token if available
1050
+ // This ensures that SSE fallback works for authenticated servers
1051
+ await connectWithSSETransport(mcpClient, mcpServerConfig, await getStoredOAuthToken(mcpServerName));
1052
+ debugLogger.log(`MCP server '${mcpServerName}': Successfully connected using SSE transport.`);
1053
+ return mcpClient;
1054
+ }
1055
+ catch (sseFallbackError) {
1056
+ sseError = sseFallbackError;
1057
+ // If SSE also returned 401, handle OAuth below
1058
+ if (isAuthenticationError(sseError)) {
1059
+ debugLogger.log(`MCP server '${mcpServerName}': SSE returned 401, OAuth authentication required.`);
1060
+ // Update error to be the SSE error for OAuth handling
1061
+ error = sseError;
1062
+ // Continue to OAuth handling below
1063
+ }
1064
+ else {
1065
+ debugLogger.log(`MCP server '${mcpServerName}': SSE fallback also failed.`);
1066
+ // Both failed without 401, throw the original error
1067
+ throw firstAttemptError;
1068
+ }
1069
+ }
1070
+ }
747
1071
  // Check if this is a 401 error that might indicate OAuth is required
748
- const errorString = String(error);
749
- if (errorString.includes('401') && hasNetworkTransport(mcpServerConfig)) {
1072
+ if (isAuthenticationError(error) && hasNetworkTransport(mcpServerConfig)) {
750
1073
  mcpServerRequiresOAuth.set(mcpServerName, true);
751
- // Only trigger automatic OAuth discovery for HTTP servers or when OAuth is explicitly configured
752
- // For SSE servers, we should not trigger new OAuth flows automatically
753
- const shouldTriggerOAuth = mcpServerConfig.httpUrl || mcpServerConfig.oauth?.enabled;
1074
+ // Only trigger automatic OAuth if explicitly enabled in config
1075
+ // Otherwise, show error and tell user to run /mcp auth command
1076
+ const shouldTriggerOAuth = mcpServerConfig.oauth?.enabled;
754
1077
  if (!shouldTriggerOAuth) {
755
- // For SSE servers without explicit OAuth config, if a token was found but rejected, report it accurately.
756
- const tokenStorage = new MCPOAuthTokenStorage();
757
- const credentials = await tokenStorage.getCredentials(mcpServerName);
758
- if (credentials) {
759
- const authProvider = new MCPOAuthProvider(tokenStorage);
760
- const hasStoredTokens = await authProvider.getValidToken(mcpServerName, {
761
- // Pass client ID if available
762
- clientId: credentials.clientId,
763
- });
764
- if (hasStoredTokens) {
765
- coreEvents.emitFeedback('error', `Stored OAuth token for SSE server '${mcpServerName}' was rejected. ` +
766
- `Please re-authenticate using: /mcp auth ${mcpServerName}`);
767
- }
768
- else {
769
- coreEvents.emitFeedback('error', `401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
770
- `Please authenticate using: /mcp auth ${mcpServerName}`);
771
- }
772
- }
773
- throw new Error(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
774
- `Please authenticate using: /mcp auth ${mcpServerName}`);
1078
+ await showAuthRequiredMessage(mcpServerName);
775
1079
  }
776
1080
  // Try to extract www-authenticate header from the error
1081
+ const errorString = String(error);
777
1082
  let wwwAuthenticate = extractWWWAuthenticateHeader(errorString);
778
1083
  // If we didn't get the header from the error string, try to get it from the server
779
1084
  if (!wwwAuthenticate && hasNetworkTransport(mcpServerConfig)) {
780
1085
  debugLogger.log(`No www-authenticate header in error, trying to fetch it from server...`);
781
1086
  try {
782
1087
  const urlToFetch = mcpServerConfig.httpUrl || mcpServerConfig.url;
1088
+ // Determine correct Accept header based on what transport failed
1089
+ let acceptHeader;
1090
+ if (mcpServerConfig.httpUrl) {
1091
+ acceptHeader = 'application/json';
1092
+ }
1093
+ else if (mcpServerConfig.type === 'http') {
1094
+ acceptHeader = 'application/json';
1095
+ }
1096
+ else if (mcpServerConfig.type === 'sse') {
1097
+ acceptHeader = 'text/event-stream';
1098
+ }
1099
+ else if (httpReturned404) {
1100
+ // HTTP failed with 404, SSE returned 401 - use SSE header
1101
+ acceptHeader = 'text/event-stream';
1102
+ }
1103
+ else {
1104
+ // HTTP returned 401 - use HTTP header
1105
+ acceptHeader = 'application/json';
1106
+ }
783
1107
  const response = await fetch(urlToFetch, {
784
1108
  method: 'HEAD',
785
1109
  headers: {
786
- Accept: mcpServerConfig.httpUrl
787
- ? 'application/json'
788
- : 'text/event-stream',
1110
+ Accept: acceptHeader,
789
1111
  },
790
1112
  signal: AbortSignal.timeout(5000),
791
1113
  });
@@ -806,38 +1128,12 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
806
1128
  const oauthSuccess = await handleAutomaticOAuth(mcpServerName, mcpServerConfig, wwwAuthenticate);
807
1129
  if (oauthSuccess) {
808
1130
  // Retry connection with OAuth token
809
- debugLogger.log(`Retrying connection to '${mcpServerName}' with OAuth token...`);
810
- // Get the valid token - we need to create a proper OAuth config
811
- // The token should already be available from the authentication process
812
- const tokenStorage = new MCPOAuthTokenStorage();
813
- const credentials = await tokenStorage.getCredentials(mcpServerName);
814
- if (credentials) {
815
- const authProvider = new MCPOAuthProvider(tokenStorage);
816
- const accessToken = await authProvider.getValidToken(mcpServerName, {
817
- // Pass client ID if available
818
- clientId: credentials.clientId,
819
- });
820
- if (accessToken) {
821
- // Create transport with OAuth token
822
- const oauthTransport = await createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken);
823
- if (oauthTransport) {
824
- await mcpClient.connect(oauthTransport, {
825
- timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
826
- });
827
- // Connection successful with OAuth
828
- return mcpClient;
829
- }
830
- else {
831
- throw new Error(`Failed to create OAuth transport for server '${mcpServerName}'`);
832
- }
833
- }
834
- else {
835
- throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
836
- }
837
- }
838
- else {
839
- throw new Error(`Failed to get credentials for server '${mcpServerName}' after successful OAuth authentication`);
1131
+ const accessToken = await getStoredOAuthToken(mcpServerName);
1132
+ if (!accessToken) {
1133
+ throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
840
1134
  }
1135
+ await retryWithOAuth(mcpClient, mcpServerName, mcpServerConfig, accessToken, httpReturned404);
1136
+ return mcpClient;
841
1137
  }
842
1138
  else {
843
1139
  throw new Error(`Failed to handle automatic OAuth for server '${mcpServerName}'`);
@@ -845,29 +1141,10 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
845
1141
  }
846
1142
  else {
847
1143
  // No www-authenticate header found, but we got a 401
848
- // Only try OAuth discovery for HTTP servers or when OAuth is explicitly configured
849
- // For SSE servers, we should not trigger new OAuth flows automatically
850
- const shouldTryDiscovery = mcpServerConfig.httpUrl || mcpServerConfig.oauth?.enabled;
1144
+ // Only try OAuth discovery when OAuth is explicitly enabled in config
1145
+ const shouldTryDiscovery = mcpServerConfig.oauth?.enabled;
851
1146
  if (!shouldTryDiscovery) {
852
- const tokenStorage = new MCPOAuthTokenStorage();
853
- const credentials = await tokenStorage.getCredentials(mcpServerName);
854
- if (credentials) {
855
- const authProvider = new MCPOAuthProvider(tokenStorage);
856
- const hasStoredTokens = await authProvider.getValidToken(mcpServerName, {
857
- // Pass client ID if available
858
- clientId: credentials.clientId,
859
- });
860
- if (hasStoredTokens) {
861
- coreEvents.emitFeedback('error', `Stored OAuth token for SSE server '${mcpServerName}' was rejected. ` +
862
- `Please re-authenticate using: /mcp auth ${mcpServerName}`);
863
- }
864
- else {
865
- coreEvents.emitFeedback('error', `401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
866
- `Please authenticate using: /mcp auth ${mcpServerName}`);
867
- }
868
- }
869
- throw new Error(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
870
- `Please authenticate using: /mcp auth ${mcpServerName}`);
1147
+ await showAuthRequiredMessage(mcpServerName);
871
1148
  }
872
1149
  // For SSE/HTTP servers, try to discover OAuth configuration from the base URL
873
1150
  debugLogger.log(`🔍 Attempting OAuth discovery for '${mcpServerName}'...`);
@@ -892,35 +1169,20 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
892
1169
  const authProvider = new MCPOAuthProvider(new MCPOAuthTokenStorage());
893
1170
  await authProvider.authenticate(mcpServerName, oauthAuthConfig, authServerUrl);
894
1171
  // Retry connection with OAuth token
895
- const tokenStorage = new MCPOAuthTokenStorage();
896
- const credentials = await tokenStorage.getCredentials(mcpServerName);
897
- if (credentials) {
898
- const authProvider = new MCPOAuthProvider(tokenStorage);
899
- const accessToken = await authProvider.getValidToken(mcpServerName, {
900
- // Pass client ID if available
901
- clientId: credentials.clientId,
902
- });
903
- if (accessToken) {
904
- // Create transport with OAuth token
905
- const oauthTransport = await createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken);
906
- if (oauthTransport) {
907
- await mcpClient.connect(oauthTransport, {
908
- timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
909
- });
910
- // Connection successful with OAuth
911
- return mcpClient;
912
- }
913
- else {
914
- throw new Error(`Failed to create OAuth transport for server '${mcpServerName}'`);
915
- }
916
- }
917
- else {
918
- throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
919
- }
1172
+ const accessToken = await getStoredOAuthToken(mcpServerName);
1173
+ if (!accessToken) {
1174
+ throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
920
1175
  }
921
- else {
922
- throw new Error(`Failed to get stored credentials for server '${mcpServerName}'`);
1176
+ // Create transport with OAuth token
1177
+ const oauthTransport = await createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken);
1178
+ if (!oauthTransport) {
1179
+ throw new Error(`Failed to create OAuth transport for server '${mcpServerName}'`);
923
1180
  }
1181
+ await mcpClient.connect(oauthTransport, {
1182
+ timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
1183
+ });
1184
+ // Connection successful with OAuth
1185
+ return mcpClient;
924
1186
  }
925
1187
  else {
926
1188
  throw new Error(`OAuth configuration failed for '${mcpServerName}'. Please authenticate manually with /mcp auth ${mcpServerName}`);
@@ -933,24 +1195,39 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
933
1195
  }
934
1196
  else {
935
1197
  // Handle other connection errors
936
- // Create a concise error message
937
- const errorMessage = error.message || String(error);
938
- const isNetworkError = errorMessage.includes('ENOTFOUND') ||
939
- errorMessage.includes('ECONNREFUSED');
940
- let conciseError;
941
- if (isNetworkError) {
942
- conciseError = `Cannot connect to '${mcpServerName}' - server may be down or URL incorrect`;
943
- }
944
- else {
945
- conciseError = `Connection failed for '${mcpServerName}': ${errorMessage}`;
946
- }
947
- if (process.env['SANDBOX']) {
948
- conciseError += ` (check sandbox availability)`;
949
- }
950
- throw new Error(conciseError);
1198
+ // Re-throw the original error to preserve its structure
1199
+ throw error;
951
1200
  }
952
1201
  }
953
1202
  }
1203
+ /**
1204
+ * Helper function to create the appropriate transport based on config
1205
+ * This handles the logic for httpUrl/url/type consistently
1206
+ */
1207
+ function createUrlTransport(mcpServerName, mcpServerConfig, transportOptions) {
1208
+ // Priority 1: httpUrl (deprecated)
1209
+ if (mcpServerConfig.httpUrl) {
1210
+ if (mcpServerConfig.url) {
1211
+ debugLogger.warn(`MCP server '${mcpServerName}': Both 'httpUrl' and 'url' are configured. ` +
1212
+ `Using deprecated 'httpUrl'. Please migrate to 'url' with 'type: "http"'.`);
1213
+ }
1214
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.httpUrl), transportOptions);
1215
+ }
1216
+ // Priority 2 & 3: url with explicit type
1217
+ if (mcpServerConfig.url && mcpServerConfig.type) {
1218
+ if (mcpServerConfig.type === 'http') {
1219
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.url), transportOptions);
1220
+ }
1221
+ else if (mcpServerConfig.type === 'sse') {
1222
+ return new SSEClientTransport(new URL(mcpServerConfig.url), transportOptions);
1223
+ }
1224
+ }
1225
+ // Priority 4: url without type (default to HTTP)
1226
+ if (mcpServerConfig.url) {
1227
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.url), transportOptions);
1228
+ }
1229
+ throw new Error(`No URL configured for MCP server '${mcpServerName}'`);
1230
+ }
954
1231
  /** Visible for Testing */
955
1232
  export async function createTransport(mcpServerName, mcpServerConfig, debugMode) {
956
1233
  const noUrl = !mcpServerConfig.url && !mcpServerConfig.httpUrl;
@@ -965,37 +1242,28 @@ export async function createTransport(mcpServerName, mcpServerConfig, debugMode)
965
1242
  }
966
1243
  if (mcpServerConfig.httpUrl || mcpServerConfig.url) {
967
1244
  const authProvider = createAuthProvider(mcpServerConfig);
968
- const headers = {};
1245
+ const headers = (await authProvider?.getRequestHeaders?.()) ?? {};
969
1246
  let accessToken = null;
970
- let hasOAuthConfig = mcpServerConfig.oauth?.enabled;
1247
+ const hasOAuthConfig = mcpServerConfig.oauth?.enabled;
971
1248
  if (authProvider === undefined) {
972
1249
  // Check if we have OAuth configuration or stored tokens
973
- if (hasOAuthConfig && mcpServerConfig.oauth) {
1250
+ if (mcpServerConfig.oauth?.enabled && mcpServerConfig.oauth) {
974
1251
  const tokenStorage = new MCPOAuthTokenStorage();
975
1252
  const mcpAuthProvider = new MCPOAuthProvider(tokenStorage);
976
1253
  accessToken = await mcpAuthProvider.getValidToken(mcpServerName, mcpServerConfig.oauth);
977
1254
  if (!accessToken) {
978
- throw new Error(`MCP server '${mcpServerName}' requires OAuth authentication. ` +
979
- `Please authenticate using the /mcp auth command.`);
1255
+ // Emit info message (not error) since this is expected behavior
1256
+ coreEvents.emitFeedback('info', `MCP server '${mcpServerName}' requires authentication using: /mcp auth ${mcpServerName}`);
980
1257
  }
981
1258
  }
982
1259
  else {
983
1260
  // Check if we have stored OAuth tokens for this server (from previous authentication)
984
- const tokenStorage = new MCPOAuthTokenStorage();
985
- const credentials = await tokenStorage.getCredentials(mcpServerName);
986
- if (credentials) {
987
- const mcpAuthProvider = new MCPOAuthProvider(tokenStorage);
988
- accessToken = await mcpAuthProvider.getValidToken(mcpServerName, {
989
- // Pass client ID if available
990
- clientId: credentials.clientId,
991
- });
992
- if (accessToken) {
993
- hasOAuthConfig = true;
994
- debugLogger.log(`Found stored OAuth token for server '${mcpServerName}'`);
995
- }
1261
+ accessToken = await getStoredOAuthToken(mcpServerName);
1262
+ if (accessToken) {
1263
+ debugLogger.log(`Found stored OAuth token for server '${mcpServerName}'`);
996
1264
  }
997
1265
  }
998
- if (hasOAuthConfig && accessToken) {
1266
+ if (accessToken) {
999
1267
  headers['Authorization'] = `Bearer ${accessToken}`;
1000
1268
  }
1001
1269
  }
@@ -1012,13 +1280,8 @@ export async function createTransport(mcpServerName, mcpServerConfig, debugMode)
1012
1280
  },
1013
1281
  };
1014
1282
  }
1015
- else if (mcpServerConfig.headers) {
1016
- transportOptions.requestInit = {
1017
- headers: mcpServerConfig.headers,
1018
- };
1019
- }
1020
1283
  await applyAgentAuthHeaderIfNeeded(mcpServerConfig, transportOptions);
1021
- return createUrlTransport(mcpServerConfig, transportOptions);
1284
+ return createUrlTransport(mcpServerName, mcpServerConfig, transportOptions);
1022
1285
  }
1023
1286
  if (mcpServerConfig.command) {
1024
1287
  const transport = new StdioClientTransport({