rea-agents 2.5.0 → 3.1.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 (253) hide show
  1. package/README.md +20 -12
  2. package/bridge/ghidra/ReaGhidraBridge.java +477 -4
  3. package/bridge/hopper_bridge.py +54 -4
  4. package/dist/application/AnalysisContextQueries.js +142 -0
  5. package/dist/application/AnalysisSnapshotCache.js +4 -2
  6. package/dist/application/ApplicationWorkflowEvidenceResolver.js +19 -11
  7. package/dist/application/ArtifactInventory/policy.js +17 -0
  8. package/dist/application/ArtifactInventory/reader.js +1 -4
  9. package/dist/application/ArtifactInventory/scanCanonical.js +0 -3
  10. package/dist/application/ArtifactInventory/scanReader.js +7 -7
  11. package/dist/application/ArtifactInventory/types.js +1 -5
  12. package/dist/application/BinarySession.js +19 -20
  13. package/dist/application/BinarySessionComposition.js +21 -0
  14. package/dist/application/BinarySessionRecords.js +106 -10
  15. package/dist/application/BinarySessionStatus.js +11 -5
  16. package/dist/application/BrowserEvidence.js +3 -5
  17. package/dist/application/CapabilityClientRequirements.js +26 -0
  18. package/dist/application/CapabilityInventory.js +140 -55
  19. package/dist/application/ClientRegistrationStatus.js +4 -1
  20. package/dist/application/CrossVersionInventory.js +7 -6
  21. package/dist/application/DirectAnalysis.js +6 -2
  22. package/dist/application/ElectronActiveEvidence.js +55 -0
  23. package/dist/application/ElectronActiveObservationPort.js +1 -0
  24. package/dist/application/ElectronActiveObservationService.js +81 -0
  25. package/dist/application/EnhancedTools.js +49 -17
  26. package/dist/application/EvidenceBundleCommands.js +5 -1
  27. package/dist/application/EvidenceLedger.js +53 -17
  28. package/dist/application/JavaScriptArtifactAnalysis.js +13 -4
  29. package/dist/application/JavaScriptReplayPermission.js +1 -1
  30. package/dist/application/JavaScriptReplayService.js +23 -15
  31. package/dist/application/LazyAnalysisProvider.js +77 -0
  32. package/dist/application/LoopbackReplay.js +1 -1
  33. package/dist/application/ManagedRuntimeCorrelationService.js +9 -5
  34. package/dist/application/NativeApiInspection.js +80 -0
  35. package/dist/application/NodeRuntimeCharacterizationService.js +8 -9
  36. package/dist/application/ProcessCaptureLifecycle.js +5 -0
  37. package/dist/application/ProcessCli.js +2 -1
  38. package/dist/application/ProcessHarness.js +8 -3
  39. package/dist/application/ProcessNormalization.js +2 -1
  40. package/dist/application/ProjectPermissionStore.js +1 -0
  41. package/dist/application/ReferenceSourceImport.js +2 -2
  42. package/dist/application/SessionProviderRouter.js +6 -6
  43. package/dist/application/SetupClientConfiguration.js +10 -3
  44. package/dist/application/WindowsCapabilities.js +5 -4
  45. package/dist/application/runtime.js +26 -9
  46. package/dist/artifacts/ArtifactProvider.js +8 -10
  47. package/dist/artifacts/SafeOutputTree.js +7 -8
  48. package/dist/browser/CdpCaptureStorageFingerprints.js +10 -7
  49. package/dist/browser/CdpElectronInspection.js +3 -1
  50. package/dist/browser/JavaScriptRuntimeScope.js +5 -0
  51. package/dist/browser/PlaywrightBrowserScenarioProvider.js +8 -2
  52. package/dist/browser/PlaywrightElectronActiveActions.js +324 -0
  53. package/dist/browser/PlaywrightElectronActiveProvider.js +294 -0
  54. package/dist/browser/PlaywrightScenarioBrowser.js +4 -4
  55. package/dist/browser/PlaywrightScenarioSession.js +4 -4
  56. package/dist/browser/SensitiveTextCapture.js +1 -1
  57. package/dist/browser/V8InspectorCaptureProjection.js +1 -0
  58. package/dist/browser/V8InspectorProvider.js +3 -3
  59. package/dist/catalogIdentity.js +15 -9
  60. package/dist/cli/artifactCommands.js +5 -3
  61. package/dist/cli/coreAnalysisCommands.js +41 -0
  62. package/dist/cli/managedCommands.js +1 -1
  63. package/dist/cliApplicationCommands.js +2 -2
  64. package/dist/cliBrowserAdvancedCommands.js +11 -5
  65. package/dist/cliBrowserCommands.js +14 -7
  66. package/dist/cliCommandNames.js +2 -0
  67. package/dist/cliElectronCommands.js +46 -4
  68. package/dist/cliJavaScriptRuntimeCommands.js +14 -6
  69. package/dist/cliObservationOptions.js +4 -0
  70. package/dist/cliPolicyCommands.js +1 -0
  71. package/dist/config/browserScenario.js +77 -0
  72. package/dist/config/electronAutomation.js +35 -0
  73. package/dist/config/environment.js +6 -0
  74. package/dist/config/javascriptReplay.js +41 -0
  75. package/dist/config/managedRuntime.js +25 -0
  76. package/dist/config/parseConfig.js +56 -200
  77. package/dist/config/parsers.js +10 -1
  78. package/dist/config/passiveObservation.js +157 -0
  79. package/dist/config/processCapture.js +47 -0
  80. package/dist/contracts/applicationToolContracts.js +2 -5
  81. package/dist/contracts/applicationWorkflowInputContracts.js +86 -96
  82. package/dist/contracts/artifactToolContracts.js +35 -37
  83. package/dist/contracts/browserToolContracts.js +2 -2
  84. package/dist/contracts/electronToolContracts.js +30 -1
  85. package/dist/contracts/enhancedInputs.js +21 -27
  86. package/dist/contracts/functionWorkflowToolContracts.js +29 -0
  87. package/dist/contracts/managedToolContracts.js +4 -9
  88. package/dist/contracts/managedWorkflowExamples.js +12 -9
  89. package/dist/contracts/managedWorkflowToolContracts.js +30 -27
  90. package/dist/contracts/nativeToolContracts.js +2 -3
  91. package/dist/contracts/promptContracts.js +14 -15
  92. package/dist/contracts/sessionToolSchemas.js +61 -0
  93. package/dist/contracts/toolContractExamples.js +4 -0
  94. package/dist/contracts/toolContractHelpers.js +23 -0
  95. package/dist/contracts/toolContracts.js +12 -67
  96. package/dist/contracts/toolEffects.js +19 -0
  97. package/dist/contracts/toolOutputSchemaGroups.js +66 -11
  98. package/dist/contracts/toolOutputSchemaPrimitives.js +76 -26
  99. package/dist/contracts/toolSchemaMetadata.js +128 -0
  100. package/dist/doctorRuntime.js +1 -1
  101. package/dist/domain/analysisErrorPresentation.js +8 -2
  102. package/dist/domain/analysisErrorProjection.js +1 -0
  103. package/dist/domain/androidApplication.js +2 -0
  104. package/dist/domain/appleApplication.js +2 -0
  105. package/dist/domain/binaryTarget.js +7 -5
  106. package/dist/domain/binaryTargetTypes.js +1 -0
  107. package/dist/domain/browserCaptureComparison.js +21 -69
  108. package/dist/domain/browserObservation.js +22 -9
  109. package/dist/domain/bytecodeProvider.js +177 -0
  110. package/dist/domain/callPath.js +3 -2
  111. package/dist/domain/conformancePackage.js +169 -0
  112. package/dist/domain/conformanceReplay.js +104 -0
  113. package/dist/domain/conformanceTrustGate.js +328 -0
  114. package/dist/domain/customProtocolCapture.js +137 -0
  115. package/dist/domain/electronActiveObservation.js +277 -0
  116. package/dist/domain/electronObservation.js +15 -11
  117. package/dist/domain/electronStaticAnalysisValues.js +4 -1
  118. package/dist/domain/eventProcessTree.js +217 -0
  119. package/dist/domain/evidenceBundle.js +47 -0
  120. package/dist/domain/functionComparisonNormalization.js +15 -8
  121. package/dist/domain/functionDossierEvidence.js +9 -4
  122. package/dist/domain/hopperStartupFailure.js +1 -1
  123. package/dist/domain/hopperValues.js +68 -68
  124. package/dist/domain/inputIssueProjection.js +11 -2
  125. package/dist/domain/investigationWorkspace.js +16 -15
  126. package/dist/domain/javascriptExportShapeComparisonSchemas.js +2 -2
  127. package/dist/domain/javascriptReplay.js +79 -63
  128. package/dist/domain/javascriptRuntimeObservation.js +1 -0
  129. package/dist/domain/javascriptRuntimeReconciliationActive.js +89 -0
  130. package/dist/domain/javascriptRuntimeReconciliationGraph.js +11 -10
  131. package/dist/domain/javascriptRuntimeReconciliationMatching.js +57 -49
  132. package/dist/domain/javascriptRuntimeReconciliationParsing.js +5 -1
  133. package/dist/domain/javascriptRuntimeReconciliationResult.js +21 -14
  134. package/dist/domain/javascriptRuntimeReconciliationSchemas.js +1 -1
  135. package/dist/domain/javascriptSemanticAnalysis.js +8 -12
  136. package/dist/domain/javascriptSourceParser.js +15 -0
  137. package/dist/domain/javascriptStaticAnalysis.js +8 -12
  138. package/dist/domain/knownPageCoverage.js +15 -7
  139. package/dist/domain/mobileApplicationInvestigation.js +159 -0
  140. package/dist/domain/nativeApiBoundary.js +138 -0
  141. package/dist/domain/nodeRuntimeCharacterization.js +14 -13
  142. package/dist/domain/objcSwiftMetadata.js +150 -0
  143. package/dist/domain/packageAnalysis.js +123 -0
  144. package/dist/domain/peInspection.js +196 -0
  145. package/dist/domain/processCaptureReactiveValidation.js +8 -3
  146. package/dist/domain/processCaptureValidation.js +7 -3
  147. package/dist/domain/processComparison.js +12 -7
  148. package/dist/domain/processObservation.js +5 -6
  149. package/dist/domain/processReactiveMatching.js +14 -7
  150. package/dist/domain/processReactiveTransition.js +9 -3
  151. package/dist/domain/processScenario.js +6 -3
  152. package/dist/domain/processTraceComparison.js +3 -2
  153. package/dist/domain/protocolCapture.js +245 -0
  154. package/dist/domain/reconstructionReadinessSchemas.js +30 -2
  155. package/dist/domain/referenceSourceImportParsing.js +2 -2
  156. package/dist/domain/replayMachineRuntime.js +5 -3
  157. package/dist/domain/sourceToBundleComparison.js +2 -2
  158. package/dist/domain/sourceToBundleComparisonSchemas.js +8 -8
  159. package/dist/domain/sourceToBundleSignals.js +7 -1
  160. package/dist/domain/staticRuntimeCorrelation.js +7 -5
  161. package/dist/domain/webBundleAnalysis.js +14 -14
  162. package/dist/domain/webCaptureDiff.js +15 -12
  163. package/dist/dotnet/ManagedNativeBoundaryInspector.js +2 -3
  164. package/dist/dotnet/ManagedStaticProvider.js +34 -5
  165. package/dist/generatedMcpToolCatalog.js +37 -0
  166. package/dist/generatedPackageMetadata.js +4 -4
  167. package/dist/ghidra/GhidraClient.js +1 -1
  168. package/dist/ghidra/GhidraClientStartup.js +1 -1
  169. package/dist/ghidra/GhidraDefaults.js +1 -1
  170. package/dist/ghidra/GhidraFunctionValues.js +44 -16
  171. package/dist/ghidra/GhidraInventoryValues.js +57 -47
  172. package/dist/ghidra/GhidraProvider.js +18 -10
  173. package/dist/ghidra/GhidraProviderCapabilities.js +45 -39
  174. package/dist/ghidra/GhidraSocketConnection.js +1 -1
  175. package/dist/ghidra/protocol.js +19 -42
  176. package/dist/hopper/BridgeLauncher.js +3 -1
  177. package/dist/hopper/HopperAnalysisProfile.js +2 -4
  178. package/dist/hopper/HopperCleanup.js +5 -6
  179. package/dist/hopper/HopperClient.js +27 -3
  180. package/dist/hopper/HopperProvider.js +42 -44
  181. package/dist/hopper/HopperRequestQueue.js +32 -4
  182. package/dist/hopper/HopperResponseStream.js +2 -2
  183. package/dist/hopper/LinuxPrivateDisplayProbe.js +16 -10
  184. package/dist/hopper/protocol.js +63 -21
  185. package/dist/main/reload.js +1 -6
  186. package/dist/main/state.js +0 -14
  187. package/dist/main/transport.js +31 -41
  188. package/dist/main.js +17 -13
  189. package/dist/mcpDoctor.js +4 -26
  190. package/dist/mcpStartupPolicy.js +14 -0
  191. package/dist/process/PrivateRuntimeRoot.js +17 -0
  192. package/dist/process/ProcessOwnership.js +64 -128
  193. package/dist/process/ProcessOwnershipIdentity.js +13 -0
  194. package/dist/process/ProcessOwnershipObservation.js +88 -0
  195. package/dist/process/ProcessOwnershipProcessTree.js +22 -0
  196. package/dist/process/ProviderDeadline.js +8 -12
  197. package/dist/process/WindowsAuthority.js +32 -0
  198. package/dist/reference/ReferenceSourceReader.js +3 -3
  199. package/dist/reference/ReferenceSourceReaderEntries.js +2 -2
  200. package/dist/replay/JavaScriptReplayWorker.js +95 -11
  201. package/dist/replay/JavaScriptReplayWorkerTypes.js +1 -0
  202. package/dist/replay/LinuxJavaScriptReplayRunner.js +10 -15
  203. package/dist/replay/ReplayOutcome.js +26 -15
  204. package/dist/replay/ReplayWorkerProtocol.js +34 -29
  205. package/dist/server/createServer.js +101 -144
  206. package/dist/server/mcpClientMetadata.js +32 -0
  207. package/dist/server/registerApplicationTools/characterization.js +6 -13
  208. package/dist/server/registerApplicationTools/compareExportShapes.js +2 -7
  209. package/dist/server/registerApplicationTools/compareSourceToBundle.js +2 -7
  210. package/dist/server/registerApplicationTools/compareVersions.js +3 -8
  211. package/dist/server/registerApplicationTools/controlledReplay.js +6 -11
  212. package/dist/server/registerApplicationTools/coverage.js +13 -19
  213. package/dist/server/registerApplicationTools/obligationLedger.js +1 -6
  214. package/dist/server/registerApplicationTools/readiness.js +1 -6
  215. package/dist/server/registerApplicationTools/traceFeature.js +3 -8
  216. package/dist/server/registerApplicationTools/traceSemantics.js +1 -6
  217. package/dist/server/registerArtifactComparisonTool.js +12 -16
  218. package/dist/server/registerBrowserScenarioTool.js +1 -6
  219. package/dist/server/registerBrowserTools.js +37 -79
  220. package/dist/server/registerBundleComparisonTool.js +10 -14
  221. package/dist/server/registerCloseLifecycleTool.js +6 -14
  222. package/dist/server/registerElectronTools.js +30 -47
  223. package/dist/server/registerEnhancedTools.js +124 -122
  224. package/dist/server/registerEvidenceResources.js +50 -101
  225. package/dist/server/registerEvidenceTools.js +5 -9
  226. package/dist/server/registerFunctionComparisonTool.js +11 -15
  227. package/dist/server/registerInvestigationTools.js +42 -59
  228. package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -4
  229. package/dist/server/registerJavaScriptRuntimeObservationTools.js +13 -27
  230. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -9
  231. package/dist/server/registerManagedWorkflowTools/contract.js +2 -3
  232. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
  233. package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
  234. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +8 -13
  235. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +4 -9
  236. package/dist/server/registerOfficialTools.js +8 -9
  237. package/dist/server/registerProcessComparisonTool.js +19 -24
  238. package/dist/server/registerReconstructionObligationLedgerResource.js +0 -7
  239. package/dist/server/registerReconstructionReadinessResource.js +0 -7
  240. package/dist/server/registerReplayMachineTool.js +4 -10
  241. package/dist/server/registerSessionRecordTools.js +146 -47
  242. package/dist/server/registerSessionStatusTool.js +14 -29
  243. package/dist/server/registerSessionTools.js +45 -41
  244. package/dist/server/sessionAvailabilityPolicy.js +2 -1
  245. package/dist/server/sessionToolPolicies.js +1 -5
  246. package/dist/server/toolRegistrationOptions.js +4 -177
  247. package/dist/server/toolResult.js +14 -18
  248. package/package.json +35 -16
  249. package/scripts/electron-active-hook-boundaries.cjs +394 -0
  250. package/scripts/electron-active-hook.cjs +501 -0
  251. package/skills/reverse-engineer-anything/SKILL.md +10 -3
  252. package/dist/server/DynamicToolAvailability.js +0 -70
  253. package/dist/server/toolInputValidation.js +0 -77
