Skip to main content
Glama
ebowwa

Xcode MCP Server

by ebowwa

xcode_create_project

Create a new Xcode project with basic structure by specifying project path, name, bundle identifier, and target platform (iOS/macOS).

Instructions

Create a new Xcode project with basic structure

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
project_pathYesPath where the project should be created
project_nameYesName of the project
bundle_idYesBundle identifier (e.g., com.company.app)
platformNoTarget platform (ios/macos)ios

Implementation Reference

  • Core handler function that implements the Xcode project creation logic using xcodegen or fallback manual structure creation.
    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);
      }
    }
  • Internal command handler that invokes the FileManager's createXcodeProject method for the 'create_project' command, which corresponds to the 'xcode_create_project' tool.
    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;
  • Dynamically generates MCP tool definitions for all loaded commands, creating the 'xcode_create_project' tool name and schema from the 'create_project' command definition.
    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) : []
        }
      }));
    }
  • MCP CallTool request handler that dispatches 'xcode_create_project' calls to CommandExecutor.executeCommand('create_project', args).
      // 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) {
  • Registers the ListTools handler which returns the dynamically generated tools list including 'xcode_create_project'.
    this.server.setRequestHandler(ListToolsRequestSchema, async () => ({
      tools: [...tools, ...webMonitorTools],
    }));

Latest Blog Posts

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/ebowwa/xcode-mcp'

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