Files
rea/tests/boundary/mcp/contractToolHandlerTargetContent.test.ts
T
morluto 92f32981da refactor(mcp): remove the duplicate result delivery class
Construct the canonical ToolResultDelivery through the native continuation policy factory. Move type and lifecycle spy consumers to the core owner while preserving explicit response budgets and the deferred runtime composition.

Validation: runtime build and 335 focused tests passed; 41 Linux-only firmware cases were skipped on macOS. Tests use authored local fixtures, not real external providers.
2026-10-25 02:28:09 +08:00

132 lines
4.8 KiB
TypeScript

import { describe, expect, it, vi } from "vitest";
import type {
CallToolResult,
ServerContext,
} from "@modelcontextprotocol/server";
import { STDIO_DEFAULT_MAX_BUFFER_SIZE } from "@modelcontextprotocol/server";
import { toolContract } from "../../../src/contracts/toolContracts.js";
import { AnalysisCancelledError } from "../../../src/domain/analysisErrorCore.js";
import { createEvidence } from "../../../src/domain/evidence.js";
import type { Evidence } from "../../../src/domain/evidence.js";
import { projectAnalysisError } from "../../../src/domain/analysisErrorProjection.js";
import type { FridaDeviceList } from "../../../src/domain/fridaDiscovery.js";
import { err, ok } from "../../../src/domain/result.js";
import { silentLogger } from "../../../src/logger.js";
import { createEvidenceToolHandler } from "../../../src/server/contractToolHandler.js";
import { EvidenceMcpServer } from "../../../src/server/EvidenceMcpServer.js";
import { createToolResultDelivery } from "../../../src/server/toolResult.js";
import { parseMcpToolError } from "../../fixtures/mcpToolError.js";
const UNTRUSTED_TARGET_CONTENT = {
provenance: { untrusted_content: true, source: "analysis_target" },
};
const context = {
mcpReq: { signal: new AbortController().signal },
} as ServerContext;
/**
* Deliver one retained partial-observation failure through the shared Evidence
* handler. The handler is the producer of the result: `EvidenceMcpServer` only
* adds the marker later for results that bypass `ToolResultDelivery`, so a
* missing marker here also undercounts the wire budget by the marker's bytes.
*/
const deliverPartialFailure = async (): Promise<{
readonly result: CallToolResult;
readonly evidence: Evidence;
}> => {
const evidence = createEvidence(
undefined,
{ id: "fixture", name: "Completed capture fixture", version: "1" },
{
operation: "inspect_packet_capture",
parameters: { path: "recording.pcap" },
result: { packets: [{ "frame.number": ["1"] }] },
confidence: "observed",
},
);
const failure = new AnalysisCancelledError("inspect_packet_capture", {
partialObservation: evidence,
});
const writer = { recordEvidence: () => ok("added" as const) };
const server = new EvidenceMcpServer(
{ name: "partial-error-framing-test", version: "1" },
{ capabilities: {} },
writer.recordEvidence,
createToolResultDelivery(STDIO_DEFAULT_MAX_BUFFER_SIZE),
);
const contract = toolContract("inspect_packet_capture");
const handler = createEvidenceToolHandler(
server,
async () => err(failure),
silentLogger,
writer.recordEvidence,
);
return {
result: await handler(contract)({ path: "recording.pcap" }, context),
evidence,
};
};
describe("shared Evidence handler target-content framing", () => {
it("keeps a non-Evidence partial with a caller-selected evidence_id inline without recording it", async () => {
const partial = {
devices: [],
cleanup_error: null,
evidence_id: "caller-selected",
};
const observation: FridaDeviceList = partial;
const reason = { request: "cancel capture" };
const failure = new AnalysisCancelledError("inspect_packet_capture", {
cause: reason,
partialObservation: observation,
});
const recordEvidence = vi.fn(() => ok("added" as const));
const server = new EvidenceMcpServer(
{ name: "inline-partial-error-test", version: "1" },
{ capabilities: {} },
recordEvidence,
createToolResultDelivery(STDIO_DEFAULT_MAX_BUFFER_SIZE),
);
const contract = toolContract("inspect_packet_capture");
const handler = createEvidenceToolHandler(
server,
async () => err(failure),
silentLogger,
recordEvidence,
);
const result = await handler(contract)({ path: "recording.pcap" }, context);
const projected = parseMcpToolError(result);
expect(projected.error).toMatchObject({
code: "cancelled",
message: projectAnalysisError(failure).message,
details: { operation: "inspect_packet_capture" },
});
expect(projected.error.details?.partial_observation).toEqual(partial);
expect(result.structuredContent).toEqual(projected);
expect(recordEvidence).not.toHaveBeenCalled();
expect(failure.cause).toBe(reason);
expect(failure.partialObservation).toBe(partial);
expect(result._meta).toEqual(UNTRUSTED_TARGET_CONTENT);
});
it("marks a retained partial-observation error as untrusted target content", async () => {
const { result, evidence } = await deliverPartialFailure();
expect(result.isError).toBe(true);
expect(result.structuredContent).toMatchObject({
error: {
details: {
partial_observation: {
kind: "retained-evidence",
evidence_id: evidence.evidence_id,
},
},
},
});
expect(result._meta).toEqual(UNTRUSTED_TARGET_CONTENT);
});
});