@@ -1,51 +1,83 @@
1
1
  import { randomBytes } from "node:crypto";
2
2
  import { CLIENT_CAPABILITIES_META_KEY, createRequestStateCodec, McpServer, PROTOCOL_VERSION_META_KEY, } from "@modelcontextprotocol/server";
3
+ import { MANAGED_RUNTIME_DISABLED } from "../application/ManagedRuntimeCorrelationService.js";
3
4
  import { PRODUCT_IDENTITY } from "../identity.js";
4
- import { registerEnhancedTools } from "./registerEnhancedTools.js";
5
- import { registerOfficialTools } from "./registerOfficialTools.js";
6
- import { registerSessionTools } from "./registerSessionTools.js";
7
- import { registerNativeTools } from "./registerNativeTools.js";
8
- import { registerArtifactTools } from "./registerArtifactTools.js";
9
- import { registerManagedTools } from "./registerManagedTools.js";
10
- import { registerManagedWorkflowTools } from "./registerManagedWorkflowTools.js";
11
5
  import { silentLogger } from "../logger.js";
12
- import { registerGuidedPrompts } from "./registerPrompts.js";
13
- import { registerEvidenceResources } from "./registerEvidenceResources.js";
14
- import { createServerIdentity } from "../serverIdentity.js";
15
- import { registerBrowserTools } from "./registerBrowserTools.js";
6
+ import { LinuxJavaScriptReplayRunner } from "../replay/LinuxJavaScriptReplayRunner.js";
7
+ import { SystemJavaScriptReplayHost } from "../replay/SystemJavaScriptReplayHost.js";
8
+ import { mcpClientMetadata, mcpEnvelopeValue } from "./mcpClientMetadata.js";
9
+ import { PROCESS_CAPTURE_ELICITATION_POLICY, } from "./ProcessCaptureElicitation.js";
10
+ import { registerApplicationTools } from "./registerApplicationTools.js";
11
+ import { registerArtifactTools } from "./registerArtifactTools.js";
16
12
  import { registerBrowserScenarioTool } from "./registerBrowserScenarioTool.js";
