xcode_create_project
Generate a new Xcode project with a basic structure by specifying the project path, name, bundle ID, and target platform (iOS/macOS).
Instructions
Create a new Xcode project with basic structure
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| bundle_id | Yes | Bundle identifier (e.g., com.company.app) | |
| platform | No | Target platform (ios/macos) | ios |
| project_name | Yes | Name of the project | |
| project_path | Yes | Path where the project should be created |
Implementation Reference
- src/file-manager.ts:94-131 (handler)Core implementation of Xcode project creation: generates xcodegen config, creates source directories and basic Swift files, runs xcodegen to generate .xcodeproj, with fallback manual structure if xcodegen fails. Automatically detects development team for signing.async createXcodeProject(projectPath: string, projectName: string, bundleId: string, platform: string = 'ios'): Promise<void> { // Create project directory await this.createDirectory(projectPath); // Create source directory for xcodegen (must exist before generation) const sourcesDir = path.join(projectPath, projectName); await this.createDirectory(sourcesDir); // Generate xcodegen config with automatic team detection const xcodegenConfig = await this.generateXcodegenConfig(projectName, bundleId, platform); // Write xcodegen spec const specPath = path.join(projectPath, 'project.yml'); await this.writeFile(specPath, xcodegenConfig); // Check if xcodegen is available try { await execAsync('which xcodegen'); // Create basic Swift files BEFORE running xcodegen await this.createBasicSwiftFiles(sourcesDir, projectName, platform); // Generate project using xcodegen const { stdout, stderr } = await execAsync(`cd "${projectPath}" && xcodegen generate 2>&1`); console.log('xcodegen output:', stdout); if (stderr) console.error('xcodegen stderr:', stderr); // Check if .xcodeproj was created const xcodeprojPath = path.join(projectPath, `${projectName}.xcodeproj`); if (!await this.fileExists(xcodeprojPath)) { throw new Error('xcodegen did not create .xcodeproj file'); } } catch (error) { console.error('xcodegen failed:', error); // Fallback: create basic structure manually await this.createBasicProjectStructure(projectPath, projectName, bundleId, platform); } }
- src/command-executor.ts:181-189 (handler)Switch case handler for internal 'create_project' command that invokes FileManager.createXcodeProject with provided arguments and sets success output message.case 'create_project': await this.fileManager.createXcodeProject( args.project_path, args.project_name, args.bundle_id, args.platform || 'ios' ); output = `Project '${args.project_name}' created successfully at: ${args.project_path}`; break;
- src/index.ts:135-156 (handler)MCP CallToolRequestSchema handler that dispatches 'xcode_*' tools (including xcode_create_project) to CommandExecutor.executeCommand by stripping 'xcode_' prefix, formats result output including errors.// 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, }, ], }; } catch (error) {
- src/command-executor.ts:281-306 (schema)Dynamically generates MCP tool specifications from loaded XcodeCommand definitions, creating name 'xcode_create_project', description, and inputSchema with properties/required from command.parameters for validation.generateMCPToolDefinitions(): 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 ListTools handler that returns all MCP tools including dynamically generated xcode_* tools like xcode_create_project.this.server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: [...tools, ...webMonitorTools], }));