Skip to main content
Glama

Peekaboo MCP

by steipete
mcp-server.test.tsβ€’9.89 kB
import { vi } from "vitest"; import { pino } from "pino"; // Mock all the tool handlers to avoid import.meta issues const mockImageToolHandler = vi.fn(); const mockListToolHandler = vi.fn(); const mockAnalyzeToolHandler = vi.fn(); vi.mock("../../Server/src/tools/image", () => ({ imageToolHandler: mockImageToolHandler, })); vi.mock("../../Server/src/tools/list", () => ({ listToolHandler: mockListToolHandler, })); vi.mock("../../Server/src/tools/analyze", () => ({ analyzeToolHandler: mockAnalyzeToolHandler, })); // Create a mock logger for tests const mockLogger = pino({ level: "silent" }); const mockContext = { logger: mockLogger }; describe("MCP Server Integration", () => { beforeEach(() => { vi.clearAllMocks(); }); describe("Tool Integration Tests", () => { describe("Image Tool", () => { it("should capture screen successfully", async () => { const mockResult = { content: [ { type: "text", text: "Captured 1 image in screen mode.\n\nSaved files:\n1. /tmp/screen_capture.png (Screen Capture)", }, ], saved_files: [ { path: "/tmp/screen_capture.png", item_label: "Screen Capture", mime_type: "image/png", }, ], }; mockImageToolHandler.mockResolvedValue(mockResult); const result = await mockImageToolHandler( { format: "png", path: "/tmp/screen_capture.png", capture_focus: "background", }, mockContext, ); expect(result.content).toHaveLength(1); expect(result.content[0].type).toBe("text"); expect(result.content[0].text).toContain( "Captured 1 image in screen mode", ); expect(result.isError).toBeFalsy(); }); it("should handle permission errors", async () => { const mockResult = { content: [ { type: "text", text: "Image capture failed: Permission denied. Screen recording permission is required.", }, ], isError: true, _meta: { backend_error_code: "PERMISSION_DENIED", }, }; mockImageToolHandler.mockResolvedValue(mockResult); const result = await mockImageToolHandler( { format: "png", capture_focus: "background", }, mockContext, ); expect(result.content[0].text).toContain("Permission"); expect(result.isError).toBe(true); }); }); describe("List Tool", () => { it("should list running applications", async () => { const mockResult = { content: [ { type: "text", text: "Found 3 running applications:\n\n1. Safari (com.apple.Safari) - PID: 1234 [ACTIVE] - Windows: 2\n2. Cursor (com.todesktop.230313mzl4w4u92) - PID: 5678 - Windows: 1\n3. Terminal (com.apple.Terminal) - PID: 9012 - Windows: 1", }, ], application_list: [], }; mockListToolHandler.mockResolvedValue(mockResult); const result = await mockListToolHandler( { item_type: "running_applications", }, mockContext, ); expect(result.content[0].text).toContain( "Found 3 running applications", ); expect(result.content[0].text).toContain("Safari"); expect(result.content[0].text).toContain("Cursor"); expect(result.isError).toBeFalsy(); }); it("should list application windows", async () => { const mockResult = { content: [ { type: "text", text: "Found 2 windows for application: Safari (com.apple.Safari) - PID: 1234\n\nWindows:\n1. Safari - Main Window (ID: 12345, Index: 0)\n2. Safari - Secondary Window (ID: 12346, Index: 1)", }, ], window_list: [], target_application_info: {}, }; mockListToolHandler.mockResolvedValue(mockResult); const result = await mockListToolHandler( { item_type: "application_windows", app: "Safari", }, mockContext, ); expect(result.content[0].text).toContain( "Found 2 windows for application: Safari", ); expect(result.content[0].text).toContain("Safari - Main Window"); expect(result.isError).toBeFalsy(); }); it("should require app parameter for application_windows", async () => { const mockResult = { content: [ { type: "text", text: "For 'application_windows', 'app' identifier is required.", }, ], isError: true, }; mockListToolHandler.mockResolvedValue(mockResult); const result = await mockListToolHandler( { item_type: "application_windows", }, mockContext, ); expect(result.content[0].text).toContain( "For 'application_windows', 'app' identifier is required", ); expect(result.isError).toBe(true); }); }); describe("Analyze Tool", () => { beforeEach(() => { process.env.PEEKABOO_AI_PROVIDERS = "ollama/llava"; }); it("should analyze image successfully", async () => { const mockResult = { content: [ { type: "text", text: "Image Analysis:\n\nThis is a screenshot of Safari browser showing a webpage with various elements including navigation bars, content areas, and user interface components.", }, ], analysis_text: "This is a screenshot of Safari browser showing a webpage with various elements including navigation bars, content areas, and user interface components.", }; mockAnalyzeToolHandler.mockResolvedValue(mockResult); const result = await mockAnalyzeToolHandler( { image_path: "/tmp/test.png", question: "What do you see?", }, mockContext, ); expect(result.content[0].text).toContain( "This is a screenshot of Safari browser", ); expect(result.analysis_text).toBeDefined(); expect(result.isError).toBeFalsy(); }); it("should handle missing AI configuration", async () => { const mockResult = { content: [ { type: "text", text: "AI analysis not configured. Please set PEEKABOO_AI_PROVIDERS environment variable.", }, ], isError: true, }; mockAnalyzeToolHandler.mockResolvedValue(mockResult); const result = await mockAnalyzeToolHandler( { image_path: "/tmp/test.png", question: "What do you see?", }, mockContext, ); expect(result.content[0].text).toContain("AI analysis not configured"); expect(result.isError).toBe(true); }); }); }); describe("Error Handling", () => { it("should handle Swift CLI errors gracefully", async () => { const mockResult = { content: [ { type: "text", text: "Image capture failed: Swift CLI crashed", }, ], isError: true, _meta: { backend_error_code: "SWIFT_CLI_CRASH", }, }; mockImageToolHandler.mockResolvedValue(mockResult); const result = await mockImageToolHandler( { format: "png", capture_focus: "background", }, mockContext, ); expect(result.isError).toBe(true); expect(result.content[0].text).toContain("Image capture failed"); }); it("should handle unexpected errors", async () => { const mockResult = { content: [ { type: "text", text: "Unexpected error: Network connection failed", }, ], isError: true, }; mockListToolHandler.mockResolvedValue(mockResult); const result = await mockListToolHandler( { item_type: "running_applications", }, mockContext, ); expect(result.content[0].text).toContain("Unexpected error"); expect(result.isError).toBe(true); }); }); describe("Cross-tool Integration", () => { it("should work with concurrent tool calls", async () => { const mockListResult = { content: [ { type: "text", text: "Found 3 running applications:\n\n1. Safari\n2. Cursor\n3. Terminal", }, ], application_list: [], }; const mockImageResult = { content: [ { type: "text", text: "Captured 1 image in screen mode.", }, ], saved_files: [], }; mockListToolHandler.mockResolvedValue(mockListResult); mockImageToolHandler.mockResolvedValue(mockImageResult); // Make concurrent requests const [listResult, imageResult] = await Promise.all([ mockListToolHandler({ item_type: "running_applications" }, mockContext), mockImageToolHandler( { format: "png", capture_focus: "background" }, mockContext, ), ]); expect(listResult.content[0].text).toContain( "Found 3 running applications", ); expect(imageResult.content[0].text).toContain( "Captured 1 image in screen mode", ); expect(mockListToolHandler).toHaveBeenCalledTimes(1); expect(mockImageToolHandler).toHaveBeenCalledTimes(1); }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/steipete/Peekaboo'

If you have feedback or need assistance with the MCP directory API, please join our Discord server