13
+ import { registerBrowserTools } from "./registerBrowserTools.js";
17
14
  import { registerElectronTools } from "./registerElectronTools.js";
15
+ import { registerEnhancedTools } from "./registerEnhancedTools.js";
16
+ import { registerEvidenceResources } from "./registerEvidenceResources.js";
18
17
  import { registerJavaScriptRuntimeObservationTools } from "./registerJavaScriptRuntimeObservationTools.js";
19
- import { registerApplicationTools } from "./registerApplicationTools.js";
18
+ import { registerManagedTools } from "./registerManagedTools.js";
19
+ import { registerManagedWorkflowTools } from "./registerManagedWorkflowTools.js";
20
+ import { registerNativeTools } from "./registerNativeTools.js";
21
+ import { registerOfficialTools } from "./registerOfficialTools.js";
22
+ import { registerGuidedPrompts } from "./registerPrompts.js";
23
+ import { registerSessionTools } from "./registerSessionTools.js";
20
24
  import { sessionAvailabilityPolicy } from "./sessionAvailabilityPolicy.js";
21
25
  import { DENY_EVIDENCE_FILE_POLICY, DENY_PROCESS_POLICY, } from "./sessionToolPolicies.js";
22
- import { installDynamicToolAvailability } from "./DynamicToolAvailability.js";
23
- const TARGET_FREE_INSTRUCTIONS = "REA analyzes shipped artifacts. Route: ASAR/JavaScript -> analyze_javascript_application (configured root); archive/package -> inspect_artifact; managed PE/CLI -> inspect_managed_artifact; passive browser/Electron -> list_browser_targets/list_electron_targets; approved browser interaction -> capture_browser_scenario; Node/Electron Inspector -> list_javascript_runtime_targets; native binary/database -> open_binary, then binary_overview. Check binary_session policy. Start with summaries and cite Evidence IDs. Never repeat identical analysis or read full Evidence without need.";
26
+ const TARGET_FREE_INSTRUCTIONS = "ASAR/JavaScript -> analyze_javascript_application; archive/package -> open_binary(path), then inspect_artifact/inventory_artifact (active target); managed PE/CLI -> inspect_managed_artifact; browser/Electron -> list_browser_targets/list_electron_targets; approved -> capture_browser_scenario/capture_electron_scenario; Node/Electron Inspector -> list_javascript_runtime_targets; native binary/database -> open_binary, then binary_overview. Start with binary_session; use tools/list; capabilities via binary_session. Use summaries, cite Evidence IDs; Never repeat identical analysis or read full Evidence.";
24
27
  const ACTIVE_TARGET_INSTRUCTIONS = "REA analyzes the active reverse-engineering target. Start native analysis with binary_overview, then narrow with analyze_function, literal search, callers, callees, and xrefs. Prefer summary views, never repeat an identical call, and read full Evidence only when the task requires it.";
