@within-7/minto 0.3.10 → 0.4.0

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 (306) hide show
  1. package/dist/Tool.js.map +2 -2
  2. package/dist/commands/agents/AgentsCommand.js +2 -2
  3. package/dist/commands/agents/AgentsCommand.js.map +2 -2
  4. package/dist/commands/ctx_viz.js +1 -1
  5. package/dist/commands/effort.js +87 -0
  6. package/dist/commands/effort.js.map +7 -0
  7. package/dist/commands/export.js +19 -9
  8. package/dist/commands/export.js.map +2 -2
  9. package/dist/commands/ide.js +18 -0
  10. package/dist/commands/ide.js.map +7 -0
  11. package/dist/commands/mcp-interactive.js +14 -8
  12. package/dist/commands/mcp-interactive.js.map +2 -2
  13. package/dist/commands/memory.js +168 -0
  14. package/dist/commands/memory.js.map +7 -0
  15. package/dist/commands/model.js +45 -2
  16. package/dist/commands/model.js.map +2 -2
  17. package/dist/commands/outputStyle.js +64 -0
  18. package/dist/commands/outputStyle.js.map +7 -0
  19. package/dist/commands/plugin/utils.js +33 -1
  20. package/dist/commands/plugin/utils.js.map +2 -2
  21. package/dist/commands/plugin.js +10 -1
  22. package/dist/commands/plugin.js.map +2 -2
  23. package/dist/commands/refreshCommands.js +2 -0
  24. package/dist/commands/refreshCommands.js.map +2 -2
  25. package/dist/commands/review.js +51 -0
  26. package/dist/commands/review.js.map +7 -0
  27. package/dist/commands/terminalSetup.js +6 -0
  28. package/dist/commands/terminalSetup.js.map +2 -2
  29. package/dist/commands/undo.js +8 -0
  30. package/dist/commands/undo.js.map +2 -2
  31. package/dist/commands/vim.js +22 -0
  32. package/dist/commands/vim.js.map +7 -0
  33. package/dist/commands.js +12 -0
  34. package/dist/commands.js.map +2 -2
  35. package/dist/components/HighlightedCode.js +1 -0
  36. package/dist/components/HighlightedCode.js.map +2 -2
  37. package/dist/components/ModelSelector/ModelSelector.js +250 -143
  38. package/dist/components/ModelSelector/ModelSelector.js.map +2 -2
  39. package/dist/components/PromptInput.js +21 -6
  40. package/dist/components/PromptInput.js.map +2 -2
  41. package/dist/components/PulseLabel.js +44 -0
  42. package/dist/components/PulseLabel.js.map +7 -0
  43. package/dist/components/RequestStatusIndicator.js +1 -1
  44. package/dist/components/RequestStatusIndicator.js.map +1 -1
  45. package/dist/components/Spinner.js +12 -42
  46. package/dist/components/Spinner.js.map +3 -3
  47. package/dist/components/StartupStatus.js +57 -0
  48. package/dist/components/StartupStatus.js.map +7 -0
  49. package/dist/components/SubagentBlock.js +43 -6
  50. package/dist/components/SubagentBlock.js.map +2 -2
  51. package/dist/components/TabbedListView/TabBar.js +13 -8
  52. package/dist/components/TabbedListView/TabBar.js.map +2 -2
  53. package/dist/components/TabbedListView/TabbedListView.js +1 -1
  54. package/dist/components/TabbedListView/TabbedListView.js.map +2 -2
  55. package/dist/components/TodoPanel.js +1 -1
  56. package/dist/components/TodoPanel.js.map +1 -1
  57. package/dist/components/ToolUseLoader.js +5 -0
  58. package/dist/components/ToolUseLoader.js.map +2 -2
  59. package/dist/components/TrustDialog.js +0 -2
  60. package/dist/components/TrustDialog.js.map +2 -2
  61. package/dist/components/messages/TaskInModuleView.js +1 -1
  62. package/dist/components/messages/TaskInModuleView.js.map +2 -2
  63. package/dist/components/messages/TaskToolMessage.js +1 -1
  64. package/dist/components/messages/TaskToolMessage.js.map +2 -2
  65. package/dist/components/messages/UserPromptMessage.js +6 -1
  66. package/dist/components/messages/UserPromptMessage.js.map +2 -2
  67. package/dist/constants/modelCapabilities.js +103 -18
  68. package/dist/constants/modelCapabilities.js.map +2 -2
  69. package/dist/constants/product.js +2 -0
  70. package/dist/constants/product.js.map +2 -2
  71. package/dist/constants/prompts/agentPrompt.js +30 -0
  72. package/dist/constants/prompts/agentPrompt.js.map +7 -0
  73. package/dist/constants/prompts/codeConventions.js +27 -0
  74. package/dist/constants/prompts/codeConventions.js.map +7 -0
  75. package/dist/constants/prompts/doingTasks.js +15 -0
  76. package/dist/constants/prompts/doingTasks.js.map +7 -0
  77. package/dist/constants/prompts/envInfo.js +17 -0
  78. package/dist/constants/prompts/envInfo.js.map +7 -0
  79. package/dist/constants/prompts/executingWithCare.js +17 -0
  80. package/dist/constants/prompts/executingWithCare.js.map +7 -0
  81. package/dist/constants/prompts/identity.js +10 -0
  82. package/dist/constants/prompts/identity.js.map +7 -0
  83. package/dist/constants/prompts/index.js +78 -0
  84. package/dist/constants/prompts/index.js.map +7 -0
  85. package/dist/constants/prompts/taskManagement.js +60 -0
  86. package/dist/constants/prompts/taskManagement.js.map +7 -0
  87. package/dist/constants/prompts/toneAndStyle.js +62 -0
  88. package/dist/constants/prompts/toneAndStyle.js.map +7 -0
  89. package/dist/constants/prompts/toolUsagePolicy.js +38 -0
  90. package/dist/constants/prompts/toolUsagePolicy.js.map +7 -0
  91. package/dist/constants/prompts.js +5 -176
  92. package/dist/constants/prompts.js.map +2 -2
  93. package/dist/constants/providerRegistry.js +235 -0
  94. package/dist/constants/providerRegistry.js.map +7 -0
  95. package/dist/constants/providers.js +35 -0
  96. package/dist/constants/providers.js.map +7 -0
  97. package/dist/context/PermissionContext.js +0 -1
  98. package/dist/context/PermissionContext.js.map +2 -2
  99. package/dist/context.js +87 -31
  100. package/dist/context.js.map +2 -2
  101. package/dist/core/backupHook.js +2 -2
  102. package/dist/core/backupHook.js.map +2 -2
  103. package/dist/core/config/defaults.js +4 -1
  104. package/dist/core/config/defaults.js.map +2 -2
  105. package/dist/core/config/schema.js +7 -1
  106. package/dist/core/config/schema.js.map +2 -2
  107. package/dist/core/costTracker.js +18 -0
  108. package/dist/core/costTracker.js.map +2 -2
  109. package/dist/core/index.js +0 -1
  110. package/dist/core/index.js.map +2 -2
  111. package/dist/core/tokenStatsManager.js +22 -4
  112. package/dist/core/tokenStatsManager.js.map +2 -2
  113. package/dist/entrypoints/cli.js +65 -84
  114. package/dist/entrypoints/cli.js.map +2 -2
  115. package/dist/hooks/useAgentTokenStats.js +1 -1
  116. package/dist/hooks/useAgentTokenStats.js.map +2 -2
  117. package/dist/hooks/useAgentTranscripts.js +2 -1
  118. package/dist/hooks/useAgentTranscripts.js.map +2 -2
  119. package/dist/hooks/useBackgroundShells.js +29 -0
  120. package/dist/hooks/useBackgroundShells.js.map +7 -0
  121. package/dist/hooks/useCanUseTool.js +1 -1
  122. package/dist/hooks/useCanUseTool.js.map +2 -2
  123. package/dist/hooks/useDeferredLoading.js +64 -0
  124. package/dist/hooks/useDeferredLoading.js.map +7 -0
  125. package/dist/hooks/useHookStatus.js +1 -1
  126. package/dist/hooks/useHookStatus.js.map +2 -2
  127. package/dist/hooks/useSessionTracking.js +55 -0
  128. package/dist/hooks/useSessionTracking.js.map +7 -0
  129. package/dist/hooks/useTerminalSize.js +21 -0
  130. package/dist/hooks/useTerminalSize.js.map +2 -2
  131. package/dist/hooks/useTextInput.js +1 -0
  132. package/dist/hooks/useTextInput.js.map +2 -2
  133. package/dist/hooks/useUnifiedCompletion.js +3 -2
  134. package/dist/hooks/useUnifiedCompletion.js.map +2 -2
  135. package/dist/i18n/locales/en.js +8 -9
  136. package/dist/i18n/locales/en.js.map +2 -2
  137. package/dist/i18n/locales/zh-CN.js +8 -9
  138. package/dist/i18n/locales/zh-CN.js.map +2 -2
  139. package/dist/i18n/types.js.map +1 -1
  140. package/dist/messages.js +41 -17
  141. package/dist/messages.js.map +2 -2
  142. package/dist/permissions.js +94 -1
  143. package/dist/permissions.js.map +2 -2
  144. package/dist/query.js +27 -19
  145. package/dist/query.js.map +2 -2
  146. package/dist/screens/REPL.js +83 -74
  147. package/dist/screens/REPL.js.map +2 -2
  148. package/dist/services/adapters/responsesAPI.js +6 -0
  149. package/dist/services/adapters/responsesAPI.js.map +2 -2
  150. package/dist/services/agentTeams/index.js +35 -0
  151. package/dist/services/agentTeams/index.js.map +7 -0
  152. package/dist/services/agentTeams/mailbox.js +114 -0
  153. package/dist/services/agentTeams/mailbox.js.map +7 -0
  154. package/dist/services/agentTeams/teamManager.js +149 -0
  155. package/dist/services/agentTeams/teamManager.js.map +7 -0
  156. package/dist/services/agentTeams/teamTaskStore.js +114 -0
  157. package/dist/services/agentTeams/teamTaskStore.js.map +7 -0
  158. package/dist/services/agentTeams/teammateSpawner.js +80 -0
  159. package/dist/services/agentTeams/teammateSpawner.js.map +7 -0
  160. package/dist/services/checkpointManager.js +16 -3
  161. package/dist/services/checkpointManager.js.map +2 -2
  162. package/dist/services/claude.js +19 -1728
  163. package/dist/services/claude.js.map +3 -3
  164. package/dist/services/gpt5ConnectionTest.js +4 -2
  165. package/dist/services/gpt5ConnectionTest.js.map +2 -2
  166. package/dist/services/hookExecutor.js +411 -127
  167. package/dist/services/hookExecutor.js.map +2 -2
  168. package/dist/services/llm/anthropicProvider.js +807 -0
  169. package/dist/services/llm/anthropicProvider.js.map +7 -0
  170. package/dist/services/llm/dispatch.js +218 -0
  171. package/dist/services/llm/dispatch.js.map +7 -0
  172. package/dist/services/llm/index.js +44 -0
  173. package/dist/services/llm/index.js.map +7 -0
  174. package/dist/services/llm/mintoContext.js +69 -0
  175. package/dist/services/llm/mintoContext.js.map +7 -0
  176. package/dist/services/llm/openaiProvider.js +622 -0
  177. package/dist/services/llm/openaiProvider.js.map +7 -0
  178. package/dist/services/llm/types.js +157 -0
  179. package/dist/services/llm/types.js.map +7 -0
  180. package/dist/services/mcpClient.js +183 -33
  181. package/dist/services/mcpClient.js.map +2 -2
  182. package/dist/services/notifier.js +14 -0
  183. package/dist/services/notifier.js.map +2 -2
  184. package/dist/services/oauth.js +4 -2
  185. package/dist/services/oauth.js.map +2 -2
  186. package/dist/services/openai.js +66 -56
  187. package/dist/services/openai.js.map +3 -3
  188. package/dist/services/outputStyles.js +102 -21
  189. package/dist/services/outputStyles.js.map +2 -2
  190. package/dist/services/plugins/skillMarketplace.js +4 -1
  191. package/dist/services/plugins/skillMarketplace.js.map +2 -2
  192. package/dist/services/sentry.js +1 -1
  193. package/dist/services/sentry.js.map +2 -2
  194. package/dist/services/sessionMemory.js +16 -3
  195. package/dist/services/sessionMemory.js.map +2 -2
  196. package/dist/services/systemReminder.js +350 -3
  197. package/dist/services/systemReminder.js.map +2 -2
  198. package/dist/services/taskStore.js +19 -0
  199. package/dist/services/taskStore.js.map +2 -2
  200. package/dist/tools/ArchitectTool/ArchitectTool.js.map +1 -1
  201. package/dist/tools/AskUserQuestionTool/AskUserQuestionTool.js.map +1 -1
  202. package/dist/tools/BashOutputTool/BashOutputTool.js.map +1 -1
  203. package/dist/tools/BashTool/BashTool.js +28 -0
  204. package/dist/tools/BashTool/BashTool.js.map +2 -2
  205. package/dist/tools/FileEditTool/FileEditTool.js +1 -1
  206. package/dist/tools/FileEditTool/FileEditTool.js.map +2 -2
  207. package/dist/tools/FileReadTool/FileReadTool.js +14 -0
  208. package/dist/tools/FileReadTool/FileReadTool.js.map +2 -2
  209. package/dist/tools/FileWriteTool/FileWriteTool.js +3 -1
  210. package/dist/tools/FileWriteTool/FileWriteTool.js.map +2 -2
  211. package/dist/tools/GlobTool/GlobTool.js.map +1 -1
  212. package/dist/tools/GrepTool/GrepTool.js.map +1 -1
  213. package/dist/tools/KillShellTool/KillShellTool.js.map +1 -1
  214. package/dist/tools/ListMcpResourcesTool/ListMcpResourcesTool.js.map +2 -2
  215. package/dist/tools/LspTool/LspTool.js +11 -2
  216. package/dist/tools/LspTool/LspTool.js.map +2 -2
  217. package/dist/tools/MCPTool/MCPTool.js.map +1 -1
  218. package/dist/tools/MemoryReadTool/MemoryReadTool.js +2 -1
  219. package/dist/tools/MemoryReadTool/MemoryReadTool.js.map +2 -2
  220. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js +2 -1
  221. package/dist/tools/MemoryWriteTool/MemoryWriteTool.js.map +2 -2
  222. package/dist/tools/MultiEditTool/MultiEditTool.js.map +1 -1
  223. package/dist/tools/NotebookEditTool/NotebookEditTool.js.map +1 -1
  224. package/dist/tools/NotebookReadTool/NotebookReadTool.js.map +1 -1
  225. package/dist/tools/PlanModeTool/EnterPlanModeTool.js +8 -2
  226. package/dist/tools/PlanModeTool/EnterPlanModeTool.js.map +2 -2
  227. package/dist/tools/PlanModeTool/ExitPlanModeTool.js +2 -0
  228. package/dist/tools/PlanModeTool/ExitPlanModeTool.js.map +2 -2
  229. package/dist/tools/ReadMcpResourceTool/ReadMcpResourceTool.js.map +1 -1
  230. package/dist/tools/SlashCommandTool/SlashCommandTool.js +174 -18
  231. package/dist/tools/SlashCommandTool/SlashCommandTool.js.map +3 -3
  232. package/dist/tools/TaskCreateTool/TaskCreateTool.js.map +1 -1
  233. package/dist/tools/TaskGetTool/TaskGetTool.js.map +1 -1
  234. package/dist/tools/TaskListTool/TaskListTool.js.map +1 -1
  235. package/dist/tools/TaskOutputTool/TaskOutputTool.js.map +1 -1
  236. package/dist/tools/TaskStopTool/TaskStopTool.js.map +1 -1
  237. package/dist/tools/TaskTool/TaskTool.js +75 -5
  238. package/dist/tools/TaskTool/TaskTool.js.map +2 -2
  239. package/dist/tools/TaskTool/prompt.js +12 -6
  240. package/dist/tools/TaskTool/prompt.js.map +2 -2
  241. package/dist/tools/TaskUpdateTool/TaskUpdateTool.js.map +1 -1
  242. package/dist/tools/ThinkTool/ThinkTool.js.map +1 -1
  243. package/dist/tools/TodoWriteTool/TodoWriteTool.js.map +1 -1
  244. package/dist/tools/URLFetcherTool/URLFetcherTool.js.map +1 -1
  245. package/dist/tools/WebSearchTool/WebSearchTool.js.map +1 -1
  246. package/dist/tools/WebSearchTool/searchProviders.js +2 -1
  247. package/dist/tools/WebSearchTool/searchProviders.js.map +2 -2
  248. package/dist/tools/lsTool/lsTool.js.map +2 -2
  249. package/dist/tools/lsTool/prompt.js.map +1 -1
  250. package/dist/tools.js +14 -3
  251. package/dist/tools.js.map +2 -2
  252. package/dist/types/PermissionMode.js +21 -1
  253. package/dist/types/PermissionMode.js.map +2 -2
  254. package/dist/types/agentTeams.js +1 -0
  255. package/dist/types/agentTeams.js.map +7 -0
  256. package/dist/types/hooks.js +8 -2
  257. package/dist/types/hooks.js.map +2 -2
  258. package/dist/types/plugin.js +1 -1
  259. package/dist/types/plugin.js.map +2 -2
  260. package/dist/utils/agentLoader.js +25 -3
  261. package/dist/utils/agentLoader.js.map +2 -2
  262. package/dist/utils/animationManager.js +1 -1
  263. package/dist/utils/animationManager.js.map +2 -2
  264. package/dist/utils/ask.js +1 -1
  265. package/dist/utils/async.js +5 -1
  266. package/dist/utils/async.js.map +2 -2
  267. package/dist/utils/autoCompactCore.js +60 -0
  268. package/dist/utils/autoCompactCore.js.map +2 -2
  269. package/dist/utils/config.js +26 -128
  270. package/dist/utils/config.js.map +2 -2
  271. package/dist/utils/configSchema.js +227 -0
  272. package/dist/utils/configSchema.js.map +7 -0
  273. package/dist/utils/debugLogger.js.map +2 -2
  274. package/dist/utils/env.js +4 -3
  275. package/dist/utils/env.js.map +2 -2
  276. package/dist/utils/envConfig.js +34 -0
  277. package/dist/utils/envConfig.js.map +3 -3
  278. package/dist/utils/gpt5.js +146 -0
  279. package/dist/utils/gpt5.js.map +7 -0
  280. package/dist/utils/hookManager.js +374 -140
  281. package/dist/utils/hookManager.js.map +2 -2
  282. package/dist/utils/markdown.js +47 -0
  283. package/dist/utils/markdown.js.map +2 -2
  284. package/dist/utils/memoizeWithTTL.js +25 -0
  285. package/dist/utils/memoizeWithTTL.js.map +7 -0
  286. package/dist/utils/model.js +34 -9
  287. package/dist/utils/model.js.map +2 -2
  288. package/dist/utils/pluginInstaller.js +34 -5
  289. package/dist/utils/pluginInstaller.js.map +2 -2
  290. package/dist/utils/pluginLoader.js +201 -32
  291. package/dist/utils/pluginLoader.js.map +2 -2
  292. package/dist/utils/safeFetch.js +45 -0
  293. package/dist/utils/safeFetch.js.map +7 -0
  294. package/dist/utils/skillLoader.js +59 -6
  295. package/dist/utils/skillLoader.js.map +2 -2
  296. package/dist/utils/streamingState.js +52 -0
  297. package/dist/utils/streamingState.js.map +7 -0
  298. package/dist/utils/style.js +6 -3
  299. package/dist/utils/style.js.map +2 -2
  300. package/dist/utils/teamConfig.js +9 -3
  301. package/dist/utils/teamConfig.js.map +2 -2
  302. package/dist/utils/toolRiskClassification.js +0 -6
  303. package/dist/utils/toolRiskClassification.js.map +2 -2
  304. package/dist/version.js +2 -2
  305. package/dist/version.js.map +1 -1
  306. package/package.json +2 -1
