@machina.ai/cell-cli-core 1.0.17-rc1 → 1.0.21-rc2

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 (399) hide show
  1. package/dist/index.d.ts +3 -0
  2. package/dist/index.js +3 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/package.json +9 -2
  5. package/dist/src/code_assist/converter.d.ts +4 -2
  6. package/dist/src/code_assist/converter.js +2 -1
  7. package/dist/src/code_assist/converter.js.map +1 -1
  8. package/dist/src/code_assist/converter.test.js +48 -1
  9. package/dist/src/code_assist/converter.test.js.map +1 -1
  10. package/dist/src/code_assist/oauth2.d.ts +1 -0
  11. package/dist/src/code_assist/oauth2.js +38 -21
  12. package/dist/src/code_assist/oauth2.js.map +1 -1
  13. package/dist/src/code_assist/oauth2.test.js +51 -8
  14. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  15. package/dist/src/code_assist/server.js +1 -1
  16. package/dist/src/code_assist/server.js.map +1 -1
  17. package/dist/src/code_assist/server.test.js +4 -1
  18. package/dist/src/code_assist/server.test.js.map +1 -1
  19. package/dist/src/code_assist/setup.js +48 -17
  20. package/dist/src/code_assist/setup.js.map +1 -1
  21. package/dist/src/code_assist/setup.test.js +114 -8
  22. package/dist/src/code_assist/setup.test.js.map +1 -1
  23. package/dist/src/config/config.d.ts +41 -11
  24. package/dist/src/config/config.js +85 -27
  25. package/dist/src/config/config.js.map +1 -1
  26. package/dist/src/config/config.test.js +117 -3
  27. package/dist/src/config/config.test.js.map +1 -1
  28. package/dist/src/config/flashFallback.test.js +0 -4
  29. package/dist/src/config/flashFallback.test.js.map +1 -1
  30. package/dist/src/core/client.d.ts +12 -16
  31. package/dist/src/core/client.js +218 -135
  32. package/dist/src/core/client.js.map +1 -1
  33. package/dist/src/core/client.test.js +636 -37
  34. package/dist/src/core/client.test.js.map +1 -1
  35. package/dist/src/core/contentGenerator.js +23 -21
  36. package/dist/src/core/contentGenerator.js.map +1 -1
  37. package/dist/src/core/contentGenerator.test.js +30 -126
  38. package/dist/src/core/contentGenerator.test.js.map +1 -1
  39. package/dist/src/core/coreToolScheduler.d.ts +23 -8
  40. package/dist/src/core/coreToolScheduler.js +179 -64
  41. package/dist/src/core/coreToolScheduler.js.map +1 -1
  42. package/dist/src/core/coreToolScheduler.test.js +250 -97
  43. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  44. package/dist/src/core/geminiChat.d.ts +7 -6
  45. package/dist/src/core/geminiChat.js +43 -43
  46. package/dist/src/core/geminiChat.js.map +1 -1
  47. package/dist/src/core/logger.d.ts +23 -1
  48. package/dist/src/core/logger.js +115 -11
  49. package/dist/src/core/logger.js.map +1 -1
  50. package/dist/src/core/logger.test.js +112 -17
  51. package/dist/src/core/logger.test.js.map +1 -1
  52. package/dist/src/core/loggingContentGenerator.d.ts +25 -0
  53. package/dist/src/core/loggingContentGenerator.js +95 -0
  54. package/dist/src/core/loggingContentGenerator.js.map +1 -0
  55. package/dist/src/core/nonInteractiveToolExecutor.js +28 -1
  56. package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
  57. package/dist/src/core/nonInteractiveToolExecutor.test.js +85 -62
  58. package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
  59. package/dist/src/core/prompts.js +4 -4
  60. package/dist/src/core/prompts.js.map +1 -1
  61. package/dist/src/core/subagent.d.ts +230 -0
  62. package/dist/src/core/subagent.js +447 -0
  63. package/dist/src/core/subagent.js.map +1 -0
  64. package/dist/src/core/subagent.test.d.ts +6 -0
  65. package/dist/src/core/subagent.test.js +515 -0
  66. package/dist/src/core/subagent.test.js.map +1 -0
  67. package/dist/src/core/turn.js +1 -0
  68. package/dist/src/core/turn.js.map +1 -1
  69. package/dist/src/core/turn.test.js +4 -0
  70. package/dist/src/core/turn.test.js.map +1 -1
  71. package/dist/src/generated/git-commit.d.ts +7 -0
  72. package/dist/src/generated/git-commit.js +10 -0
  73. package/dist/src/generated/git-commit.js.map +1 -0
  74. package/dist/src/ide/constants.d.ts +6 -0
  75. package/dist/src/ide/constants.js +7 -0
  76. package/dist/src/ide/constants.js.map +1 -0
  77. package/dist/src/ide/detect-ide.d.ts +12 -2
  78. package/dist/src/ide/detect-ide.js +64 -5
  79. package/dist/src/ide/detect-ide.js.map +1 -1
  80. package/dist/src/ide/detect-ide.test.d.ts +6 -0
  81. package/dist/src/ide/detect-ide.test.js +65 -0
  82. package/dist/src/ide/detect-ide.test.js.map +1 -0
  83. package/dist/src/ide/ide-client.d.ts +34 -11
  84. package/dist/src/ide/ide-client.js +230 -62
  85. package/dist/src/ide/ide-client.js.map +1 -1
  86. package/dist/src/ide/ide-client.test.d.ts +6 -0
  87. package/dist/src/ide/ide-client.test.js +43 -0
  88. package/dist/src/ide/ide-client.test.js.map +1 -0
  89. package/dist/src/ide/ide-installer.js +23 -34
  90. package/dist/src/ide/ide-installer.js.map +1 -1
  91. package/dist/src/ide/ide-installer.test.js +6 -8
  92. package/dist/src/ide/ide-installer.test.js.map +1 -1
  93. package/dist/src/ide/ideContext.d.ts +97 -2
  94. package/dist/src/ide/ideContext.js +45 -0
  95. package/dist/src/ide/ideContext.js.map +1 -1
  96. package/dist/src/ide/process-utils.d.ts +14 -0
  97. package/dist/src/ide/process-utils.js +57 -0
  98. package/dist/src/ide/process-utils.js.map +1 -0
  99. package/dist/src/index.d.ts +7 -1
  100. package/dist/src/index.js +7 -1
  101. package/dist/src/index.js.map +1 -1
  102. package/dist/src/mcp/google-auth-provider.js +9 -0
  103. package/dist/src/mcp/google-auth-provider.js.map +1 -1
  104. package/dist/src/mcp/google-auth-provider.test.js +45 -10
  105. package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
  106. package/dist/src/mcp/oauth-provider.d.ts +1 -1
  107. package/dist/src/mcp/oauth-provider.js +185 -59
  108. package/dist/src/mcp/oauth-provider.js.map +1 -1
  109. package/dist/src/mcp/oauth-provider.test.js +134 -62
  110. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  111. package/dist/src/mcp/oauth-utils.d.ts +3 -1
  112. package/dist/src/mcp/oauth-utils.js +50 -12
  113. package/dist/src/mcp/oauth-utils.js.map +1 -1
  114. package/dist/src/mcp/oauth-utils.test.js +17 -2
  115. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  116. package/dist/src/mocks/msw.d.ts +6 -0
  117. package/dist/src/mocks/msw.js +8 -0
  118. package/dist/src/mocks/msw.js.map +1 -0
  119. package/dist/src/prompts/prompt-registry.d.ts +8 -0
  120. package/dist/src/prompts/prompt-registry.js +16 -0
  121. package/dist/src/prompts/prompt-registry.js.map +1 -1
  122. package/dist/src/services/chatRecordingService.d.ts +150 -0
  123. package/dist/src/services/chatRecordingService.js +318 -0
  124. package/dist/src/services/chatRecordingService.js.map +1 -0
  125. package/dist/src/services/chatRecordingService.test.d.ts +6 -0
  126. package/dist/src/services/chatRecordingService.test.js +288 -0
  127. package/dist/src/services/chatRecordingService.test.js.map +1 -0
  128. package/dist/src/services/fileSystemService.d.ts +31 -0
  129. package/dist/src/services/fileSystemService.js +18 -0
  130. package/dist/src/services/fileSystemService.js.map +1 -0
  131. package/dist/src/services/fileSystemService.test.d.ts +6 -0
  132. package/dist/src/services/fileSystemService.test.js +41 -0
  133. package/dist/src/services/fileSystemService.test.js.map +1 -0
  134. package/dist/src/services/loopDetectionService.js +19 -16
  135. package/dist/src/services/loopDetectionService.js.map +1 -1
  136. package/dist/src/services/loopDetectionService.test.js +191 -0
  137. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  138. package/dist/src/services/shellExecutionService.js +29 -9
  139. package/dist/src/services/shellExecutionService.js.map +1 -1
  140. package/dist/src/services/shellExecutionService.test.js +21 -3
  141. package/dist/src/services/shellExecutionService.test.js.map +1 -1
  142. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +78 -9
  143. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +316 -205
  144. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  145. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +17 -0
  146. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +342 -0
  147. package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -0
  148. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +14 -2
  149. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +32 -9
  150. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  151. package/dist/src/telemetry/constants.d.ts +2 -0
  152. package/dist/src/telemetry/constants.js +2 -0
  153. package/dist/src/telemetry/constants.js.map +1 -1
  154. package/dist/src/telemetry/index.d.ts +2 -2
  155. package/dist/src/telemetry/index.js +2 -2
  156. package/dist/src/telemetry/index.js.map +1 -1
  157. package/dist/src/telemetry/integration.test.circular.js +1 -0
  158. package/dist/src/telemetry/integration.test.circular.js.map +1 -1
  159. package/dist/src/telemetry/loggers.d.ts +4 -1
  160. package/dist/src/telemetry/loggers.js +55 -6
  161. package/dist/src/telemetry/loggers.js.map +1 -1
  162. package/dist/src/telemetry/loggers.test.circular.js +7 -2
  163. package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
  164. package/dist/src/telemetry/loggers.test.js +43 -8
  165. package/dist/src/telemetry/loggers.test.js.map +1 -1
  166. package/dist/src/telemetry/metrics.d.ts +7 -2
  167. package/dist/src/telemetry/metrics.js +26 -6
  168. package/dist/src/telemetry/metrics.js.map +1 -1
  169. package/dist/src/telemetry/metrics.test.js +81 -1
  170. package/dist/src/telemetry/metrics.test.js.map +1 -1
  171. package/dist/src/telemetry/sdk.d.ts +1 -1
  172. package/dist/src/telemetry/sdk.js +77 -41
  173. package/dist/src/telemetry/sdk.js.map +1 -1
  174. package/dist/src/telemetry/sdk.test.d.ts +6 -0
  175. package/dist/src/telemetry/sdk.test.js +82 -0
  176. package/dist/src/telemetry/sdk.test.js.map +1 -0
  177. package/dist/src/telemetry/telemetry.test.js +2 -4
  178. package/dist/src/telemetry/telemetry.test.js.map +1 -1
  179. package/dist/src/telemetry/tool-call-decision.d.ts +13 -0
  180. package/dist/src/telemetry/tool-call-decision.js +29 -0
  181. package/dist/src/telemetry/tool-call-decision.js.map +1 -0
  182. package/dist/src/telemetry/types.d.ts +55 -21
  183. package/dist/src/telemetry/types.js +83 -43
  184. package/dist/src/telemetry/types.js.map +1 -1
  185. package/dist/src/telemetry/uiTelemetry.d.ts +8 -1
  186. package/dist/src/telemetry/uiTelemetry.js +17 -2
  187. package/dist/src/telemetry/uiTelemetry.js.map +1 -1
  188. package/dist/src/telemetry/uiTelemetry.test.js +57 -10
  189. package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
  190. package/dist/src/test-utils/config.d.ts +16 -0
  191. package/dist/src/test-utils/config.js +32 -0
  192. package/dist/src/test-utils/config.js.map +1 -0
  193. package/dist/src/test-utils/tools.d.ts +44 -0
  194. package/dist/src/test-utils/tools.js +105 -0
  195. package/dist/src/test-utils/tools.js.map +1 -0
  196. package/dist/src/tools/diffOptions.d.ts +2 -0
  197. package/dist/src/tools/diffOptions.js +28 -0
  198. package/dist/src/tools/diffOptions.js.map +1 -1
  199. package/dist/src/tools/diffOptions.test.d.ts +6 -0
  200. package/dist/src/tools/diffOptions.test.js +119 -0
  201. package/dist/src/tools/diffOptions.test.js.map +1 -0
  202. package/dist/src/tools/edit.d.ts +10 -34
  203. package/dist/src/tools/edit.js +152 -136
  204. package/dist/src/tools/edit.js.map +1 -1
  205. package/dist/src/tools/edit.test.js +125 -51
  206. package/dist/src/tools/edit.test.js.map +1 -1
  207. package/dist/src/tools/glob.d.ts +4 -11
  208. package/dist/src/tools/glob.js +87 -91
  209. package/dist/src/tools/glob.js.map +1 -1
  210. package/dist/src/tools/glob.test.js +42 -12
  211. package/dist/src/tools/glob.test.js.map +1 -1
  212. package/dist/src/tools/grep.d.ts +4 -36
  213. package/dist/src/tools/grep.js +107 -84
  214. package/dist/src/tools/grep.js.map +1 -1
  215. package/dist/src/tools/grep.test.js +40 -23
  216. package/dist/src/tools/grep.test.js.map +1 -1
  217. package/dist/src/tools/ls.d.ts +4 -23
  218. package/dist/src/tools/ls.js +77 -79
  219. package/dist/src/tools/ls.js.map +1 -1
  220. package/dist/src/tools/ls.test.js +62 -34
  221. package/dist/src/tools/ls.test.js.map +1 -1
  222. package/dist/src/tools/mcp-client-manager.d.ts +38 -0
  223. package/dist/src/tools/mcp-client-manager.js +74 -0
  224. package/dist/src/tools/mcp-client-manager.js.map +1 -0
  225. package/dist/src/tools/mcp-client-manager.test.d.ts +6 -0
  226. package/dist/src/tools/mcp-client-manager.test.js +39 -0
  227. package/dist/src/tools/mcp-client-manager.test.js.map +1 -0
  228. package/dist/src/tools/mcp-client.d.ts +57 -3
  229. package/dist/src/tools/mcp-client.js +235 -10
  230. package/dist/src/tools/mcp-client.js.map +1 -1
  231. package/dist/src/tools/mcp-client.test.js +234 -87
  232. package/dist/src/tools/mcp-client.test.js.map +1 -1
  233. package/dist/src/tools/mcp-tool.d.ts +6 -13
  234. package/dist/src/tools/mcp-tool.js +62 -34
  235. package/dist/src/tools/mcp-tool.js.map +1 -1
  236. package/dist/src/tools/mcp-tool.test.js +118 -59
  237. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  238. package/dist/src/tools/memoryTool.d.ts +10 -14
  239. package/dist/src/tools/memoryTool.js +123 -121
  240. package/dist/src/tools/memoryTool.js.map +1 -1
  241. package/dist/src/tools/memoryTool.test.js +38 -18
  242. package/dist/src/tools/memoryTool.test.js.map +1 -1
  243. package/dist/src/tools/modifiable-tool.d.ts +9 -6
  244. package/dist/src/tools/modifiable-tool.js +6 -3
  245. package/dist/src/tools/modifiable-tool.js.map +1 -1
  246. package/dist/src/tools/modifiable-tool.test.js +12 -12
  247. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  248. package/dist/src/tools/read-file.d.ts +4 -6
  249. package/dist/src/tools/read-file.js +95 -50
  250. package/dist/src/tools/read-file.js.map +1 -1
  251. package/dist/src/tools/read-file.test.js +199 -129
  252. package/dist/src/tools/read-file.test.js.map +1 -1
  253. package/dist/src/tools/read-many-files.d.ts +3 -5
  254. package/dist/src/tools/read-many-files.js +204 -138
  255. package/dist/src/tools/read-many-files.js.map +1 -1
  256. package/dist/src/tools/read-many-files.test.js +197 -33
  257. package/dist/src/tools/read-many-files.test.js.map +1 -1
  258. package/dist/src/tools/shell.d.ts +4 -6
  259. package/dist/src/tools/shell.js +112 -102
  260. package/dist/src/tools/shell.js.map +1 -1
  261. package/dist/src/tools/shell.test.js +55 -28
  262. package/dist/src/tools/shell.test.js.map +1 -1
  263. package/dist/src/tools/tool-error.d.ts +5 -0
  264. package/dist/src/tools/tool-error.js +5 -0
  265. package/dist/src/tools/tool-error.js.map +1 -1
  266. package/dist/src/tools/tool-registry.d.ts +25 -22
  267. package/dist/src/tools/tool-registry.js +100 -116
  268. package/dist/src/tools/tool-registry.js.map +1 -1
  269. package/dist/src/tools/tool-registry.test.js +29 -212
  270. package/dist/src/tools/tool-registry.test.js.map +1 -1
  271. package/dist/src/tools/tools.d.ts +137 -92
  272. package/dist/src/tools/tools.js +188 -61
  273. package/dist/src/tools/tools.js.map +1 -1
  274. package/dist/src/tools/tools.test.d.ts +6 -0
  275. package/dist/src/tools/tools.test.js +206 -0
  276. package/dist/src/tools/tools.test.js.map +1 -0
  277. package/dist/src/tools/web-fetch.d.ts +4 -7
  278. package/dist/src/tools/web-fetch.js +58 -64
  279. package/dist/src/tools/web-fetch.js.map +1 -1
  280. package/dist/src/tools/web-fetch.test.js +8 -4
  281. package/dist/src/tools/web-fetch.test.js.map +1 -1
  282. package/dist/src/tools/web-search.d.ts +4 -5
  283. package/dist/src/tools/web-search.js +47 -51
  284. package/dist/src/tools/web-search.js.map +1 -1
  285. package/dist/src/tools/web-search.test.d.ts +6 -0
  286. package/dist/src/tools/web-search.test.js +139 -0
  287. package/dist/src/tools/web-search.test.js.map +1 -0
  288. package/dist/src/tools/write-file.d.ts +20 -11
  289. package/dist/src/tools/write-file.js +197 -142
  290. package/dist/src/tools/write-file.js.map +1 -1
  291. package/dist/src/tools/write-file.test.js +156 -96
  292. package/dist/src/tools/write-file.test.js.map +1 -1
  293. package/dist/src/utils/bfsFileSearch.test.js +28 -56
  294. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  295. package/dist/src/utils/browser.js +4 -3
  296. package/dist/src/utils/browser.js.map +1 -1
  297. package/dist/src/utils/editCorrector.js +21 -22
  298. package/dist/src/utils/editCorrector.js.map +1 -1
  299. package/dist/src/utils/editor.d.ts +1 -1
  300. package/dist/src/utils/editor.js +14 -6
  301. package/dist/src/utils/editor.js.map +1 -1
  302. package/dist/src/utils/editor.test.js +48 -16
  303. package/dist/src/utils/editor.test.js.map +1 -1
  304. package/dist/src/utils/environmentContext.d.ts +21 -0
  305. package/dist/src/utils/environmentContext.js +90 -0
  306. package/dist/src/utils/environmentContext.js.map +1 -0
  307. package/dist/src/utils/environmentContext.test.d.ts +6 -0
  308. package/dist/src/utils/environmentContext.test.js +140 -0
  309. package/dist/src/utils/environmentContext.test.js.map +1 -0
  310. package/dist/src/utils/errorParsing.d.ts +8 -0
  311. package/dist/src/utils/errorParsing.js +93 -0
  312. package/dist/src/utils/errorParsing.js.map +1 -0
  313. package/dist/src/utils/errorParsing.test.d.ts +6 -0
  314. package/dist/src/utils/errorParsing.test.js +172 -0
  315. package/dist/src/utils/errorParsing.test.js.map +1 -0
  316. package/dist/src/utils/fileUtils.d.ts +9 -1
  317. package/dist/src/utils/fileUtils.js +18 -15
  318. package/dist/src/utils/fileUtils.js.map +1 -1
  319. package/dist/src/utils/fileUtils.test.js +24 -22
  320. package/dist/src/utils/fileUtils.test.js.map +1 -1
  321. package/dist/src/utils/filesearch/crawlCache.d.ts +25 -0
  322. package/dist/src/utils/filesearch/crawlCache.js +57 -0
  323. package/dist/src/utils/filesearch/crawlCache.js.map +1 -0
  324. package/dist/src/utils/filesearch/crawlCache.test.d.ts +6 -0
  325. package/dist/src/utils/filesearch/crawlCache.test.js +103 -0
  326. package/dist/src/utils/filesearch/crawlCache.test.js.map +1 -0
  327. package/dist/src/utils/filesearch/crawler.d.ts +15 -0
  328. package/dist/src/utils/filesearch/crawler.js +50 -0
  329. package/dist/src/utils/filesearch/crawler.js.map +1 -0
  330. package/dist/src/utils/filesearch/crawler.test.d.ts +6 -0
  331. package/dist/src/utils/filesearch/crawler.test.js +468 -0
  332. package/dist/src/utils/filesearch/crawler.test.js.map +1 -0
  333. package/dist/src/utils/filesearch/fileSearch.d.ts +37 -0
  334. package/dist/src/utils/filesearch/fileSearch.js +186 -0
  335. package/dist/src/utils/filesearch/fileSearch.js.map +1 -0
  336. package/dist/src/utils/filesearch/fileSearch.test.d.ts +6 -0
  337. package/dist/src/utils/filesearch/fileSearch.test.js +552 -0
  338. package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -0
  339. package/dist/src/utils/filesearch/ignore.d.ts +42 -0
  340. package/dist/src/utils/filesearch/ignore.js +106 -0
  341. package/dist/src/utils/filesearch/ignore.js.map +1 -0
  342. package/dist/src/utils/filesearch/ignore.test.d.ts +6 -0
  343. package/dist/src/utils/filesearch/ignore.test.js +144 -0
  344. package/dist/src/utils/filesearch/ignore.test.js.map +1 -0
  345. package/dist/src/utils/filesearch/result-cache.d.ts +33 -0
  346. package/dist/src/utils/filesearch/result-cache.js +59 -0
  347. package/dist/src/utils/filesearch/result-cache.js.map +1 -0
  348. package/dist/src/utils/filesearch/result-cache.test.d.ts +6 -0
  349. package/dist/src/utils/filesearch/result-cache.test.js +46 -0
  350. package/dist/src/utils/filesearch/result-cache.test.js.map +1 -0
  351. package/dist/src/utils/flashFallback.integration.test.js +0 -2
  352. package/dist/src/utils/flashFallback.integration.test.js.map +1 -1
  353. package/dist/src/utils/memoryDiscovery.js +7 -4
  354. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  355. package/dist/src/utils/memoryDiscovery.test.js +3 -2
  356. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  357. package/dist/src/utils/memoryImportProcessor.js +3 -7
  358. package/dist/src/utils/memoryImportProcessor.js.map +1 -1
  359. package/dist/src/utils/memoryImportProcessor.test.js +17 -20
  360. package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
  361. package/dist/src/utils/nextSpeakerChecker.js +5 -6
  362. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  363. package/dist/src/utils/nextSpeakerChecker.test.js +2 -2
  364. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  365. package/dist/src/utils/paths.d.ts +7 -0
  366. package/dist/src/utils/paths.js +15 -0
  367. package/dist/src/utils/paths.js.map +1 -1
  368. package/dist/src/utils/paths.test.js +74 -2
  369. package/dist/src/utils/paths.test.js.map +1 -1
  370. package/dist/src/utils/quotaErrorDetection.d.ts +1 -5
  371. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  372. package/dist/src/utils/schemaValidator.d.ts +1 -8
  373. package/dist/src/utils/schemaValidator.js +1 -32
  374. package/dist/src/utils/schemaValidator.js.map +1 -1
  375. package/dist/src/utils/secure-browser-launcher.js +4 -3
  376. package/dist/src/utils/secure-browser-launcher.js.map +1 -1
  377. package/dist/src/utils/shell-utils.d.ts +39 -0
  378. package/dist/src/utils/shell-utils.js +72 -2
  379. package/dist/src/utils/shell-utils.js.map +1 -1
  380. package/dist/src/utils/shell-utils.test.js +132 -4
  381. package/dist/src/utils/shell-utils.test.js.map +1 -1
  382. package/dist/src/utils/systemEncoding.js +1 -1
  383. package/dist/src/utils/systemEncoding.js.map +1 -1
  384. package/dist/src/utils/systemEncoding.test.js +23 -23
  385. package/dist/src/utils/systemEncoding.test.js.map +1 -1
  386. package/dist/src/utils/user_account.js +58 -48
  387. package/dist/src/utils/user_account.js.map +1 -1
  388. package/dist/src/utils/user_account.test.js +76 -9
  389. package/dist/src/utils/user_account.test.js.map +1 -1
  390. package/dist/src/utils/workspaceContext.d.ts +22 -7
  391. package/dist/src/utils/workspaceContext.js +81 -55
  392. package/dist/src/utils/workspaceContext.js.map +1 -1
  393. package/dist/src/utils/workspaceContext.test.js +221 -137
  394. package/dist/src/utils/workspaceContext.test.js.map +1 -1
  395. package/dist/tsconfig.tsbuildinfo +1 -1
  396. package/package.json +11 -2
  397. package/dist/src/core/modelCheck.d.ts +0 -14
  398. package/dist/src/core/modelCheck.js +0 -62
  399. package/dist/src/core/modelCheck.js.map +0 -1