25
- import { LinuxJavaScriptReplayRunner } from "../replay/LinuxJavaScriptReplayRunner.js";
26
- import { SystemJavaScriptReplayHost } from "../replay/SystemJavaScriptReplayHost.js";
27
- import { PROCESS_CAPTURE_ELICITATION_POLICY, } from "./ProcessCaptureElicitation.js";
28
28
  const installSessionToolAvailability = (server, session, options) => {
29
29
  if (session === undefined)
30
30
  return undefined;
31
31
  const policy = sessionAvailabilityPolicy(options.availabilityPolicy, {
32
- processPolicy: options.processPolicy ?? DENY_PROCESS_POLICY,
32
+ processPolicy: options.processPolicy?.() ?? DENY_PROCESS_POLICY,
33
33
  evidenceFilePolicy: options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY,
34
34
  investigationInputRoots: options.investigationInputRoots ?? [],
35
35
  optionalFeatures: {
36
36
  browserObservationEnabled: options.browserObservation !== undefined,
37
37
  browserScenarioEnabled: options.browserScenarioCapture !== undefined,
38
38
  electronObservationEnabled: options.electronObservation !== undefined,
39
+ electronAutomationEnabled: options.electronActiveObservation !== undefined &&
40
+ options.permissionAuthority !== undefined,
39
41
  v8InspectorObservationEnabled: options.javascriptRuntimeObservation !== undefined,
40
- javascriptReplayEnabled: options.javascriptReplayPolicy?.enabled ?? false,
41
- managedRuntimeEnabled: options.managedRuntimePolicy?.enabled ?? false,
42
+ javascriptReplayEnabled: options.javascriptReplayPolicy?.().status === "enabled",
43
+ managedRuntimeEnabled: options.managedRuntimePolicy?.().status === "enabled",
42
44
  },
43
45
  });
44
46
  return {
45
47
  policy,
46
- controller: installDynamicToolAvailability(server, session, policy),
47
48
  };
48
49
  };
