81 lines
2.8 KiB
JavaScript
81 lines
2.8 KiB
JavaScript
import { describe, expect, test } from "bun:test";
|
|
import { MCP_TOOLS } from "./mcp-tools";
|
|
|
|
describe("MCP tool catalog", () => {
|
|
test("keeps tool names unique and schemas object-shaped", () => {
|
|
const names = MCP_TOOLS.map((tool) => tool.name);
|
|
|
|
expect(new Set(names).size).toBe(names.length);
|
|
expect(MCP_TOOLS.length).toBeGreaterThan(20);
|
|
for (const tool of MCP_TOOLS) {
|
|
expect(tool.inputSchema.type).toBe("object");
|
|
expect(tool.outputSchema).toEqual({ type: "object" });
|
|
expect(tool.annotations.openWorldHint).toBe(false);
|
|
}
|
|
});
|
|
|
|
test("marks reads and destructive writes consistently", () => {
|
|
const byName = new Map(MCP_TOOLS.map((tool) => [tool.name, tool]));
|
|
|
|
expect(byName.get("get_memo")?.annotations).toMatchObject({
|
|
readOnlyHint: true,
|
|
destructiveHint: false,
|
|
idempotentHint: true,
|
|
});
|
|
expect(byName.get("trash_memos")?.annotations).toMatchObject({
|
|
readOnlyHint: false,
|
|
destructiveHint: true,
|
|
idempotentHint: false,
|
|
});
|
|
expect(byName.get("move_memos")?.annotations).toMatchObject({
|
|
readOnlyHint: false,
|
|
destructiveHint: false,
|
|
idempotentHint: true,
|
|
});
|
|
expect(byName.get("create_diagram_memo")?.annotations).toMatchObject({
|
|
readOnlyHint: false,
|
|
destructiveHint: false,
|
|
idempotentHint: false,
|
|
});
|
|
expect(byName.get("create_diagram_memo")?.inputSchema).toMatchObject({
|
|
required: ["notebookId", "kind", "nodes"],
|
|
properties: {
|
|
kind: { enum: ["mind-map", "flowchart", "architecture"] },
|
|
nodes: {
|
|
minItems: 1,
|
|
maxItems: 200,
|
|
items: { required: ["id", "label"] },
|
|
},
|
|
edges: { maxItems: 400 },
|
|
layout: { properties: { direction: { enum: ["left-to-right", "top-to-bottom"] } } },
|
|
},
|
|
});
|
|
expect(byName.get("create_diagram_memo")?.inputSchema.properties.nodes.items.properties.x).toBeUndefined();
|
|
expect(byName.get("create_diagram_memo")?.inputSchema.properties.nodes.items.properties.width).toBeUndefined();
|
|
expect(byName.get("rename_notebook")?.annotations).toMatchObject({
|
|
readOnlyHint: false,
|
|
destructiveHint: false,
|
|
idempotentHint: true,
|
|
});
|
|
expect(byName.get("rename_notebook")?.inputSchema).toMatchObject({
|
|
required: ["notebookId", "name"],
|
|
properties: {
|
|
name: { type: "string", minLength: 1, maxLength: 80 },
|
|
},
|
|
});
|
|
expect(byName.get("list_note_templates")?.annotations).toMatchObject({
|
|
readOnlyHint: true,
|
|
destructiveHint: false,
|
|
});
|
|
expect(byName.get("delete_note_template")?.annotations).toMatchObject({
|
|
readOnlyHint: false,
|
|
destructiveHint: true,
|
|
});
|
|
expect(byName.get("restore_default_ai_instructions")?.annotations).toMatchObject({
|
|
readOnlyHint: false,
|
|
destructiveHint: false,
|
|
idempotentHint: true,
|
|
});
|
|
});
|
|
});
|