@mxf-dev/core 2.0.5 → 3.0.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 (466) hide show
  1. package/dist/config/ModelContextLimits.d.ts.map +1 -1
  2. package/dist/config/ModelContextLimits.js +7 -1
  3. package/dist/config/ModelContextLimits.js.map +1 -1
  4. package/dist/constants/CoreTools.d.ts +6 -5
  5. package/dist/constants/CoreTools.d.ts.map +1 -1
  6. package/dist/constants/CoreTools.js +6 -5
  7. package/dist/constants/CoreTools.js.map +1 -1
  8. package/dist/constants/DefaultPhaseProfiles.d.ts.map +1 -1
  9. package/dist/constants/DefaultPhaseProfiles.js +29 -0
  10. package/dist/constants/DefaultPhaseProfiles.js.map +1 -1
  11. package/dist/constants/ReservedIdentities.d.ts +14 -0
  12. package/dist/constants/ReservedIdentities.d.ts.map +1 -0
  13. package/dist/constants/ReservedIdentities.js +42 -0
  14. package/dist/constants/ReservedIdentities.js.map +1 -0
  15. package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.d.ts +16 -16
  16. package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.d.ts.map +1 -1
  17. package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.js +98 -36
  18. package/dist/database/adapters/mongodb/MongoKnowledgeGraphRepository.js.map +1 -1
  19. package/dist/events/ClientEventBus.d.ts +28 -0
  20. package/dist/events/ClientEventBus.d.ts.map +1 -1
  21. package/dist/events/ClientEventBus.js +87 -40
  22. package/dist/events/ClientEventBus.js.map +1 -1
  23. package/dist/events/EventBus.d.ts +19 -1
  24. package/dist/events/EventBus.d.ts.map +1 -1
  25. package/dist/events/EventBus.js +23 -0
  26. package/dist/events/EventBus.js.map +1 -1
  27. package/dist/events/EventBusBase.d.ts +37 -6
  28. package/dist/events/EventBusBase.d.ts.map +1 -1
  29. package/dist/events/EventBusBase.js +75 -27
  30. package/dist/events/EventBusBase.js.map +1 -1
  31. package/dist/events/EventNames.d.ts +49 -36
  32. package/dist/events/EventNames.d.ts.map +1 -1
  33. package/dist/events/EventNames.js +38 -36
  34. package/dist/events/EventNames.js.map +1 -1
  35. package/dist/events/PublicEvents.d.ts +5 -1
  36. package/dist/events/PublicEvents.d.ts.map +1 -1
  37. package/dist/events/PublicEvents.js +7 -0
  38. package/dist/events/PublicEvents.js.map +1 -1
  39. package/dist/events/ServerEventBus.d.ts +7 -54
  40. package/dist/events/ServerEventBus.d.ts.map +1 -1
  41. package/dist/events/ServerEventBus.js +10 -96
  42. package/dist/events/ServerEventBus.js.map +1 -1
  43. package/dist/events/event-definitions/ControlLoopEvents.d.ts +35 -0
  44. package/dist/events/event-definitions/ControlLoopEvents.d.ts.map +1 -1
  45. package/dist/events/event-definitions/ControlLoopEvents.js +6 -0
  46. package/dist/events/event-definitions/ControlLoopEvents.js.map +1 -1
  47. package/dist/events/event-definitions/SdkEvents.d.ts +55 -0
  48. package/dist/events/event-definitions/SdkEvents.d.ts.map +1 -0
  49. package/dist/events/event-definitions/SdkEvents.js +36 -0
  50. package/dist/events/event-definitions/SdkEvents.js.map +1 -0
  51. package/dist/events/event-definitions/TaskEvents.d.ts +2 -7
  52. package/dist/events/event-definitions/TaskEvents.d.ts.map +1 -1
  53. package/dist/index.d.ts +4 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +2 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/interfaces/AgentInterfaces.d.ts +5 -0
  58. package/dist/interfaces/AgentInterfaces.d.ts.map +1 -1
  59. package/dist/interfaces/ChannelConfig.d.ts +2 -2
  60. package/dist/interfaces/ChannelConfig.d.ts.map +1 -1
  61. package/dist/interfaces/ConversationMessage.d.ts +1 -1
  62. package/dist/interfaces/ConversationMessage.d.ts.map +1 -1
  63. package/dist/interfaces/IMemoryPersistence.d.ts +47 -1
  64. package/dist/interfaces/IMemoryPersistence.d.ts.map +1 -1
  65. package/dist/interfaces/SocketServiceInterface.d.ts +3 -2
  66. package/dist/interfaces/SocketServiceInterface.d.ts.map +1 -1
  67. package/dist/interfaces/TaskInterfaces.d.ts +14 -1
  68. package/dist/interfaces/TaskInterfaces.d.ts.map +1 -1
  69. package/dist/models/agent.d.ts +0 -1
  70. package/dist/models/agent.d.ts.map +1 -1
  71. package/dist/models/agent.js +0 -5
  72. package/dist/models/agent.js.map +1 -1
  73. package/dist/models/agentIdentityReservation.d.ts +42 -0
  74. package/dist/models/agentIdentityReservation.d.ts.map +1 -0
  75. package/dist/models/agentIdentityReservation.js +52 -0
  76. package/dist/models/agentIdentityReservation.js.map +1 -0
  77. package/dist/models/channel.d.ts +2 -0
  78. package/dist/models/channel.d.ts.map +1 -1
  79. package/dist/models/channel.js.map +1 -1
  80. package/dist/models/channelKey.d.ts +1 -0
  81. package/dist/models/channelKey.d.ts.map +1 -1
  82. package/dist/models/channelKey.js +5 -0
  83. package/dist/models/channelKey.js.map +1 -1
  84. package/dist/models/memory.d.ts +1 -1
  85. package/dist/models/memory.d.ts.map +1 -1
  86. package/dist/models/memory.js +9 -12
  87. package/dist/models/memory.js.map +1 -1
  88. package/dist/models/memoryStrata.d.ts +3 -16
  89. package/dist/models/memoryStrata.d.ts.map +1 -1
  90. package/dist/models/memoryStrata.js +3 -5
  91. package/dist/models/memoryStrata.js.map +1 -1
  92. package/dist/models/plan.d.ts +2 -2
  93. package/dist/models/plan.d.ts.map +1 -1
  94. package/dist/models/plan.js +1 -1
  95. package/dist/models/plan.js.map +1 -1
  96. package/dist/models/taskEffectiveness.d.ts +1 -0
  97. package/dist/models/taskEffectiveness.d.ts.map +1 -1
  98. package/dist/models/taskEffectiveness.js +7 -1
  99. package/dist/models/taskEffectiveness.js.map +1 -1
  100. package/dist/models/user.d.ts +4 -0
  101. package/dist/models/user.d.ts.map +1 -1
  102. package/dist/models/user.js +8 -0
  103. package/dist/models/user.js.map +1 -1
  104. package/dist/protocols/mcp/LlmTestEnvironmentGuard.d.ts +16 -0
  105. package/dist/protocols/mcp/LlmTestEnvironmentGuard.d.ts.map +1 -0
  106. package/dist/protocols/mcp/LlmTestEnvironmentGuard.js +25 -0
  107. package/dist/protocols/mcp/LlmTestEnvironmentGuard.js.map +1 -0
  108. package/dist/protocols/mcp/McpServerTypes.d.ts +9 -0
  109. package/dist/protocols/mcp/McpServerTypes.d.ts.map +1 -1
  110. package/dist/protocols/mcp/providers/AnthropicMcpClient.d.ts.map +1 -1
  111. package/dist/protocols/mcp/providers/AnthropicMcpClient.js +1 -0
  112. package/dist/protocols/mcp/providers/AnthropicMcpClient.js.map +1 -1
  113. package/dist/protocols/mcp/providers/AzureOpenAiMcpClient.d.ts.map +1 -1
  114. package/dist/protocols/mcp/providers/AzureOpenAiMcpClient.js +1 -0
  115. package/dist/protocols/mcp/providers/AzureOpenAiMcpClient.js.map +1 -1
  116. package/dist/protocols/mcp/providers/BaseMcpClient.d.ts +4 -0
  117. package/dist/protocols/mcp/providers/BaseMcpClient.d.ts.map +1 -1
  118. package/dist/protocols/mcp/providers/BaseMcpClient.js +10 -0
  119. package/dist/protocols/mcp/providers/BaseMcpClient.js.map +1 -1
  120. package/dist/protocols/mcp/providers/CustomMcpClient.d.ts.map +1 -1
  121. package/dist/protocols/mcp/providers/CustomMcpClient.js +7 -0
  122. package/dist/protocols/mcp/providers/CustomMcpClient.js.map +1 -1
  123. package/dist/protocols/mcp/providers/GeminiMcpClient.d.ts.map +1 -1
  124. package/dist/protocols/mcp/providers/GeminiMcpClient.js +1 -0
  125. package/dist/protocols/mcp/providers/GeminiMcpClient.js.map +1 -1
  126. package/dist/protocols/mcp/providers/OllamaMcpClient.d.ts +1 -0
  127. package/dist/protocols/mcp/providers/OllamaMcpClient.d.ts.map +1 -1
  128. package/dist/protocols/mcp/providers/OllamaMcpClient.js +1 -0
  129. package/dist/protocols/mcp/providers/OllamaMcpClient.js.map +1 -1
  130. package/dist/protocols/mcp/providers/OpenAiMcpClient.d.ts.map +1 -1
  131. package/dist/protocols/mcp/providers/OpenAiMcpClient.js +1 -0
  132. package/dist/protocols/mcp/providers/OpenAiMcpClient.js.map +1 -1
  133. package/dist/protocols/mcp/providers/OpenRouterMcpClient.d.ts.map +1 -1
  134. package/dist/protocols/mcp/providers/OpenRouterMcpClient.js +2 -0
  135. package/dist/protocols/mcp/providers/OpenRouterMcpClient.js.map +1 -1
  136. package/dist/protocols/mcp/providers/XaiMcpClient.d.ts.map +1 -1
  137. package/dist/protocols/mcp/providers/XaiMcpClient.js +1 -0
  138. package/dist/protocols/mcp/providers/XaiMcpClient.js.map +1 -1
  139. package/dist/protocols/mcp/security/BrowserTargetGuard.d.ts +14 -0
  140. package/dist/protocols/mcp/security/BrowserTargetGuard.d.ts.map +1 -0
  141. package/dist/protocols/mcp/security/BrowserTargetGuard.js +55 -0
  142. package/dist/protocols/mcp/security/BrowserTargetGuard.js.map +1 -0
  143. package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.d.ts +24 -0
  144. package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.d.ts.map +1 -0
  145. package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.js +33 -0
  146. package/dist/protocols/mcp/security/ExternalMcpRegistrationPolicy.js.map +1 -0
  147. package/dist/protocols/mcp/security/HttpTargetGuard.d.ts.map +1 -1
  148. package/dist/protocols/mcp/security/HttpTargetGuard.js +68 -6
  149. package/dist/protocols/mcp/security/HttpTargetGuard.js.map +1 -1
  150. package/dist/protocols/mcp/security/McpSecurityGuard.d.ts.map +1 -1
  151. package/dist/protocols/mcp/security/McpSecurityGuard.js +7 -5
  152. package/dist/protocols/mcp/security/McpSecurityGuard.js.map +1 -1
  153. package/dist/protocols/mcp/security/McpToolPolicy.d.ts +18 -0
  154. package/dist/protocols/mcp/security/McpToolPolicy.d.ts.map +1 -1
  155. package/dist/protocols/mcp/security/McpToolPolicy.js +60 -0
  156. package/dist/protocols/mcp/security/McpToolPolicy.js.map +1 -1
  157. package/dist/protocols/mcp/services/ExternalMcpServerManager.d.ts +25 -0
  158. package/dist/protocols/mcp/services/ExternalMcpServerManager.d.ts.map +1 -1
  159. package/dist/protocols/mcp/services/ExternalMcpServerManager.js +93 -17
  160. package/dist/protocols/mcp/services/ExternalMcpServerManager.js.map +1 -1
  161. package/dist/protocols/mcp/services/ExternalServerConfigs.d.ts +2 -2
  162. package/dist/protocols/mcp/services/ExternalServerConfigs.d.ts.map +1 -1
  163. package/dist/protocols/mcp/services/ExternalServerConfigs.js +25 -8
  164. package/dist/protocols/mcp/services/ExternalServerConfigs.js.map +1 -1
  165. package/dist/protocols/mcp/tools/AnalyticsTools.d.ts +3 -37
  166. package/dist/protocols/mcp/tools/AnalyticsTools.d.ts.map +1 -1
  167. package/dist/protocols/mcp/tools/AnalyticsTools.js +134 -614
  168. package/dist/protocols/mcp/tools/AnalyticsTools.js.map +1 -1
  169. package/dist/protocols/mcp/tools/CodeAnalysisTools.d.ts.map +1 -1
  170. package/dist/protocols/mcp/tools/CodeAnalysisTools.js +16 -13
  171. package/dist/protocols/mcp/tools/CodeAnalysisTools.js.map +1 -1
  172. package/dist/protocols/mcp/tools/EffectivenessTools.d.ts.map +1 -1
  173. package/dist/protocols/mcp/tools/EffectivenessTools.js +94 -30
  174. package/dist/protocols/mcp/tools/EffectivenessTools.js.map +1 -1
  175. package/dist/protocols/mcp/tools/GitTools.d.ts.map +1 -1
  176. package/dist/protocols/mcp/tools/GitTools.js +9 -5
  177. package/dist/protocols/mcp/tools/GitTools.js.map +1 -1
  178. package/dist/protocols/mcp/tools/InfrastructureTools.d.ts +10 -40
  179. package/dist/protocols/mcp/tools/InfrastructureTools.d.ts.map +1 -1
  180. package/dist/protocols/mcp/tools/InfrastructureTools.js +29 -70
  181. package/dist/protocols/mcp/tools/InfrastructureTools.js.map +1 -1
  182. package/dist/protocols/mcp/tools/JsonTools.d.ts.map +1 -1
  183. package/dist/protocols/mcp/tools/JsonTools.js +4 -4
  184. package/dist/protocols/mcp/tools/JsonTools.js.map +1 -1
  185. package/dist/protocols/mcp/tools/KnowledgeGraphTools.d.ts +55 -592
  186. package/dist/protocols/mcp/tools/KnowledgeGraphTools.d.ts.map +1 -1
  187. package/dist/protocols/mcp/tools/KnowledgeGraphTools.js +169 -119
  188. package/dist/protocols/mcp/tools/KnowledgeGraphTools.js.map +1 -1
  189. package/dist/protocols/mcp/tools/MemorySearchTools.d.ts +6 -6
  190. package/dist/protocols/mcp/tools/MemorySearchTools.d.ts.map +1 -1
  191. package/dist/protocols/mcp/tools/MemorySearchTools.js +107 -39
  192. package/dist/protocols/mcp/tools/MemorySearchTools.js.map +1 -1
  193. package/dist/protocols/mcp/tools/MemoryUtilityTools.d.ts +4 -5
  194. package/dist/protocols/mcp/tools/MemoryUtilityTools.d.ts.map +1 -1
  195. package/dist/protocols/mcp/tools/MemoryUtilityTools.js +59 -208
  196. package/dist/protocols/mcp/tools/MemoryUtilityTools.js.map +1 -1
  197. package/dist/protocols/mcp/tools/PlanningTools.d.ts +2 -1
  198. package/dist/protocols/mcp/tools/PlanningTools.d.ts.map +1 -1
  199. package/dist/protocols/mcp/tools/PlanningTools.js +111 -49
  200. package/dist/protocols/mcp/tools/PlanningTools.js.map +1 -1
  201. package/dist/protocols/mcp/tools/ProjectContextTools.d.ts.map +1 -1
  202. package/dist/protocols/mcp/tools/ProjectContextTools.js +18 -12
  203. package/dist/protocols/mcp/tools/ProjectContextTools.js.map +1 -1
  204. package/dist/protocols/mcp/tools/SafetyTools.d.ts.map +1 -1
  205. package/dist/protocols/mcp/tools/SafetyTools.js +16 -13
  206. package/dist/protocols/mcp/tools/SafetyTools.js.map +1 -1
  207. package/dist/protocols/mcp/tools/SearchProjectTools.d.ts +24 -7
  208. package/dist/protocols/mcp/tools/SearchProjectTools.d.ts.map +1 -1
  209. package/dist/protocols/mcp/tools/SearchProjectTools.js +226 -126
  210. package/dist/protocols/mcp/tools/SearchProjectTools.js.map +1 -1
  211. package/dist/protocols/mcp/tools/TaskPlanningTools.d.ts +0 -32
  212. package/dist/protocols/mcp/tools/TaskPlanningTools.d.ts.map +1 -1
  213. package/dist/protocols/mcp/tools/TaskPlanningTools.js +363 -450
  214. package/dist/protocols/mcp/tools/TaskPlanningTools.js.map +1 -1
  215. package/dist/protocols/mcp/tools/TestTools.d.ts.map +1 -1
  216. package/dist/protocols/mcp/tools/TestTools.js +18 -11
  217. package/dist/protocols/mcp/tools/TestTools.js.map +1 -1
  218. package/dist/protocols/mcp/tools/TypeScriptTools.d.ts.map +1 -1
  219. package/dist/protocols/mcp/tools/TypeScriptTools.js +22 -12
  220. package/dist/protocols/mcp/tools/TypeScriptTools.js.map +1 -1
  221. package/dist/protocols/mcp/tools/UserInputTools.d.ts.map +1 -1
  222. package/dist/protocols/mcp/tools/UserInputTools.js +14 -1
  223. package/dist/protocols/mcp/tools/UserInputTools.js.map +1 -1
  224. package/dist/protocols/mcp/tools/UserMemoryTools.d.ts +3 -1
  225. package/dist/protocols/mcp/tools/UserMemoryTools.d.ts.map +1 -1
  226. package/dist/protocols/mcp/tools/UserMemoryTools.js +27 -62
  227. package/dist/protocols/mcp/tools/UserMemoryTools.js.map +1 -1
  228. package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.d.ts.map +1 -1
  229. package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.js +14 -60
  230. package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.js.map +1 -1
  231. package/dist/protocols/mcp/tools/shell/ShellSandbox.d.ts.map +1 -1
  232. package/dist/protocols/mcp/tools/shell/ShellSandbox.js +9 -27
  233. package/dist/protocols/mcp/tools/shell/ShellSandbox.js.map +1 -1
  234. package/dist/repositories/interfaces/IKnowledgeGraphRepository.d.ts +40 -30
  235. package/dist/repositories/interfaces/IKnowledgeGraphRepository.d.ts.map +1 -1
  236. package/dist/schemas/EventPayloadSchema.d.ts +28 -0
  237. package/dist/schemas/EventPayloadSchema.d.ts.map +1 -1
  238. package/dist/schemas/EventPayloadSchema.js +30 -1
  239. package/dist/schemas/EventPayloadSchema.js.map +1 -1
  240. package/dist/schemas/MxpProtocolSchemas.d.ts +6 -6
  241. package/dist/services/AgentPerformanceService.d.ts +11 -0
  242. package/dist/services/AgentPerformanceService.d.ts.map +1 -1
  243. package/dist/services/AgentPerformanceService.js +59 -33
  244. package/dist/services/AgentPerformanceService.js.map +1 -1
  245. package/dist/services/AutoCorrectionService.d.ts +3 -0
  246. package/dist/services/AutoCorrectionService.d.ts.map +1 -1
  247. package/dist/services/AutoCorrectionService.js +19 -2
  248. package/dist/services/AutoCorrectionService.js.map +1 -1
  249. package/dist/services/BackgroundTaskManager.d.ts +23 -7
  250. package/dist/services/BackgroundTaskManager.d.ts.map +1 -1
  251. package/dist/services/BackgroundTaskManager.js +137 -57
  252. package/dist/services/BackgroundTaskManager.js.map +1 -1
  253. package/dist/services/BrowserManager.d.ts +2 -0
  254. package/dist/services/BrowserManager.d.ts.map +1 -1
  255. package/dist/services/BrowserManager.js +18 -15
  256. package/dist/services/BrowserManager.js.map +1 -1
  257. package/dist/services/ChannelContextMemoryOperations.d.ts +8 -1
  258. package/dist/services/ChannelContextMemoryOperations.d.ts.map +1 -1
  259. package/dist/services/ChannelContextMemoryOperations.js +89 -165
  260. package/dist/services/ChannelContextMemoryOperations.js.map +1 -1
  261. package/dist/services/ChannelContextMessageOperations.d.ts +4 -3
  262. package/dist/services/ChannelContextMessageOperations.d.ts.map +1 -1
  263. package/dist/services/ChannelContextMessageOperations.js +72 -212
  264. package/dist/services/ChannelContextMessageOperations.js.map +1 -1
  265. package/dist/services/MemoryService.d.ts +52 -21
  266. package/dist/services/MemoryService.d.ts.map +1 -1
  267. package/dist/services/MemoryService.js +775 -548
  268. package/dist/services/MemoryService.js.map +1 -1
  269. package/dist/services/PatternLearningService.d.ts +5 -0
  270. package/dist/services/PatternLearningService.d.ts.map +1 -1
  271. package/dist/services/PatternLearningService.js +26 -3
  272. package/dist/services/PatternLearningService.js.map +1 -1
  273. package/dist/services/PerformanceOptimizationService.d.ts +2 -1
  274. package/dist/services/PerformanceOptimizationService.d.ts.map +1 -1
  275. package/dist/services/PerformanceOptimizationService.js +21 -6
  276. package/dist/services/PerformanceOptimizationService.js.map +1 -1
  277. package/dist/services/PredictiveAnalyticsService.d.ts +1 -0
  278. package/dist/services/PredictiveAnalyticsService.d.ts.map +1 -1
  279. package/dist/services/PredictiveAnalyticsService.js +18 -6
  280. package/dist/services/PredictiveAnalyticsService.js.map +1 -1
  281. package/dist/services/ProactiveValidationService.d.ts +6 -0
  282. package/dist/services/ProactiveValidationService.d.ts.map +1 -1
  283. package/dist/services/ProactiveValidationService.js +58 -39
  284. package/dist/services/ProactiveValidationService.js.map +1 -1
  285. package/dist/services/TaskEffectivenessService.d.ts +55 -31
  286. package/dist/services/TaskEffectivenessService.d.ts.map +1 -1
  287. package/dist/services/TaskEffectivenessService.js +243 -125
  288. package/dist/services/TaskEffectivenessService.js.map +1 -1
  289. package/dist/services/ToolExecutionInterceptor.d.ts +4 -0
  290. package/dist/services/ToolExecutionInterceptor.d.ts.map +1 -1
  291. package/dist/services/ToolExecutionInterceptor.js +31 -5
  292. package/dist/services/ToolExecutionInterceptor.js.map +1 -1
  293. package/dist/services/UserInputRequestManager.d.ts +13 -3
  294. package/dist/services/UserInputRequestManager.d.ts.map +1 -1
  295. package/dist/services/UserInputRequestManager.js +42 -6
  296. package/dist/services/UserInputRequestManager.js.map +1 -1
  297. package/dist/services/UserMemoryService.d.ts +2 -0
  298. package/dist/services/UserMemoryService.d.ts.map +1 -1
  299. package/dist/services/UserMemoryService.js +9 -4
  300. package/dist/services/UserMemoryService.js.map +1 -1
  301. package/dist/services/ValidationAnalyticsService.d.ts +4 -0
  302. package/dist/services/ValidationAnalyticsService.d.ts.map +1 -1
  303. package/dist/services/ValidationAnalyticsService.js +30 -8
  304. package/dist/services/ValidationAnalyticsService.js.map +1 -1
  305. package/dist/services/ValidationCacheService.d.ts +3 -1
  306. package/dist/services/ValidationCacheService.d.ts.map +1 -1
  307. package/dist/services/ValidationCacheService.js +25 -4
  308. package/dist/services/ValidationCacheService.js.map +1 -1
  309. package/dist/services/ValidationMiddleware.d.ts +7 -0
  310. package/dist/services/ValidationMiddleware.d.ts.map +1 -1
  311. package/dist/services/ValidationMiddleware.js +53 -10
  312. package/dist/services/ValidationMiddleware.js.map +1 -1
  313. package/dist/services/ValidationPerformanceService.d.ts +3 -0
  314. package/dist/services/ValidationPerformanceService.d.ts.map +1 -1
  315. package/dist/services/ValidationPerformanceService.js +28 -11
  316. package/dist/services/ValidationPerformanceService.js.map +1 -1
  317. package/dist/services/WebSearchService.d.ts.map +1 -1
  318. package/dist/services/WebSearchService.js +9 -0
  319. package/dist/services/WebSearchService.js.map +1 -1
  320. package/dist/services/dag/TaskDagService.d.ts +3 -0
  321. package/dist/services/dag/TaskDagService.d.ts.map +1 -1
  322. package/dist/services/dag/TaskDagService.js +18 -0
  323. package/dist/services/dag/TaskDagService.js.map +1 -1
  324. package/dist/services/kg/EntityQValueManager.d.ts +3 -1
  325. package/dist/services/kg/EntityQValueManager.d.ts.map +1 -1
  326. package/dist/services/kg/EntityQValueManager.js +10 -10
  327. package/dist/services/kg/EntityQValueManager.js.map +1 -1
  328. package/dist/services/kg/GraphSurpriseCalculator.d.ts +0 -4
  329. package/dist/services/kg/GraphSurpriseCalculator.d.ts.map +1 -1
  330. package/dist/services/kg/GraphSurpriseCalculator.js +0 -9
  331. package/dist/services/kg/GraphSurpriseCalculator.js.map +1 -1
  332. package/dist/services/kg/KnowledgeGraphService.d.ts +12 -12
  333. package/dist/services/kg/KnowledgeGraphService.d.ts.map +1 -1
  334. package/dist/services/kg/KnowledgeGraphService.js +43 -51
  335. package/dist/services/kg/KnowledgeGraphService.js.map +1 -1
  336. package/dist/services/kg/OrparGraphIntegration.d.ts.map +1 -1
  337. package/dist/services/kg/OrparGraphIntegration.js +6 -5
  338. package/dist/services/kg/OrparGraphIntegration.js.map +1 -1
  339. package/dist/services/orpar-memory/CycleConsolidationTrigger.d.ts +1 -0
  340. package/dist/services/orpar-memory/CycleConsolidationTrigger.d.ts.map +1 -1
  341. package/dist/services/orpar-memory/CycleConsolidationTrigger.js +8 -1
  342. package/dist/services/orpar-memory/CycleConsolidationTrigger.js.map +1 -1
  343. package/dist/services/orpar-memory/OrparMemoryCoordinator.d.ts +8 -1
  344. package/dist/services/orpar-memory/OrparMemoryCoordinator.d.ts.map +1 -1
  345. package/dist/services/orpar-memory/OrparMemoryCoordinator.js +93 -45
  346. package/dist/services/orpar-memory/OrparMemoryCoordinator.js.map +1 -1
  347. package/dist/services/orpar-memory/SurpriseOrparAdapter.d.ts +1 -0
  348. package/dist/services/orpar-memory/SurpriseOrparAdapter.d.ts.map +1 -1
  349. package/dist/services/orpar-memory/SurpriseOrparAdapter.js +8 -1
  350. package/dist/services/orpar-memory/SurpriseOrparAdapter.js.map +1 -1
  351. package/dist/types/ChannelContext.d.ts +2 -1
  352. package/dist/types/ChannelContext.d.ts.map +1 -1
  353. package/dist/types/EffectivenessTypes.d.ts +4 -1
  354. package/dist/types/EffectivenessTypes.d.ts.map +1 -1
  355. package/dist/types/TaskCompletionTypes.d.ts +7 -5
  356. package/dist/types/TaskCompletionTypes.d.ts.map +1 -1
  357. package/dist/types/TaskTypes.d.ts +8 -1
  358. package/dist/types/TaskTypes.d.ts.map +1 -1
  359. package/dist/utils/GlobMatcher.d.ts +37 -0
  360. package/dist/utils/GlobMatcher.d.ts.map +1 -0
  361. package/dist/utils/GlobMatcher.js +131 -0
  362. package/dist/utils/GlobMatcher.js.map +1 -0
  363. package/package.json +1 -1
  364. package/src/config/ModelContextLimits.ts +7 -1
  365. package/src/constants/CoreTools.ts +6 -5
  366. package/src/constants/DefaultPhaseProfiles.ts +29 -0
  367. package/src/constants/ReservedIdentities.ts +51 -0
  368. package/src/database/adapters/mongodb/MongoKnowledgeGraphRepository.ts +115 -36
  369. package/src/events/ClientEventBus.ts +117 -48
  370. package/src/events/EventBus.ts +32 -2
  371. package/src/events/EventBusBase.ts +132 -39
  372. package/src/events/EventNames.ts +43 -36
  373. package/src/events/PublicEvents.ts +8 -0
  374. package/src/events/ServerEventBus.ts +9 -128
  375. package/src/events/event-definitions/ControlLoopEvents.ts +12 -0
  376. package/src/events/event-definitions/SdkEvents.ts +58 -0
  377. package/src/events/event-definitions/TaskEvents.ts +2 -2
  378. package/src/index.ts +15 -0
  379. package/src/interfaces/AgentInterfaces.ts +5 -0
  380. package/src/interfaces/ChannelConfig.ts +2 -2
  381. package/src/interfaces/ConversationMessage.ts +5 -0
  382. package/src/interfaces/IMemoryPersistence.ts +55 -1
  383. package/src/interfaces/SocketServiceInterface.ts +3 -2
  384. package/src/interfaces/TaskInterfaces.ts +16 -1
  385. package/src/models/agent.ts +0 -6
  386. package/src/models/agentIdentityReservation.ts +77 -0
  387. package/src/models/channel.ts +2 -0
  388. package/src/models/channelKey.ts +10 -0
  389. package/src/models/memory.ts +18 -19
  390. package/src/models/memoryStrata.ts +9 -23
  391. package/src/models/plan.ts +3 -3
  392. package/src/models/taskEffectiveness.ts +9 -2
  393. package/src/models/user.ts +12 -0
  394. package/src/protocols/mcp/LlmTestEnvironmentGuard.ts +30 -0
  395. package/src/protocols/mcp/McpServerTypes.ts +9 -0
  396. package/src/protocols/mcp/providers/AnthropicMcpClient.ts +2 -0
  397. package/src/protocols/mcp/providers/AzureOpenAiMcpClient.ts +1 -0
  398. package/src/protocols/mcp/providers/BaseMcpClient.ts +13 -0
  399. package/src/protocols/mcp/providers/CustomMcpClient.ts +7 -0
  400. package/src/protocols/mcp/providers/GeminiMcpClient.ts +2 -0
  401. package/src/protocols/mcp/providers/OllamaMcpClient.ts +3 -1
  402. package/src/protocols/mcp/providers/OpenAiMcpClient.ts +2 -0
  403. package/src/protocols/mcp/providers/OpenRouterMcpClient.ts +3 -0
  404. package/src/protocols/mcp/providers/XaiMcpClient.ts +2 -0
  405. package/src/protocols/mcp/security/BrowserTargetGuard.ts +64 -0
  406. package/src/protocols/mcp/security/ExternalMcpRegistrationPolicy.ts +38 -0
  407. package/src/protocols/mcp/security/HttpTargetGuard.ts +77 -6
  408. package/src/protocols/mcp/security/McpSecurityGuard.ts +7 -5
  409. package/src/protocols/mcp/security/McpToolPolicy.ts +74 -0
  410. package/src/protocols/mcp/services/ExternalMcpServerManager.ts +146 -17
  411. package/src/protocols/mcp/services/ExternalServerConfigs.ts +26 -8
  412. package/src/protocols/mcp/tools/AnalyticsTools.ts +167 -641
  413. package/src/protocols/mcp/tools/CodeAnalysisTools.ts +44 -14
  414. package/src/protocols/mcp/tools/EffectivenessTools.ts +185 -45
  415. package/src/protocols/mcp/tools/GitTools.ts +15 -5
  416. package/src/protocols/mcp/tools/InfrastructureTools.ts +42 -90
  417. package/src/protocols/mcp/tools/JsonTools.ts +7 -4
  418. package/src/protocols/mcp/tools/KnowledgeGraphTools.ts +313 -164
  419. package/src/protocols/mcp/tools/MemorySearchTools.ts +158 -46
  420. package/src/protocols/mcp/tools/MemoryUtilityTools.ts +85 -232
  421. package/src/protocols/mcp/tools/PlanningTools.ts +137 -59
  422. package/src/protocols/mcp/tools/ProjectContextTools.ts +33 -12
  423. package/src/protocols/mcp/tools/SafetyTools.ts +49 -13
  424. package/src/protocols/mcp/tools/SearchProjectTools.ts +294 -153
  425. package/src/protocols/mcp/tools/TaskPlanningTools.ts +437 -514
  426. package/src/protocols/mcp/tools/TestTools.ts +41 -11
  427. package/src/protocols/mcp/tools/TypeScriptTools.ts +61 -12
  428. package/src/protocols/mcp/tools/UserInputTools.ts +15 -1
  429. package/src/protocols/mcp/tools/UserMemoryTools.ts +27 -62
  430. package/src/protocols/mcp/tools/shell/ShellExecuteHandler.ts +26 -84
  431. package/src/protocols/mcp/tools/shell/ShellSandbox.ts +13 -31
  432. package/src/repositories/interfaces/IKnowledgeGraphRepository.ts +45 -27
  433. package/src/schemas/EventPayloadSchema.ts +45 -1
  434. package/src/services/AgentPerformanceService.ts +85 -36
  435. package/src/services/AutoCorrectionService.ts +25 -6
  436. package/src/services/BackgroundTaskManager.ts +183 -76
  437. package/src/services/BrowserManager.ts +20 -16
  438. package/src/services/ChannelContextMemoryOperations.ts +169 -202
  439. package/src/services/ChannelContextMessageOperations.ts +112 -274
  440. package/src/services/MemoryService.ts +1053 -760
  441. package/src/services/PatternLearningService.ts +32 -7
  442. package/src/services/PerformanceOptimizationService.ts +26 -9
  443. package/src/services/PredictiveAnalyticsService.ts +23 -10
  444. package/src/services/ProactiveValidationService.ts +66 -40
  445. package/src/services/TaskEffectivenessService.ts +421 -206
  446. package/src/services/ToolExecutionInterceptor.ts +40 -9
  447. package/src/services/UserInputRequestManager.ts +51 -6
  448. package/src/services/UserMemoryService.ts +12 -3
  449. package/src/services/ValidationAnalyticsService.ts +36 -11
  450. package/src/services/ValidationCacheService.ts +30 -7
  451. package/src/services/ValidationMiddleware.ts +62 -14
  452. package/src/services/ValidationPerformanceService.ts +47 -25
  453. package/src/services/WebSearchService.ts +16 -4
  454. package/src/services/dag/TaskDagService.ts +20 -1
  455. package/src/services/kg/EntityQValueManager.ts +21 -10
  456. package/src/services/kg/GraphSurpriseCalculator.ts +0 -14
  457. package/src/services/kg/KnowledgeGraphService.ts +56 -48
  458. package/src/services/kg/OrparGraphIntegration.ts +11 -5
  459. package/src/services/orpar-memory/CycleConsolidationTrigger.ts +10 -1
  460. package/src/services/orpar-memory/OrparMemoryCoordinator.ts +142 -71
  461. package/src/services/orpar-memory/SurpriseOrparAdapter.ts +10 -1
  462. package/src/types/ChannelContext.ts +3 -1
  463. package/src/types/EffectivenessTypes.ts +6 -2
  464. package/src/types/TaskCompletionTypes.ts +9 -9
  465. package/src/types/TaskTypes.ts +12 -1
  466. package/src/utils/GlobMatcher.ts +157 -0