@@ -1,4 +1,5 @@
1
1
  import { zipObject } from "lodash-es";
2
+ import { debug as debugLogger } from "../utils/debugLogger.js";
2
3
  import {
3
4
  getCurrentProjectConfig,
4
5
  saveCurrentProjectConfig,
@@ -20,13 +21,31 @@ import {
20
21
  ListPromptsResultSchema,
21
22
  ListToolsResultSchema,
22
23
  ListResourcesResultSchema,
23
- ReadResourceResultSchema
24
+ ReadResourceResultSchema,
25
+ ToolListChangedNotificationSchema
24
26
  } from "@modelcontextprotocol/sdk/types.js";
25
27
  import { memoize, pickBy } from "lodash-es";
26
28
  import { MCPTool } from "../tools/MCPTool/MCPTool.js";
27
29
  import { logMCPError } from "../utils/log.js";
30
+ import { ensureProxyBypass } from "../utils/envConfig.js";
28
31
  import { PRODUCT_COMMAND } from "../constants/product.js";
29
32
  import { CircuitBreakerRegistry, CircuitOpenError } from "../utils/CircuitBreaker.js";
33
+ import { emitReminderEvent } from "./systemReminder.js";
34
+ const SENSITIVE_ENV_PREFIXES = [
35
+ "ANTHROPIC_",
36
+ "OPENAI_",
37
+ "AWS_SECRET",
38
+ "GITHUB_TOKEN",
39
+ "GH_TOKEN",
40
+ "MINTO_API"
41
+ ];
42
+ function filterSensitiveEnv(env) {
43
+ return Object.fromEntries(
44
+ Object.entries(env).filter(
45
+ ([k]) => !SENSITIVE_ENV_PREFIXES.some((p) => k.startsWith(p) || k === p)
46
+ ).filter((e) => e[1] !== void 0)
47
+ );
48
+ }
30
49
  const mcpCircuitBreakers = new CircuitBreakerRegistry({
31
50
  failureThreshold: 5,
32
51
  successThreshold: 2,
@@ -74,7 +93,11 @@ function addMcpServer(name, server, scope = "project") {
74
93
  if (existingConfig && typeof existingConfig === "object") {
75
94
  mcprcConfig = existingConfig;
76
95
  }
77
- } catch {
96
+ } catch (e) {
97
+ debugLogger.warn(
98
+ "MCP_CONFIG",
99
+ `Failed to read/parse .mcprc: ${e instanceof Error ? e.message : String(e)}`
100
+ );
78
101
  }
79
102
  }
80
103
  mcprcConfig[name] = server;
@@ -168,16 +191,30 @@ function getMcpServer(name) {
168
191
  return void 0;
169
192
  }
170
193
  async function connectToServer(name, serverRef) {
171
- const transport = serverRef.type === "sse" ? new SSEClientTransport(new URL(serverRef.url)) : new StdioClientTransport({
172
- command: serverRef.command,
173
- args: serverRef.args,
174
- env: {
175
- ...process.env,
176
- ...serverRef.env
177
- },
178
- stderr: "pipe"
179
- // prevents error output from the MCP server from printing to the UI
180
- });
194
+ let transport;
195
+ if (serverRef.type === "http") {
196
+ const { StreamableHTTPClientTransport } = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
197
+ transport = new StreamableHTTPClientTransport(
198
+ new URL(serverRef.url),
199
+ {
200
+ // Pass headers but never log sensitive values
201
+ requestInit: serverRef.headers ? { headers: serverRef.headers } : void 0
202
+ }
203
+ );
204
+ } else if (serverRef.type === "sse") {
205
+ transport = new SSEClientTransport(new URL(serverRef.url));
206
+ } else {
207
+ transport = new StdioClientTransport({
208
+ command: serverRef.command,
209
+ args: serverRef.args,
210
+ env: ensureProxyBypass({
211
+ ...filterSensitiveEnv(process.env),
212
+ ...serverRef.env
213
+ }),
214
+ stderr: "pipe"
215
+ // prevents error output from the MCP server from printing to the UI
216
+ });
217
+ }
181
218
  const client = new Client(
182
219
  {
183
220
  name: PRODUCT_COMMAND,
@@ -187,16 +224,16 @@ async function connectToServer(name, serverRef) {
187
224
  capabilities: {}
188
225
  }
189
226
  );
190
- const CONNECTION_TIMEOUT_MS = 5e3;
227
+ const connectionTimeout = poolConfig.connectionTimeout;
191
228
  const connectPromise = client.connect(transport);
192
229
  const timeoutPromise = new Promise((_, reject) => {
193
230
  const timeoutId = setTimeout(() => {
194
231
  reject(
195
232
  new Error(
196
- `Connection to MCP server "${name}" timed out after ${CONNECTION_TIMEOUT_MS}ms`
233
+ `Connection to MCP server "${name}" timed out after ${connectionTimeout}ms`
197
234
  )
198
235
  );
199
- }, CONNECTION_TIMEOUT_MS);
236
+ }, connectionTimeout);
200
237
  connectPromise.then(
201
238
  () => clearTimeout(timeoutId),
202
239
  () => clearTimeout(timeoutId)
@@ -212,6 +249,11 @@ async function connectToServer(name, serverRef) {
212
249
  }
213
250
  });
214
251
  }
252
+ client.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
253
+ if (typeof getMCPTools.cache?.clear === "function") {
254
+ getMCPTools.cache.clear();
255
+ }
256
+ });
215
257
  return client;
