Files
reverse-engineering-anything/src/contracts/toolSchemaMetadata.test.ts
T
morluto fcc0a8c454 perf(mcp): build advertised tool schemas once per contract (#10421)
* perf(mcp): build advertised tool schemas once per contract

The MCP SDK reprojects every registered tool schema on each tools/list.
REA memoized that projection, but per wrapper, and each server built new
wrappers for every contract, so each new server reconverted the whole
catalog: about 280 ms per tools/list for 255 tools with the full input
profile. Each wrapper also registered a new schema in zod's global
registry, so heap grew with every server.

Contracts are immutable module values, so build each advertised input
and output wrapper once per contract. tools/list on later servers drops
to about 26 ms (full profile) or 48 ms (compact).

* test(mcp): load only the contract family under test
2026-11-14 11:47:51 +08:00

33 lines
1.3 KiB
TypeScript

import { expect, it } from "vitest";
import { ELECTRON_TOOL_CONTRACTS } from "./javascript/electronToolContracts.js";
import {
toolInputSchemaWithMetadata,
toolOutputSchemaWithMetadata,
} from "./toolSchemaMetadata.js";
// Each MCP server registers every contract. The SDK reprojects registered
// schemas on every tools/list, so a wrapper rebuilt per server would repeat
// the whole catalog's JSON Schema conversion for each new server.
it("shares one advertised wrapper and projection per contract across registrations", () => {
const contract = ELECTRON_TOOL_CONTRACTS.find(
({ name }) => name === "analyze_javascript_application",
);
if (contract === undefined) throw new Error("Missing contract fixture");
const options = { target: "draft-2020-12" } as const;
const firstInput = toolInputSchemaWithMetadata(contract);
const secondInput = toolInputSchemaWithMetadata(contract);
expect(secondInput).toBe(firstInput);
expect(secondInput["~standard"].jsonSchema.input(options)).toBe(
firstInput["~standard"].jsonSchema.input(options),
);
const firstOutput = toolOutputSchemaWithMetadata(contract);
const secondOutput = toolOutputSchemaWithMetadata(contract);
expect(secondOutput).toBe(firstOutput);
expect(secondOutput["~standard"].jsonSchema.output(options)).toBe(
firstOutput["~standard"].jsonSchema.output(options),
);
});