@@ -117,6 +117,75 @@ function ipv4InCidr(address: string, cidr: string): boolean {
117
117
  return (addressInt & mask) === (networkInt & mask);
118
118
  }
119
119
 
120
+ /**
121
+ * Decode an IPv6 literal into its eight 16-bit words.
122
+ *
123
+ * Node's `isIP()` tells us that a value is IPv6, but it does not expose the
124
+ * embedded IPv4 address from mapped forms. Browsers and operating systems
125
+ * accept both dotted (`::ffff:127.0.0.1`) and hexadecimal
126
+ * (`::ffff:7f00:1`) spellings, so matching only the dotted text leaves a
127
+ * loopback/metadata bypass.
128
+ */
129
+ function parseIpv6Words(address: string): number[] | null {
130
+ let normalized = address.toLowerCase();
131
+ const embeddedIpv4 = normalized.match(/^(.*:)(\d{1,3}(?:\.\d{1,3}){3})$/);
132
+ if (embeddedIpv4) {
133
+ const ipv4 = ipv4ToInt(embeddedIpv4[2]);
134
+ if (ipv4 === null) {
135
+ return null;
136
+ }
137
+ normalized = `${embeddedIpv4[1]}${(ipv4 >>> 16).toString(16)}:${(ipv4 & 0xffff).toString(16)}`;
138
+ }
139
+
140
+ const compressedParts = normalized.split('::');
141
+ if (compressedParts.length > 2) {
142
+ return null;
143
+ }
144
+
145
+ const parseSide = (side: string): number[] | null => {
146
+ if (side.length === 0) {
147
+ return [];
148
+ }
149
+ const words = side.split(':');
150
+ if (words.some(word => !/^[0-9a-f]{1,4}$/.test(word))) {
151
+ return null;
152
+ }
153
+ return words.map(word => Number.parseInt(word, 16));
154
+ };
155
+
156
+ const left = parseSide(compressedParts[0]);
157
+ const right = parseSide(compressedParts[1] ?? '');
158
+ if (!left || !right) {
159
+ return null;
160
+ }
161
+
162
+ if (compressedParts.length === 1) {
163
+ return left.length === 8 ? left : null;
164
+ }
165
+
166
+ const omittedWordCount = 8 - left.length - right.length;
167
+ if (omittedWordCount < 1) {
168
+ return null;
169
+ }
170
+ return [...left, ...Array<number>(omittedWordCount).fill(0), ...right];
171
+ }
172
+
173
+ /** Return the dotted IPv4 address carried by an IPv4-mapped IPv6 literal. */
174
+ function mappedIpv4Address(address: string): string | null {
175
+ const words = parseIpv6Words(address);
176
+ if (!words || words.length !== 8 ||
177
+ words.slice(0, 5).some(word => word !== 0) || words[5] !== 0xffff) {
178
+ return null;
179
+ }
180
+
181
+ return [
182
+ words[6] >>> 8,
183
+ words[6] & 0xff,
184
+ words[7] >>> 8,
185
+ words[7] & 0xff
186
+ ].join('.');
187
+ }
188
+
120
189
  /**
121
190
  * Is this address one the server must not be steered into?
122
191
  *
@@ -137,6 +206,14 @@ function matchBlockedRange(address: string): string | null {
137
206
  if (version === 6) {
138
207
  const normalized = address.toLowerCase();
139
208
 
209
+ // IPv4-mapped addresses have multiple equivalent textual forms. Decode
210
+ // the address instead of applying a dotted-quad-only regex, then run the
211
+ // embedded address through the complete IPv4 policy.
212
+ const mappedIpv4 = mappedIpv4Address(normalized);
213
+ if (mappedIpv4) {
214
+ return matchBlockedRange(mappedIpv4);
215
+ }
216
+
140
217
  // IPv6 loopback
141
218
  if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1') {
142
219
  return 'IPv6 loopback';
@@ -153,12 +230,6 @@ function matchBlockedRange(address: string): string | null {
153
230
  if (/^fe[89ab][0-9a-f]:/.test(normalized)) {
154
231
  return 'IPv6 link-local address';
155
232
  }
156
- // IPv4-mapped (::ffff:127.0.0.1) — re-check the embedded IPv4 address,
157
- // otherwise ::ffff:169.254.169.254 would walk straight past this guard.
158
- const mapped = normalized.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
159
- if (mapped) {
160
- return matchBlockedRange(mapped[1]);
161
- }
162
233
  return null;
163
234
  }
164
235
 
@@ -235,17 +235,19 @@ export class McpSecurityGuard {
235
235
  const parsed = parseCommand(command);
236
236
  const effectiveCommands = extractEffectiveCommands(command);
237
237
 
238
- // Subshell constructs ($() or backticks) cannot be safely parsed the parser
239
- // detects their presence but doesn't extract commands inside them. Require
240
- // confirmation so agents can't bypass validation with `echo $(rm -rf /)`.
238
+ // Subshell constructs ($() or backticks) are run by the shell but never
239
+ // reach this parser, so the commands inside them are checked against
240
+ // neither the block rules nor the configured allowlist. `git status
241
+ // $(bash -c ...)` would pass on the strength of `git`. They are denied
242
+ // outright; an agent that needs a value from one command can run it as
243
+ // its own command first.
241
244
  if (parsed.hasSubshells) {
242
245
  const destructiveWarnings = getDestructiveWarnings(command);
243
246
  const warningMessages = destructiveWarnings.length > 0
244
247
  ? destructiveWarnings.map(w => w.warning)
245
248
  : undefined;
246
249
  return {
247
- allowed: true,
248
- requiresConfirmation: true,
250
+ allowed: false,
249
251
  reason: 'Command contains subshell constructs ($() or backticks) that cannot be statically validated',
250
252
  riskLevel: 'high',
251
253
  warnings: warningMessages
@@ -47,6 +47,8 @@
47
47
  */
