Skip to main content
Glama

Peekaboo MCP

by steipete
MCPCommandTests.swiftβ€’7.05 kB
import ArgumentParser import Foundation import PeekabooCore import Testing @testable import peekaboo @Suite("MCP Command Tests") struct MCPCommandTests { // MARK: - Command Structure Tests @Test("MCP command has correct subcommands") func mCPCommandSubcommands() throws { let command = MCPCommand.self #expect(command.configuration.commandName == "mcp") #expect(command.configuration.subcommands.count == 10) let subcommandNames = command.configuration.subcommands.map { $0.configuration.commandName } #expect(subcommandNames.contains("serve")) #expect(subcommandNames.contains("call")) #expect(subcommandNames.contains("list")) #expect(subcommandNames.contains("inspect")) #expect(subcommandNames.contains("add")) #expect(subcommandNames.contains("remove")) #expect(subcommandNames.contains("test")) #expect(subcommandNames.contains("info")) #expect(subcommandNames.contains("enable")) #expect(subcommandNames.contains("disable")) } @Test("MCP serve command default options") func mCPServeDefaults() throws { let serve = try MCPCommand.Serve.parse([]) #expect(serve.transport == "stdio") #expect(serve.port == 8080) } @Test("MCP serve command custom options") func mCPServeCustomOptions() throws { let serve = try MCPCommand.Serve.parse(["--transport", "http", "--port", "9000"]) #expect(serve.transport == "http") #expect(serve.port == 9000) } // MARK: - Help Text Tests @Test("MCP command help text") func mCPCommandHelp() { let helpText = MCPCommand.helpMessage() #expect(helpText.contains("Model Context Protocol server and client operations")) #expect(helpText.contains("serve")) #expect(helpText.contains("call")) #expect(helpText.contains("list")) #expect(helpText.contains("inspect")) } @Test("MCP serve help text") func mCPServeHelp() { let helpText = MCPCommand.Serve.helpMessage() #expect(helpText.contains("Start Peekaboo as an MCP server")) #expect(helpText.contains("claude mcp add peekaboo")) #expect(helpText.contains("npx @modelcontextprotocol/inspector")) #expect(helpText.contains("--transport")) #expect(helpText.contains("--port")) } // MARK: - Argument Parsing Tests @Test("Parse serve command with all transports") func parseServeAllTransports() throws { let transports = ["stdio", "http", "sse"] for transport in transports { let serve = try MCPCommand.Serve.parse(["--transport", transport]) #expect(serve.transport == transport) } } @Test("Parse call command") func parseCallCommand() throws { let call = try MCPCommand.Call.parse(["test-server", "--tool", "echo", "--args", "{\"message\": \"hello\"}"]) #expect(call.server == "test-server") #expect(call.tool == "echo") #expect(call.args == "{\"message\": \"hello\"}") } @Test("Parse inspect command") func parseInspectCommand() throws { // With server argument let inspect1 = try MCPCommand.Inspect.parse(["my-server"]) #expect(inspect1.server == "my-server") // Without server argument let inspect2 = try MCPCommand.Inspect.parse([]) #expect(inspect2.server == nil) } // MARK: - Validation Tests @Test("Invalid port number throws error") func invalidPortNumber() throws { #expect(throws: Error.self) { _ = try MCPCommand.Serve.parse(["--port", "-1"]) } #expect(throws: Error.self) { _ = try MCPCommand.Serve.parse(["--port", "not-a-number"]) } } @Test("Call command requires tool argument") func callCommandRequiresToolArgument() throws { #expect(throws: Error.self) { _ = try MCPCommand.Call.parse(["test-server"]) } } } @Suite("MCP Command Integration Tests", .tags(.integration)) struct MCPCommandIntegrationTests { @Test("Serve command transport type conversion") func serveCommandTransportConversion() async throws { let serve = try MCPCommand.Serve.parse(["--transport", "stdio"]) // This test would need to actually run the serve command // and verify it starts the server with the correct transport // Since we can't easily test the actual server startup in unit tests, // we can at least verify the transport string maps correctly let expectedTransport: PeekabooCore.TransportType = .stdio #expect(serve.transport == expectedTransport.description) } @Test("Call command JSON parsing") func callCommandJSONParsing() throws { let validJSON = """ { "path": "/tmp/test.png", "format": "png", "nested": { "value": 123 } } """ let call = try MCPCommand.Call.parse([ "server", "--tool", "test", "--args", validJSON ]) // Verify the JSON is stored correctly #expect(call.args == validJSON) // In the actual implementation, this JSON would be parsed // We can verify it's valid JSON let data = Data(call.args.utf8) #expect(throws: Never.self) { _ = try JSONSerialization.jsonObject(with: data) } } } @Suite("MCP Command Error Handling Tests") struct MCPCommandErrorHandlingTests { @Test("Unimplemented commands return appropriate exit codes") func unimplementedCommands() async throws { // These commands are marked as not implemented // They should fail with appropriate error messages var call = try MCPCommand.Call.parse(["test", "--tool", "echo"]) await #expect(throws: ExitCode.self) { try await call.run() } let inspect = MCPCommand.Inspect() await #expect(throws: ExitCode.self) { try await inspect.run() } } } // MARK: - Mock Tests for Server Behavior @Suite("MCP Server Behavior Tests") struct MCPServerBehaviorTests { @Test("Server exits cleanly on SIGTERM") func serverSIGTERMHandling() async throws { // This would test that the server handles SIGTERM gracefully // In practice, this requires spawning a subprocess and sending signals // For unit testing, we can at least verify the serve command structure let serve = MCPCommand.Serve() #expect(serve.transport == "stdio") // Default value } @Test("Server validates transport types") func serverTransportValidation() async throws { var serve = MCPCommand.Serve() // Test that invalid transport types are handled serve.transport = "invalid" // When run() is called, it should default to stdio for invalid types // This behavior is implemented in the run() method } }

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