UNPKG

xc-mcp

Version:

MCP server that wraps Xcode command-line tools for iOS/macOS development workflows

79 lines 3.79 kB
import { McpError, ErrorCode } from '@modelcontextprotocol/sdk/types.js'; /** * Validate App Capabilities Against Project * * Compare Info.plist required permissions with simulator granted permissions * * Full documentation: See src/tools/xcodebuild/validate-capabilities.md * * @param args Tool arguments * @returns Capabilities validation report */ export async function validateCapabilitiesTool(args) { const { projectPath, scheme, udid } = args; if (!projectPath || !scheme) { throw new McpError(ErrorCode.InvalidRequest, 'projectPath and scheme are required'); } try { // Dynamic import to avoid circular dependencies const { buildSettingsCache } = await import('../../state/build-settings-cache.js'); // Get build settings to extract Info.plist capabilities const buildSettings = await buildSettingsCache.getBuildSettings(projectPath, scheme); // Map of Info.plist keys to capability services const capabilityMap = { NSCameraUsageDescription: { service: 'camera', description: 'Camera access' }, NSMicrophoneUsageDescription: { service: 'microphone', description: 'Microphone access' }, NSLocationWhenInUseUsageDescription: { service: 'location', description: 'Location (when in use)', }, NSLocationAlwaysAndWhenInUseUsageDescription: { service: 'location', description: 'Location (always)', }, NSContactsUsageDescription: { service: 'contacts', description: 'Contacts access' }, NSPhotoLibraryUsageDescription: { service: 'photos', description: 'Photo library access' }, NSCalendarsUsageDescription: { service: 'calendar', description: 'Calendar access' }, NSHealthShareUsageDescription: { service: 'health', description: 'Health data access' }, NSRemindersUsageDescription: { service: 'reminders', description: 'Reminders access' }, NSMotionUsageDescription: { service: 'motion', description: 'Motion/fitness access' }, }; // Extract required capabilities from build settings const requiredCapabilities = []; for (const [key, capability] of Object.entries(capabilityMap)) { // eslint-disable-next-line @typescript-eslint/no-explicit-any if (buildSettings[key]) { requiredCapabilities.push({ service: capability.service, description: capability.description, infoPlistKey: key, }); } } const responseData = { success: true, capabilities: { required: requiredCapabilities, count: requiredCapabilities.length, }, guidance: [ `Found ${requiredCapabilities.length} required capabilities in project`, ...(udid ? [ 'To grant permissions on simulator:', ...requiredCapabilities.map(cap => ` simctl-privacy udid: "${udid}" action: "grant" service: "${cap.service}" bundleId: "com.example.App"`), ] : ['Specify udid parameter to see permission grant commands']), ], }; const responseText = JSON.stringify(responseData, null, 2); return { content: [{ type: 'text', text: responseText }], isError: false, }; } catch (error) { throw new McpError(ErrorCode.InternalError, `Failed to validate capabilities: ${error instanceof Error ? error.message : String(error)}`); } } //# sourceMappingURL=validate-capabilities.js.map