48
48
 
49
49
  import * as path from 'path';
50
+ import { extractEffectiveCommands } from '../tools/shell/ShellCommandParser.js';
51
+ import * as fs from 'fs';
50
52
 
51
53
  /**
52
54
  * Environment variables always forwarded to a shell child.
@@ -110,6 +112,33 @@ export function getShellAllowedCommands(): string[] {
110
112
  return parseList(process.env.MXF_SHELL_ALLOWED_COMMANDS);
111
113
  }
112
114
 
115
+ /**
116
+ * Enforce MXF_SHELL_ALLOWED_COMMANDS against a full command line.
117
+ *
118
+ * Applies to every agent-driven command, whether it arrives through
119
+ * shell_execute or through a host tool that calls executeShellCommand.
120
+ * Wrappers and env prefixes (`sudo cmd`, `FOO=bar cmd`, `timeout 5 cmd`) are
121
+ * resolved to the command they run, and compound lines (`a && b`) are checked
122
+ * command by command, so an allowlisted wrapper cannot smuggle another binary.
123
+ *
124
+ * @throws Error when an allowlist is configured and any effective command is not on it
125
+ */
126
+ export function assertCommandAllowlisted(commandLine: string): void {
127
+ if (!hasShellAllowlist()) {
128
+ return;
129
+ }
130
+ const allowedCommands = getShellAllowedCommands();
131
+ for (const effectiveCommand of extractEffectiveCommands(commandLine)) {
132
+ const baseCommand = effectiveCommand.trim().split(/\s+/)[0];
133
+ if (!allowedCommands.includes(baseCommand)) {
134
+ throw new Error(
135
+ `Command '${baseCommand}' is not in the configured allowlist ` +
136
+ `(MXF_SHELL_ALLOWED_COMMANDS). Allowed: ${allowedCommands.join(', ')}`
137
+ );
138
+ }
139
+ }
140
+ }
141
+
113
142
  /**
114
143
  * Is a command allowlist configured at all?
115
144
  */
