xcode_test_project
Execute tests for an Xcode project by specifying the project path, test scheme, and destination. Ideal for automating iOS/macOS project testing within the Xcode MCP Server environment.
Instructions
Run tests for an Xcode project
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| destination | No | Test destination | |
| project_path | Yes | Path to .xcodeproj file | |
| scheme | Yes | Test scheme name |
Implementation Reference
- src/index.ts:134-155 (handler)MCP CallTool handler for 'xcode_test_project': strips 'xcode_' prefix to get 'test_project', executes via CommandExecutor, formats result as text content// Handle Xcode commands // Remove 'xcode_' prefix if present const commandName = name.startsWith('xcode_') ? name.slice(6) : name; const result = await this.commandExecutor.executeCommand(commandName, args); let responseText = result.output; if (result.error) { responseText += `\n\nWarnings/Errors:\n${result.error}`; } if (!result.success) { responseText = `Command failed: ${result.error}\n\nCommand executed: ${result.command}`; } return { content: [ { type: 'text', text: responseText, }, ], };
- src/command-executor.ts:281-306 (schema)Generates the inputSchema and tool definition for MCP tool 'xcode_test_project' from the 'test_project' command definition in commands.jsongenerateMCPToolDefinitions(): Array<{ name: string; description: string; inputSchema: any; }> { return Object.entries(this.commands).map(([name, command]) => ({ name: `xcode_${name}`, description: command.description, inputSchema: { type: 'object', properties: command.parameters ? Object.fromEntries( Object.entries(command.parameters).map(([paramName, paramDef]) => [ paramName, { type: paramDef.type, description: paramDef.description, ...(paramDef.default !== undefined && { default: paramDef.default }) } ]) ) : {}, required: command.parameters ? Object.entries(command.parameters) .filter(([_, paramDef]) => paramDef.required) .map(([paramName]) => paramName) : [] } })); }
- src/index.ts:87-89 (registration)Registers the list of available tools including dynamically generated xcode_* tools from CommandExecutorthis.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [...tools, ...webMonitorTools], }));
- src/command-executor.ts:124-162 (helper)Core execution logic for 'test_project' command: validates params, builds shell command from template, executes via child_process.execAsyncasync executeCommand(name: string, args: Record<string, any> = {}): Promise<{ success: boolean; output: string; error?: string; command: string; }> { const command = this.getCommand(name); if (!command) { throw new Error(`Command '${name}' not found`); } this.validateParameters(command, args); // Handle internal commands if (command.command.startsWith('internal:')) { return await this.executeInternalCommand(command, args); } // Handle external commands const builtCommand = this.buildCommand(command, args); try { const { stdout, stderr } = await execAsync(builtCommand); return { success: true, output: stdout, error: stderr || undefined, command: builtCommand }; } catch (error) { return { success: false, output: '', error: error instanceof Error ? error.message : String(error), command: builtCommand }; } }
- src/command-executor.ts:45-54 (helper)Loads command definitions including 'test_project' from commands.json (located at ../commands.json)async loadCommands(): Promise<void> { try { const content = await fs.readFile(this.commandsPath, 'utf-8'); const definitions: CommandDefinitions = JSON.parse(content); this.commands = definitions.xcode_commands; } catch (error) { throw new Error(`Failed to load commands from ${this.commandsPath}: ${error}`); } }