@@ -0,0 +1,74 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { McpClient, MCPDiscoveryState, populateMcpServerCommand, } from './mcp-client.js';
7
+ import { getErrorMessage } from '../utils/errors.js';
8
+ /**
9
+ * Manages the lifecycle of multiple MCP clients, including local child processes.
10
+ * This class is responsible for starting, stopping, and discovering tools from
11
+ * a collection of MCP servers defined in the configuration.
12
+ */
13
+ export class McpClientManager {
14
+ clients = new Map();
15
+ mcpServers;
16
+ mcpServerCommand;
17
+ toolRegistry;
18
+ promptRegistry;
19
+ debugMode;
20
+ workspaceContext;
21
+ discoveryState = MCPDiscoveryState.NOT_STARTED;
22
+ constructor(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext) {
23
+ this.mcpServers = mcpServers;
24
+ this.mcpServerCommand = mcpServerCommand;
25
+ this.toolRegistry = toolRegistry;
26
+ this.promptRegistry = promptRegistry;
27
+ this.debugMode = debugMode;
28
+ this.workspaceContext = workspaceContext;
29
+ }
30
+ /**
31
+ * Initiates the tool discovery process for all configured MCP servers.
32
+ * It connects to each server, discovers its available tools, and registers
33
+ * them with the `ToolRegistry`.
34
+ */
35
+ async discoverAllMcpTools() {
36
+ await this.stop();
37
+ this.discoveryState = MCPDiscoveryState.IN_PROGRESS;
38
+ const servers = populateMcpServerCommand(this.mcpServers, this.mcpServerCommand);
39
+ const discoveryPromises = Object.entries(servers).map(async ([name, config]) => {
40
+ const client = new McpClient(name, config, this.toolRegistry, this.promptRegistry, this.workspaceContext, this.debugMode);
41
+ this.clients.set(name, client);
42
+ try {
43
+ await client.connect();
44
+ await client.discover();
45
+ }
46
+ catch (error) {
47
+ // Log the error but don't let a single failed server stop the others
48
+ console.error(`Error during discovery for server '${name}': ${getErrorMessage(error)}`);
49
+ }
50
+ });
51
+ await Promise.all(discoveryPromises);
52
+ this.discoveryState = MCPDiscoveryState.COMPLETED;
53
+ }
54
+ /**
55
+ * Stops all running local MCP servers and closes all client connections.
56
+ * This is the cleanup method to be called on application exit.
57
+ */
58
+ async stop() {
59
+ const disconnectionPromises = Array.from(this.clients.entries()).map(async ([name, client]) => {
60
+ try {
61
+ await client.disconnect();
62
+ }
63
+ catch (error) {
64
+ console.error(`Error stopping client '${name}': ${getErrorMessage(error)}`);
65
+ }
66
+ });
67
+ await Promise.all(disconnectionPromises);
68
+ this.clients.clear();
69
+ }
70
+ getDiscoveryState() {
71
+ return this.discoveryState;
72
+ }
73
+ }
74
+ //# sourceMappingURL=mcp-client-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client-manager.js","sourceRoot":"","sources":["../../../src/tools/mcp-client-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IACnB,OAAO,GAA2B,IAAI,GAAG,EAAE,CAAC;IACnC,UAAU,CAAkC;IAC5C,gBAAgB,CAAqB;IACrC,YAAY,CAAe;IAC3B,cAAc,CAAiB;IAC/B,SAAS,CAAU;IACnB,gBAAgB,CAAmB;IAC5C,cAAc,GAAsB,iBAAiB,CAAC,WAAW,CAAC;IAE1E,YACE,UAA2C,EAC3C,gBAAoC,EACpC,YAA0B,EAC1B,cAA8B,EAC9B,SAAkB,EAClB,gBAAkC;QAElC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,mBAAmB;QACvB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC,WAAW,CAAC;QACpD,MAAM,OAAO,GAAG,wBAAwB,CACtC,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,gBAAgB,CACtB,CAAC;QAEF,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CACnD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,IAAI,EACJ,MAAM,EACN,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,SAAS,CACf,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;gBACvB,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC1B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qEAAqE;gBACrE,OAAO,CAAC,KAAK,CACX,sCAAsC,IAAI,MAAM,eAAe,CAC7D,KAAK,CACN,EAAE,CACJ,CAAC;YACJ,CAAC;QACH,CAAC,CACF,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC,SAAS,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,qBAAqB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAClE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CACX,0BAA0B,IAAI,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,CAC7D,CAAC;YACJ,CAAC;QACH,CAAC,CACF,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ export {};
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @license
3
+ * Copyright 2025 Google LLC
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+ import { afterEach, describe, expect, it, vi } from 'vitest';
7
+ import { McpClientManager } from './mcp-client-manager.js';
8
+ import { McpClient } from './mcp-client.js';
9
+ vi.mock('./mcp-client.js', async () => {
10
+ const originalModule = await vi.importActual('./mcp-client.js');
11
+ return {
12
+ ...originalModule,
13
+ McpClient: vi.fn(),
14
+ populateMcpServerCommand: vi.fn(() => ({
15
+ 'test-server': {},
16
+ })),
17
+ };
18
+ });
19
+ describe('McpClientManager', () => {
20
+ afterEach(() => {
21
+ vi.restoreAllMocks();
22
+ });
23
+ it('should discover tools from all servers', async () => {
24
+ const mockedMcpClient = {
25
+ connect: vi.fn(),
26
+ discover: vi.fn(),
27
+ disconnect: vi.fn(),
28
+ getStatus: vi.fn(),
29
+ };
30
+ vi.mocked(McpClient).mockReturnValue(mockedMcpClient);
31
+ const manager = new McpClientManager({
32
+ 'test-server': {},
33
+ }, '', {}, {}, false, {});
34
+ await manager.discoverAllMcpTools();
35
+ expect(mockedMcpClient.connect).toHaveBeenCalledOnce();
36
+ expect(mockedMcpClient.discover).toHaveBeenCalledOnce();
37
+ });
38
+ });
39
+ //# sourceMappingURL=mcp-client-manager.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-client-manager.test.js","sourceRoot":"","sources":["../../../src/tools/mcp-client-manager.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;IACpC,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAChE,OAAO;QACL,GAAG,cAAc;QACjB,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;QAClB,wBAAwB,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;YACrC,aAAa,EAAE,EAAE;SAClB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,eAAe,GAAG;YACtB,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;YAChB,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;YACjB,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;YACnB,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;SACnB,CAAC;QACF,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,eAAe,CAClC,eAAuC,CACxC,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAClC;YACE,aAAa,EAAE,EAAE;SAClB,EACD,EAAE,EACF,EAAkB,EAClB,EAAoB,EACpB,KAAK,EACL,EAAsB,CACvB,CAAC;QACF,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACpC,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,oBAAoB,EAAE,CAAC;QACvD,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -11,6 +11,7 @@ import { DiscoveredMCPTool } from './mcp-tool.js';
11
11
  import { FunctionDeclaration } from '@google/genai';
