import { expect, it } from "bun:test"; import type { Tool } from "@modelcontextprotocol/client"; import { nativeQueryTimeout, queryTimeouts } from "../../src/mcp/query-timeouts.js"; const simulation: Tool = { name: "run_simulation", inputSchema: { type: "object", properties: { timeout_seconds: { type: "integer", minimum: 1, maximum: 3600, default: 120 }, } } }; it("budgets calculations independently from their simulated duration and from ordinary reads", () => { expect(queryTimeouts(simulation, { duration: 86400, timeout_seconds: 900 })).toEqual({ executionMs: 900_000, callMs: 905_000, requestMs: 960_000 }); expect(queryTimeouts(simulation, {})).toEqual({ executionMs: 120_000, callMs: 125_000, requestMs: 180_000 }); expect(queryTimeouts({ name: "list_elements", inputSchema: { type: "object" } }, {})).toEqual({ executionMs: 30_000, callMs: 30_000, requestMs: 35_000 }); }); it("honors the effective advertised maximum and rejects invalid per-call budgets", () => { for (const timeout_seconds of [0, -1, 1.5, 3601, "900", null, true, NaN, Infinity]) { expect(() => queryTimeouts(simulation, { timeout_seconds })).toThrow(); } const limited = { ...simulation, inputSchema: { type: "object" as const, properties: { timeout_seconds: { type: "integer", maximum: 120, default: 120 }, } } }; expect(queryTimeouts(limited, { timeout_seconds: 120 }).executionMs).toBe(120_000); expect(() => queryTimeouts(limited, { timeout_seconds: 121 })).toThrow(); expect(nativeQueryTimeout([simulation, limited])).toBe(3_665_000); expect(nativeQueryTimeout([limited])).toBe(185_000); });