Skip to main content
Glama

scaffold_macos_project

Create a new macOS Xcode project with workspace structure, SPM package for features, and proper macOS configuration from templates.

Instructions

Scaffold a new macOS project from templates. Creates a modern Xcode project with workspace structure, SPM package for features, and proper macOS configuration.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
projectNameYesName of the new project
outputPathYesPath where the project should be created
bundleIdentifierNoBundle identifier (e.g., com.example.myapp). If not provided, will use com.example.projectname
displayNameNoApp display name (shown on home screen/dock). If not provided, will use projectName
marketingVersionNoMarketing version (e.g., 1.0, 2.1.3). If not provided, will use 1.0
currentProjectVersionNoBuild number (e.g., 1, 42, 100). If not provided, will use 1
customizeNamesNoWhether to customize project names and identifiers. Default is true.
deploymentTargetNomacOS deployment target (e.g., 15.4, 14.0). If not provided, will use 15.4

Implementation Reference

  • The async handler function registered for 'scaffold_macos_project' that handles parameters, calls the core scaffoldProject function, formats success/error responses, and returns MCP content.
    async (params) => { try { const projectParams: ScaffoldProjectParams = { ...params, platform: 'macOS' }; const projectPath = await scaffoldProject(projectParams); const response = { success: true, projectPath, platform: 'macOS', message: `Successfully scaffolded macOS project "${params.projectName}" at ${projectPath}`, nextSteps: [ `Open the project: open ${projectPath}/${params.customizeNames ? params.projectName : 'MyProject'}.xcworkspace`, `Build for macOS: build_mac_ws --workspace-path "${projectPath}/${params.customizeNames ? params.projectName : 'MyProject'}.xcworkspace" --scheme "${params.customizeNames ? params.projectName : 'MyProject'}"`, `Run and run on macOS: build_run_mac_ws --workspace-path "${projectPath}/${params.customizeNames ? params.projectName : 'MyProject'}.xcworkspace" --scheme "${params.customizeNames ? params.projectName : 'MyProject'}"`, ], }; return { content: [ { type: 'text', text: JSON.stringify(response, null, 2), }, ], }; } catch (error) { log( 'error', `Failed to scaffold macOS project: ${error instanceof Error ? error.message : String(error)}`, ); return { content: [ { type: 'text', text: JSON.stringify( { success: false, error: error instanceof Error ? error.message : 'Unknown error occurred', }, null, 2, ), }, ], }; }
  • macOS-specific Zod schema for scaffold_macos_project parameters, extending the base schema with deploymentTarget.
    const ScaffoldmacOSProjectSchema = BaseScaffoldSchema.extend({ deploymentTarget: z .string() .optional() .describe('macOS deployment target (e.g., 15.4, 14.0). If not provided, will use 15.4'), });
  • Registration of the 'scaffold_macos_project' tool using registerTool, specifying name, description, and schema.
    registerTool<ScaffoldmacOSProjectParams>( server, 'scaffold_macos_project', 'Scaffold a new macOS project from templates. Creates a modern Xcode project with workspace structure, SPM package for features, and proper macOS configuration.', ScaffoldmacOSProjectSchema.shape,
  • Core helper function that performs the actual project scaffolding: validates params, gets template, processes directory recursively, handles cleanup.
    async function scaffoldProject(params: ScaffoldProjectParams): Promise<string> { const { projectName, outputPath, platform, customizeNames = true } = params; log('info', `Scaffolding project: ${projectName} (${platform}) at ${outputPath}`); // Validate project name if (!/^[a-zA-Z][a-zA-Z0-9_]*$/.test(projectName)) { throw new ValidationError( 'Project name must start with a letter and contain only letters, numbers, and underscores', ); } // Get template path from TemplateManager let templatePath: string; try { templatePath = await TemplateManager.getTemplatePath(platform); } catch (error) { throw new ValidationError( `Failed to get template for ${platform}: ${error instanceof Error ? error.message : String(error)}`, ); } // Create output directory const projectPath = join(outputPath, customizeNames ? projectName : 'MyProject'); if (existsSync(projectPath)) { throw new ValidationError(`Project directory already exists at ${projectPath}`); } try { // Process the template await processDirectory(templatePath, projectPath, params); return projectPath; } finally { // Clean up downloaded template if needed await TemplateManager.cleanup(templatePath); } }
  • Helper function to update .xcconfig files with project parameters, bundle ID, versions, deployment targets, orientations, and platform-specific settings.
    function updateXCConfigFile(content: string, params: ScaffoldProjectParams): string { let result = content; // Update project identity settings result = result.replace(/PRODUCT_NAME = .+/g, `PRODUCT_NAME = ${params.projectName}`); result = result.replace( /PRODUCT_DISPLAY_NAME = .+/g, `PRODUCT_DISPLAY_NAME = ${params.displayName || params.projectName}`, ); result = result.replace( /PRODUCT_BUNDLE_IDENTIFIER = .+/g, `PRODUCT_BUNDLE_IDENTIFIER = ${params.bundleIdentifier || `com.example.${params.projectName.toLowerCase().replace(/[^a-z0-9]/g, '')}`}`, ); result = result.replace( /MARKETING_VERSION = .+/g, `MARKETING_VERSION = ${params.marketingVersion || '1.0'}`, ); result = result.replace( /CURRENT_PROJECT_VERSION = .+/g, `CURRENT_PROJECT_VERSION = ${params.currentProjectVersion || '1'}`, ); // Platform-specific updates if (params.platform === 'iOS') { const iosParams = params as ScaffoldiOSProjectParams & { platform: 'iOS' }; // iOS deployment target if (iosParams.deploymentTarget) { result = result.replace( /IPHONEOS_DEPLOYMENT_TARGET = .+/g, `IPHONEOS_DEPLOYMENT_TARGET = ${iosParams.deploymentTarget}`, ); } // Device family if (iosParams.targetedDeviceFamily) { const deviceFamilyValue = deviceFamilyToNumeric(iosParams.targetedDeviceFamily); result = result.replace( /TARGETED_DEVICE_FAMILY = .+/g, `TARGETED_DEVICE_FAMILY = ${deviceFamilyValue}`, ); } // iPhone orientations if (iosParams.supportedOrientations && iosParams.supportedOrientations.length > 0) { // Filter out any empty strings and validate const validOrientations = iosParams.supportedOrientations.filter((o) => o && o.trim() !== ''); if (validOrientations.length > 0) { const orientations = validOrientations.map(orientationToIOSConstant).join(' '); result = result.replace( /INFOPLIST_KEY_UISupportedInterfaceOrientations = .+/g, `INFOPLIST_KEY_UISupportedInterfaceOrientations = ${orientations}`, ); } } // iPad orientations if (iosParams.supportedOrientationsIpad && iosParams.supportedOrientationsIpad.length > 0) { // Filter out any empty strings and validate const validOrientations = iosParams.supportedOrientationsIpad.filter( (o) => o && o.trim() !== '', ); if (validOrientations.length > 0) { const orientations = validOrientations.map(orientationToIOSConstant).join(' '); result = result.replace( /INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = .+/g, `INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = ${orientations}`, ); } } } else if (params.platform === 'macOS') { const macosParams = params as ScaffoldmacOSProjectParams & { platform: 'macOS' }; // macOS deployment target if (macosParams.deploymentTarget) { result = result.replace( /MACOSX_DEPLOYMENT_TARGET = .+/g, `MACOSX_DEPLOYMENT_TARGET = ${macosParams.deploymentTarget}`, ); } // Update entitlements path for macOS result = result.replace( /CODE_SIGN_ENTITLEMENTS = .+/g, `CODE_SIGN_ENTITLEMENTS = ${params.projectName}/${params.projectName}.entitlements`, ); } // Update test bundle identifier and target name result = result.replace(/TEST_TARGET_NAME = .+/g, `TEST_TARGET_NAME = ${params.projectName}`); return result; }

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/SampsonKY/XcodeBuildMCP'

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