UNPKG

systemprompt-mcp-core

Version:

A specialized Model Context Protocol (MCP) server that integrates with systemprompt.io to provide powerful prompt management capabilities. This server enables seamless creation, management, and versioning of system prompts and agents through MCP. It works

287 lines (286 loc) 12.9 kB
import { handleListTools, handleToolCall } from "../tool-handlers.js"; import { SystemPromptService } from "../../services/systemprompt-service.js"; // Mock the SystemPromptService jest.mock("../../services/systemprompt-service.js"); describe("Tool Handlers", () => { let mockSystemPromptService; beforeEach(() => { // Clear all mocks before each test jest.clearAllMocks(); // Setup mock implementation mockSystemPromptService = { createPrompt: jest.fn(), editPrompt: jest.fn(), createBlock: jest.fn(), editBlock: jest.fn(), }; // Replace the service instance with our mock SystemPromptService.mockImplementation(() => mockSystemPromptService); }); describe("handleListTools", () => { let tools; beforeEach(() => { const result = handleListTools(); tools = result.tools; }); it("should return all available tools with their schemas", () => { expect(tools).toHaveLength(4); expect(tools.map((t) => t.name)).toEqual([ "create_prompt", "edit_prompt", "create_block", "edit_block", ]); // Verify each tool has required properties tools.forEach((tool) => { expect(tool).toHaveProperty("name"); expect(tool).toHaveProperty("description"); expect(tool).toHaveProperty("inputSchema"); expect(tool.inputSchema).toHaveProperty("type", "object"); expect(tool.inputSchema).toHaveProperty("properties"); expect(tool.inputSchema).toHaveProperty("required"); }); }); it("should have valid create_prompt schema", () => { const createPrompt = tools.find((t) => t.name === "create_prompt"); expect(createPrompt?.inputSchema.required).toContain("instruction"); expect(createPrompt?.inputSchema.required).toContain("input"); expect(createPrompt?.inputSchema.required).toContain("output"); expect(createPrompt?.inputSchema.required).toContain("metadata"); const props = createPrompt?.inputSchema.properties; expect(props?.instruction.required).toContain("static"); expect(props?.input.required).toContain("name"); expect(props?.input.required).toContain("description"); expect(props?.input.required).toContain("type"); expect(props?.output.required).toContain("name"); expect(props?.output.required).toContain("description"); expect(props?.output.required).toContain("type"); expect(props?.metadata.required).toContain("title"); expect(props?.metadata.required).toContain("description"); }); it("should have valid edit_prompt schema", () => { const editPrompt = tools.find((t) => t.name === "edit_prompt"); expect(editPrompt?.inputSchema.required).toContain("uuid"); expect(editPrompt?.inputSchema.properties).toHaveProperty("instruction"); expect(editPrompt?.inputSchema.properties).toHaveProperty("input"); expect(editPrompt?.inputSchema.properties).toHaveProperty("output"); expect(editPrompt?.inputSchema.properties).toHaveProperty("metadata"); }); it("should have valid create_block schema", () => { const createBlock = tools.find((t) => t.name === "create_block"); expect(createBlock?.inputSchema.required).toContain("content"); expect(createBlock?.inputSchema.required).toContain("metadata"); expect(createBlock?.inputSchema.properties.prefix.pattern).toBe("^[a-zA-Z_]+$"); expect(createBlock?.inputSchema.properties.metadata.required).toContain("title"); expect(createBlock?.inputSchema.properties.metadata.required).toContain("description"); }); it("should have valid edit_block schema", () => { const editBlock = tools.find((t) => t.name === "edit_block"); expect(editBlock?.inputSchema.required).toContain("uuid"); expect(editBlock?.inputSchema.properties).toHaveProperty("content"); expect(editBlock?.inputSchema.properties).toHaveProperty("prefix"); expect(editBlock?.inputSchema.properties).toHaveProperty("metadata"); expect(editBlock?.inputSchema.properties.prefix.pattern).toBe("^[a-zA-Z_]+$"); }); }); describe("handleToolCall", () => { describe("create_prompt", () => { const validPromptData = { instruction: { static: "Test instruction", state: "Test state", dynamic: "Test dynamic", }, input: { name: "test_input", description: "Test input description", type: ["message"], }, output: { name: "test_output", description: "Test output description", type: ["message"], }, metadata: { title: "Test prompt", description: "Test description", tag: ["test"], }, }; it("should create a prompt successfully", async () => { const mockResult = { id: "test-uuid", ...validPromptData, _link: "test-link", metadata: { ...validPromptData.metadata, created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Created", }, }; mockSystemPromptService.createPrompt.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "create_prompt", arguments: validPromptData, }, }); expect(mockSystemPromptService.createPrompt).toHaveBeenCalledWith(validPromptData); expect(result.content[0].text).toBe(`Created prompt with ID: ${mockResult.id}`); expect(result._meta.prompt).toEqual(mockResult); }); }); describe("edit_prompt", () => { const validEditData = { uuid: "test-uuid", instruction: { static: "Updated instruction", }, metadata: { title: "Updated title", description: "Test description", }, }; it("should edit a prompt successfully", async () => { const mockResult = { id: "test-uuid", instruction: { static: "Updated instruction" }, input: { name: "test_input", description: "Test input description", type: ["message"], }, output: { name: "test_output", description: "Test output description", type: ["message"], }, metadata: { title: "Updated title", description: "Test description", created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Updated", }, _link: "test-link", }; mockSystemPromptService.editPrompt.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "edit_prompt", arguments: validEditData, }, }); expect(mockSystemPromptService.editPrompt).toHaveBeenCalledWith(validEditData.uuid, expect.objectContaining({ instruction: validEditData.instruction, metadata: validEditData.metadata, })); expect(result.content[0].text).toBe(`Updated prompt with ID: ${mockResult.id}`); expect(result._meta.prompt).toEqual(mockResult); }); }); describe("create_block", () => { const validBlockData = { content: "Test block content", prefix: "test_block", metadata: { title: "Test block", description: "Test description", tag: ["test"], }, }; it("should create a block successfully", async () => { const mockResult = { id: "test-uuid", ...validBlockData, _link: "test-link", metadata: { ...validBlockData.metadata, created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Created", }, }; mockSystemPromptService.createBlock.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "create_block", arguments: validBlockData, }, }); expect(mockSystemPromptService.createBlock).toHaveBeenCalledWith(validBlockData); expect(result.content[0].text).toBe(`Created block with ID: ${mockResult.id}`); expect(result._meta.block).toEqual(mockResult); }); }); describe("edit_block", () => { const validEditData = { uuid: "test-uuid", content: "Updated content", metadata: { title: "Updated title", description: "Test description", }, }; it("should edit a block successfully", async () => { const mockResult = { id: "test-uuid", content: "Updated content", metadata: { title: "Updated title", description: "Test description", created: "2024-01-01", updated: "2024-01-01", version: 1, status: "draft", author: "test", log_message: "Updated", }, _link: "test-link", }; mockSystemPromptService.editBlock.mockResolvedValue(mockResult); const result = await handleToolCall({ params: { name: "edit_block", arguments: validEditData, }, }); expect(mockSystemPromptService.editBlock).toHaveBeenCalledWith(validEditData.uuid, expect.objectContaining({ content: validEditData.content, metadata: validEditData.metadata, })); expect(result.content[0].text).toBe(`Updated block with ID: ${mockResult.id}`); expect(result._meta.block).toEqual(mockResult); }); }); describe("error handling", () => { it("should throw error for unknown tool", async () => { await expect(handleToolCall({ params: { name: "unknown_tool", arguments: {}, }, })).rejects.toThrow("Unknown tool"); }); it("should propagate service errors", async () => { mockSystemPromptService.createPrompt.mockRejectedValue(new Error("Service error")); await expect(handleToolCall({ params: { name: "create_prompt", arguments: {}, }, })).rejects.toThrow("Service error"); }); }); }); });