50
+ const createProcessCaptureElicitation = (stateCodec) => ({
51
+ stateCodec,
52
+ supported: (context) => {
53
+ const envelope = context.mcpReq.envelope;
54
+ const version = mcpEnvelopeValue(envelope, PROTOCOL_VERSION_META_KEY);
55
+ const capabilities = mcpEnvelopeValue(envelope, CLIENT_CAPABILITIES_META_KEY);
56
+ return (typeof version === "string" &&
57
+ PROCESS_CAPTURE_ELICITATION_POLICY.protocolVersions.some((supported) => supported === version) &&
58
+ isRecord(capabilities) &&
59
+ isRecord(capabilities.elicitation) &&
60
+ capabilities.elicitation.form !== undefined);
61
+ },
62
+ now: Date.now,
63
+ consumedNonces: new Map(),
64
+ });
65
+ const createMcpServer = (processCaptureStateCodec, session) => new McpServer({
66
+ name: PRODUCT_IDENTITY.mcpServerKey,
67
+ version: PRODUCT_IDENTITY.packageVersion,
68
+ }, {
69
+ capabilities: {
70
+ resources: { subscribe: true },
71
+ },
72
+ inputRequired: {
73
+ maxRounds: 3,
74
+ roundTimeoutMs: PROCESS_CAPTURE_ELICITATION_POLICY.roundTimeoutMs,
75
+ },
76
+ requestState: { verify: processCaptureStateCodec.verify },
77
+ instructions: session === undefined
78
+ ? ACTIVE_TARGET_INSTRUCTIONS
79
+ : TARGET_FREE_INSTRUCTIONS,
80
+ });
49
81
  /**
50
82
  * Construct one MCP server without acquiring subprocess resources.
51
83
  * Supplying a session adds target lifecycle tools; omitting it retains the
@@ -59,33 +91,15 @@ export const createServer = (analysis, session, options = {}) => {
59
91
  key: randomBytes(32),
60
92
  ttlSeconds: PROCESS_CAPTURE_ELICITATION_POLICY.stateTtlSeconds,
61
93
  });
62
- const server = new McpServer({
63
- name: PRODUCT_IDENTITY.mcpServerKey,
64
- version: PRODUCT_IDENTITY.packageVersion,
65
- }, {
66
- capabilities: {
67
- tools: { listChanged: true },
68
- resources: { listChanged: true },
69
- },
70
- inputRequired: {
71
- maxRounds: 3,
72
- roundTimeoutMs: PROCESS_CAPTURE_ELICITATION_POLICY.roundTimeoutMs,
73
- },
74
- requestState: { verify: processCaptureStateCodec.verify },
75
- instructions: session === undefined
76
- ? ACTIVE_TARGET_INSTRUCTIONS
77
- : TARGET_FREE_INSTRUCTIONS,
78
- });
79
- const dynamicTools = installSessionToolAvailability(server, session, options);
94
+ const server = createMcpServer(processCaptureStateCodec, session);
95
+ const availability = installSessionToolAvailability(server, session, options);
80
96
  server.server.onclose = () => {
81
97
  permissionAuthority?.clearSessionGrants();
82
98
  };
83
- if (dynamicTools !== undefined)
84
- server.server.oninitialized = () => server.sendToolListChanged();
85
- session?.onAvailabilityChanged?.(() => server.sendToolListChanged());
86
99
  registerServerIdentityResource(server, startedAt);
87
100
  const toolLogger = logger.child({ layer: "server" });
88
101
  const { activeTarget, recordEvidence, recordEvidenceWithUnknown } = createSessionRecorders(server, session);
102
+ const processCaptureElicitation = createProcessCaptureElicitation(processCaptureStateCodec);
89
103
  const toolContext = {
90
104
  server,
91
105
  analysis,
@@ -104,105 +118,55 @@ export const createServer = (analysis, session, options = {}) => {
104
118
  registerEvidenceResources(server, session);
105
119
  registerSessionTools(server, session, toolLogger, {
106
120
  ...options,
107
- ...(dynamicTools === undefined
121
+ ...(availability === undefined
108
122
  ? {}
109
- : { availabilityPolicy: dynamicTools.policy }),
123
+ : { availabilityPolicy: availability.policy }),
110
124
  ...(permissionAuthority === undefined ? {} : { permissionAuthority }),
111
125
  startedAt,
112
- processCaptureElicitation: {
113
- stateCodec: processCaptureStateCodec,
114
- supported: (context) => {
115
- const envelope = context.mcpReq.envelope;
116
- const version = envelope?.[PROTOCOL_VERSION_META_KEY];
117
- const capabilities = envelope?.[CLIENT_CAPABILITIES_META_KEY];
118
- return (typeof version === "string" &&
119
- PROCESS_CAPTURE_ELICITATION_POLICY.protocolVersions.some((supported) => supported === version) &&
120
- isRecord(capabilities) &&
121
- isRecord(capabilities.elicitation) &&
122
- capabilities.elicitation.form !== undefined);
123
- },
124
- now: Date.now,
125
- consumedNonces: new Map(),
126
- },
126
+ processCaptureElicitation,
127
127
  });
128
128
  }
129
- dynamicTools?.controller.synchronize();
130
129
  return server;
131
130
  };
131
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
132
132
  const createSessionRecorders = (server, session) => ({
133
133
  activeTarget: session === undefined ? undefined : () => session.activeTarget(),
134
134
  recordEvidence: session === undefined
135
135
  ? undefined
136
136
  : (evidence) => {
137
137
  const recorded = session.recordEvidence(evidence);
138
- if (recorded.ok && recorded.value === "added")
139
- server.sendResourceListChanged();
140
138
  return recorded;
141
139
  },
142
140
  recordEvidenceWithUnknown: session === undefined
143
141
  ? undefined
144
142
  : (evidence, input) => {
145
143
  const recorded = session.recordEvidenceWithUnknown(evidence, input);
146
- if (recorded.ok)
147
- server.sendResourceListChanged();
148
144
  return recorded;
149
145
  },
150
146
  });
151
- const registerServerIdentityResource = (server, startedAt) => {
152
- server.registerResource("server-identity", "rea://server/identity", {
153
- title: "REA server identity",
154
- description: "Live package, SDK, protocol, and catalog identity.",
155
- mimeType: "application/json",
156
- }, (uri) => {
157
- const client = server.server.getClientVersion();
158
- const protocolVersion = server.server.getNegotiatedProtocolVersion();
159
- return {
160
- contents: [
161
- {
162
- uri: uri.href,
163
- mimeType: "application/json",
164
- text: JSON.stringify(createServerIdentity({
165
- startedAt,
166
- ...(client === undefined ? {} : { client }),
167
- ...(protocolVersion === undefined ? {} : { protocolVersion }),
168
- }), null, 2),
169
- },
170
- ],
171
- };
172
- });
173
- };
174
147
  const registerBinaryAnalysisTools = ({ server, analysis, session, options, logger, permissionAuthority, activeTarget, recordEvidence, recordEvidenceWithUnknown, }) => {
175
148
  const recordUnknown = session === undefined
176
149
  ? undefined
177
150
  : (input) => session.recordUnknown(input);
178
- registerOfficialTools(server, analysis, {
151
+ const analysisOptions = {
179
152
  logger,
180
153
  activeTarget,
181
154
  recordEvidence,
182
155
  recordUnknown,
183
- });
156
+ };
157
+ registerOfficialTools(server, analysis, analysisOptions);
184
158
  registerEnhancedTools(server, analysis, {
185
- logger,
186
- activeTarget,
159
+ ...analysisOptions,
187
160
  analysisProfile: session === undefined ? undefined : () => session.analysisProfile(),
188
- recordEvidence,
189
- recordUnknown,
190
- });
191
- registerNativeTools(server, analysis, {
192
- logger,
193
- activeTarget,
194
- recordEvidence,
195
161
  });
162
+ const evidenceOptions = { logger, activeTarget, recordEvidence };
163
+ registerNativeTools(server, analysis, evidenceOptions);
196
164
  registerArtifactTools(server, analysis, {
197
- logger,
198
- activeTarget,
199
- recordEvidence,
165
+ ...evidenceOptions,
200
166
  ...(permissionAuthority === undefined ? {} : { permissionAuthority }),
201
167
  });
202
168
  registerManagedTools(server, analysis, {
203
- logger,
204
- activeTarget,
205
- recordEvidence,
169
+ ...evidenceOptions,
206
170
  session,
207
171
  });
208
172
  if (session !== undefined)
@@ -212,39 +176,29 @@ const registerBinaryAnalysisTools = ({ server, analysis, session, options, logge
212
176
  recordEvidenceWithUnknown,
213
177
  session,
214
178
  runtime: {
215
- policy: options.managedRuntimePolicy ?? {
216
- enabled: false,
217
- roots: [],
218
- executablePath: "/usr/bin/dotnet",
219
- },
179
+ policy: options.managedRuntimePolicy ?? (() => MANAGED_RUNTIME_DISABLED),
220
180
  authority: permissionAuthority,
221
181
  },
222
182
  });
223
183
  };
224
184
  const registerObservationTools = ({ server, session, options, logger, permissionAuthority, recordEvidence, recordEvidenceWithUnknown, }) => {
185
+ const common = { logger, permissionAuthority, recordEvidence };
225
186
  registerBrowserTools(server, {
226
- logger,
187
+ ...common,
227
188
  browser: options.browserObservation,
228
- permissionAuthority,
229
- recordEvidence,
230
189
  });
231
190
  registerBrowserScenarioTool(server, {
232
- logger,
191
+ ...common,
233
192
  provider: options.browserScenarioCapture,
234
- permissionAuthority,
235
- recordEvidence,
236
193
  });
237
194
  registerElectronTools(server, {
238
- logger,
195
+ ...common,
239
196
  electron: options.electronObservation,
240
- permissionAuthority,
241
- recordEvidence,
197
+ electronActive: options.electronActiveObservation,
242
198
  });
243
199
  registerJavaScriptRuntimeObservationTools(server, {
244
- logger,
200
+ ...common,
245
201
  runtime: options.javascriptRuntimeObservation,
246
- permissionAuthority,
247
- recordEvidence,
248
202
  });
249
203
  registerApplicationTools(server, {
250
204
  logger,
@@ -253,36 +207,39 @@ const registerObservationTools = ({ server, session, options, logger, permission
253
207
  evidenceLookup: session === undefined
254
208
  ? undefined
255
209
  : (evidenceId) => session.evidenceById(evidenceId),
256
- evidenceFilePolicy: options.evidenceFilePolicy ?? {
257
- roots: [],
258
- maxBytes: 1,
259
- maxDepth: 1,
260
- maxStringLength: 1,
261
- maxNodes: 1,
262
- },
210
+ evidenceFilePolicy: options.evidenceFilePolicy ?? DENY_EVIDENCE_FILE_POLICY,
263
211
  permissionAuthority,
264
212
  retainCoverageWorkspace: session === undefined
265
213
  ? undefined
266
- : (workspace) => {
267
- const retained = session.retainReconstructionCoverageWorkspace(workspace);
268
- if (retained === "added")
269
- server.sendResourceListChanged();
270
- return retained;
271
- },
214
+ : (workspace) => session.retainReconstructionCoverageWorkspace(workspace),
272
215
  replay: {
273
- policy: options.javascriptReplayPolicy ?? {
274
- enabled: false,
275
- roots: [],
276
- nodePath: process.execPath,
277
- bubblewrapPath: "/usr/bin/bwrap",
278
- systemdRunPath: "/usr/bin/systemd-run",
279
- systemctlPath: "/usr/bin/systemctl",
280
- shellPath: "/usr/bin/bash",
281
- },
216
+ policy: options.javascriptReplayPolicy ?? (() => ({ status: "disabled" })),
282
217
  host: options.javascriptReplayHost ?? new SystemJavaScriptReplayHost(),
283
218
  runner: options.javascriptReplayRunner ?? new LinuxJavaScriptReplayRunner(),
284
219
  authority: permissionAuthority,
285
220
  },
286
221
  });
287
222
  };
288
- const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
223
+ const registerServerIdentityResource = (server, startedAt) => {
224
+ server.registerResource("server-identity", "rea://server/identity", {
225
+ title: "REA server identity",
226
+ description: "Live package, SDK, protocol, and catalog identity.",
227
+ mimeType: "application/json",
228
+ }, async (uri, context) => {
229
+ const { createServerIdentity } = await import("../serverIdentity.js");
230
+ const { client, protocolVersion } = mcpClientMetadata(context);
231
+ return {
232
+ contents: [
233
+ {
234
+ uri: uri.href,
235
+ mimeType: "application/json",
236
+ text: JSON.stringify(createServerIdentity({
237
+ startedAt,
238
+ ...(client === undefined ? {} : { client }),
239
+ ...(protocolVersion === undefined ? {} : { protocolVersion }),
240
+ }), null, 2),
241
+ },
242
+ ],
243
+ };
244
+ });
245
+ };
@@ -0,0 +1,32 @@
1
+ import { CLIENT_CAPABILITIES_META_KEY, CLIENT_INFO_META_KEY, PROTOCOL_VERSION_META_KEY, } from "@modelcontextprotocol/server";
2
+ /** Client metadata bound to the current SDK request rather than server-global state. */
3
+ export const mcpClientMetadata = (context) => {
4
+ const envelope = context.mcpReq.envelope;
5
+ const client = implementation(mcpEnvelopeValue(envelope, CLIENT_INFO_META_KEY));
6
+ const protocolVersion = mcpEnvelopeValue(envelope, PROTOCOL_VERSION_META_KEY);
7
+ return {
8
+ ...(client === undefined ? {} : { client }),
9
+ clientFeatures: capabilityFeatures(mcpEnvelopeValue(envelope, CLIENT_CAPABILITIES_META_KEY)),
10
+ ...(typeof protocolVersion === "string" ? { protocolVersion } : {}),
11
+ };
12
+ };
13
+ /** Read an SDK-defined metadata key from the SDK's currently opaque envelope type. */
14
+ export const mcpEnvelopeValue = (envelope, key) => (envelope === undefined ? undefined : Reflect.get(envelope, key));
15
+ const implementation = (value) => isRecord(value) &&
16
+ typeof value.name === "string" &&
17
+ typeof value.version === "string"
18
+ ? { name: value.name, version: value.version }
19
+ : undefined;
20
+ const capabilityFeatures = (value) => {
21
+ const capabilities = isRecord(value) ? value : {};
22
+ const elicitation = isRecord(capabilities.elicitation)
23
+ ? capabilities.elicitation
24
+ : {};
25
+ return {
26
+ elicitation_form: elicitation.form !== undefined,
27
+ elicitation_url: elicitation.url !== undefined,
28
+ roots: capabilities.roots !== undefined,
29
+ sampling: capabilities.sampling !== undefined,
30
+ };
31
+ };
32
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1,22 +1,18 @@
1
1
  import { executeNodeCharacterization, prepareNodeCharacterization, } from "../../application/NodeRuntimeCharacterizationService.js";
