Files
reverse-engineering-anything/src/server/createServer.ts
T
b675073b73 feat(mcp): scope advertised tools by family (#7228)
Scope MCP discovery, setup, doctor, status and recovery guidance by selected tool families using one contract inventory and shared catalog identity. Preserve default discovery, canonical validation and complete Evidence.

Fixes #3246. Builds on #3026. Real libcrypto workflow verifies all 5,367 exports and identical complete Evidence. Static/source/build/docs/Windows/package/Greptile checks pass; ten assertions reproduced identically on clean main and feature across Node 24/22, with cancelled coverage explicitly unverified. Merge uses the user-authorized bypass for baseline failures and unchecked human-readiness declarations, without attesting human review.

Co-authored-by: 0xLLVEL <fakhrezan1@gmail.com>
Co-authored-by: Codebuff <noreply@codebuff.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-10-26 19:50:12 +08:00

1337 lines
46 KiB
TypeScript

import { AnalysisSettings } from "../application/AnalysisSettings.js";
import { registerAnalysisSettingsTools } from "./registerAnalysisSettingsTools.js";
import type { DevicetreeService } from "../application/binaryDiagnostics/DevicetreeService.js";
import { registerDevicetreeTool } from "./registerDevicetreeTool.js";
import { pcapCaptureHostSupported } from "../domain/pcap/pcapAnalysis.js";
import { createGpuCodeObjectsService } from "../composition/gpu.js";
import { registerGpuCodeObjectsTools } from "./registerGpuCodeObjectsTools.js";
import type { PacketCaptureService } from "../application/captures/PacketCaptureService.js";
import { serverInstructions } from "./serverInstructions.js";
import {
createPacketCaptureService,
tsharkHostSupported,
} from "../composition/captures.js";
import { registerCaptureTools } from "./registerCaptureTools.js";
import type { SignalRecordingService } from "../application/signals/SignalRecordingService.js";
import {
createSignalRecordingService,
sigrokHostSupported,
} from "../composition/signals.js";
import { registerSignalTools } from "./registerSignalTools.js";
import type { WasmArtifactService } from "../application/wasm/WasmArtifactService.js";
import { wasmArtifactModule } from "../composition/wasm.js";
import { registerWasmTools } from "./registerWasmTools.js";
import type { ApkSignatureService } from "../application/apkSignature/ApkSignatureService.js";
import { apkSignatureModule } from "../composition/apkSignature.js";
import { registerApkSignatureTools } from "./registerApkSignatureTools.js";
import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
import { captureProviderEnvironment } from "./providerEnvironment.js";
import {
createElfNotesService,
createAppleIpsService,
createDevicetreeService,
createKernelModuleService,
createPeLoadConfigService,
createPeCertificatesService,
createPeImportsService,
createNativeExportsService,
createPeResourcesService,
createRecordedCrashService,
createByteEntropyService,
createBinaryLayoutService,
pwntoolsHostSupported,
} from "../composition/binaryDiagnostics.js";
import type { ElfNotesService } from "../application/binaryDiagnostics/ElfNotesService.js";
import type { AppleIpsService } from "../application/binaryDiagnostics/AppleIpsService.js";
import type { KernelModuleService } from "../application/binaryDiagnostics/KernelModuleService.js";
import type { PeLoadConfigService } from "../application/binaryDiagnostics/PeLoadConfigService.js";
import type { PeCertificatesService } from "../application/binaryDiagnostics/PeCertificatesService.js";
import type { PeImportsService } from "../application/binaryDiagnostics/PeImportsService.js";
import type { PeResourcesService } from "../application/binaryDiagnostics/PeResourcesService.js";
import type { NativeExportsService } from "../application/binaryDiagnostics/NativeExportsService.js";
import { registerElfNotesTool } from "./registerElfNotesTool.js";
import { registerAppleIpsTool } from "./registerAppleIpsTool.js";
import { registerKernelModuleTool } from "./registerKernelModuleTool.js";
import { registerPeLoadConfigTool } from "./registerPeLoadConfigTool.js";
import { registerPeCertificatesTool } from "./registerPeCertificatesTool.js";
import { registerPeImportsTool } from "./registerPeImportsTool.js";
import { registerPeResourcesTool } from "./registerPeResourcesTool.js";
import { registerNativeExportsTool } from "./registerNativeExportsTool.js";
import type { EvmInterfaceService } from "../application/evm/EvmInterfaceService.js";
import {
evmHostSupported,
evmInterfaceModule,
evmLimiterAvailability,
} from "../composition/evm.js";
import { registerEvmTools } from "./registerEvmTools.js";
import type { SqliteDatabaseService } from "../application/sqlite/SqliteDatabaseService.js";
import { createSqliteDatabaseService } from "../composition/sqlite.js";
import { registerSqliteTools } from "./registerSqliteTools.js";
import { registerRecordedCrashTools } from "./registerRecordedCrashTools.js";
import { createDesktopApplicationService } from "../composition/desktop.js";
import { registerDesktopApplicationTool } from "./registerDesktopApplicationTool.js";
import { createGoBinaryService } from "../composition/go.js";
import { createModelArtifactService } from "../composition/model.js";
import { registerModelArtifactTools } from "./registerModelArtifactTools.js";
import { createIl2cppMetadataService } from "../composition/il2cpp.js";
import type { Il2cppMetadataService } from "../application/il2cpp/Il2cppMetadataService.js";
import type { GoBinaryService } from "../application/go/GoBinaryService.js";
import { createElectronFuseService } from "../composition/electronFuses.js";
import type { ElectronFuseService } from "../application/electron/ElectronFuseService.js";
import { registerGoTools } from "./registerGoTools.js";
import { registerIl2cppTools } from "./registerIl2cppTools.js";
import { createRustBinaryService } from "../composition/rust.js";
import type { RustBinaryService } from "../application/rust/RustBinaryService.js";
import { registerRustTools } from "./registerRustTools.js";
import { createPythonPycService } from "../composition/pythonPyc.js";
import type { PythonPycService } from "../application/python/PythonPycService.js";
import { registerPythonPycTool } from "./registerPythonPycTool.js";
import { createBeamService } from "../composition/erlang.js";
import type { BeamService } from "../application/erlang/BeamService.js";
import { registerErlangTools } from "./registerErlangTools.js";
import type { RecordedCrashService } from "../application/binaryDiagnostics/RecordedCrashService.js";
import { registerAnalysisViewTool } from "./registerAnalysisViewTool.js";
import { registerBinaryDiagnosticsTools } from "./registerBinaryDiagnosticsTools.js";
import { FridaInstrumentationManager } from "../frida/FridaInstrumentationManager.js";
import { registerFridaTools } from "./registerFridaTools.js";
import type { BinaryLayoutService } from "../application/binaryDiagnostics/BinaryLayoutService.js";
import { EvidenceMcpServer } from "./EvidenceMcpServer.js";
import { catalogIdentityForToolFamilies } from "../catalogIdentity.js";
import { parseMcpToolFamilies } from "../config/mcpToolFamilies.js";
import { createToolResultDelivery } from "./toolResult.js";
import type { ToolResultDelivery } from "./ToolResultDelivery.js";
import { parseMcpResponseBudget } from "../config/mcpResponseBudget.js";
import {
parseMcpOutputSchemaProfile,
type McpOutputSchemaProfile,
} from "../config/mcpOutputSchemaProfile.js";
import {
compactPresentationForMcpInputSchemaProfile,
parseMcpInputSchemaProfile,
} from "../config/mcpInputSchemaProfile.js";
import type { CompactInputSchemaPresentation } from "./EvidenceMcpServer.js";
import { isAbsolute } from "node:path";
import type { BinarySessionPort } from "../application/binary/BinarySessionPort.js";
import type { BrowserObservationPort } from "../application/BrowserObservationPort.js";
import type { BrowserScenarioCapturePort } from "../application/BrowserScenarioCapturePort.js";
import type { ElectronActiveObservationPort } from "../application/javascript/ElectronActiveObservationPort.js";
import type { ElectronObservationPort } from "../application/javascript/ElectronObservationPort.js";
import type { JavaScriptRuntimeObservationPort } from "../application/javascript/JavaScriptRuntimeObservationPort.js";
import type { FridaInstrumentationPort } from "../application/frida/FridaInstrumentationPort.js";
import type { OptionalProviderLoadFailures } from "../application/OptionalObservationProviders.js";
import { PRODUCT_IDENTITY } from "../identity.js";
import { silentLogger } from "../logger.js";
import type { Logger } from "pino";
import { registerApplicationTools } from "./registerApplicationTools.js";
import { registerArtifactTools } from "./registerArtifactTools.js";
import { registerNativeTools } from "./registerNativeTools.js";
import { registerBrowserScenarioTool } from "./registerBrowserScenarioTool.js";
import { registerBrowserTools } from "./registerBrowserTools.js";
import { registerWebScriptTool } from "./registerWebScriptTool.js";
import { registerWebModuleTool } from "./registerWebModuleTool.js";
import type { WebModuleTraceService } from "../application/WebModuleTraceService.js";
import { createWebModuleTraceService } from "../composition/webModules.js";
import { createWebSourceLocationService } from "../composition/webSourceLocations.js";
import { registerWebSourceLocationTool } from "./registerWebSourceLocationTool.js";
import type { WebSourceLocationService } from "../application/WebSourceLocationService.js";
import type { WebRuntimeService } from "../application/WebRuntimeService.js";
import { createWebRuntimeService } from "../composition/webRuntime.js";
import { registerWebRuntimeTools } from "./registerWebRuntimeTools.js";
import type { WebNetworkCaptureService } from "../application/WebNetworkCaptureService.js";
import { createWebNetworkCaptureService } from "../composition/webNetworkCaptures.js";
import { registerWebNetworkCaptureTool } from "./registerWebNetworkCaptureTool.js";
import { registerJavaScriptRecoveryTool } from "./registerJavaScriptRecoveryTool.js";
import { JavaScriptRecoveryService } from "../application/javascript/JavaScriptRecoveryService.js";
import type { JavaScriptRecoveryPort } from "../application/javascript/JavaScriptRecoveryPort.js";
import {
createJavaScriptRecoveryProvider,
wakaruHostSupported,
} from "../composition/javascriptRecovery.js";
import { registerElectronTools } from "./registerElectronTools.js";
import { ArtifactResourceScope } from "../artifacts/ArtifactResourceScope.js";
import { registerEnhancedTools } from "./registerEnhancedTools.js";
import { registerJavaScriptRuntimeObservationTools } from "./registerJavaScriptRuntimeObservationTools.js";
import { registerManagedTools } from "./registerManagedTools.js";
import { registerFirmwareTools } from "./registerFirmwareTools.js";
import { FirmwareAnalysisService } from "../application/firmware/FirmwareAnalysisService.js";
import type { FirmwareAnalysisPort } from "../application/firmware/FirmwareAnalysisPort.js";
import {
createFirmwareAnalysisProvider,
firmwareHostSupported,
} from "../composition/firmware.js";
import { registerAndroidTools } from "./registerAndroidTools.js";
import { registerApktoolTools } from "./registerApktoolTools.js";
import { registerPcapTools } from "./registerPcapTools.js";
import { registerFlutterTools } from "./registerFlutterTools.js";
import { registerJebTools } from "./registerJebTools.js";
import { registerAdbTools } from "./registerAdbTools.js";
import { AndroidAnalysisService } from "../application/android/AndroidAnalysisService.js";
import { JebAnalysisService } from "../application/jeb/JebAnalysisService.js";
import type { AndroidAnalysisPort } from "../application/android/AndroidAnalysisPort.js";
import type { ApktoolResourceAnalysisPort } from "../application/apktool/ApktoolResourceAnalysisPort.js";
import type { PcapAnalysisPort } from "../application/pcap/PcapAnalysisPort.js";
import { PcapAnalysisService } from "../application/pcap/PcapAnalysisService.js";
import {
locateWiresharkTool,
selectWiresharkTool,
} from "../pcap/PcapConfiguration.js";
import { ApktoolResourceAnalysisService } from "../application/apktool/ApktoolResourceAnalysisService.js";
import type { FlutterBuildAnalysisPort } from "../application/flutter/FlutterBuildAnalysisPort.js";
import { FlutterBuildAnalysisService } from "../application/flutter/FlutterBuildAnalysisService.js";
import { createAndroidAnalysisProvider } from "../composition/android.js";
import { createApktoolResourceAnalysisProvider } from "../composition/apktool.js";
import { createPcapAnalysisProvider } from "../composition/pcap.js";
import { createFlutterBuildAnalysisProvider } from "../composition/flutter.js";
import type { JebAnalysisPort } from "../application/jeb/JebAnalysisPort.js";
import { createJebAnalysisProvider } from "../composition/jeb.js";
import type { AdbDeviceAnalysisPort } from "../application/adb/AdbDeviceAnalysisPort.js";
import { AdbDeviceAnalysisService } from "../application/adb/AdbDeviceAnalysisService.js";
import { createAdbDeviceAnalysisProvider } from "../composition/adb.js";
import { registerManagedWorkflowTools } from "./registerManagedWorkflowTools.js";
import { registerOfficialTools } from "./registerOfficialTools.js";
import { registerGuidedPrompts } from "./registerPrompts.js";
import { registerSessionTools } from "./registerSessionTools.js";
import type { AvailabilityPolicy } from "../application/CapabilityInventory.js";
import { sessionAvailabilityPolicy } from "./sessionAvailabilityPolicy.js";
import {
withAdmittedAnalysis,
type ServerAnalysisSource,
type WithAdmittedAnalysis,
} from "./analysisAdmission.js";
import { createReverseEngineeringService } from "../composition/reverseEngineering.js";
import { registerReverseEngineeringTools } from "./registerReverseEngineeringTools.js";
import { CutterBridgeClient } from "../cutter/CutterBridgeClient.js";
import { CutterBridgeService } from "../cutter/CutterBridgeService.js";
import { registerCutterTools } from "./registerCutterTools.js";
import { GdbSessionManager } from "../gdb/GdbSessionManager.js";
import { registerGdbTools } from "./registerGdbTools.js";
import { RizinDebugSessionManager } from "../rizin/RizinDebugSessionManager.js";
import { registerRizinDebugTools } from "./registerRizinDebugTools.js";
export interface CreateServerOptions {
readonly analysisSettings?: AnalysisSettings;
/** Preserve the connection's creation time when materializing its runtime. */
readonly startedAt?: string;
/** Existing SDK server whose deferred registrations are being materialized. */
readonly mcpServer?: EvidenceMcpServer;
readonly environment?: Readonly<NodeJS.ProcessEnv>;
readonly delivery?: ToolResultDelivery;
readonly packetCapture?: PacketCaptureService;
readonly signalRecording?: SignalRecordingService;
readonly wasmArtifact?: WasmArtifactService;
readonly apkSignature?: ApkSignatureService;
readonly providerEnvironment?: Readonly<NodeJS.ProcessEnv>;
readonly evmInterface?: EvmInterfaceService;
readonly sqliteDatabase?: SqliteDatabaseService;
readonly logger?: Logger;
readonly binaryLayout?: BinaryLayoutService;
readonly goBinary?: GoBinaryService;
readonly il2cppMetadata?: Il2cppMetadataService;
readonly rustBinary?: RustBinaryService;
readonly pythonPyc?: PythonPycService;
readonly erlangBeam?: BeamService;
readonly electronFuses?: ElectronFuseService;
readonly recordedCrash?: RecordedCrashService;
readonly firmwareAnalysis?: FirmwareAnalysisPort;
readonly javascriptRecovery?: JavaScriptRecoveryPort;
readonly webModuleTrace?: WebModuleTraceService;
readonly webSourceLocation?: WebSourceLocationService;
readonly webRuntime?: WebRuntimeService;
readonly webNetworkCapture?: WebNetworkCaptureService;
readonly androidAnalysis?: AndroidAnalysisPort;
readonly apktoolAnalysis?: ApktoolResourceAnalysisPort;
readonly pcapAnalysis?: PcapAnalysisPort;
readonly flutterAnalysis?: FlutterBuildAnalysisPort;
readonly jebAnalysis?: JebAnalysisPort;
readonly adbDeviceAnalysis?: AdbDeviceAnalysisPort;
readonly browserObservation?: BrowserObservationPort;
readonly browserScenarioCapture?: BrowserScenarioCapturePort;
readonly electronObservation?: ElectronObservationPort;
/** Selects who closes the shared optional observation providers. */
readonly optionalObservationProviderOwner?: "server" | "caller";
readonly electronActiveObservation?: ElectronActiveObservationPort;
readonly javascriptRuntimeObservation?: JavaScriptRuntimeObservationPort;
readonly fridaInstrumentation?: FridaInstrumentationPort;
readonly availabilityPolicy?: () => AvailabilityPolicy;
readonly optionalProviderLoadFailures?: OptionalProviderLoadFailures;
}
/** Apply the shared TShark selection rule without starting the tool. */
const tsharkLocatable = (environment: Readonly<NodeJS.ProcessEnv>): boolean => {
try {
return (
locateWiresharkTool(
selectWiresharkTool(environment, "tshark"),
environment,
) !== undefined
);
} catch {
// A relative REA_TSHARK_COMMAND is configuration the tool reports at execution.
return false;
}
};
const installSessionToolAvailability = (
session: BinarySessionPort | undefined,
options: CreateServerOptions,
environment: Readonly<NodeJS.ProcessEnv>,
fridaInstrumentation: FridaInstrumentationPort,
) => {
if (session === undefined) return undefined;
const { platform, arch } = process;
// Each provider owns its verified host; discovery and execution share it.
const verifiedHost = {
packetCapture: tsharkHostSupported(platform),
pcapCapture: pcapCaptureHostSupported(platform),
signalRecording: sigrokHostSupported(platform),
evmInterface: evmHostSupported(platform, arch),
pwntools: pwntoolsHostSupported(platform, arch),
firmware: firmwareHostSupported(platform),
javascriptRecovery: wakaruHostSupported(platform, arch),
};
const pwntools =
verifiedHost.pwntools && isAbsolute(environment.REA_PWNTOOLS_PYTHON ?? "");
// Injected services own their availability on any host. Otherwise no
// configuration lets an integration pass its execution host check.
const outsideVerifiedHost = (injected: unknown, supported: boolean) =>
injected === undefined && !supported;
const basePolicy = sessionAvailabilityPolicy(options.availabilityPolicy, {
optionalProviderLoadFailures: options.optionalProviderLoadFailures,
hostUnsupported: {
pcapCapture: outsideVerifiedHost(
options.pcapAnalysis,
verifiedHost.pcapCapture,
),
packetCapture: outsideVerifiedHost(
options.packetCapture,
verifiedHost.packetCapture,
),
signalRecording: outsideVerifiedHost(
options.signalRecording,
verifiedHost.signalRecording,
),
evmInterface: outsideVerifiedHost(
options.evmInterface,
verifiedHost.evmInterface,
),
binaryLayout: outsideVerifiedHost(
options.binaryLayout,
verifiedHost.pwntools,
),
recordedCrash: outsideVerifiedHost(
options.recordedCrash,
verifiedHost.pwntools,
),
firmwareInspection: outsideVerifiedHost(
options.firmwareAnalysis,
verifiedHost.firmware,
),
firmwareExtraction: outsideVerifiedHost(
options.firmwareAnalysis,
verifiedHost.firmware,
),
javascriptRecovery: outsideVerifiedHost(
options.javascriptRecovery,
verifiedHost.javascriptRecovery,
),
},
optionalFeatures: {
packetCaptureEnabled:
options.packetCapture !== undefined ||
(verifiedHost.packetCapture && tsharkLocatable(environment)),
signalRecordingEnabled:
options.signalRecording !== undefined ||
(verifiedHost.signalRecording &&
isAbsolute(environment.REA_SIGROK_COMMAND ?? "")),
wasmArtifactEnabled:
options.wasmArtifact !== undefined ||
isAbsolute(environment.REA_WABT_BIN_DIRECTORY ?? ""),
evmInterfaceEnabled:
options.evmInterface !== undefined || verifiedHost.evmInterface,
webModuleResolutionEnabled:
options.webModuleTrace !== undefined ||
isAbsolute(environment.REA_BROWSER_EXECUTABLE ?? ""),
recordedCrashEnabled: options.recordedCrash !== undefined || pwntools,
binaryLayoutEnabled: options.binaryLayout !== undefined || pwntools,
firmwareInspectionEnabled:
options.firmwareAnalysis !== undefined ||
(verifiedHost.firmware &&
isAbsolute(environment.REA_BINWALK_COMMAND ?? "")),
firmwareExtractionEnabled:
options.firmwareAnalysis !== undefined ||
(verifiedHost.firmware &&
isAbsolute(environment.REA_UNBLOB_COMMAND ?? "")),
browserObservationEnabled: options.browserObservation !== undefined,
javascriptRecoveryEnabled:
options.javascriptRecovery !== undefined ||
(verifiedHost.javascriptRecovery &&
isAbsolute(environment.REA_WAKARU_COMMAND ?? "")),
browserScenarioEnabled: options.browserScenarioCapture !== undefined,
electronObservationEnabled: options.electronObservation !== undefined,
electronAutomationEnabled:
options.electronActiveObservation !== undefined,
v8InspectorObservationEnabled:
options.javascriptRuntimeObservation !== undefined,
},
});
const policy = (): AvailabilityPolicy => {
const value = basePolicy();
const fridaFailure =
options.optionalProviderLoadFailures?.fridaInstrumentation ??
fridaInstrumentation.availabilityFailure?.();
return fridaFailure === undefined
? value
: {
...value,
optionalProviderLoadFailures: {
...value.optionalProviderLoadFailures,
fridaInstrumentation: fridaFailure,
},
};
};
return {
policy,
...(options.evmInterface !== undefined || !verifiedHost.evmInterface
? {}
: {
evmLimiterAvailability: (signal: AbortSignal) =>
evmLimiterAvailability(environment, { signal }),
}),
};
};
const createMcpServer = (
session: BinarySessionPort | undefined,
delivery: ToolResultDelivery,
compactPresentation: CompactInputSchemaPresentation | undefined,
outputSchemaProfile: McpOutputSchemaProfile,
advertisedToolFamilies: ReadonlySet<string> | undefined,
): EvidenceMcpServer =>
new EvidenceMcpServer(
{
name: PRODUCT_IDENTITY.mcpServerKey,
version: PRODUCT_IDENTITY.packageVersion,
},
{
capabilities: {},
instructions: serverInstructions(
session !== undefined,
advertisedToolFamilies,
),
},
session === undefined
? undefined
: (evidence) => session.recordEvidence(evidence),
delivery,
compactPresentation,
outputSchemaProfile,
catalogIdentityForToolFamilies(
compactPresentation,
outputSchemaProfile,
advertisedToolFamilies,
),
advertisedToolFamilies,
);
/**
* Construct one MCP server without acquiring subprocess resources.
* Supplying a session adds target lifecycle tools; omitting it retains the
* fixed-target seam used by focused tests and embedders.
*/
export const createServer = (
source: ServerAnalysisSource,
options: CreateServerOptions = {},
): EvidenceMcpServer => {
const session = source.kind === "session" ? source.session : undefined;
const analysis = source.kind === "session" ? source.session : source.analysis;
const environment = snapshotEnvironment(options.environment ?? process.env);
const analysisSettings =
options.analysisSettings ?? new AnalysisSettings(environment);
const compactInputPresentation =
selectCompactInputSchemaPresentation(environment);
const selectedOutputSchemaProfile = outputSchemaProfile(environment);
const advertisedToolFamilies = selectAdvertisedToolFamilies(environment);
const providerEnvironment = captureProviderEnvironment(
options.providerEnvironment,
environment,
);
const delivery = selectToolResultDelivery(environment, options.delivery);
const evmInterface =
options.evmInterface ?? evmInterfaceModule.create(environment);
const sqliteDatabase =
options.sqliteDatabase ?? createSqliteDatabaseService(environment);
const binaryLayout =
options.binaryLayout ?? createBinaryLayoutService(environment);
const recordedCrash =
options.recordedCrash ?? createRecordedCrashService(environment);
const webSourceLocation =
options.webSourceLocation ?? createWebSourceLocationService(environment);
const webModuleTrace =
options.webModuleTrace ?? createWebModuleTraceService(environment);
const desktopApplication = createDesktopApplicationService();
const goBinary = options.goBinary ?? createGoBinaryService();
const rustBinary = options.rustBinary ?? createRustBinaryService();
const erlangBeam = options.erlangBeam ?? createBeamService();
const modelArtifact = createModelArtifactService();
const gpuCodeObjects = createGpuCodeObjectsService();
const il2cppMetadata =
options.il2cppMetadata ?? createIl2cppMetadataService();
const peResources = createPeResourcesService();
const nativeExports = createNativeExportsService();
const devicetree = createDevicetreeService();
const elfNotes = createElfNotesService();
const appleIps = createAppleIpsService();
const kernelModule = createKernelModuleService();
const peLoadConfig = createPeLoadConfigService();
const peCertificates = createPeCertificatesService();
const peImports = createPeImportsService();
const electronFuses = options.electronFuses ?? createElectronFuseService();
const pythonPyc = options.pythonPyc ?? createPythonPycService();
const webNetworkCapture =
options.webNetworkCapture ??
createWebNetworkCaptureService(environment, analysisSettings.read);
const javascriptRecovery =
options.javascriptRecovery ?? createJavaScriptRecoveryProvider(environment);
const artifactResources = new ArtifactResourceScope();
const reverseEngineering =
createReverseEngineeringService(providerEnvironment);
const firmwareAnalysis = new FirmwareAnalysisService(
options.firmwareAnalysis ?? createFirmwareAnalysisProvider(environment),
);
const selectedOptions = {
...options,
environment,
delivery,
evmInterface,
sqliteDatabase,
binaryLayout,
recordedCrash,
webSourceLocation,
webModuleTrace,
javascriptRecovery,
};
const startedAt = options.startedAt ?? new Date().toISOString();
const logger = options.logger ?? silentLogger;
const server =
options.mcpServer ??
createMcpServer(
session,
delivery,
compactInputPresentation,
selectedOutputSchemaProfile,
advertisedToolFamilies,
);
server.analysisSettings = analysisSettings;
registerAnalysisSettingsTools(server, analysisSettings);
if (options.mcpServer !== undefined) {
server.attachRuntime(
session === undefined
? undefined
: (evidence) => session.recordEvidence(evidence),
delivery,
catalogIdentityForToolFamilies(
compactInputPresentation,
selectedOutputSchemaProfile,
advertisedToolFamilies,
),
);
}
const gdbSessions = new GdbSessionManager({
environment: providerEnvironment,
});
const rizinDebugSessions = new RizinDebugSessionManager(providerEnvironment);
const android =
options.androidAnalysis ??
createAndroidAnalysisProvider(
environment,
undefined,
analysisSettings.read,
);
const pcap = options.pcapAnalysis ?? createPcapAnalysisProvider(environment);
const flutter =
options.flutterAnalysis ?? createFlutterBuildAnalysisProvider();
const fridaInstrumentation =
options.fridaInstrumentation ?? new FridaInstrumentationManager();
const wasmArtifact = wasmArtifactModule.create(
environment,
options.wasmArtifact,
analysisSettings.read,
);
const apkSignature = apkSignatureModule.create(
environment,
options.apkSignature,
);
const packetCapture =
options.packetCapture ?? createPacketCaptureService(environment);
const signalRecording =
options.signalRecording ?? createSignalRecordingService(environment);
const webRuntime = options.webRuntime ?? createWebRuntimeService();
const apktool =
options.apktoolAnalysis ??
createApktoolResourceAnalysisProvider(environment);
const jeb = options.jebAnalysis ?? createJebAnalysisProvider(environment);
const adbDevice =
options.adbDeviceAnalysis ?? createAdbDeviceAnalysisProvider(environment);
const cutter = new CutterBridgeService(
new CutterBridgeClient(providerEnvironment),
);
let providerClose: Promise<void> | undefined;
const closeProviders = (): Promise<void> => {
providerClose ??= Promise.allSettled([
android.close(),
cutter.close(),
fridaInstrumentation.closeAll(),
wasmArtifact.close(),
apkSignature.close(),
packetCapture.close(),
signalRecording.close(),
apktool.close(),
jeb.close(),
adbDevice.close(),
flutter.close(),
pcap.close(),
evmInterface.close(),
sqliteDatabase.close(),
binaryLayout.close(),
recordedCrash.close(),
webSourceLocation.close(),
webModuleTrace.close(),
desktopApplication.close(),
goBinary.close(),
rustBinary.close(),
erlangBeam.close(),
il2cppMetadata.close(),
modelArtifact.close(),
gpuCodeObjects.close(),
peResources.close(),
nativeExports.close(),
devicetree.close(),
elfNotes.close(),
appleIps.close(),
kernelModule.close(),
peLoadConfig.close(),
peCertificates.close(),
peImports.close(),
electronFuses.close(),
pythonPyc.close(),
webNetworkCapture.close(),
javascriptRecovery.close?.() ?? Promise.resolve(),
...(options.optionalObservationProviderOwner === "caller"
? []
: [
options.browserObservation?.close?.() ?? Promise.resolve(),
options.browserScenarioCapture?.close?.() ?? Promise.resolve(),
options.electronObservation?.close?.() ?? Promise.resolve(),
options.electronActiveObservation?.close?.() ?? Promise.resolve(),
options.javascriptRuntimeObservation?.close?.() ??
Promise.resolve(),
]),
webRuntime.provider.close?.() ?? Promise.resolve(),
artifactResources.close(),
reverseEngineering.close(),
firmwareAnalysis.close(),
gdbSessions.closeAll(),
rizinDebugSessions.closeAll(),
])
.then((results) => {
const failures = results.flatMap((result) =>
result.status === "rejected" ? [result.reason] : [],
);
if (failures.length > 0)
throw new AggregateError(failures, "REA provider cleanup failed");
})
.catch((cause: unknown) => {
providerClose = undefined;
throw cause;
});
return providerClose;
};
const availability = installSessionToolAvailability(
session,
options,
environment,
fridaInstrumentation,
);
const toolLogger = logger.child({ layer: "server" });
const {
evidenceById,
activeTarget,
recordEvidence,
recordEvidenceWithUnknown,
} = createSessionRecorders(server, session);
const analysisAdmission = withAdmittedAnalysis(source);
const toolContext: ServerToolContext = {
server,
session,
options: selectedOptions,
environment,
logger: toolLogger,
evidenceById,
activeTarget,
recordEvidence,
recordEvidenceWithUnknown,
withAdmittedAnalysis: analysisAdmission,
artifactResources,
goBinary,
rustBinary,
erlangBeam,
il2cppMetadata,
peResources,
nativeExports,
devicetree,
elfNotes,
appleIps,
kernelModule,
peLoadConfig,
peCertificates,
peImports,
electronFuses,
pythonPyc,
webNetworkCapture,
};
registerDesktopApplicationTool(
server,
desktopApplication,
toolLogger,
recordEvidence,
analysisAdmission,
evidenceById,
);
registerModelArtifactTools(
server,
modelArtifact,
toolLogger,
recordEvidence,
analysisAdmission,
evidenceById,
);
registerGpuCodeObjectsTools(
server,
gpuCodeObjects,
toolLogger,
recordEvidence,
analysisAdmission,
evidenceById,
);
registerBinaryAnalysisTools(toolContext);
registerReverseEngineeringTools(
server,
reverseEngineering,
toolLogger,
delivery,
session === undefined
? undefined
: (evidence) => session.recordEvidence(evidence),
analysisAdmission,
session === undefined
? undefined
: () => session.invalidateSnapshotForExternalMutation(),
session === undefined
? undefined
: (path, signal, operation, rebindFailure) =>
session.withAdmittedExternalMutation(
path,
signal,
operation,
rebindFailure,
),
evidenceById,
);
registerFridaTools(
server,
fridaInstrumentation,
toolLogger,
delivery,
session === undefined
? undefined
: (evidence) => session.recordEvidence(evidence),
evidenceById,
);
registerCutterTools(
server,
cutter,
toolLogger,
delivery,
session === undefined
? undefined
: (evidence) => session.recordEvidence(evidence),
session,
);
registerGdbTools(
server,
gdbSessions,
toolLogger,
delivery,
session === undefined
? undefined
: (evidence) => session.recordEvidence(evidence),
session,
evidenceById,
);
registerRizinDebugTools(
server,
rizinDebugSessions,
toolLogger,
delivery,
session === undefined
? undefined
: (evidence) => session.recordEvidence(evidence),
session,
);
const previousOnclose = server.server.onclose;
server.server.onclose = () => {
previousOnclose?.();
void closeProviders().catch((cause: unknown) => {
logger.error(
{ error: cause instanceof Error ? cause.message : String(cause) },
"Provider cleanup failed during server shutdown",
);
});
};
const closeServer = server.close.bind(server);
server.close = async () => {
const results = await Promise.allSettled([closeServer(), closeProviders()]);
for (const result of results)
if (result.status === "rejected") throw result.reason;
};
registerCaptureTools(
server,
packetCapture,
toolLogger,
recordEvidence,
analysisAdmission,
);
registerSignalTools(
server,
signalRecording,
toolLogger,
recordEvidence,
analysisAdmission,
);
registerConfiguredAnalysisTools(
toolContext,
android,
wasmArtifact,
apkSignature,
evmInterface,
jeb,
firmwareAnalysis,
webRuntime,
);
registerAdbTools(
server,
new AdbDeviceAnalysisService(adbDevice),
toolLogger,
recordEvidence,
analysisAdmission,
);
registerPcapTools(
server,
new PcapAnalysisService(pcap),
toolLogger,
recordEvidence,
analysisAdmission,
evidenceById,
);
registerFlutterTools(
server,
new FlutterBuildAnalysisService(flutter),
toolLogger,
recordEvidence,
analysisAdmission,
evidenceById,
);
registerApktoolTools(
server,
new ApktoolResourceAnalysisService(apktool),
toolLogger,
recordEvidence,
analysisAdmission,
);
registerObservationTools(toolContext);
registerGuidedPrompts(server, analysis, session);
if (session !== undefined) {
registerSessionTools(server, session, toolLogger, {
...selectedOptions,
artifactResources,
...(availability === undefined
? {}
: { availabilityPolicy: availability.policy }),
...(availability?.evmLimiterAvailability === undefined
? {}
: { evmLimiterAvailability: availability.evmLimiterAvailability }),
androidAnalysisAvailability: (signal) =>
android.inspectAvailability(signal),
adbAnalysisAvailability: (signal) =>
adbDevice.inspectAvailability(signal),
apktoolAnalysisAvailability: (signal) =>
apktool.inspectAvailability(signal),
jebAnalysisAvailability: (signal) => jeb.inspectAvailability(signal),
startedAt,
});
}
return server;
};
const selectToolResultDelivery = (
environment: Readonly<NodeJS.ProcessEnv>,
selected: ToolResultDelivery | undefined,
): ToolResultDelivery => {
if (selected !== undefined) return selected;
const configured = parseMcpResponseBudget(
environment.REA_MCP_MAX_RESPONSE_BYTES,
);
if (!configured.ok) throw configured.error;
return createToolResultDelivery(configured.value);
};
const outputSchemaProfile = (
environment: Readonly<NodeJS.ProcessEnv>,
): McpOutputSchemaProfile => {
const configured = parseMcpOutputSchemaProfile(
environment.REA_MCP_OUTPUT_SCHEMA_PROFILE,
);
if (!configured.ok) throw configured.error;
return configured.value ?? "full";
};
const selectCompactInputSchemaPresentation = (
environment: Readonly<NodeJS.ProcessEnv>,
): CompactInputSchemaPresentation | undefined => {
const configured = parseMcpInputSchemaProfile(
environment.REA_MCP_INPUT_SCHEMA_PROFILE,
);
if (!configured.ok) throw configured.error;
return compactPresentationForMcpInputSchemaProfile(configured.value);
};
const registerConfiguredAnalysisTools = (
{
server,
options,
environment,
logger: toolLogger,
evidenceById,
recordEvidence,
withAdmittedAnalysis,
goBinary,
rustBinary,
erlangBeam,
il2cppMetadata,
peResources,
nativeExports,
devicetree,
elfNotes,
appleIps,
kernelModule,
peLoadConfig,
peCertificates,
peImports,
pythonPyc,
webNetworkCapture,
artifactResources,
}: ServerToolContext,
android: AndroidAnalysisPort,
wasmArtifact: Pick<WasmArtifactService, "inspect" | "close">,
apkSignature: Pick<ApkSignatureService, "inspect" | "close">,
evmInterface: EvmInterfaceService,
jeb: JebAnalysisPort,
firmwareAnalysis: FirmwareAnalysisService,
webRuntime: WebRuntimeService,
): void => {
registerAndroidTools(
server,
new AndroidAnalysisService(android, recordEvidence),
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerJebTools(
server,
new JebAnalysisService(jeb),
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerBinaryDiagnosticsTools(
server,
options.binaryLayout ?? createBinaryLayoutService(environment),
createByteEntropyService(artifactResources),
toolLogger,
recordEvidence,
evidenceById,
withAdmittedAnalysis,
);
registerAnalysisViewTool(
server,
toolLogger,
evidenceById,
recordEvidence,
withAdmittedAnalysis,
artifactResources,
);
registerPeResourcesTool(
server,
peResources,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerNativeExportsTool(
server,
nativeExports,
toolLogger,
recordEvidence,
evidenceById,
withAdmittedAnalysis,
);
registerDevicetreeTool(
server,
devicetree,
toolLogger,
recordEvidence,
evidenceById,
withAdmittedAnalysis,
);
registerElfNotesTool(
server,
elfNotes,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerAppleIpsTool(
server,
appleIps,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerKernelModuleTool(
server,
kernelModule,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerPeLoadConfigTool(
server,
peLoadConfig,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerPeCertificatesTool(
server,
peCertificates,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerPeImportsTool(
server,
peImports,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerGoTools(
server,
goBinary,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerIl2cppTools(
server,
il2cppMetadata,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerRustTools(
server,
rustBinary,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerPythonPycTool(
server,
pythonPyc,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerErlangTools(
server,
erlangBeam,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerWasmTools(
server,
wasmArtifact,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerApkSignatureTools(
server,
apkSignature,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerEvmTools(
server,
evmInterface,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerSqliteTools(
server,
options.sqliteDatabase ?? createSqliteDatabaseService(environment),
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerRecordedCrashTools(
server,
options.recordedCrash ?? createRecordedCrashService(environment),
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerFirmwareTools(
server,
firmwareAnalysis,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerWebModuleTool(
server,
options.webModuleTrace ?? createWebModuleTraceService(environment),
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerWebSourceLocationTool(
server,
options.webSourceLocation ?? createWebSourceLocationService(environment),
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerWebRuntimeTools(
server,
webRuntime,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
registerWebNetworkCaptureTool(
server,
webNetworkCapture,
toolLogger,
recordEvidence,
withAdmittedAnalysis,
evidenceById,
);
registerJavaScriptRecoveryTool(
server,
new JavaScriptRecoveryService(
options.javascriptRecovery ??
createJavaScriptRecoveryProvider(environment),
),
toolLogger,
recordEvidence,
withAdmittedAnalysis,
);
};
const createSessionRecorders = (
server: EvidenceMcpServer,
session: BinarySessionPort | undefined,
) => ({
evidenceById:
session === undefined
? undefined
: session.evidenceForAnalysis.bind(session),
activeTarget:
session === undefined ? undefined : () => session.activeTarget(),
recordEvidence:
session === undefined
? undefined
: (evidence: Parameters<typeof session.recordEvidence>[0]) =>
session.recordEvidence(evidence),
recordEvidenceWithUnknown:
session === undefined
? undefined
: (
evidence: Parameters<typeof session.recordEvidenceWithUnknown>[0],
input: Parameters<typeof session.recordEvidenceWithUnknown>[1],
) => session.recordEvidenceWithUnknown(evidence, input),
});
interface ServerToolContext extends ReturnType<typeof createSessionRecorders> {
readonly goBinary: GoBinaryService;
readonly rustBinary: RustBinaryService;
readonly erlangBeam: BeamService;
readonly il2cppMetadata: Il2cppMetadataService;
readonly peResources: PeResourcesService;
readonly nativeExports: NativeExportsService;
readonly devicetree: DevicetreeService;
readonly elfNotes: ElfNotesService;
readonly appleIps: AppleIpsService;
readonly kernelModule: KernelModuleService;
readonly peLoadConfig: PeLoadConfigService;
readonly peCertificates: PeCertificatesService;
readonly peImports: PeImportsService;
readonly electronFuses: ElectronFuseService;
readonly pythonPyc: PythonPycService;
readonly webNetworkCapture: WebNetworkCaptureService;
readonly artifactResources: ArtifactResourceScope;
readonly server: EvidenceMcpServer;
readonly session: BinarySessionPort | undefined;
readonly options: CreateServerOptions;
readonly environment: Readonly<NodeJS.ProcessEnv>;
readonly logger: Logger;
readonly withAdmittedAnalysis: WithAdmittedAnalysis;
}
const registerBinaryAnalysisTools = ({
server,
session,
logger,
activeTarget,
recordEvidence,
recordEvidenceWithUnknown,
evidenceById,
withAdmittedAnalysis,
}: ServerToolContext): void => {
const recordUnknown =
session === undefined
? undefined
: (input: Parameters<typeof session.recordUnknown>[0]) =>
session.recordUnknown(input);
const analysisOptions = {
logger,
activeTarget,
recordEvidence,
recordUnknown,
evidenceById,
withAdmittedAnalysis,
};
registerOfficialTools(server, analysisOptions);
registerEnhancedTools(server, {
...analysisOptions,
analysisProfile:
session === undefined
? undefined
: (operation) =>
session.analysisProfile() ?? session.analysisProfile(operation),
allowsSnapshotReplay:
session === undefined
? undefined
: (operation) => session.allowsSnapshotReplay(operation),
recordWorkflowSnapshot:
session === undefined
? undefined
: (input) => session.recordWorkflowSnapshot(input),
});
const evidenceOptions = {
logger,
activeTarget,
recordEvidence,
withAdmittedAnalysis,
};
registerNativeTools(server, { ...evidenceOptions, evidenceById });
registerArtifactTools(server, { ...evidenceOptions, evidenceById });
registerManagedTools(server, { ...evidenceOptions, evidenceById });
if (session !== undefined)
registerManagedWorkflowTools(server, {
logger,
recordEvidence,
recordEvidenceWithUnknown,
session,
withAdmittedAnalysis,
});
};
const registerObservationTools = ({
electronFuses,
evidenceById,
server,
options,
logger,
recordEvidence,
recordEvidenceWithUnknown,
withAdmittedAnalysis,
artifactResources,
environment,
}: ServerToolContext): void => {
const common = { logger, recordEvidence, withAdmittedAnalysis };
registerWebScriptTool(server, { ...common, artifactResources });
registerBrowserTools(server, {
...common,
evidenceById,
browser: options.browserObservation,
loadFailure: options.optionalProviderLoadFailures?.browserObservation,
});
registerBrowserScenarioTool(server, {
...common,
evidenceById,
provider: options.browserScenarioCapture,
loadFailure: options.optionalProviderLoadFailures?.browserScenarioCapture,
});
registerElectronTools(server, {
...common,
artifactResources,
environment,
evidenceById,
electron: options.electronObservation,
electronActive: options.electronActiveObservation,
electronFuses,
observationLoadFailure:
options.optionalProviderLoadFailures?.electronObservation,
activeLoadFailure:
options.optionalProviderLoadFailures?.electronActiveObservation,
});
registerJavaScriptRuntimeObservationTools(server, {
...common,
runtime: options.javascriptRuntimeObservation,
loadFailure:
options.optionalProviderLoadFailures?.javascriptRuntimeObservation,
});
registerApplicationTools(server, {
artifactResources,
evidenceById,
logger,
recordEvidence,
recordEvidenceWithUnknown,
withAdmittedAnalysis,
});
};
const selectAdvertisedToolFamilies = (
environment: Readonly<NodeJS.ProcessEnv>,
): ReadonlySet<string> | undefined => {
const configured = parseMcpToolFamilies(environment.REA_MCP_TOOL_FAMILIES);
if (!configured.ok) throw configured.error;
return configured.value === undefined ? undefined : new Set(configured.value);
};