@@ -207,6 +236,51 @@ export function requireWorkspaceRoot(consumer: string): string {
207
236
  return root;
208
237
  }
209
238
 
239
+ const isWithinPath = (root: string, candidate: string): boolean => (
240
+ candidate === root || candidate.startsWith(`${root}${path.sep}`)
241
+ );
242
+
243
+ /**
244
+ * Resolve a caller path under MXF_WORKSPACE_ROOT and reject lexical and symlink
245
+ * escapes. Non-existent leaf paths are checked through their nearest existing
246
+ * ancestor so create/write operations cannot traverse an existing symlink.
247
+ */
248
+ export function resolveWorkspacePath(
249
+ candidate: string | undefined,
250
+ consumer: string
251
+ ): string {
252
+ const configuredRoot = requireWorkspaceRoot(consumer);
253
+ const realRoot = fs.realpathSync(configuredRoot);
254
+ const resolved = candidate && candidate.trim().length > 0
255
+ ? path.resolve(realRoot, candidate.trim())
256
+ : realRoot;
257
+
258
+ if (!isWithinPath(realRoot, resolved)) {
259
+ throw new Error(`${consumer} path is outside MXF_WORKSPACE_ROOT`);
260
+ }
261
+
262
+ let existingAncestor = resolved;
263
+ while (!fs.existsSync(existingAncestor)) {
264
+ const parent = path.dirname(existingAncestor);
265
+ if (parent === existingAncestor) {
266
+ throw new Error(`${consumer} path has no existing workspace ancestor`);
267
+ }
268
+ existingAncestor = parent;
269
+ }
270
+
271
+ const realAncestor = fs.realpathSync(existingAncestor);
272
+ if (!isWithinPath(realRoot, realAncestor)) {
273
+ throw new Error(`${consumer} path escapes MXF_WORKSPACE_ROOT through a symlink`);
274
+ }
275
+
276
+ const suffix = path.relative(existingAncestor, resolved);
277
+ const finalPath = path.resolve(realAncestor, suffix);
278
+ if (!isWithinPath(realRoot, finalPath)) {
279
+ throw new Error(`${consumer} path is outside MXF_WORKSPACE_ROOT`);
280
+ }
281
+ return finalPath;
282
+ }
283
+
210
284
  /**
211
285
  * May api_fetch reach loopback and private-network addresses?
212
286
  *
@@ -43,11 +43,30 @@ import { AutoCorrectionService } from '../../../services/AutoCorrectionService.j
43
43
  import { IToolEventEmitter } from './IToolEventEmitter.js';
44
44
  import { Events } from '../../../events/EventNames.js';
45
45
  import { v4 as uuidv4 } from 'uuid';
46
+ import { assertUnsafeStdioMcpEnabled } from '../security/ExternalMcpRegistrationPolicy.js';
46
47
 
47
48
  // Create logger and validator instances
48
49
  const logger = new Logger('info', 'ExternalMcpServerManager', 'server');
49
50
  const validator = createStrictValidator('ExternalMcpServerManager');
50
51
 
52
+ interface ExternalMcpRegistrationRequestData extends Partial<ExternalServerConfig> {
53
+ id: string;
54
+ name: string;
55
+ channelId?: string;
56
+ keepAliveMinutes?: number;
57
+ }
58
+
59
+ interface ExternalMcpUnregistrationRequestData {
60
+ serverId: string;
61
+ channelId?: string;
62
+ }
63
+
64
+ interface ExternalMcpLifecycleRequestPayload<TData> {
65
+ agentId: AgentId;
66
+ channelId: ChannelId;
67
+ data: TData;
68
+ }
69
+
51
70
  /**
52
71
  * Configuration for an external MCP server
53
72
  */
