@mxf-dev/core 1.0.1 → 2.0.1

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 (303) hide show
  1. package/README.md +18 -0
  2. package/dist/adapters/FrameworkAdapter.js +1 -1
  3. package/dist/adapters/FrameworkAdapter.js.map +1 -1
  4. package/dist/config/ConfigManager.d.ts +9 -8
  5. package/dist/config/ConfigManager.d.ts.map +1 -1
  6. package/dist/config/ConfigManager.js +47 -17
  7. package/dist/config/ConfigManager.js.map +1 -1
  8. package/dist/config/memory-strata.config.d.ts +25 -0
  9. package/dist/config/memory-strata.config.d.ts.map +1 -0
  10. package/dist/config/memory-strata.config.js +107 -0
  11. package/dist/config/memory-strata.config.js.map +1 -0
  12. package/dist/constants/ToolNames.d.ts +1 -29
  13. package/dist/constants/ToolNames.d.ts.map +1 -1
  14. package/dist/constants/ToolNames.js +4 -17
  15. package/dist/constants/ToolNames.js.map +1 -1
  16. package/dist/database/DatabaseAdapterFactory.d.ts +14 -2
  17. package/dist/database/DatabaseAdapterFactory.d.ts.map +1 -1
  18. package/dist/database/DatabaseAdapterFactory.js +21 -6
  19. package/dist/database/DatabaseAdapterFactory.js.map +1 -1
  20. package/dist/database/adapters/mongodb/MongoBaseRepository.d.ts +7 -1
  21. package/dist/database/adapters/mongodb/MongoBaseRepository.d.ts.map +1 -1
  22. package/dist/database/adapters/mongodb/MongoBaseRepository.js +12 -2
  23. package/dist/database/adapters/mongodb/MongoBaseRepository.js.map +1 -1
  24. package/dist/events/ClientEventBus.d.ts +16 -77
  25. package/dist/events/ClientEventBus.d.ts.map +1 -1
  26. package/dist/events/ClientEventBus.js +38 -311
  27. package/dist/events/ClientEventBus.js.map +1 -1
  28. package/dist/events/EventBus.d.ts +1 -1
  29. package/dist/events/EventBus.d.ts.map +1 -1
  30. package/dist/events/EventBus.js +5 -4
  31. package/dist/events/EventBus.js.map +1 -1
  32. package/dist/events/EventBusBase.d.ts +139 -34
  33. package/dist/events/EventBusBase.d.ts.map +1 -1
  34. package/dist/events/EventBusBase.js +366 -88
  35. package/dist/events/EventBusBase.js.map +1 -1
  36. package/dist/events/EventNames.d.ts +10 -1
  37. package/dist/events/EventNames.d.ts.map +1 -1
  38. package/dist/events/EventNames.js +3 -0
  39. package/dist/events/EventNames.js.map +1 -1
  40. package/dist/events/PublicEvents.d.ts +6 -2
  41. package/dist/events/PublicEvents.d.ts.map +1 -1
  42. package/dist/events/PublicEvents.js +7 -4
  43. package/dist/events/PublicEvents.js.map +1 -1
  44. package/dist/events/ServerEventBus.d.ts +23 -112
  45. package/dist/events/ServerEventBus.d.ts.map +1 -1
  46. package/dist/events/ServerEventBus.js +58 -323
  47. package/dist/events/ServerEventBus.js.map +1 -1
  48. package/dist/events/event-definitions/LlmBudgetEvents.d.ts +68 -0
  49. package/dist/events/event-definitions/LlmBudgetEvents.d.ts.map +1 -0
  50. package/dist/events/event-definitions/LlmBudgetEvents.js +35 -0
  51. package/dist/events/event-definitions/LlmBudgetEvents.js.map +1 -0
  52. package/dist/interfaces/IMemoryPersistence.d.ts +41 -0
  53. package/dist/interfaces/IMemoryPersistence.d.ts.map +1 -0
  54. package/dist/interfaces/IMemoryPersistence.js +15 -0
  55. package/dist/interfaces/IMemoryPersistence.js.map +1 -0
  56. package/dist/middleware/MxpMiddleware.d.ts +8 -1
  57. package/dist/middleware/MxpMiddleware.d.ts.map +1 -1
  58. package/dist/middleware/MxpMiddleware.js +42 -20
  59. package/dist/middleware/MxpMiddleware.js.map +1 -1
  60. package/dist/models/channelKey.d.ts +1 -0
  61. package/dist/models/channelKey.d.ts.map +1 -1
  62. package/dist/models/channelKey.js +5 -0
  63. package/dist/models/channelKey.js.map +1 -1
  64. package/dist/models/memoryUtility.d.ts +39 -0
  65. package/dist/models/memoryUtility.d.ts.map +1 -0
  66. package/dist/models/memoryUtility.js +39 -0
  67. package/dist/models/memoryUtility.js.map +1 -0
  68. package/dist/models/user.d.ts.map +1 -1
  69. package/dist/models/user.js +23 -1
  70. package/dist/models/user.js.map +1 -1
  71. package/dist/mxp/BinaryProtocolLayer.d.ts +24 -8
  72. package/dist/mxp/BinaryProtocolLayer.d.ts.map +1 -1
  73. package/dist/mxp/BinaryProtocolLayer.js +90 -103
  74. package/dist/mxp/BinaryProtocolLayer.js.map +1 -1
  75. package/dist/mxp/ContextCompressionEngine.d.ts +57 -10
  76. package/dist/mxp/ContextCompressionEngine.d.ts.map +1 -1
  77. package/dist/mxp/ContextCompressionEngine.js +170 -128
  78. package/dist/mxp/ContextCompressionEngine.js.map +1 -1
  79. package/dist/mxp/MxpTokenOptimizer.d.ts +7 -3
  80. package/dist/mxp/MxpTokenOptimizer.d.ts.map +1 -1
  81. package/dist/mxp/MxpTokenOptimizer.js +8 -5
  82. package/dist/mxp/MxpTokenOptimizer.js.map +1 -1
  83. package/dist/prompts/MxfAgentSystemPrompt.d.ts +1 -1
  84. package/dist/prompts/MxfAgentSystemPrompt.d.ts.map +1 -1
  85. package/dist/prompts/MxfAgentSystemPrompt.js +47 -57
  86. package/dist/prompts/MxfAgentSystemPrompt.js.map +1 -1
  87. package/dist/protocols/mcp/ToolError.d.ts +123 -0
  88. package/dist/protocols/mcp/ToolError.d.ts.map +1 -0
  89. package/dist/protocols/mcp/ToolError.js +108 -0
  90. package/dist/protocols/mcp/ToolError.js.map +1 -0
  91. package/dist/protocols/mcp/defineTool.d.ts +133 -0
  92. package/dist/protocols/mcp/defineTool.d.ts.map +1 -0
  93. package/dist/protocols/mcp/defineTool.js +236 -0
  94. package/dist/protocols/mcp/defineTool.js.map +1 -0
  95. package/dist/protocols/mcp/security/HttpTargetGuard.d.ts +38 -0
  96. package/dist/protocols/mcp/security/HttpTargetGuard.d.ts.map +1 -0
  97. package/dist/protocols/mcp/security/HttpTargetGuard.js +227 -0
  98. package/dist/protocols/mcp/security/HttpTargetGuard.js.map +1 -0
  99. package/dist/protocols/mcp/security/McpSecurityGuard.d.ts +9 -1
  100. package/dist/protocols/mcp/security/McpSecurityGuard.d.ts.map +1 -1
  101. package/dist/protocols/mcp/security/McpSecurityGuard.js +10 -2
  102. package/dist/protocols/mcp/security/McpSecurityGuard.js.map +1 -1
  103. package/dist/protocols/mcp/security/McpToolPolicy.d.ts +81 -0
  104. package/dist/protocols/mcp/security/McpToolPolicy.d.ts.map +1 -0
  105. package/dist/protocols/mcp/security/McpToolPolicy.js +202 -0
  106. package/dist/protocols/mcp/security/McpToolPolicy.js.map +1 -0
  107. package/dist/protocols/mcp/services/ExternalMcpServerManager.d.ts +51 -18
  108. package/dist/protocols/mcp/services/ExternalMcpServerManager.d.ts.map +1 -1
  109. package/dist/protocols/mcp/services/ExternalMcpServerManager.js +256 -283
  110. package/dist/protocols/mcp/services/ExternalMcpServerManager.js.map +1 -1
  111. package/dist/protocols/mcp/services/ExternalServerConfigs.d.ts +39 -6
  112. package/dist/protocols/mcp/services/ExternalServerConfigs.d.ts.map +1 -1
  113. package/dist/protocols/mcp/services/ExternalServerConfigs.js +76 -18
  114. package/dist/protocols/mcp/services/ExternalServerConfigs.js.map +1 -1
  115. package/dist/protocols/mcp/tools/AnalyticsTools.js +1 -1
  116. package/dist/protocols/mcp/tools/AnalyticsTools.js.map +1 -1
  117. package/dist/protocols/mcp/tools/CodeAnalysisTools.d.ts.map +1 -1
  118. package/dist/protocols/mcp/tools/CodeAnalysisTools.js +15 -0
  119. package/dist/protocols/mcp/tools/CodeAnalysisTools.js.map +1 -1
  120. package/dist/protocols/mcp/tools/EffectivenessTools.js +3 -3
  121. package/dist/protocols/mcp/tools/EffectivenessTools.js.map +1 -1
  122. package/dist/protocols/mcp/tools/GitTools.d.ts +9 -369
  123. package/dist/protocols/mcp/tools/GitTools.d.ts.map +1 -1
  124. package/dist/protocols/mcp/tools/GitTools.js +222 -517
  125. package/dist/protocols/mcp/tools/GitTools.js.map +1 -1
  126. package/dist/protocols/mcp/tools/InfrastructureTools.d.ts +56 -24
  127. package/dist/protocols/mcp/tools/InfrastructureTools.d.ts.map +1 -1
  128. package/dist/protocols/mcp/tools/InfrastructureTools.js +117 -26
  129. package/dist/protocols/mcp/tools/InfrastructureTools.js.map +1 -1
  130. package/dist/protocols/mcp/tools/MemorySearchTools.d.ts +0 -3
  131. package/dist/protocols/mcp/tools/MemorySearchTools.d.ts.map +1 -1
  132. package/dist/protocols/mcp/tools/MemorySearchTools.js +58 -1
  133. package/dist/protocols/mcp/tools/MemorySearchTools.js.map +1 -1
  134. package/dist/protocols/mcp/tools/OrparTools.d.ts +8 -0
  135. package/dist/protocols/mcp/tools/OrparTools.d.ts.map +1 -1
  136. package/dist/protocols/mcp/tools/OrparTools.js +66 -0
  137. package/dist/protocols/mcp/tools/OrparTools.js.map +1 -1
  138. package/dist/protocols/mcp/tools/SafetyTools.d.ts +7 -525
  139. package/dist/protocols/mcp/tools/SafetyTools.d.ts.map +1 -1
  140. package/dist/protocols/mcp/tools/SafetyTools.js +349 -514
  141. package/dist/protocols/mcp/tools/SafetyTools.js.map +1 -1
  142. package/dist/protocols/mcp/tools/TaskPlanningTools.d.ts.map +1 -1
  143. package/dist/protocols/mcp/tools/TaskPlanningTools.js +56 -26
  144. package/dist/protocols/mcp/tools/TaskPlanningTools.js.map +1 -1
  145. package/dist/protocols/mcp/tools/TestTools.d.ts +15 -376
  146. package/dist/protocols/mcp/tools/TestTools.d.ts.map +1 -1
  147. package/dist/protocols/mcp/tools/TestTools.js +241 -363
  148. package/dist/protocols/mcp/tools/TestTools.js.map +1 -1
  149. package/dist/protocols/mcp/tools/TypeScriptTools.d.ts +6 -276
  150. package/dist/protocols/mcp/tools/TypeScriptTools.d.ts.map +1 -1
  151. package/dist/protocols/mcp/tools/TypeScriptTools.js +223 -337
  152. package/dist/protocols/mcp/tools/TypeScriptTools.js.map +1 -1
  153. package/dist/protocols/mcp/tools/WebTools.d.ts +15 -728
  154. package/dist/protocols/mcp/tools/WebTools.d.ts.map +1 -1
  155. package/dist/protocols/mcp/tools/WebTools.js +151 -257
  156. package/dist/protocols/mcp/tools/WebTools.js.map +1 -1
  157. package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.d.ts +5 -3
  158. package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.d.ts.map +1 -1
  159. package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.js +31 -6
  160. package/dist/protocols/mcp/tools/shell/ShellExecuteHandler.js.map +1 -1
  161. package/dist/schemas/EventPayloadSchema.d.ts +21 -0
  162. package/dist/schemas/EventPayloadSchema.d.ts.map +1 -1
  163. package/dist/schemas/EventPayloadSchema.js +14 -0
  164. package/dist/schemas/EventPayloadSchema.js.map +1 -1
  165. package/dist/services/BackgroundTaskManager.d.ts.map +1 -1
  166. package/dist/services/BackgroundTaskManager.js +12 -4
  167. package/dist/services/BackgroundTaskManager.js.map +1 -1
  168. package/dist/services/BrowserManager.d.ts +1 -1
  169. package/dist/services/BrowserManager.d.ts.map +1 -1
  170. package/dist/services/BrowserManager.js +26 -3
  171. package/dist/services/BrowserManager.js.map +1 -1
  172. package/dist/services/MemoryCompressor.d.ts +11 -2
  173. package/dist/services/MemoryCompressor.d.ts.map +1 -1
  174. package/dist/services/MemoryCompressor.js +8 -26
  175. package/dist/services/MemoryCompressor.js.map +1 -1
  176. package/dist/services/MemoryService.d.ts +16 -3
  177. package/dist/services/MemoryService.d.ts.map +1 -1
  178. package/dist/services/MemoryService.js +79 -55
  179. package/dist/services/MemoryService.js.map +1 -1
  180. package/dist/services/MxfMLService.d.ts +5 -0
  181. package/dist/services/MxfMLService.d.ts.map +1 -1
  182. package/dist/services/MxfMLService.js +32 -6
  183. package/dist/services/MxfMLService.js.map +1 -1
  184. package/dist/services/PredictiveAnalyticsService.d.ts +45 -9
  185. package/dist/services/PredictiveAnalyticsService.d.ts.map +1 -1
  186. package/dist/services/PredictiveAnalyticsService.js +82 -44
  187. package/dist/services/PredictiveAnalyticsService.js.map +1 -1
  188. package/dist/services/QValueManager.d.ts +7 -0
  189. package/dist/services/QValueManager.d.ts.map +1 -1
  190. package/dist/services/QValueManager.js +9 -0
  191. package/dist/services/QValueManager.js.map +1 -1
  192. package/dist/services/RewardSignalProcessor.d.ts +38 -1
  193. package/dist/services/RewardSignalProcessor.d.ts.map +1 -1
  194. package/dist/services/RewardSignalProcessor.js +109 -7
  195. package/dist/services/RewardSignalProcessor.js.map +1 -1
  196. package/dist/services/SharedStateService.d.ts +16 -2
  197. package/dist/services/SharedStateService.d.ts.map +1 -1
  198. package/dist/services/SharedStateService.js +44 -3
  199. package/dist/services/SharedStateService.js.map +1 -1
  200. package/dist/services/TaskEffectivenessService.d.ts +34 -18
  201. package/dist/services/TaskEffectivenessService.d.ts.map +1 -1
  202. package/dist/services/TaskEffectivenessService.js +91 -155
  203. package/dist/services/TaskEffectivenessService.js.map +1 -1
  204. package/dist/services/WebSearchService.d.ts.map +1 -1
  205. package/dist/services/WebSearchService.js.map +1 -1
  206. package/dist/services/dag/TaskDagService.d.ts.map +1 -1
  207. package/dist/services/dag/TaskDagService.js +2 -0
  208. package/dist/services/dag/TaskDagService.js.map +1 -1
  209. package/dist/services/orpar-memory/OrparMemoryCoordinator.d.ts +7 -0
  210. package/dist/services/orpar-memory/OrparMemoryCoordinator.d.ts.map +1 -1
  211. package/dist/services/orpar-memory/OrparMemoryCoordinator.js +71 -10
  212. package/dist/services/orpar-memory/OrparMemoryCoordinator.js.map +1 -1
  213. package/dist/types/MemoryUtilityTypes.d.ts +2 -0
  214. package/dist/types/MemoryUtilityTypes.d.ts.map +1 -1
  215. package/dist/types/MemoryUtilityTypes.js.map +1 -1
  216. package/dist/utils/Logger.d.ts +43 -3
  217. package/dist/utils/Logger.d.ts.map +1 -1
  218. package/dist/utils/Logger.js +78 -36
  219. package/dist/utils/Logger.js.map +1 -1
  220. package/dist/utils/MxpEncryption.d.ts +19 -6
  221. package/dist/utils/MxpEncryption.d.ts.map +1 -1
  222. package/dist/utils/MxpEncryption.js +48 -16
  223. package/dist/utils/MxpEncryption.js.map +1 -1
  224. package/package.json +19 -4
  225. package/src/adapters/FrameworkAdapter.ts +1 -1
  226. package/src/config/ConfigManager.ts +52 -19
  227. package/src/config/memory-strata.config.ts +136 -0
  228. package/src/constants/ToolNames.ts +4 -18
  229. package/src/database/DatabaseAdapterFactory.ts +23 -6
  230. package/src/database/adapters/mongodb/MongoBaseRepository.ts +16 -2
  231. package/src/events/ClientEventBus.ts +68 -403
  232. package/src/events/EventBus.ts +7 -8
  233. package/src/events/EventBusBase.ts +479 -116
  234. package/src/events/EventNames.ts +6 -0
  235. package/src/events/PublicEvents.ts +7 -4
  236. package/src/events/ServerEventBus.ts +78 -473
  237. package/src/events/event-definitions/LlmBudgetEvents.ts +74 -0
  238. package/src/interfaces/IMemoryPersistence.ts +51 -0
  239. package/src/middleware/MxpMiddleware.ts +51 -24
  240. package/src/models/channelKey.ts +18 -4
  241. package/src/models/memoryUtility.ts +64 -0
  242. package/src/models/user.ts +36 -4
  243. package/src/mxp/BinaryProtocolLayer.ts +108 -124
  244. package/src/mxp/ContextCompressionEngine.ts +219 -161
  245. package/src/mxp/MxpTokenOptimizer.ts +10 -10
  246. package/src/prompts/MxfAgentSystemPrompt.ts +45 -55
  247. package/src/protocols/mcp/ToolError.ts +201 -0
  248. package/src/protocols/mcp/defineTool.ts +379 -0
  249. package/src/protocols/mcp/security/HttpTargetGuard.ts +267 -0
  250. package/src/protocols/mcp/security/McpSecurityGuard.ts +10 -3
  251. package/src/protocols/mcp/security/McpToolPolicy.ts +221 -0
  252. package/src/protocols/mcp/services/ExternalMcpServerManager.ts +340 -322
  253. package/src/protocols/mcp/services/ExternalServerConfigs.ts +82 -19
  254. package/src/protocols/mcp/tools/AnalyticsTools.ts +1 -1
  255. package/src/protocols/mcp/tools/CodeAnalysisTools.ts +15 -0
  256. package/src/protocols/mcp/tools/EffectivenessTools.ts +3 -3
  257. package/src/protocols/mcp/tools/GitTools.ts +290 -569
  258. package/src/protocols/mcp/tools/InfrastructureTools.ts +189 -43
  259. package/src/protocols/mcp/tools/MemorySearchTools.ts +77 -1
  260. package/src/protocols/mcp/tools/OrparTools.ts +87 -0
  261. package/src/protocols/mcp/tools/SafetyTools.ts +501 -579
  262. package/src/protocols/mcp/tools/TaskPlanningTools.ts +81 -39
  263. package/src/protocols/mcp/tools/TestTools.ts +339 -419
  264. package/src/protocols/mcp/tools/TypeScriptTools.ts +316 -376
  265. package/src/protocols/mcp/tools/WebTools.ts +209 -307
  266. package/src/protocols/mcp/tools/shell/ShellExecuteHandler.ts +53 -14
  267. package/src/schemas/EventPayloadSchema.ts +37 -0
  268. package/src/services/BackgroundTaskManager.ts +12 -4
  269. package/src/services/BrowserManager.ts +41 -1
  270. package/src/services/MemoryCompressor.ts +20 -32
  271. package/src/services/MemoryService.ts +96 -58
  272. package/src/services/MxfMLService.ts +41 -7
  273. package/src/services/PredictiveAnalyticsService.ts +101 -51
  274. package/src/services/QValueManager.ts +10 -0
  275. package/src/services/RewardSignalProcessor.ts +138 -9
  276. package/src/services/SharedStateService.ts +56 -8
  277. package/src/services/TaskEffectivenessService.ts +114 -187
  278. package/src/services/WebSearchService.ts +2 -1
  279. package/src/services/dag/TaskDagService.ts +2 -0
  280. package/src/services/orpar-memory/OrparMemoryCoordinator.ts +86 -10
  281. package/src/types/MemoryUtilityTypes.ts +2 -0
  282. package/src/utils/Logger.ts +116 -40
  283. package/src/utils/MxpEncryption.ts +69 -34
  284. package/dist/mxp/MxpEventForwardingEnhancer.d.ts +0 -134
  285. package/dist/mxp/MxpEventForwardingEnhancer.d.ts.map +0 -1
  286. package/dist/mxp/MxpEventForwardingEnhancer.js +0 -361
  287. package/dist/mxp/MxpEventForwardingEnhancer.js.map +0 -1
  288. package/dist/protocols/mcp/services/ToolSchemaEnhancements.d.ts +0 -56
  289. package/dist/protocols/mcp/services/ToolSchemaEnhancements.d.ts.map +0 -1
  290. package/dist/protocols/mcp/services/ToolSchemaEnhancements.js +0 -57
  291. package/dist/protocols/mcp/services/ToolSchemaEnhancements.js.map +0 -1
  292. package/dist/protocols/mcp/tools/ControlLoopLifecycle.d.ts +0 -270
  293. package/dist/protocols/mcp/tools/ControlLoopLifecycle.d.ts.map +0 -1
  294. package/dist/protocols/mcp/tools/ControlLoopLifecycle.js +0 -256
  295. package/dist/protocols/mcp/tools/ControlLoopLifecycle.js.map +0 -1
  296. package/dist/protocols/mcp/tools/LspTools.d.ts +0 -495
  297. package/dist/protocols/mcp/tools/LspTools.d.ts.map +0 -1
  298. package/dist/protocols/mcp/tools/LspTools.js +0 -469
  299. package/dist/protocols/mcp/tools/LspTools.js.map +0 -1
  300. package/src/mxp/MxpEventForwardingEnhancer.ts +0 -471
  301. package/src/protocols/mcp/services/ToolSchemaEnhancements.ts +0 -92
  302. package/src/protocols/mcp/tools/ControlLoopLifecycle.ts +0 -302
  303. package/src/protocols/mcp/tools/LspTools.ts +0 -476
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Copyright 2024 Brad Anderson
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @author Brad Anderson <BradA1878@pm.me>
17
+ * @repository https://github.com/BradA1878/model-exchange-framework
18
+ * @documentation https://mxf-dev.github.io/mxf/
19
+ */
20
+ import { McpToolDefinition, McpToolHandlerResult, McpToolResultContent } from './McpServerTypes.js';
21
+ import { McpToolExample } from './McpToolSchema.js';
22
+ import { ToolErrorData } from './ToolError.js';
23
+ /**
24
+ * The single result shape every `defineTool` tool returns.
25
+ *
26
+ * Extends the framework's McpToolHandlerResult, so these tools drop into the
27
+ * existing registries and socket paths unchanged, and adds the explicit
28
+ * `isError` flag those shapes were missing.
29
+ */
30
+ export interface ToolResultEnvelope<TData = unknown> extends McpToolHandlerResult {
31
+ /** Result payload. `data` holds the tool's own output, or a ToolErrorData on failure. */
32
+ content: McpToolResultContent & {
33
+ data: TData | ToolErrorData;
34
+ };
35
+ /** True when the tool failed. Callers branch on this — never on payload shape. */
36
+ isError: boolean;
37
+ /** Execution metadata (tool name, timing, and the error code when isError). */
38
+ metadata: {
39
+ toolName: string;
40
+ executedAt: number;
41
+ durationMs: number;
42
+ /** Present only when isError is true */
43
+ errorCode?: string;
44
+ [key: string]: unknown;
45
+ };
46
+ }
47
+ /**
48
+ * Context handed to a tool's `run` function.
49
+ *
50
+ * agentId, channelId and requestId are always present — `defineTool` rejects the
51
+ * call before `run` is reached if any is missing, so `run` never has to check.
52
+ */
53
+ export interface ToolRunContext {
54
+ /** Agent that invoked the tool. Always present. */
55
+ agentId: string;
56
+ /** Channel the invocation belongs to. Always present. */
57
+ channelId: string;
58
+ /** Correlation id for events and logs. Always present. */
59
+ requestId: string;
60
+ /** Any extra context the caller attached. */
61
+ data?: Record<string, unknown>;
62
+ }
63
+ /**
64
+ * Options accepted by {@link defineTool}.
65
+ */
66
+ export interface DefineToolOptions<TInput, TOutput> {
67
+ /** Tool name exposed to the model. Must be unique across the whole tool set. */
68
+ name: string;
69
+ /**
70
+ * What the tool does, written for the model that decides whether to call it.
71
+ * This is prompt text: state the behavior plainly, and describe only what the
72
+ * implementation actually does.
73
+ */
74
+ description: string;
75
+ /** Category used for grouping and filtering. */
76
+ category: string;
77
+ /** JSON Schema for the tool's input. Enforced on every entry path. */
78
+ inputSchema: Record<string, any>;
79
+ /**
80
+ * The tool's behavior. Return the payload to send back; throw a ToolError to
81
+ * fail. Do not catch-and-wrap — the factory owns error handling.
82
+ */
83
+ run: (input: TInput, context: ToolRunContext) => Promise<TOutput> | TOutput;
84
+ /** Optional worked examples surfaced in tool documentation. */
85
+ examples?: McpToolExample[];
86
+ /** Where the tool may execute. Defaults to 'server'. */
87
+ executionSide?: 'server' | 'client' | 'either';
88
+ /** Whether the tool is enabled. Defaults to true. */
89
+ enabled?: boolean;
90
+ /** Extra metadata merged into the registered tool definition. */
91
+ metadata?: Record<string, any>;
92
+ }
93
+ /**
94
+ * A tool produced by {@link defineTool}.
95
+ *
96
+ * Structurally a McpToolDefinition, so it registers exactly like a hand-written
97
+ * tool, plus the `category` it was declared with.
98
+ */
99
+ export interface DefinedMcpTool extends McpToolDefinition {
100
+ category: string;
101
+ }
102
+ /**
103
+ * Declare an MCP tool.
104
+ *
105
+ * @example
106
+ * export const gitStatusTool = defineTool({
107
+ * name: 'git_status',
108
+ * category: TOOL_CATEGORIES.VERSION_CONTROL,
109
+ * description: 'Report staged, modified and untracked files by running `git status`.',
110
+ * inputSchema: {
111
+ * type: 'object',
112
+ * properties: { workingDirectory: { type: 'string' } }
113
+ * },
114
+ * run: async (input, context) => {
115
+ * const result = await runGit(['status'], input.workingDirectory);
116
+ * if (result.exitCode !== 0) {
117
+ * throw ToolError.executionFailed(`git status failed: ${result.stderr}`);
118
+ * }
119
+ * return { files: parse(result.stdout) };
120
+ * }
121
+ * });
122
+ */
123
+ export declare function defineTool<TInput = Record<string, any>, TOutput = unknown>(options: DefineToolOptions<TInput, TOutput>): DefinedMcpTool;
124
+ /**
125
+ * Type guard: did this tool call fail?
126
+ *
127
+ * Use this instead of inspecting the payload. Results produced by `defineTool`
128
+ * always carry an explicit `isError`.
129
+ */
130
+ export declare function isToolError(result: unknown): result is ToolResultEnvelope & {
131
+ isError: true;
132
+ };
133
+ //# sourceMappingURL=defineTool.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineTool.d.ts","sourceRoot":"","sources":["../../../src/protocols/mcp/defineTool.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AA+BH,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AACpG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAa,aAAa,EAAe,MAAM,gBAAgB,CAAC;AAoCvE;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK,GAAG,OAAO,CAAE,SAAQ,oBAAoB;IAC7E,yFAAyF;IACzF,OAAO,EAAE,oBAAoB,GAAG;QAAE,IAAI,EAAE,KAAK,GAAG,aAAa,CAAA;KAAE,CAAC;IAChE,kFAAkF;IAClF,OAAO,EAAE,OAAO,CAAC;IACjB,+EAA+E;IAC/E,QAAQ,EAAE;QACN,QAAQ,EAAE,MAAM,CAAC;QACjB,UAAU,EAAE,MAAM,CAAC;QACnB,UAAU,EAAE,MAAM,CAAC;QACnB,wCAAwC;QACxC,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KAC1B,CAAC;CACL;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC3B,mDAAmD;IACnD,OAAO,EAAE,MAAM,CAAC;IAChB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;IAClB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB,CAAC,MAAM,EAAE,OAAO;IAC9C,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACjC;;;OAGG;IACH,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC5E,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,cAAc,EAAE,CAAC;IAC5B,wDAAwD;IACxD,aAAa,CAAC,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAC/C,qDAAqD;IACrD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAClC;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAe,SAAQ,iBAAiB;IACrD,QAAQ,EAAE,MAAM,CAAC;CACpB;AAqBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,UAAU,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,OAAO,EACtE,OAAO,EAAE,iBAAiB,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5C,cAAc,CAyJhB;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,kBAAkB,GAAG;IAAE,OAAO,EAAE,IAAI,CAAA;CAAE,CAO7F"}
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Copyright 2024 Brad Anderson
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @author Brad Anderson <BradA1878@pm.me>
17
+ * @repository https://github.com/BradA1878/model-exchange-framework
18
+ * @documentation https://mxf-dev.github.io/mxf/
19
+ */
20
+ /**
21
+ * defineTool.ts
22
+ *
23
+ * The one way to declare an MCP tool.
24
+ *
25
+ * Tools used to hand-roll their own scaffolding: each file repeated its own
26
+ * try/catch, its own `error instanceof Error ? error.message : String(error)`,
27
+ * its own logger call, and its own result wrapper. Four different result shapes
28
+ * emerged across the tool set, so there was no reliable way to tell that a tool
29
+ * had failed.
30
+ *
31
+ * `defineTool` owns that scaffolding. A tool supplies a schema and a `run`
32
+ * function that returns a value or throws a {@link ToolError}; the factory:
33
+ *
34
+ * 1. validates the execution context (agentId / channelId / requestId),
35
+ * 2. validates the input against `inputSchema` with AJV on every entry path —
36
+ * not just the socket path, so a direct handler call is checked too,
37
+ * 3. runs `run` inside a single try/catch,
38
+ * 4. returns one envelope: `{ content: { type, data }, isError, metadata }`.
39
+ *
40
+ * `isError` is explicit (MCP-spec style). Callers test that flag; they never
41
+ * shape-sniff the payload.
42
+ */
43
+ import { Ajv } from 'ajv';
44
+ import * as ajvFormatsModule from 'ajv-formats';
45
+ import { Logger } from '../../utils/Logger.js';
46
+ import { ToolError, toToolError } from './ToolError.js';
47
+ const ajvFormatsAny = ajvFormatsModule;
48
+ const addFormats = (typeof ajvFormatsAny.default === 'function' ? ajvFormatsAny.default : ajvFormatsModule);
49
+ const logger = new Logger('info', 'defineTool', 'server');
50
+ /**
51
+ * Shared AJV instance for input validation.
52
+ *
53
+ * `strict: false` because tool schemas carry annotation keywords AJV does not
54
+ * know (for example `default` inside nested properties, and MXF's own metadata).
55
+ * `coerceTypes` is deliberately OFF: an LLM sending `"5"` where the schema says
56
+ * `number` is a real mistake worth surfacing, not one to paper over.
57
+ */
58
+ const ajv = new Ajv({
59
+ allErrors: true,
60
+ strict: false,
61
+ validateFormats: true,
62
+ coerceTypes: false,
63
+ useDefaults: true
64
+ });
65
+ addFormats(ajv);
66
+ /**
67
+ * Content type used for structured tool results.
68
+ */
69
+ const JSON_CONTENT_TYPE = 'application/json';
70
+ /**
71
+ * Format AJV errors into one line a model can act on.
72
+ */
73
+ function formatSchemaErrors(validate) {
74
+ const errors = validate.errors ?? [];
75
+ if (errors.length === 0) {
76
+ return 'input did not match the tool schema';
77
+ }
78
+ return errors
79
+ .map(err => {
80
+ // instancePath is '' for a root-level failure (e.g. a missing required
81
+ // property); name that root explicitly rather than printing an empty path.
82
+ const where = err.instancePath ? err.instancePath.replace(/^\//, '') : 'input';
83
+ return `${where} ${err.message}`;
84
+ })
85
+ .join('; ');
86
+ }
87
+ /**
88
+ * Declare an MCP tool.
89
+ *
90
+ * @example
91
+ * export const gitStatusTool = defineTool({
92
+ * name: 'git_status',
93
+ * category: TOOL_CATEGORIES.VERSION_CONTROL,
94
+ * description: 'Report staged, modified and untracked files by running `git status`.',
95
+ * inputSchema: {
96
+ * type: 'object',
97
+ * properties: { workingDirectory: { type: 'string' } }
98
+ * },
99
+ * run: async (input, context) => {
100
+ * const result = await runGit(['status'], input.workingDirectory);
101
+ * if (result.exitCode !== 0) {
102
+ * throw ToolError.executionFailed(`git status failed: ${result.stderr}`);
103
+ * }
104
+ * return { files: parse(result.stdout) };
105
+ * }
106
+ * });
107
+ */
108
+ export function defineTool(options) {
109
+ const { name, description, category, inputSchema, run, examples, executionSide = 'server', enabled = true, metadata = {} } = options;
110
+ // Fail at module load, not at call time, if a tool is declared wrong. A tool
111
+ // with no name or no schema cannot be registered or described to a model.
112
+ if (!name || typeof name !== 'string') {
113
+ throw new Error('defineTool: name must be a non-empty string');
114
+ }
115
+ if (!description || typeof description !== 'string') {
116
+ throw new Error(`defineTool(${name}): description must be a non-empty string`);
117
+ }
118
+ if (!category || typeof category !== 'string') {
119
+ throw new Error(`defineTool(${name}): category must be a non-empty string`);
120
+ }
121
+ if (!inputSchema || typeof inputSchema !== 'object') {
122
+ throw new Error(`defineTool(${name}): inputSchema must be an object`);
123
+ }
124
+ if (typeof run !== 'function') {
125
+ throw new Error(`defineTool(${name}): run must be a function`);
126
+ }
127
+ // Compile the schema once, at declaration. A schema AJV cannot compile is a
128
+ // bug in the tool, and it surfaces here rather than on first invocation.
129
+ let validateInput;
130
+ try {
131
+ validateInput = ajv.compile(inputSchema);
132
+ }
133
+ catch (error) {
134
+ throw new Error(`defineTool(${name}): inputSchema failed to compile: ` +
135
+ `${error instanceof Error ? error.message : String(error)}`);
136
+ }
137
+ const handler = async (rawInput, rawContext) => {
138
+ const startedAt = Date.now();
139
+ const fail = (toolError) => {
140
+ toolError.toolName = name;
141
+ logger.error(`Tool ${name} failed [${toolError.code}]: ${toolError.message}`);
142
+ return {
143
+ content: {
144
+ type: JSON_CONTENT_TYPE,
145
+ data: toolError.toData()
146
+ },
147
+ isError: true,
148
+ metadata: {
149
+ toolName: name,
150
+ executedAt: Date.now(),
151
+ durationMs: Date.now() - startedAt,
152
+ errorCode: toolError.code
153
+ }
154
+ };
155
+ };
156
+ // ── 1. Validate the execution context ──────────────────────────────
157
+ // agentId and channelId gate every downstream security and memory
158
+ // decision. A missing one is a wiring bug — never default it.
159
+ const context = rawContext;
160
+ if (!context || typeof context !== 'object') {
161
+ return fail(ToolError.invalidInput(`Tool ${name} was called without an execution context. ` +
162
+ `agentId, channelId and requestId are required.`));
163
+ }
164
+ if (typeof context.agentId !== 'string' || context.agentId.length === 0) {
165
+ return fail(ToolError.invalidInput(`Tool ${name} was called without a valid agentId. ` +
166
+ `agentId is required for all MCP tool execution.`));
167
+ }
168
+ if (typeof context.channelId !== 'string' || context.channelId.length === 0) {
169
+ return fail(ToolError.invalidInput(`Tool ${name} was called without a valid channelId. ` +
170
+ `channelId is required for all MCP tool execution.`));
171
+ }
172
+ if (typeof context.requestId !== 'string' || context.requestId.length === 0) {
173
+ return fail(ToolError.invalidInput(`Tool ${name} was called without a valid requestId. ` +
174
+ `requestId is required to correlate tool events.`));
175
+ }
176
+ const runContext = {
177
+ agentId: context.agentId,
178
+ channelId: context.channelId,
179
+ requestId: context.requestId,
180
+ data: context.data
181
+ };
182
+ // ── 2. Validate the input against the schema ───────────────────────
183
+ // AJV runs here so a direct handler call is checked exactly like a call
184
+ // arriving over the socket. `useDefaults` fills declared defaults in place.
185
+ const input = (rawInput ?? {});
186
+ if (!validateInput(input)) {
187
+ return fail(ToolError.invalidInput(`Invalid arguments for ${name}: ${formatSchemaErrors(validateInput)}`, { schemaErrors: validateInput.errors ?? [] }));
188
+ }
189
+ // ── 3. Run the tool ────────────────────────────────────────────────
190
+ try {
191
+ const output = await run(input, runContext);
192
+ return {
193
+ content: {
194
+ type: JSON_CONTENT_TYPE,
195
+ data: output
196
+ },
197
+ isError: false,
198
+ metadata: {
199
+ toolName: name,
200
+ executedAt: Date.now(),
201
+ durationMs: Date.now() - startedAt
202
+ }
203
+ };
204
+ }
205
+ catch (error) {
206
+ return fail(toToolError(error));
207
+ }
208
+ };
209
+ return {
210
+ name,
211
+ description,
212
+ category,
213
+ inputSchema,
214
+ enabled,
215
+ executionSide,
216
+ examples,
217
+ metadata: {
218
+ ...metadata,
219
+ category
220
+ },
221
+ handler: handler
222
+ };
223
+ }
224
+ /**
225
+ * Type guard: did this tool call fail?
226
+ *
227
+ * Use this instead of inspecting the payload. Results produced by `defineTool`
228
+ * always carry an explicit `isError`.
229
+ */
230
+ export function isToolError(result) {
231
+ return (typeof result === 'object' &&
232
+ result !== null &&
233
+ 'isError' in result &&
234
+ result.isError === true);
235
+ }
236
+ //# sourceMappingURL=defineTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"defineTool.js","sourceRoot":"","sources":["../../../src/protocols/mcp/defineTool.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Copyright 2024 Brad Anderson
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @author Brad Anderson <BradA1878@pm.me>
17
+ * @repository https://github.com/BradA1878/model-exchange-framework
18
+ * @documentation https://mxf-dev.github.io/mxf/
19
+ */
20
+ /**
21
+ * Result of checking a URL.
22
+ */
23
+ export interface HttpTargetCheck {
24
+ /** Whether the fetch may proceed */
25
+ allowed: boolean;
26
+ /** Why it was refused — written for the model, so it can correct course */
27
+ reason?: string;
28
+ /** The addresses the hostname resolved to */
29
+ resolvedAddresses?: string[];
30
+ }
31
+ /**
32
+ * Check whether an agent-supplied URL may be fetched.
33
+ *
34
+ * @param rawUrl - The URL the tool was asked to fetch
35
+ * @returns Whether the fetch may proceed, and why not when it may not
36
+ */
37
+ export declare function checkHttpTarget(rawUrl: string): Promise<HttpTargetCheck>;
38
+ //# sourceMappingURL=HttpTargetGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpTargetGuard.d.ts","sourceRoot":"","sources":["../../../../src/protocols/mcp/security/HttpTargetGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAyBH;;GAEG;AACH,MAAM,WAAW,eAAe;IAC5B,oCAAoC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,6CAA6C;IAC7C,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;CAChC;AAkHD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA6F9E"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Copyright 2024 Brad Anderson
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ *
16
+ * @author Brad Anderson <BradA1878@pm.me>
17
+ * @repository https://github.com/BradA1878/model-exchange-framework
18
+ * @documentation https://mxf-dev.github.io/mxf/
19
+ */
20
+ /**
21
+ * HttpTargetGuard.ts
22
+ *
23
+ * Decides whether an agent-supplied URL may be fetched from the server.
24
+ *
25
+ * The server sits inside the trust boundary: it can reach the MXF API on
26
+ * localhost:3001, Meilisearch, MongoDB, and — on a cloud host — the instance
27
+ * metadata endpoint at 169.254.169.254 that hands out IAM credentials. A tool
28
+ * that fetches an arbitrary URL on the model's behalf turns the server into a
29
+ * proxy across that boundary (server-side request forgery).
30
+ *
31
+ * This guard resolves the hostname and checks every address it resolves to, so a
32
+ * public name that points at 127.0.0.1 is caught as well as a literal IP.
33
+ *
34
+ * The guard fails closed: a target that cannot be resolved or cannot be parsed
35
+ * is refused, with an error saying why. It never silently skips the check.
36
+ */
37
+ import { promises as dns } from 'dns';
38
+ import { isIP } from 'net';
39
+ import { allowPrivateHttpHosts } from './McpToolPolicy.js';
40
+ /**
41
+ * IPv4 ranges the server must not be steered into.
42
+ * Each entry is [first octet-based CIDR, human name].
43
+ */
44
+ const BLOCKED_IPV4_RANGES = [
45
+ { cidr: '0.0.0.0/8', name: '"this network"' },
46
+ { cidr: '10.0.0.0/8', name: 'RFC1918 private network' },
47
+ { cidr: '100.64.0.0/10', name: 'carrier-grade NAT' },
48
+ { cidr: '127.0.0.0/8', name: 'loopback' },
49
+ { cidr: '169.254.0.0/16', name: 'link-local / cloud instance metadata' },
50
+ { cidr: '172.16.0.0/12', name: 'RFC1918 private network' },
51
+ { cidr: '192.0.0.0/24', name: 'IETF protocol assignments' },
52
+ { cidr: '192.168.0.0/16', name: 'RFC1918 private network' },
53
+ { cidr: '198.18.0.0/15', name: 'benchmark network' },
54
+ { cidr: '224.0.0.0/4', name: 'multicast' },
55
+ { cidr: '240.0.0.0/4', name: 'reserved' }
56
+ ];
57
+ /** Convert a dotted-quad IPv4 string to a 32-bit unsigned integer. */
58
+ function ipv4ToInt(address) {
59
+ const octets = address.split('.');
60
+ if (octets.length !== 4) {
61
+ return null;
62
+ }
63
+ let value = 0;
64
+ for (const octet of octets) {
65
+ // Reject empty, non-numeric, or out-of-range octets rather than coercing.
66
+ if (!/^\d{1,3}$/.test(octet)) {
67
+ return null;
68
+ }
69
+ const num = Number(octet);
70
+ if (num > 255) {
71
+ return null;
72
+ }
73
+ value = (value << 8) | num;
74
+ }
75
+ // `>>> 0` forces the result back to unsigned — the shifts above produce a
76
+ // signed 32-bit int for addresses above 127.255.255.255.
77
+ return value >>> 0;
78
+ }
79
+ /** Is an IPv4 address inside the given CIDR block? */
80
+ function ipv4InCidr(address, cidr) {
81
+ const [network, prefixText] = cidr.split('/');
82
+ const prefix = Number(prefixText);
83
+ const addressInt = ipv4ToInt(address);
84
+ const networkInt = ipv4ToInt(network);
85
+ if (addressInt === null || networkInt === null) {
86
+ return false;
87
+ }
88
+ // A /0 mask would shift by 32, which is a no-op in JS — handle it explicitly.
89
+ if (prefix === 0) {
90
+ return true;
91
+ }
92
+ const mask = (0xffffffff << (32 - prefix)) >>> 0;
93
+ return (addressInt & mask) === (networkInt & mask);
94
+ }
95
+ /**
96
+ * Is this address one the server must not be steered into?
97
+ *
98
+ * @returns the name of the matched range, or null when the address is fine
99
+ */
100
+ function matchBlockedRange(address) {
101
+ const version = isIP(address);
102
+ if (version === 4) {
103
+ for (const range of BLOCKED_IPV4_RANGES) {
104
+ if (ipv4InCidr(address, range.cidr)) {
105
+ return range.name;
106
+ }
107
+ }
108
+ return null;
109
+ }
110
+ if (version === 6) {
111
+ const normalized = address.toLowerCase();
112
+ // IPv6 loopback
113
+ if (normalized === '::1' || normalized === '0:0:0:0:0:0:0:1') {
114
+ return 'IPv6 loopback';
115
+ }
116
+ // Unspecified address
117
+ if (normalized === '::' || normalized === '0:0:0:0:0:0:0:0') {
118
+ return 'IPv6 unspecified address';
119
+ }
120
+ // Unique local addresses, fc00::/7
121
+ if (/^f[cd][0-9a-f]{2}:/.test(normalized)) {
122
+ return 'IPv6 unique local address';
123
+ }
124
+ // Link-local, fe80::/10
125
+ if (/^fe[89ab][0-9a-f]:/.test(normalized)) {
126
+ return 'IPv6 link-local address';
127
+ }
128
+ // IPv4-mapped (::ffff:127.0.0.1) — re-check the embedded IPv4 address,
129
+ // otherwise ::ffff:169.254.169.254 would walk straight past this guard.
130
+ const mapped = normalized.match(/^::ffff:(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$/);
131
+ if (mapped) {
132
+ return matchBlockedRange(mapped[1]);
133
+ }
134
+ return null;
135
+ }
136
+ return null;
137
+ }
138
+ /**
139
+ * Check whether an agent-supplied URL may be fetched.
140
+ *
141
+ * @param rawUrl - The URL the tool was asked to fetch
142
+ * @returns Whether the fetch may proceed, and why not when it may not
143
+ */
144
+ export async function checkHttpTarget(rawUrl) {
145
+ let url;
146
+ try {
147
+ url = new URL(rawUrl);
148
+ }
149
+ catch {
150
+ return {
151
+ allowed: false,
152
+ reason: `"${rawUrl}" is not a valid URL.`
153
+ };
154
+ }
155
+ // Only HTTP(S). file:, gopher:, ftp: and friends reach places an HTTP client
156
+ // has no business reaching.
157
+ if (url.protocol !== 'http:' && url.protocol !== 'https:') {
158
+ return {
159
+ allowed: false,
160
+ reason: `Protocol "${url.protocol}" is not allowed. Use http: or https:.`
161
+ };
162
+ }
163
+ // The operator can open this up for local development. Off by default.
164
+ if (allowPrivateHttpHosts()) {
165
+ return { allowed: true };
166
+ }
167
+ const hostname = url.hostname.replace(/^\[|\]$/g, ''); // strip IPv6 brackets
168
+ // A literal IP needs no DNS round trip.
169
+ if (isIP(hostname) !== 0) {
170
+ const blocked = matchBlockedRange(hostname);
171
+ if (blocked) {
172
+ return {
173
+ allowed: false,
174
+ reason: `Refusing to fetch ${hostname}: it is a ${blocked} address. ` +
175
+ `This tool may only reach public internet hosts. ` +
176
+ `Set MXF_HTTP_ALLOW_PRIVATE_HOSTS=true to permit private addresses.`,
177
+ resolvedAddresses: [hostname]
178
+ };
179
+ }
180
+ return { allowed: true, resolvedAddresses: [hostname] };
181
+ }
182
+ // "localhost" and anything under .localhost resolve to loopback by definition.
183
+ const lowerHost = hostname.toLowerCase();
184
+ if (lowerHost === 'localhost' || lowerHost.endsWith('.localhost')) {
185
+ return {
186
+ allowed: false,
187
+ reason: `Refusing to fetch ${hostname}: it is a loopback address. ` +
188
+ `This tool may only reach public internet hosts. ` +
189
+ `Set MXF_HTTP_ALLOW_PRIVATE_HOSTS=true to permit private addresses.`
190
+ };
191
+ }
192
+ // Resolve the name and check every address behind it. A public hostname can
193
+ // legitimately resolve to 127.0.0.1, and a malicious one will.
194
+ let addresses;
195
+ try {
196
+ const records = await dns.lookup(hostname, { all: true, verbatim: true });
197
+ addresses = records.map(record => record.address);
198
+ }
199
+ catch (error) {
200
+ // Fail closed. An unresolvable host is not a host we quietly try anyway.
201
+ return {
202
+ allowed: false,
203
+ reason: `Could not resolve "${hostname}": ` +
204
+ `${error instanceof Error ? error.message : String(error)}`
205
+ };
206
+ }
207
+ if (addresses.length === 0) {
208
+ return {
209
+ allowed: false,
210
+ reason: `"${hostname}" did not resolve to any address.`
211
+ };
212
+ }
213
+ for (const address of addresses) {
214
+ const blocked = matchBlockedRange(address);
215
+ if (blocked) {
216
+ return {
217
+ allowed: false,
218
+ reason: `Refusing to fetch ${hostname}: it resolves to ${address}, ` +
219
+ `a ${blocked} address. This tool may only reach public internet hosts. ` +
220
+ `Set MXF_HTTP_ALLOW_PRIVATE_HOSTS=true to permit private addresses.`,
221
+ resolvedAddresses: addresses
222
+ };
223
+ }
224
+ }
225
+ return { allowed: true, resolvedAddresses: addresses };
226
+ }
227
+ //# sourceMappingURL=HttpTargetGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpTargetGuard.js","sourceRoot":"","sources":["../../../../src/protocols/mcp/security/HttpTargetGuard.ts"],"names":[],"mappings":"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"}