mirror of
https://github.com/morluto/rea.git
synced 2026-11-14 10:43:30 +00:00
* 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
33 lines
1.3 KiB
TypeScript
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),
|
|
);
|
|
});
|