@@ -64,6 +83,10 @@ export interface ExternalServerConfig {
64
83
  command: string;
65
84
  /** Arguments for the command */
66
85
  args: string[];
86
+ /** Transport requested by a remote registration. Omitted means stdio. */
87
+ transport?: 'stdio' | 'http';
88
+ /** Endpoint for an HTTP transport registration. */
89
+ url?: string;
67
90
  /** Working directory for the process */
68
91
  workingDirectory?: string;
69
92
  /** Environment variables for the process */
@@ -109,6 +132,10 @@ export interface ExternalMcpTool {
109
132
  description: string;
110
133
  inputSchema: Record<string, any>;
111
134
  serverId: string;
135
+ /** Authoritative visibility scope assigned when the server was registered. */
136
+ scope: 'global' | 'channel' | 'agent';
137
+ /** Channel or agent identifier for non-global scopes. */
138
+ scopeId?: string;
112
139
  }
113
140
 
114
141
  /**
@@ -205,6 +232,13 @@ export class ExternalMcpServerManager extends EventEmitter {
205
232
  };
206
233
  }> = new Map();
207
234
 
235
+ /**
236
+ * Channel ids which crossed their terminal deletion boundary in this
237
+ * process. Channel ids are reserved in persistence, so this tombstone never
238
+ * needs to be removed and closes register/delete races in both directions.
239
+ */
240
+ private retiredChannelIds = new Set<string>();
241
+
208
242
  private autoCorrectionService: AutoCorrectionService;
209
243
 
210
244
  /** Injectable event emitter — decouples from direct EventBus.server dependency.
@@ -212,6 +246,9 @@ export class ExternalMcpServerManager extends EventEmitter {
212
246
  * Client-side: uses ClientToolEventEmitter (wraps EventBus.client + socketEmit). */
213
247
  private toolEventEmitter: IToolEventEmitter | null = null;
214
248
 
249
+ /** EventBus subscriptions owned by this manager instance. */
250
+ private eventSubscriptions: Array<{ unsubscribe: () => void }> = [];
251
+
215
252
  /** Delay before restarting a crashed server. Overridable for tests. */
216
253
  private restartDelayMs: number = DEFAULT_RESTART_DELAY_MS;
217
254
 
@@ -256,9 +293,16 @@ export class ExternalMcpServerManager extends EventEmitter {
256
293
  private setupEventHandlers(): void {
257
294
 
258
295
  // Handle external server registration requests from SDK
259
- EventBus.server.on(Events.Mcp.EXTERNAL_SERVER_REGISTER, async (payload: any) => {
296
+ this.eventSubscriptions.push(EventBus.server.on(Events.Mcp.EXTERNAL_SERVER_REGISTER, async (
297
+ payload: ExternalMcpLifecycleRequestPayload<ExternalMcpRegistrationRequestData>
298
+ ) => {
260
299
  try {
261
300
 
301
+ // EventBus registrations originate outside this manager (normally
302
+ // from a socket). They are caller-controlled and stdio means host
303
+ // process execution, so require the operator's explicit opt-in.
304
+ assertUnsafeStdioMcpEnabled(payload.data?.transport);
305
+
262
306
  const serverConfig = {
263
307
  id: payload.data.id,
264
308
  name: payload.data.name,
@@ -310,10 +354,12 @@ export class ExternalMcpServerManager extends EventEmitter {
310
354
  }
311
355
  });
312
356
  }
313
- });
357
+ }));
314
358
 
315
359
  // Handle external server unregistration requests from SDK
316
- EventBus.server.on(Events.Mcp.EXTERNAL_SERVER_UNREGISTER, async (payload: any) => {
360
+ this.eventSubscriptions.push(EventBus.server.on(Events.Mcp.EXTERNAL_SERVER_UNREGISTER, async (
361
+ payload: ExternalMcpLifecycleRequestPayload<ExternalMcpUnregistrationRequestData>
362
+ ) => {
317
363
  try {
318
364
 
319
365
  const serverId = payload.data.serverId;
@@ -353,11 +399,17 @@ export class ExternalMcpServerManager extends EventEmitter {
353
399
  }
354
400
  });
355
401
  }
356
- });
402
+ }));
357
403
 
