import { describe, expect, it } from "vitest"; import { MCP_TOOL_NAME } from "./mcp-tool-names"; import { TOOL_META } from "./tool-meta"; describe("MCP_TOOL_NAME", () => { it("uses canonical unprefixed snake_case tool names", () => { for (const name of Object.values(MCP_TOOL_NAME)) { expect(name).toMatch(/^[a-z]+(?:_[a-z]+)*$/); expect(name.split("_").at(0)).not.toBe("reactive"); } }); it("uses the canonical read and patch names", () => { expect(MCP_TOOL_NAME.getResume).toBe("read_resume"); expect(MCP_TOOL_NAME.patchResume).toBe("apply_resume_patch"); }); it("uses canonical application tool names", () => { expect(MCP_TOOL_NAME.listApplications).toBe("list_applications"); expect(MCP_TOOL_NAME.readApplication).toBe("read_application"); expect(MCP_TOOL_NAME.createApplication).toBe("create_application"); expect(MCP_TOOL_NAME.attachApplicationDocument).toBe("attach_application_document"); expect(MCP_TOOL_NAME.autofillApplicationFromJob).toBe("autofill_application_from_job"); }); it("uses unique values for every tool", () => { const values = Object.values(MCP_TOOL_NAME); expect(new Set(values).size).toBe(values.length); }); }); describe("tool annotations", () => { it("provides annotations for every registered tool", () => { for (const name of Object.values(MCP_TOOL_NAME)) { expect(TOOL_META[name].annotations).toBeDefined(); } }); it("marks list/get tools as readOnly + idempotent + non-destructive", () => { const readOnlyTools = [ MCP_TOOL_NAME.listResumes, MCP_TOOL_NAME.listResumeTags, MCP_TOOL_NAME.getResume, MCP_TOOL_NAME.getResumeAnalysis, MCP_TOOL_NAME.getResumeStatistics, MCP_TOOL_NAME.listApplications, MCP_TOOL_NAME.readApplication, MCP_TOOL_NAME.listApplicationTags, MCP_TOOL_NAME.getApplicationStats, ]; for (const name of readOnlyTools) { const annotations = TOOL_META[name].annotations; expect(annotations.readOnlyHint, name).toBe(true); expect(annotations.destructiveHint, name).toBe(false); expect(annotations.idempotentHint, name).toBe(true); } }); it("marks PDF download URL generation as read-only but non-idempotent", () => { const annotations = TOOL_META[MCP_TOOL_NAME.downloadResumePdf].annotations; expect(annotations.readOnlyHint).toBe(true); expect(annotations.idempotentHint).toBe(false); expect(annotations.destructiveHint).toBe(false); }); it("marks deleteResume as destructive (but still idempotent)", () => { const annotations = TOOL_META[MCP_TOOL_NAME.deleteResume].annotations; expect(annotations.destructiveHint).toBe(true); expect(annotations.idempotentHint).toBe(true); expect(annotations.readOnlyHint).toBe(false); }); it("marks application delete tools as destructive", () => { for (const name of [MCP_TOOL_NAME.deleteApplication, MCP_TOOL_NAME.bulkDeleteApplications]) { const annotations = TOOL_META[name].annotations; expect(annotations.readOnlyHint, name).toBe(false); expect(annotations.destructiveHint, name).toBe(true); } }); it("marks creation/import/duplicate as non-readonly and non-idempotent", () => { for (const name of [ MCP_TOOL_NAME.createResume, MCP_TOOL_NAME.importResume, MCP_TOOL_NAME.duplicateResume, MCP_TOOL_NAME.patchResume, MCP_TOOL_NAME.updateResume, ]) { const annotations = TOOL_META[name].annotations; expect(annotations.readOnlyHint, name).toBe(false); expect(annotations.idempotentHint, name).toBe(false); expect(annotations.destructiveHint, name).toBe(false); } }); it("marks lockResume / unlockResume as idempotent and non-destructive", () => { for (const name of [MCP_TOOL_NAME.lockResume, MCP_TOOL_NAME.unlockResume]) { const annotations = TOOL_META[name].annotations; expect(annotations.idempotentHint, name).toBe(true); expect(annotations.destructiveHint, name).toBe(false); expect(annotations.readOnlyHint, name).toBe(false); } }); it("marks only job-posting autofill as open-world", () => { expect(TOOL_META[MCP_TOOL_NAME.autofillApplicationFromJob].annotations.openWorldHint).toBe(true); }); it("declares no tools as open-world by default", () => { for (const [name, { annotations }] of Object.entries(TOOL_META)) { if (name === MCP_TOOL_NAME.autofillApplicationFromJob) continue; expect(annotations.openWorldHint).toBe(false); } }); });