12
12
  import { ToolRegistry } from './tool-registry.js';
13
13
  import { PromptRegistry } from '../prompts/prompt-registry.js';
14
+ import { WorkspaceContext } from '../utils/workspaceContext.js';
14
15
  export declare const MCP_DEFAULT_TIMEOUT_MSEC: number;
15
16
  export type DiscoveredMCPPrompt = Prompt & {
16
17
  serverName: string;
@@ -38,6 +39,45 @@ export declare enum MCPDiscoveryState {
38
39
  /** Discovery has completed (with or without errors) */
39
40
  COMPLETED = "completed"
40
41
  }
42
+ /**
43
+ * A client for a single MCP server.
44
+ *
45
+ * This class is responsible for connecting to, discovering tools from, and
46
+ * managing the state of a single MCP server.
47
+ */
48
+ export declare class McpClient {
49
+ private readonly serverName;
50
+ private readonly serverConfig;
51
+ private readonly toolRegistry;
52
+ private readonly promptRegistry;
53
+ private readonly workspaceContext;
54
+ private readonly debugMode;
55
+ private client;
56
+ private transport;
57
+ private status;
58
+ private isDisconnecting;
59
+ constructor(serverName: string, serverConfig: MCPServerConfig, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, workspaceContext: WorkspaceContext, debugMode: boolean);
60
+ /**
61
+ * Connects to the MCP server.
62
+ */
63
+ connect(): Promise<void>;
64
+ /**
65
+ * Discovers tools and prompts from the MCP server.
66
+ */
67
+ discover(): Promise<void>;
68
+ /**
69
+ * Disconnects from the MCP server.
70
+ */
71
+ disconnect(): Promise<void>;
72
+ /**
73
+ * Returns the current status of the client.
74
+ */
75
+ getStatus(): MCPServerStatus;
76
+ private updateStatus;
77
+ private createTransport;
78
+ private discoverTools;
79
+ private discoverPrompts;
80
+ }
41
81
  /**
42
82
  * Map to track which MCP servers have been discovered to require OAuth
43
83
  */
@@ -54,6 +94,10 @@ export declare function addMCPStatusChangeListener(listener: StatusChangeListene
54
94
  * Remove a listener for MCP server status changes
55
95
  */
56
96
  export declare function removeMCPStatusChangeListener(listener: StatusChangeListener): void;
97
+ /**
98
+ * Update the status of an MCP server
99
+ */
100
+ export declare function updateMCPServerStatus(serverName: string, status: MCPServerStatus): void;
57
101
  /**
58
102
  * Get the current status of an MCP server
59
103
  */
@@ -76,7 +120,7 @@ export declare function getMCPDiscoveryState(): MCPDiscoveryState;
76
120
  * @param toolRegistry The central registry where discovered tools will be registered.
77
121
  * @returns A promise that resolves when the discovery process has been attempted for all servers.
78
122
  */
79
- export declare function discoverMcpTools(mcpServers: Record<string, MCPServerConfig>, mcpServerCommand: string | undefined, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean): Promise<void>;
123
+ export declare function discoverMcpTools(mcpServers: Record<string, MCPServerConfig>, mcpServerCommand: string | undefined, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean, workspaceContext: WorkspaceContext): Promise<void>;
80
124
  /** Visible for Testing */
81
125
  export declare function populateMcpServerCommand(mcpServers: Record<string, MCPServerConfig>, mcpServerCommand: string | undefined): Record<string, MCPServerConfig>;
82
126
  /**
@@ -89,7 +133,17 @@ export declare function populateMcpServerCommand(mcpServers: Record<string, MCPS
89
133
  * @param toolRegistry The registry to register discovered tools with
90
134
  * @returns Promise that resolves when discovery is complete
91
135
  */
92
- export declare function connectAndDiscover(mcpServerName: string, mcpServerConfig: MCPServerConfig, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean): Promise<void>;
136
+ export declare function connectAndDiscover(mcpServerName: string, mcpServerConfig: MCPServerConfig, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean, workspaceContext: WorkspaceContext): Promise<void>;
137
+ /**
138
+ * Recursively validates that a JSON schema and all its nested properties and
139
+ * items have a `type` defined.
140
+ *
141
+ * @param schema The JSON schema to validate.
142
+ * @returns `true` if the schema is valid, `false` otherwise.
143
+ *
144
+ * @visiblefortesting
145
+ */
146
+ export declare function hasValidTypes(schema: unknown): boolean;
93
147
  /**
94
148
  * Discovers and sanitizes tools from a connected MCP client.
95
149
  * It retrieves function declarations from the client, filters out disabled tools,
@@ -130,7 +184,7 @@ export declare function invokeMcpPrompt(mcpServerName: string, mcpClient: Client
130
184
  * @returns A promise that resolves to a connected MCP `Client` instance.
131
185
  * @throws An error if the connection fails or the configuration is invalid.
132
186
  */
133
- export declare function connectToMcpServer(mcpServerName: string, mcpServerConfig: MCPServerConfig, debugMode: boolean): Promise<Client>;
187
+ export declare function connectToMcpServer(mcpServerName: string, mcpServerConfig: MCPServerConfig, debugMode: boolean, workspaceContext: WorkspaceContext): Promise<Client>;
134
188
  /** Visible for Testing */
135
189
  export declare function createTransport(mcpServerName: string, mcpServerConfig: MCPServerConfig, debugMode: boolean): Promise<Transport>;
136
190
  /** Visible for testing */
@@ -7,7 +7,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
7
7
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
8
8
  import { SSEClientTransport, } from '@modelcontextprotocol/sdk/client/sse.js';
9
9
  import { StreamableHTTPClientTransport, } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
10
- import { ListPromptsResultSchema, GetPromptResultSchema, } from '@modelcontextprotocol/sdk/types.js';
10
+ import { ListPromptsResultSchema, GetPromptResultSchema, ListRootsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
11
11
  import { parse } from 'shell-quote';
12
12
  import { AuthProviderType } from '../config/config.js';
13
13
  import { GoogleCredentialProvider } from '../mcp/google-auth-provider.js';
@@ -17,6 +17,8 @@ import { MCPOAuthProvider } from '../mcp/oauth-provider.js';
17
17
  import { OAuthUtils } from '../mcp/oauth-utils.js';
18
18
  import { MCPOAuthTokenStorage } from '../mcp/oauth-token-storage.js';
19
19
  import { getErrorMessage } from '../utils/errors.js';
20
+ import { basename } from 'node:path';
21
+ import { pathToFileURL } from 'node:url';
20
22
  export const MCP_DEFAULT_TIMEOUT_MSEC = 10 * 60 * 1000; // default to 10 minutes
21
23
  /**
22
24
  * Enum representing the connection status of an MCP server
@@ -42,6 +44,122 @@ export var MCPDiscoveryState;
42
44
  /** Discovery has completed (with or without errors) */
43
45
  MCPDiscoveryState["COMPLETED"] = "completed";
44
46
  })(MCPDiscoveryState || (MCPDiscoveryState = {}));
47
+ /**
48
+ * A client for a single MCP server.
49
+ *
50
+ * This class is responsible for connecting to, discovering tools from, and
51
+ * managing the state of a single MCP server.
52
+ */
53
+ export class McpClient {
54
+ serverName;
55
+ serverConfig;
56
+ toolRegistry;
57
+ promptRegistry;
58
+ workspaceContext;
59
+ debugMode;
60
+ client;
61
+ transport;
62
+ status = MCPServerStatus.DISCONNECTED;
63
+ isDisconnecting = false;
64
+ constructor(serverName, serverConfig, toolRegistry, promptRegistry, workspaceContext, debugMode) {
65
+ this.serverName = serverName;
66
+ this.serverConfig = serverConfig;
67
+ this.toolRegistry = toolRegistry;
68
+ this.promptRegistry = promptRegistry;
69
+ this.workspaceContext = workspaceContext;
70
+ this.debugMode = debugMode;
71
+ this.client = new Client({
72
+ name: `gemini-cli-mcp-client-${this.serverName}`,
73
+ version: '0.0.1',
74
+ });
75
+ }
76
+ /**
77
+ * Connects to the MCP server.
78
+ */
79
+ async connect() {
80
+ this.isDisconnecting = false;
81
+ this.updateStatus(MCPServerStatus.CONNECTING);
82
+ try {
83
+ this.transport = await this.createTransport();
84
+ this.client.onerror = (error) => {
85
+ if (this.isDisconnecting) {
86
+ return;
87
+ }
88
+ console.error(`MCP ERROR (${this.serverName}):`, error.toString());
89
+ this.updateStatus(MCPServerStatus.DISCONNECTED);
90
+ };
91
+ this.client.registerCapabilities({
92
+ roots: {},
93
+ });
94
+ this.client.setRequestHandler(ListRootsRequestSchema, async () => {
95
+ const roots = [];
96
+ for (const dir of this.workspaceContext.getDirectories()) {
97
+ roots.push({
98
+ uri: pathToFileURL(dir).toString(),
99
+ name: basename(dir),
100
+ });
101
+ }
102
+ return {
103
+ roots,
104
+ };
105
+ });
106
+ await this.client.connect(this.transport, {
107
+ timeout: this.serverConfig.timeout,
108
+ });
109
+ this.updateStatus(MCPServerStatus.CONNECTED);
110
+ }
111
+ catch (error) {
112
+ this.updateStatus(MCPServerStatus.DISCONNECTED);
113
+ throw error;
114
+ }
115
+ }
116
+ /**
117
+ * Discovers tools and prompts from the MCP server.
118
+ */
119
+ async discover() {
120
+ if (this.status !== MCPServerStatus.CONNECTED) {
121
+ throw new Error('Client is not connected.');
122
+ }
123
+ const prompts = await this.discoverPrompts();
124
+ const tools = await this.discoverTools();
125
+ if (prompts.length === 0 && tools.length === 0) {
126
+ throw new Error('No prompts or tools found on the server.');
127
+ }
128
+ for (const tool of tools) {
129
+ this.toolRegistry.registerTool(tool);
130
+ }
131
+ }
132
+ /**
133
+ * Disconnects from the MCP server.
134
+ */
135
+ async disconnect() {
136
+ this.isDisconnecting = true;
137
+ if (this.transport) {
138
+ await this.transport.close();
139
+ }
140
+ this.client.close();
141
+ this.updateStatus(MCPServerStatus.DISCONNECTED);
142
+ }
143
+ /**
144
+ * Returns the current status of the client.
145
+ */
146
+ getStatus() {
147
+ return this.status;
148
+ }
149
+ updateStatus(status) {
150
+ this.status = status;
151
+ updateMCPServerStatus(this.serverName, status);
152
+ }
153
+ async createTransport() {
154
+ return createTransport(this.serverName, this.serverConfig, this.debugMode);
155
+ }
156
+ async discoverTools() {
157
+ return discoverTools(this.serverName, this.serverConfig, this.client);
158
+ }
159
+ async discoverPrompts() {
160
+ return discoverPrompts(this.serverName, this.client, this.promptRegistry);
161
+ }
162
+ }
45
163
  /**
46
164
  * Map to track the status of each MCP server within the core package
47
165
  */
@@ -73,7 +191,7 @@ export function removeMCPStatusChangeListener(listener) {
73
191
  /**
74
192
  * Update the status of an MCP server
75
193
  */
76
- function updateMCPServerStatus(serverName, status) {
194
+ export function updateMCPServerStatus(serverName, status) {
77
195
  serverStatuses.set(serverName, status);
78
196
  // Notify all listeners
79
197
  for (const listener of statusChangeListeners) {
@@ -163,8 +281,10 @@ async function handleAutomaticOAuth(mcpServerName, mcpServerConfig, wwwAuthentic
163
281
  scopes: oauthConfig.scopes || [],
164
282
  };
165
283
  // Perform OAuth authentication
284
+ // Pass the server URL for proper discovery
285
+ const serverUrl = mcpServerConfig.httpUrl || mcpServerConfig.url;
166
286
  console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
167
- await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig);
287
+ await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig, serverUrl);
168
288
  console.log(`OAuth authentication successful for server '${mcpServerName}'`);
169
289
  return true;
170
290
  }
@@ -223,11 +343,11 @@ async function createTransportWithOAuth(mcpServerName, mcpServerConfig, accessTo
223
343
  * @param toolRegistry The central registry where discovered tools will be registered.
224
344
  * @returns A promise that resolves when the discovery process has been attempted for all servers.
225
345
  */
226
- export async function discoverMcpTools(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode) {
346
+ export async function discoverMcpTools(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext) {
227
347
  mcpDiscoveryState = MCPDiscoveryState.IN_PROGRESS;
228
348
  try {
229
349
  mcpServers = populateMcpServerCommand(mcpServers, mcpServerCommand);
230
- const discoveryPromises = Object.entries(mcpServers).map(([mcpServerName, mcpServerConfig]) => connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode));
350
+ const discoveryPromises = Object.entries(mcpServers).map(([mcpServerName, mcpServerConfig]) => connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext));
231
351
  await Promise.all(discoveryPromises);
232
352
  }
233
353
  finally {
@@ -260,11 +380,11 @@ export function populateMcpServerCommand(mcpServers, mcpServerCommand) {
260
380
  * @param toolRegistry The registry to register discovered tools with
261
381
  * @returns Promise that resolves when discovery is complete
262
382
  */
263
- export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode) {
383
+ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext) {
264
384
  updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTING);
265
385
  let mcpClient;
266
386
  try {
267
- mcpClient = await connectToMcpServer(mcpServerName, mcpServerConfig, debugMode);
387
+ mcpClient = await connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext);
268
388
  mcpClient.onerror = (error) => {
269
389
  console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
270
390
  updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
@@ -291,6 +411,59 @@ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolReg
291
411
  updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
292
412
  }
293
413
  }
414
+ /**
415
+ * Recursively validates that a JSON schema and all its nested properties and
416
+ * items have a `type` defined.
417
+ *
418
+ * @param schema The JSON schema to validate.
419
+ * @returns `true` if the schema is valid, `false` otherwise.
420
+ *
421
+ * @visiblefortesting
422
+ */
423
+ export function hasValidTypes(schema) {
424
+ if (typeof schema !== 'object' || schema === null) {
425
+ // Not a schema object we can validate, or not a schema at all.
426
+ // Treat as valid as it has no properties to be invalid.
427
+ return true;
428
+ }
429
+ const s = schema;
430
+ if (!s['type']) {
431
+ // These keywords contain an array of schemas that should be validated.
432
+ //
433
+ // If no top level type was given, then they must each have a type.
434
+ let hasSubSchema = false;
435
+ const schemaArrayKeywords = ['anyOf', 'allOf', 'oneOf'];
436
+ for (const keyword of schemaArrayKeywords) {
437
+ const subSchemas = s[keyword];
438
+ if (Array.isArray(subSchemas)) {
439
+ hasSubSchema = true;
440
+ for (const subSchema of subSchemas) {
441
+ if (!hasValidTypes(subSchema)) {
442
+ return false;
443
+ }
444
+ }
445
+ }
446
+ }
447
+ // If the node itself is missing a type and had no subschemas, then it isn't valid.
448
+ if (!hasSubSchema)
449
+ return false;
450
+ }
451
+ if (s['type'] === 'object' && s['properties']) {
452
+ if (typeof s['properties'] === 'object' && s['properties'] !== null) {
453
+ for (const prop of Object.values(s['properties'])) {
454
+ if (!hasValidTypes(prop)) {
455
+ return false;
456
+ }
457
+ }
458
+ }
459
+ }
460
+ if (s['type'] === 'array' && s['items']) {
461
+ if (!hasValidTypes(s['items'])) {
462
+ return false;
463
+ }
464
+ }
465
+ return true;
466
+ }
294
467
  /**
295
468
  * Discovers and sanitizes tools from a connected MCP client.
296
469
  * It retrieves function declarations from the client, filters out disabled tools,
@@ -316,6 +489,12 @@ export async function discoverTools(mcpServerName, mcpServerConfig, mcpClient) {
316
489
  if (!isEnabled(funcDecl, mcpServerName, mcpServerConfig)) {
317
490
  continue;
318
491
  }
492
+ if (!hasValidTypes(funcDecl.parametersJsonSchema)) {
493
+ console.warn(`Skipping tool '${funcDecl.name}' from MCP server '${mcpServerName}' ` +
494
+ `because it has missing types in its parameter schema. Please file an ` +
495
+ `issue with the owner of the MCP server.`);
496
+ continue;
497
+ }
319
498
  discoveredTools.push(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, funcDecl.name, funcDecl.description ?? '', funcDecl.parametersJsonSchema ?? { type: 'object', properties: {} }, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
320
499
  }
321
500
  catch (error) {
@@ -341,6 +520,9 @@ export async function discoverTools(mcpServerName, mcpServerConfig, mcpClient) {
341
520
  */
342
521
  export async function discoverPrompts(mcpServerName, mcpClient, promptRegistry) {
343
522
  try {
523
+ // Only request prompts if the server supports them.
524
+ if (mcpClient.getServerCapabilities()?.prompts == null)
525
+ return [];
344
526
  const response = await mcpClient.request({ method: 'prompts/list', params: {} }, ListPromptsResultSchema);
345
527
  for (const prompt of response.prompts) {
346
528
  promptRegistry.registerPrompt({
@@ -399,11 +581,52 @@ export async function invokeMcpPrompt(mcpServerName, mcpClient, promptName, prom
399
581
  * @returns A promise that resolves to a connected MCP `Client` instance.
400
582
  * @throws An error if the connection fails or the configuration is invalid.
401
583
  */
402
- export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode) {
584
+ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext) {
403
585
  const mcpClient = new Client({
404
586
  name: 'gemini-cli-mcp-client',
405
587
  version: '0.0.1',
406
588
  });
589
+ mcpClient.registerCapabilities({
590
+ roots: {
591
+ listChanged: true,
592
+ },
593
+ });
594
+ mcpClient.setRequestHandler(ListRootsRequestSchema, async () => {
595
+ const roots = [];
596
+ for (const dir of workspaceContext.getDirectories()) {
597
+ roots.push({
598
+ uri: pathToFileURL(dir).toString(),
599
+ name: basename(dir),
600
+ });
601
+ }
602
+ return {
603
+ roots,
604
+ };
605
+ });
606
+ let unlistenDirectories = workspaceContext.onDirectoriesChanged(async () => {
607
+ try {
608
+ await mcpClient.notification({
609
+ method: 'notifications/roots/list_changed',
610
+ });
611
+ }
612
+ catch (_) {
613
+ // If this fails, its almost certainly because the connection was closed
614
+ // and we should just stop listening for future directory changes.
615
+ unlistenDirectories?.();
616
+ unlistenDirectories = undefined;
617
+ }
618
+ });
619
+ // Attempt to pro-actively unsubscribe if the mcp client closes. This API is
620
+ // very brittle though so we don't have any guarantees, hence the try/catch
621
+ // above as well.
622
+ //
623
+ // Be a good steward and don't just bash over onclose.
624
+ const oldOnClose = mcpClient.onclose;
625
+ mcpClient.onclose = () => {
626
+ oldOnClose?.();
627
+ unlistenDirectories?.();
628
+ unlistenDirectories = undefined;
629
+ };
407
630
  // patch Client.callTool to use request timeout as genai McpCallTool.callTool does not do it
408
631
  // TODO: remove this hack once GenAI SDK does callTool with request options
409
632
  if ('callTool' in mcpClient) {
@@ -574,8 +797,10 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
574
797
  scopes: oauthConfig.scopes || [],
575
798
  };
576
799
  // Perform OAuth authentication
800
+ // Pass the server URL for proper discovery
801
+ const serverUrl = mcpServerConfig.httpUrl || mcpServerConfig.url;
577
802
  console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
578
- await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig);
803
+ await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig, serverUrl);
579
804
  // Retry connection with OAuth token
580
805
  const credentials = await MCPOAuthTokenStorage.getToken(mcpServerName);
581
806
  if (credentials) {
@@ -643,7 +868,7 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
643
868
  else {
644
869
  conciseError = `Connection failed for '${mcpServerName}': ${errorMessage}`;
645
870
  }
646
- if (process.env.SANDBOX) {
871
+ if (process.env['SANDBOX']) {
647
872
  conciseError += ` (check sandbox availability)`;
648
873
  }
649
874
  throw new Error(conciseError);