xcode_set_active_scheme
Set the active scheme in an Xcode project by specifying the project path and scheme name to streamline build automation and development workflows.
Instructions
Set the active scheme for a specific project
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| scheme_name | Yes | Name of the scheme to activate | |
| xcodeproj | Yes | Path to the .xcodeproj file (or .xcworkspace if available) - supports both absolute (/path/to/project.xcodeproj) and relative (MyApp.xcodeproj) paths |
Input Schema (JSON Schema)
{
"properties": {
"scheme_name": {
"description": "Name of the scheme to activate",
"type": "string"
},
"xcodeproj": {
"description": "Path to the .xcodeproj file (or .xcworkspace if available) - supports both absolute (/path/to/project.xcodeproj) and relative (MyApp.xcodeproj) paths",
"type": "string"
}
},
"required": [
"xcodeproj",
"scheme_name"
],
"type": "object"
}
Implementation Reference
- src/tools/ProjectTools.ts:348-424 (handler)Core handler implementation: validates project path, opens project if needed, normalizes scheme name, executes JXA script to find and set the active scheme in Xcode workspace, handles scheme not found errors with fuzzy matching suggestionspublic static async setActiveScheme( projectPath: string, schemeName: string, openProject: OpenProjectCallback ): Promise<McpResult> { const validationError = PathValidator.validateProjectPath(projectPath); if (validationError) return validationError; await openProject(projectPath); // Normalize the scheme name for better matching const normalizedSchemeName = ParameterNormalizer.normalizeSchemeName(schemeName); const script = ` (function() { ${getWorkspaceByPathScript(projectPath)} const schemes = workspace.schemes(); const schemeNames = schemes.map(scheme => scheme.name()); // Try exact match first let targetScheme = schemes.find(scheme => scheme.name() === ${JSON.stringify(normalizedSchemeName)}); // If not found, try original name if (!targetScheme) { targetScheme = schemes.find(scheme => scheme.name() === ${JSON.stringify(schemeName)}); } if (!targetScheme) { throw new Error('Scheme not found. Available: ' + JSON.stringify(schemeNames)); } workspace.activeScheme = targetScheme; return 'Active scheme set to: ' + targetScheme.name(); })() `; try { const result = await JXAExecutor.execute(script); return { content: [{ type: 'text', text: result }] }; } catch (error) { const enhancedError = ErrorHelper.parseCommonErrors(error as Error); if (enhancedError) { return { content: [{ type: 'text', text: enhancedError }] }; } const errorMessage = error instanceof Error ? error.message : String(error); if (errorMessage.includes('not found')) { try { // Extract available schemes from error message if present let availableSchemes: string[] = []; if (errorMessage.includes('Available:')) { const availablePart = errorMessage.split('Available: ')[1]; // Find the JSON array part const jsonMatch = availablePart?.match(/\[.*?\]/); if (jsonMatch) { availableSchemes = JSON.parse(jsonMatch[0]); } } // Try to find a close match with fuzzy matching const bestMatch = ParameterNormalizer.findBestMatch(schemeName, availableSchemes); let guidance = ErrorHelper.getSchemeNotFoundGuidance(schemeName, availableSchemes); if (bestMatch && bestMatch !== schemeName) { guidance += `\n• Did you mean '${bestMatch}'?`; } return { content: [{ type: 'text', text: ErrorHelper.createErrorWithGuidance(`Scheme '${schemeName}' not found`, guidance) }] }; } catch { return { content: [{ type: 'text', text: ErrorHelper.createErrorWithGuidance(`Scheme '${schemeName}' not found`, ErrorHelper.getSchemeNotFoundGuidance(schemeName)) }] }; } } return { content: [{ type: 'text', text: `Failed to set active scheme: ${errorMessage}` }] }; } }
- src/XcodeServer.ts:499-510 (handler)MCP server dispatch handler: parameter validation and delegation to ProjectTools.setActiveSchemecase 'xcode_set_active_scheme': if (!args.xcodeproj) { throw new McpError(ErrorCode.InvalidParams, `Missing required parameter: xcodeproj`); } if (!args.scheme_name) { throw new McpError(ErrorCode.InvalidParams, `Missing required parameter: scheme_name`); } return await ProjectTools.setActiveScheme( args.xcodeproj as string, args.scheme_name as string, this.openProject.bind(this) );
- src/shared/toolDefinitions.ts:95-113 (schema)Tool schema definition: input schema with xcodeproj (optional if preferred) and required scheme_namename: 'xcode_set_active_scheme', description: 'Set the active scheme for a specific project', inputSchema: { type: 'object', properties: { xcodeproj: { type: 'string', description: preferredXcodeproj ? `Absolute path to the .xcodeproj file (or .xcworkspace if available) - defaults to ${preferredXcodeproj}` : 'Absolute path to the .xcodeproj file (or .xcworkspace if available) - e.g., /path/to/project.xcodeproj', }, scheme_name: { type: 'string', description: 'Name of the scheme to activate', }, }, required: preferredXcodeproj ? ['scheme_name'] : ['xcodeproj', 'scheme_name'], }, },
- src/XcodeServer.ts:301-319 (registration)Tool registration: dynamically registers all tools including xcode_set_active_scheme via getToolDefinitions in MCP ListTools handlerthis.server.setRequestHandler(ListToolsRequestSchema, async () => { const toolOptions: { includeClean: boolean; preferredScheme?: string; preferredXcodeproj?: string; } = { includeClean: this.includeClean }; if (this.preferredScheme) toolOptions.preferredScheme = this.preferredScheme; if (this.preferredXcodeproj) toolOptions.preferredXcodeproj = this.preferredXcodeproj; const toolDefinitions = getToolDefinitions(toolOptions); return { tools: toolDefinitions.map(tool => ({ name: tool.name, description: tool.description, inputSchema: tool.inputSchema })), }; });
- src/XcodeServer.ts:180-180 (helper)Helper: lists xcode_set_active_scheme in xcodeTools array for environment validation and tool categorizationconst xcodeTools = [...buildTools, 'xcode_open_project', 'xcode_get_schemes', 'xcode_set_active_scheme',