358
404
  // Handle channel-scoped server registration requests
359
- EventBus.server.on(Events.Mcp.CHANNEL_SERVER_REGISTER, async (payload: any) => {
405
+ this.eventSubscriptions.push(EventBus.server.on(Events.Mcp.CHANNEL_SERVER_REGISTER, async (
406
+ payload: ExternalMcpLifecycleRequestPayload<ExternalMcpRegistrationRequestData>
407
+ ) => {
360
408
  try {
409
+ // Channel membership is not permission to execute a host command.
410
+ // The HTTP/socket entry point must also establish administrator
411
+ // authority; this is the defense-in-depth feature gate.
412
+ assertUnsafeStdioMcpEnabled(payload.data?.transport);
361
413
  logger.info(`[CHANNEL_SERVER_REGISTER] Received registration request: ${JSON.stringify({ agentId: payload.agentId, channelId: payload.channelId, serverId: payload.data?.id })}`);
362
414
 
363
415
 
@@ -408,10 +460,12 @@ export class ExternalMcpServerManager extends EventEmitter {
408
460
  )
409
461
  );
410
462
  }
411
- });
463
+ }));
412
464
 
413
465
  // Handle channel server unregistration requests
414
- EventBus.server.on(Events.Mcp.CHANNEL_SERVER_UNREGISTER, async (payload: any) => {
466
+ this.eventSubscriptions.push(EventBus.server.on(Events.Mcp.CHANNEL_SERVER_UNREGISTER, async (
467
+ payload: ExternalMcpLifecycleRequestPayload<ExternalMcpUnregistrationRequestData>
468
+ ) => {
415
469
  try {
416
470
 
417
471
  const channelId = payload.data.channelId || payload.channelId;
@@ -454,7 +508,7 @@ export class ExternalMcpServerManager extends EventEmitter {
454
508
  )
455
509
  );
456
510
  }
457
- });
511
+ }));
458
512
 