216
258
  }
217
259
  function getMcprcServerStatus(serverName) {
@@ -227,10 +269,11 @@ function getMcprcServerStatus(serverName) {
227
269
  let connectedClients = [];
228
270
  const DEFAULT_POOL_CONFIG = {
229
271
  maxConnections: 10,
230
- connectionTimeout: 5e3,
272
+ connectionTimeout: Number(process.env.MCP_TIMEOUT) || 1e4,
231
273
  healthCheckInterval: 3e4,
232
274
  retryFailed: true,
233
- maxRetries: 3
275
+ maxRetries: 2,
276
+ maxOutputChars: Number(process.env.MAX_MCP_OUTPUT_CHARS) || 25e3
234
277
  };
235
278
  let poolConfig = { ...DEFAULT_POOL_CONFIG };
236
279
  let healthCheckTimer = null;
@@ -325,7 +368,11 @@ function startHealthCheck() {
325
368
  healthCheckTimer = setInterval(async () => {
326
369
  try {
327
370
  await runHealthCheck();
328
- } catch {
371
+ } catch (e) {
372
+ debugLogger.warn(
373
+ "MCP_HEALTH",
374
+ `Health check failed: ${e instanceof Error ? e.message : String(e)}`
375
+ );
329
376
  }
330
377
  }, poolConfig.healthCheckInterval);
331
378
  }
@@ -345,6 +392,27 @@ function getPoolStats() {
345
392
  unhealthyCount: health.filter((h) => h.status === "unhealthy").length
346
393
  };
347
394
  }
395
+ async function connectWithRetry(name, serverRef) {
396
+ const { retryFailed, maxRetries } = poolConfig;
397
+ let lastError;
398
+ const attempts = retryFailed ? maxRetries : 0;
399
+ for (let attempt = 0; attempt <= attempts; attempt++) {
400
+ try {
401
+ return await connectToServer(name, serverRef);
402
+ } catch (error) {
403
+ lastError = error instanceof Error ? error : new Error(String(error));
404
+ if (attempt < attempts && retryFailed) {
405
+ const delay = 1e3 * Math.pow(2, attempt);
406
+ logMCPError(
407
+ name,
408
+ `Connection attempt ${attempt + 1} failed, retrying in ${delay}ms...`
409
+ );
410
+ await new Promise((r) => setTimeout(r, delay));
411
+ }
412
+ }
413
+ }
414
+ throw lastError;
415
+ }
348
416
  const getClients = memoize(async () => {
349
417
  if (process.env.CI && process.env.NODE_ENV !== "test") {
350
418
  return [];
@@ -371,7 +439,10 @@ const getClients = memoize(async () => {
371
439
  const clients = await Promise.all(
372
440
  Object.entries(enabledServers).map(async ([name, serverRef]) => {
373
441
  try {
374
- const client = await connectToServer(name, serverRef);
442
+ const client = await connectWithRetry(
443
+ name,
444
+ serverRef
445
+ );
375
446
  return { name, client, type: "connected" };
376
447
  } catch (error) {
377
448
  logMCPError(
@@ -416,6 +487,28 @@ async function requestAll(req, resultSchema, requiredCapability) {
416
487
  (result) => result !== null
417
488
  );
418
489
  }
490
+ function isLazyMCPEnabled() {
491
+ return !!(process.env.MINTO_ENABLE_TOOL_SEARCH || process.env.ENABLE_TOOL_SEARCH);
492
+ }
493
+ const lazySchemaCache = /* @__PURE__ */ new Map();
494
+ async function getLazyInputSchema(client, toolName, fullName) {
495
+ if (lazySchemaCache.has(fullName)) {
496
+ return lazySchemaCache.get(fullName);
497
+ }
498
+ try {
499
+ const result = await client.client.request(
500
+ { method: "tools/list" },
501
+ ListToolsResultSchema
502
+ );
503
+ for (const tool of result.tools) {
504
+ const key = "mcp__" + client.name + "__" + tool.name;
505
+ lazySchemaCache.set(key, tool.inputSchema);
506
+ }
507
+ return lazySchemaCache.get(fullName);
508
+ } catch {
509
+ return void 0;
510
+ }
511
+ }
419
512
  const getMCPTools = memoize(async () => {
420
513
  const toolsList = await requestAll(
421
514
  {
@@ -424,6 +517,7 @@ const getMCPTools = memoize(async () => {
424
517
  ListToolsResultSchema,
425
518
  "tools"
426
519
  );
520
+ const lazyMode = isLazyMCPEnabled();
427
521
  return toolsList.flatMap(({ client, result: { tools } }) => {
428
522
  const validTools = tools.filter(
429
523
  (tool) => {
@@ -437,21 +531,32 @@ const getMCPTools = memoize(async () => {
437
531
  return true;
438
532
  }
439
533
  );
440
- return validTools.map(
441
- (tool) => ({
534
+ return validTools.map((tool) => {
535
+ const fullName = "mcp__" + client.name + "__" + tool.name;
536
+ if (lazyMode) {
537
+ lazySchemaCache.set(
538
+ fullName,
539
+ tool.inputSchema
540
+ );
541
+ }
542
+ return {
442
543
  ...MCPTool,
443
- name: "mcp__" + client.name + "__" + tool.name,
544
+ name: fullName,
444
545
  async description() {
445
546
  return tool.description ?? "";
446
547
  },
447
548
  async prompt() {
448
549
  return tool.description ?? "";
449
550
  },
450
- inputJSONSchema: tool.inputSchema,
551
+ // In lazy mode, schema starts as undefined and is loaded on-demand
552
+ inputJSONSchema: lazyMode ? void 0 : tool.inputSchema,
451
553
  async validateInput(input, context) {
452
554
  return { result: true };
453
555
  },
454
556
  async *call(args, context) {
557
+ if (lazyMode && !lazySchemaCache.has(fullName)) {
558
+ await getLazyInputSchema(client, tool.name, fullName);
559
+ }
455
560
  const data = await callMCPTool({ client, tool: tool.name, args });
456
561
  yield {
457
562
  type: "result",
@@ -462,8 +567,8 @@ const getMCPTools = memoize(async () => {
462
567
  userFacingName() {
463
568
  return `${client.name}:${tool.name} (MCP)`;
464
569
  }
465
- })
466
- );
570
+ };
571
+ });
467
572
  });
468
573
  });
469
574
  async function withTimeout(promise, timeoutMs, operationName) {
@@ -497,6 +602,13 @@ function isTimeoutError(error) {
497
602
  }
498
603
  const MCP_TOOL_TIMEOUT_MS = 12e4;
499
604
  const MCP_TOOL_MAX_RETRIES = 2;
605
+ function truncateMcpOutput(text) {
606
+ const limit = poolConfig.maxOutputChars;
607
+ if (text.length <= limit) return text;
608
+ return text.slice(0, limit) + `
609
+
610
+ [Output truncated: ${text.length} chars exceeded limit of ${limit}]`;
611
+ }
500
612
  async function callMCPTool({
501
613
  client: { client, name },
502
614
  tool,
@@ -527,7 +639,8 @@ async function callMCPTool({
527
639
  throw Error(errorMessage);
528
640
  }
529
641
  if ("toolResult" in result) {
530
- return String(result.toolResult);
642
+ const text = String(result.toolResult);
643
+ return truncateMcpOutput(text);
531
644
  }
532
645
  if ("content" in result && Array.isArray(result.content)) {
533
646
  return result.content.map((item) => {
@@ -618,6 +731,9 @@ async function runCommand({ name, client }, args) {
618
731
  message.content.type === "text" ? {
619
732
  type: "text",
620
733
  text: message.content.text
734
+ } : message.content.type === "resource" ? {
735
+ type: "text",
736
+ text: typeof message.content.resource?.text === "string" ? message.content.resource.text : `[MCP Resource: ${message.content.resource?.uri ?? "unknown"}]`
621
737
  } : {
622
738
  type: "image",
623
739
  source: {
@@ -637,6 +753,26 @@ async function runCommand({ name, client }, args) {
637
753
  throw error;
638
754
  }
639
755
  }
756
+ function closeClientsInBackground(clients) {
757
+ const CLOSE_TIMEOUT_MS = 5e3;
758
+ const closePromises = clients.map(async (wrappedClient) => {
759
+ if (wrappedClient.type === "connected") {
760
+ try {
761
+ await wrappedClient.client.close();
762
+ } catch (e) {
763
+ debugLogger.warn(
764
+ "MCP_CLOSE",
765
+ `Failed to close MCP client: ${e instanceof Error ? e.message : String(e)}`
766
+ );
767
+ }
768
+ }
769
+ });
770
+ Promise.race([
771
+ Promise.allSettled(closePromises),
772
+ new Promise((resolve) => setTimeout(resolve, CLOSE_TIMEOUT_MS))
773
+ ]).catch(() => {
774
+ });
775
+ }
640
776
  async function refreshMCPConnections() {
641
777
  if (pendingRefresh) {
642
778
  return;
@@ -644,6 +780,8 @@ async function refreshMCPConnections() {
644
780
  pendingRefresh = true;
645
781
  const release = await acquireConnectionLock();
646
782
  try {
783
+ const oldClients = connectedClients;
784
+ connectedClients = [];
647
785
  if (typeof getClients.cache?.clear === "function") {
648
786
  getClients.cache.clear();
649
787
  }
@@ -659,16 +797,20 @@ async function refreshMCPConnections() {
659
797
  invalidateToolsCache();
660
798
  } catch {
661
799
  }
800
+ if (oldClients.length > 0) {
801
+ closeClientsInBackground(oldClients);
802
+ }
662
803
  } finally {
663
804
  pendingRefresh = false;
664
805
  release();
665
806
  }
666
807
  }
667
808
  async function shutdownMCPClients() {
668
- if (connectedClients.length === 0) {
669
- return;
670
- }
671
- const closePromises = connectedClients.map(async (wrappedClient) => {
809
+ if (connectedClients.length === 0) return;
810
+ const oldClients = connectedClients;
811
+ connectedClients = [];
812
+ const SHUTDOWN_TIMEOUT_MS = 3e3;
813
+ const closePromises = oldClients.map(async (wrappedClient) => {
672
814
  if (wrappedClient.type === "connected") {
673
815
  try {
674
816
  await wrappedClient.client.close();
@@ -676,7 +818,6 @@ async function shutdownMCPClients() {
676
818
  }
677
819
  }
678
820
  });
679
- const SHUTDOWN_TIMEOUT_MS = 3e3;
680
821
  try {
681
822
  await Promise.race([
682
823
  Promise.allSettled(closePromises),
@@ -684,8 +825,15 @@ async function shutdownMCPClients() {
684
825
  ]);
685
826
  } catch {
686
827
  }
687
- connectedClients = [];
688
- await refreshMCPConnections();
828
+ if (typeof getClients.cache?.clear === "function") {
829
+ getClients.cache.clear();
830
+ }
831
+ if (typeof getMCPTools.cache?.clear === "function") {
832
+ getMCPTools.cache.clear();
833
+ }
834
+ if (typeof getMCPCommands.cache?.clear === "function") {
835
+ getMCPCommands.cache.clear();
836
+ }
689
837
  }
690
838
  async function listMCPResources(serverFilter) {
691
839
  const results = await requestAll(
@@ -731,6 +879,8 @@ async function readMCPResource(uri, serverName) {
731
879
  text: "text" in content ? String(content.text) : void 0,
732
880
  blob: "blob" in content ? String(content.blob) : void 0
733
881
  };
882
+ } else {
883
+ emitReminderEvent("mcp:resource_no_content", { resourceUri: uri });
734
884
  }
735
885
  } catch (error) {
736
886
  logMCPError(