2
2
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
3
- import { nodeCharacterizationExecutionInputSchema, nodeCharacterizationExecutionOutputSchema, nodeCharacterizationPreparationInputSchema, nodeCharacterizationPreparationOutputSchema, } from "../../domain/nodeRuntimeCharacterization.js";
4
3
  import { parseEvidence } from "../../domain/evidence.js";
4
+ import { nodeCharacterizationExecutionOutputSchema, nodeCharacterizationPreparationOutputSchema, } from "../../domain/nodeRuntimeCharacterization.js";
5
+ import { mcpProgressReporter } from "../mcpProgress.js";
5
6
  import { logToolExecution } from "../toolLogging.js";
6
- import { toCallToolResult } from "../toolResult.js";
7
7
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
- import { safeParseToolInput } from "../toolInputValidation.js";
9
- import { mcpProgressReporter } from "../mcpProgress.js";
8
+ import { toCallToolResult } from "../toolResult.js";
10
9
  import { recordSources } from "./helpers.js";
11
10
  const prepareContract = applicationToolContract("prepare_node_characterization");
12
11
  const executeContract = applicationToolContract("execute_node_characterization");
13
12
  /** Register node runtime characterization prepare and execute tools. */
14
13
  export const registerCharacterizationTools = (server, options) => {
15
14
  server.registerTool(prepareContract.name, toolRegistrationOptions(prepareContract), async (input, context) => {
16
- const parsed = safeParseToolInput(nodeCharacterizationPreparationInputSchema, input, prepareContract.name);
17
- if (!parsed.ok)
18
- return toCallToolResult(parsed, prepareContract);
19
- const result = await logToolExecution(options.logger, prepareContract.name, () => prepareNodeCharacterization(options.replay, parsed.value, {
15
+ const result = await logToolExecution(options.logger, prepareContract.name, () => prepareNodeCharacterization(options.replay, input, {
20
16
  signal: context.mcpReq.signal,
21
17
  progress: mcpProgressReporter(context),
22
18
  }));
@@ -31,10 +27,7 @@ export const registerCharacterizationTools = (server, options) => {
31
27
  });
32
28
  });
33
29
  server.registerTool(executeContract.name, toolRegistrationOptions(executeContract), async (input, context) => {
34
- const parsed = safeParseToolInput(nodeCharacterizationExecutionInputSchema, input, executeContract.name);
35
- if (!parsed.ok)
36
- return toCallToolResult(parsed, executeContract);
37
- const result = await logToolExecution(options.logger, executeContract.name, () => executeNodeCharacterization(options.replay, parsed.value, {
30
+ const result = await logToolExecution(options.logger, executeContract.name, () => executeNodeCharacterization(options.replay, input, {
38
31
  signal: context.mcpReq.signal,
39
32
  progress: mcpProgressReporter(context),
40
33
  }));
@@ -44,7 +37,7 @@ export const registerCharacterizationTools = (server, options) => {
44
37
  const sources = [
45
38
  output.transformation_evidence,
46
39
  ...output.replay.source_evidence,
47
- ...(output.replay.evidence === null ? [] : [output.replay.evidence]),
40
+ output.replay.evidence,
48
41
  output.evidence,
49
42
  ].map((item) => parseEvidence(item));
50
43
  const recorded = recordSources(options.recordEvidence, sources);
@@ -1,21 +1,16 @@
1
1
  import { resolveCompareJavaScriptExportShapesRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
2
  import { compareJavaScriptExportShapesEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { compareJavaScriptExportShapesRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
4
  import { javaScriptExportShapeComparisonResultSchema } from "../../domain/javascriptExportShapeComparisonSchemas.js";
6
- import { safeParseToolInput } from "../toolInputValidation.js";
7
5
  import { logToolExecution } from "../toolLogging.js";
8
- import { toCallToolResult } from "../toolResult.js";
9
6
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
7
+ import { toCallToolResult } from "../toolResult.js";
10
8
  import { recordResult, recordSources } from "./helpers.js";
11
9
  const contract = applicationToolContract("compare_javascript_export_shapes");
12
10
  /** Register the execution-free exact JavaScript export-shape comparison. */
13
11
  export const registerCompareJavaScriptExportShapesTool = (server, options) => {
14
12
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
15
- const parsedInput = safeParseToolInput(compareJavaScriptExportShapesRequestSchema, input, contract.name);
16
- if (!parsedInput.ok)
17
- return toCallToolResult(parsedInput, contract);
18
- const resolved = resolveCompareJavaScriptExportShapesRequestValidated(parsedInput.value, options.evidenceLookup);
13
+ const resolved = resolveCompareJavaScriptExportShapesRequestValidated(input, options.evidenceLookup);
19
14
  if (!resolved.ok)
20
15
  return toCallToolResult(resolved, contract);
21
16
  const parsed = resolved.value;
@@ -1,10 +1,8 @@
1
- import { compareSourceToBundleEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
1
  import { resolveCompareSourceToBundleRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
+ import { compareSourceToBundleEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { compareSourceToBundleRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
4
  import { sourceToBundleComparisonResultSchema } from "../../domain/sourceToBundleComparisonSchemas.js";
6
5
  import { logToolExecution } from "../toolLogging.js";
7
- import { safeParseToolInput } from "../toolInputValidation.js";
8
6
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
9
7
  import { toCallToolResult } from "../toolResult.js";
10
8
  import { recordResult, recordSources } from "./helpers.js";
@@ -12,10 +10,7 @@ const contract = applicationToolContract("compare_source_to_bundle");
12
10
  /** Register conservative historical-source to bundle comparison. */
13
11
  export const registerCompareSourceToBundleTool = (server, options) => {
14
12
  server.registerTool(contract.name, toolRegistrationOptions(contract), async (input) => {
15
- const parsedInput = safeParseToolInput(compareSourceToBundleRequestSchema, input, contract.name);
16
- if (!parsedInput.ok)
17
- return toCallToolResult(parsedInput, contract);
18
- const resolved = resolveCompareSourceToBundleRequestValidated(parsedInput.value, options.evidenceLookup);
13
+ const resolved = resolveCompareSourceToBundleRequestValidated(input, options.evidenceLookup);
19
14
  if (!resolved.ok)
20
15
  return toCallToolResult(resolved, contract);
21
16
  const result = await logToolExecution(options.logger, contract.name, () => Promise.resolve(compareSourceToBundleEvidenceValidated(resolved.value)));
@@ -1,21 +1,16 @@
1
- import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
2
1
  import { resolveCompareApplicationVersionsRequestValidated } from "../../application/ApplicationWorkflowEvidenceResolver.js";
2
+ import { compareApplicationVersionsEvidenceValidated } from "../../application/JavaScriptApplicationWorkflowService.js";
3
3
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
4
- import { compareApplicationVersionsRequestSchema } from "../../contracts/applicationWorkflowInputContracts.js";
5
4
  import { applicationVersionComparisonResultSchema } from "../../domain/javascriptApplicationVersionComparisonSchemas.js";
6
5
  import { logToolExecution } from "../toolLogging.js";
7
- import { toCallToolResult } from "../toolResult.js";
8
6
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
9
- import { safeParseToolInput } from "../toolInputValidation.js";
7
+ import { toCallToolResult } from "../toolResult.js";
10
8
  import { recordResult, recordSources } from "./helpers.js";
11
9
  const compareContract = applicationToolContract("compare_application_versions");
12
10
  /** Register the provider-neutral JavaScript version comparison tool. */
13
11
  export const registerCompareApplicationVersionsTool = (server, options) => {
14
12
  server.registerTool(compareContract.name, toolRegistrationOptions(compareContract), async (input) => {
15
- const parsedInput = safeParseToolInput(compareApplicationVersionsRequestSchema, input, compareContract.name);
16
- if (!parsedInput.ok)
17
- return toCallToolResult(parsedInput, compareContract);
18
- const resolved = resolveCompareApplicationVersionsRequestValidated(parsedInput.value, options.evidenceLookup);
13
+ const resolved = resolveCompareApplicationVersionsRequestValidated(input, options.evidenceLookup);
19
14
  if (!resolved.ok)
20
15
  return toCallToolResult(resolved, compareContract);
21
16
  const parsed = resolved.value;
@@ -1,29 +1,24 @@
1
1
  import { runControlledReplayValidated } from "../../application/JavaScriptReplayService.js";
2
2
  import { applicationToolContract } from "../../contracts/applicationToolContracts.js";
3
- import { controlledReplayInputSchema, controlledReplayOutputSchema, } from "../../domain/javascriptReplay.js";
4
3
  import { parseEvidence } from "../../domain/evidence.js";
4
+ import { controlledReplayOutputSchema } from "../../domain/javascriptReplay.js";
5
+ import { mcpProgressReporter } from "../mcpProgress.js";
5
6
  import { logToolExecution } from "../toolLogging.js";
6
- import { toCallToolResult } from "../toolResult.js";
7
7
  import { toolRegistrationOptions } from "../toolRegistrationOptions.js";
8
- import { safeParseToolInput } from "../toolInputValidation.js";
9
- import { mcpProgressReporter } from "../mcpProgress.js";
8
+ import { toCallToolResult } from "../toolResult.js";
10
9
  import { recordSources } from "./helpers.js";
11
10
  const replayContract = applicationToolContract("run_controlled_replay");
12
11
  /** Register the controlled JavaScript replay tool. */
13
12
  export const registerControlledReplayTool = (server, options) => {
14
13
  server.registerTool(replayContract.name, toolRegistrationOptions(replayContract), async (input, context) => {
15
- const parsedInput = safeParseToolInput(controlledReplayInputSchema, input, replayContract.name);
16
- if (!parsedInput.ok)
17
- return toCallToolResult(parsedInput, replayContract);
18
- const parsed = parsedInput.value;
19
- const result = await logToolExecution(options.logger, replayContract.name, () => runControlledReplayValidated(options.replay, parsed, {
14
+ const result = await logToolExecution(options.logger, replayContract.name, () => runControlledReplayValidated(options.replay, input, {
20
15
  signal: context.mcpReq.signal,
21
16
  progress: mcpProgressReporter(context),
22
17
  }));
23
18
  if (!result.ok)
24
19
  return toCallToolResult(result, replayContract);
25
20
  const output = controlledReplayOutputSchema.parse(result.value);
26
- if (output.evidence !== null) {
21
+ if (output.phase === "execute") {
27
22
  const sourcesRecorded = recordSources(options.recordEvidence, output.source_evidence.map((item) => parseEvidence(item)));
28
23
  if (!sourcesRecorded.ok)
29
24
  return toCallToolResult(sourcesRecorded, replayContract);
@@ -32,7 +27,7 @@ export const registerControlledReplayTool = (server, options) => {
32
27
  return toCallToolResult(recorded, replayContract);
33
28
  }
34
29
  return toCallToolResult(result, replayContract, {
35
- evidenceResourcesAvailable: output.evidence !== null && options.recordEvidence !== undefined,
30
+ evidenceResourcesAvailable: output.phase === "execute" && options.recordEvidence !== undefined,
36
31
  });
37
32
  });
38
33
  };