459
513
  }
460
514
 
@@ -462,6 +516,13 @@ export class ExternalMcpServerManager extends EventEmitter {
462
516
  * Register a new external server configuration
463
517
  */
464
518
  public async registerServer(config: ExternalServerConfig): Promise<void> {
519
+ // This manager currently speaks line-delimited MCP over child-process
520
+ // stdio only. Never let an HTTP-labelled registration fall through to
521
+ // spawn(config.command, ...), which would bypass the stdio feature gate.
522
+ if (config.transport === 'http') {
523
+ throw new Error('HTTP transport registration is not implemented by ExternalMcpServerManager');
524
+ }
525
+
465
526
  logger.info(`[REGISTER_SERVER] Registering server ${config.id}: command="${config.command}", args=${JSON.stringify(config.args)}, autoStart=${config.autoStart}`);
466
527
 
467
528
  // Validate configuration
@@ -526,6 +587,10 @@ export class ExternalMcpServerManager extends EventEmitter {
526
587
  const serverId = `${channelId}:${config.id}`;
527
588
  const keepAliveMinutes = config.keepAliveMinutes || 5;
528
589
 
590
+ if (this.retiredChannelIds.has(channelId)) {
591
+ throw new Error(`Channel ${channelId} is deleted; MCP servers cannot be registered`);
592
+ }
593
+
529
594
  const existingScope = this.serverScopes.get(serverId);
530
595
  if (existingScope?.keepAliveTimer) {
531
596
  clearTimeout(existingScope.keepAliveTimer);
@@ -549,6 +614,14 @@ export class ExternalMcpServerManager extends EventEmitter {
549
614
  const { keepAliveMinutes: _ignored, ...serverConfig } = config;
550
615
  try {
551
616
  await this.registerServer({ ...serverConfig, id: serverId });
617
+
618
+ // Deletion may have won while process startup/handshake was in
619
+ // flight. Remove the just-created runtime before returning so a
620
+ // late registration cannot resurrect a deleted channel's server.
621
+ if (this.retiredChannelIds.has(channelId)) {
622
+ await this.removeServer(serverId, 'registration raced channel deletion');
623
+ throw new Error(`Channel ${channelId} was deleted during MCP server registration`);
624
+ }
552
625
  } catch (error) {
553
626
  // Registration failed before the server record existed — do not leave
554
627
  // a scope entry behind for agents to "join" (unless one existed before).
@@ -574,6 +647,45 @@ export class ExternalMcpServerManager extends EventEmitter {
574
647
  await this.removeServer(`${channelId}:${serverId}`, 'channel server unregistration');
575
648
  }
576
649
 
650
+ /**
651
+ * Permanently retire a channel's MCP runtime in this process.
652
+ *
653
+ * The tombstone is installed before process cleanup, which makes concurrent
654
+ * registrations fail both before and after their asynchronous startup.
655
+ * Every known scoped record is removed, including orphaned records whose
656
+ * scope metadata or server entry is only partially present.
657
+ */
658
+ public async retireChannel(channelId: string): Promise<void> {
659
+ validator.assertIsNonEmptyString(channelId, 'channelId must be a non-empty string');
660
+ this.retiredChannelIds.add(channelId);
661
+
662
+ const serverIds = new Set<string>();
663
+ for (const [serverId, scopeData] of this.serverScopes.entries()) {
664
+ if (scopeData.scope === 'channel' && scopeData.scopeId === channelId) {
665
+ serverIds.add(serverId);
666
+ }
667
+ }
668
+ for (const serverId of this.servers.keys()) {
669
+ if (serverId.startsWith(`${channelId}:`)) {
670
+ serverIds.add(serverId);
671
+ }
672
+ }
673
+
674
+ const results = await Promise.allSettled(
675
+ Array.from(serverIds, serverId => (
676
+ this.removeServer(serverId, 'channel deletion')
677
+ ))
678
+ );
679
+ const failures = results.filter(
680
+ (result): result is PromiseRejectedResult => result.status === 'rejected'
681
+ );
682
+ if (failures.length > 0) {
683
+ throw new Error(
684
+ `Failed to retire ${failures.length} MCP server(s) for channel ${channelId}`
685
+ );
686
+ }
687
+ }
688
+
577
689
  /**
578
690
  * Unregister a server by its full id (global servers, and the SDK-facing
579
691
  * EXTERNAL_SERVER_UNREGISTER path). Also removes scope tracking — this
@@ -916,21 +1028,23 @@ export class ExternalMcpServerManager extends EventEmitter {
916
1028
  public getServersByScope(scope: 'global' | 'channel' | 'agent', scopeId?: string): ExternalServerStatus[] {
917
1029
  const servers: ExternalServerStatus[] = [];
918
1030
 
919
- for (const [serverId, scopeData] of this.serverScopes.entries()) {
920
- if (scopeData.scope === scope) {
1031
+ for (const [serverId, serverData] of this.servers.entries()) {
1032
+ // Servers registered through the original global registration path
1033
+ // predate serverScopes and are explicitly global, matching the tool
1034
+ // snapshot contract in getAllExternalTools().
1035
+ const scopeData = this.serverScopes.get(serverId);
1036
+ const actualScope = scopeData?.scope ?? 'global';
1037
+ if (actualScope === scope) {
921
1038
  // For channel/agent scope, match scopeId
922
- if ((scope === 'channel' || scope === 'agent') && scopeData.scopeId !== scopeId) {
1039
+ if ((scope === 'channel' || scope === 'agent') && scopeData?.scopeId !== scopeId) {
923
1040
  continue;
924
1041
  }
925
1042
 
926
- const serverData = this.servers.get(serverId);
927
- if (serverData) {
928
- servers.push(serverData.status);
929
- }
1043
+ servers.push(serverData.status);
930
1044
  }
931
1045
  }
932
1046
 
933
- return servers;
1047
+ return servers.sort((a, b) => a.id.localeCompare(b.id));
934
1048
  }
935
1049
 
936
1050
  /**
@@ -1032,10 +1146,16 @@ export class ExternalMcpServerManager extends EventEmitter {
1032
1146
  const tools: ExternalMcpTool[] = [];
1033
1147
 
1034
1148
  for (const [serverId, serverData] of this.servers) {
1149
+ const scopeData = this.serverScopes.get(serverId);
1150
+ const scope = scopeData?.scope ?? 'global';
1151
+ const scopeId = scopeData?.scopeId;
1152
+
1035
1153
  for (const tool of serverData.status.tools) {
1036
1154
  tools.push({
1037
1155
  ...tool,
1038
- serverId
1156
+ serverId,
1157
+ scope,
1158
+ scopeId
1039
1159
  });
1040
1160
  }
1041
1161
  }
@@ -1752,6 +1872,14 @@ export class ExternalMcpServerManager extends EventEmitter {
1752
1872
  */
1753
1873
  public async shutdown(): Promise<void> {
1754
1874
 
1875
+ // Stop accepting lifecycle requests before child-process teardown. Node's
1876
+ // removeAllListeners() below only affects this class's EventEmitter; it
1877
+ // does not detach RxJS EventBus subscriptions.
1878
+ for (const subscription of this.eventSubscriptions) {
1879
+ subscription.unsubscribe();
1880
+ }
1881
+ this.eventSubscriptions = [];
1882
+
1755
1883
  const shutdownPromises = Array.from(this.servers.keys()).map(serverId =>
1756
1884
  this.stopServer(serverId)
1757
1885
  );
@@ -1767,6 +1895,7 @@ export class ExternalMcpServerManager extends EventEmitter {
1767
1895
 
1768
1896
  this.servers.clear();
1769
1897
  this.serverScopes.clear();
1898
+ this.retiredChannelIds.clear();
1770
1899
  this.removeAllListeners();
1771
1900
 
1772
1901
  }
@@ -74,8 +74,8 @@ export const SEQUENTIAL_THINKING_SERVER_CONFIG: ExternalServerConfig = {
74
74
  /**
75
75
  * Configuration for the Filesystem MCP Server.
76
76
  *
77
- * The allowed roots are the configured workspace directory plus a scratch
78
- * directory. This used to pass `os.homedir()`, which handed every agent read
77
+ * The only allowed root is the configured workspace directory. This used to
78
+ * pass `os.homedir()`, which handed every agent read
79
79
  * access to the entire home directory — including ~/.ssh, ~/.aws, and
80
80
  * ~/.mxf/config.json, which is where the MXF CLI stores its own credentials.
81
81
  *
@@ -95,8 +95,7 @@ export const FILESYSTEM_SERVER_CONFIG: ExternalServerConfig = {
95
95
  '@modelcontextprotocol/server-filesystem',
96
96
  // Empty when unset. getFilesystemServerConfig() below is what callers
97
97
  // should use — it fails fast rather than spawning a server with no root.
98
- getWorkspaceRoot() ?? '',
99
- '/tmp/mcp-workspace'
98
+ getWorkspaceRoot() ?? ''
100
99
  ].filter(arg => arg.length > 0),
101
100
  // Only auto-start when a workspace is configured.
102
101
  autoStart: getWorkspaceRoot() !== undefined,
@@ -119,7 +118,12 @@ export const GIT_SERVER_CONFIG: ExternalServerConfig = {
119
118
  version: '0.6.0',
120
119
  description: 'Git repository reading, searching, and manipulation',
121
120
  command: 'uvx',
122
- args: ['mcp-server-git', '--repository', process.cwd()],
121
+ // This disabled legacy config must not silently inherit the server cwd if a
122
+ // caller imports and starts it directly. With no configured root, uvx gets
123
+ // no server arguments and fails instead of opening an implicit repository.
124
+ args: getWorkspaceRoot()
125
+ ? ['mcp-server-git', '--repository', getWorkspaceRoot()!]
126
+ : [],
123
127
  autoStart: false, // DISABLED: MCP protocol integration issues
124
128
  restartOnCrash: true,
125
129
  healthCheckInterval: 30000,
@@ -238,6 +242,19 @@ export const TIME_SERVER_CONFIG: ExternalServerConfig = {
238
242
  }
239
243
  };
240
244
 
245
+ /**
246
+ * Whether an n8n API key is configured.
247
+ *
248
+ * Gates N8N_SERVER_CONFIG's autoStart: n8n starts only when an API key is
249
+ * configured; without one the server cannot authenticate against any n8n
250
+ * instance and cannot do anything, and its `search_nodes` tool shadows the
251
+ * memory server's tool of the same name (see HybridMcpToolRegistry's
252
+ * raw-name collision handling).
253
+ */
254
+ const hasN8nApiKey = (): boolean => {
255
+ return (process.env.N8N_API_KEY ?? '').trim().length > 0;
256
+ };
257
+
241
258
  /**
242
259
  * Configuration for the n8n MCP Server
243
260
  * Provides workflow automation with 400+ service integrations
@@ -250,7 +267,9 @@ export const N8N_SERVER_CONFIG: ExternalServerConfig = {
250
267
  description: 'Workflow automation and management with 400+ integrations including Gmail, Slack, Airtable, Notion, GitHub, Stripe, and more',
251
268
  command: 'npx',
252
269
  args: ['-y', 'n8n-mcp@latest'],
253
- autoStart: true, // Enable for workflow automation capabilities
270
+ // n8n starts only when an API key is configured; without one the server
271
+ // cannot do anything and its search_nodes shadows the memory server's.
272
+ autoStart: hasN8nApiKey(),
254
273
  restartOnCrash: true,
255
274
  healthCheckInterval: 30000,
256
275
  maxRestartAttempts: 3,
@@ -341,8 +360,7 @@ export const getFilesystemServerConfig = (): ExternalServerConfig => {
341
360
  args: [
342
361
  '-y',
343
362
  '@modelcontextprotocol/server-filesystem',
344
- workspaceRoot,
345
- '/tmp/mcp-workspace'
363
+ workspaceRoot
346
364
  ],
347
365
  autoStart: true
348
366
  };