persistence-enable
Enable file-based persistence for Xcode CLI tool cache data, improving workflow efficiency by retaining build configurations, simulator preferences, and usage patterns across server restarts.
Instructions
🔒 Enable Opt-in Persistent State Management - File-based persistence for cache data across server restarts.
Privacy First: Disabled by default. Only usage patterns, build preferences, and performance metrics are stored. No source code, credentials, or personal information is persisted.
Key Benefits: • 📈 Learns Over Time - Remembers successful build configurations and simulator preferences • 🚀 Faster Workflows - Cached project information and usage patterns persist across restarts • 🤝 Team Sharing - Project-local caching allows teams to benefit from shared optimizations • 💾 CI/CD Friendly - Maintains performance insights across build environments
Storage Location Priority:
User-specified directory (cacheDir parameter)
Environment variable: XC_MCP_CACHE_DIR
XDG cache directory (Linux/macOS standard)
Project-local: .xc-mcp/cache/
User home: ~/.xc-mcp/cache/
System temp (fallback)
The system automatically selects the first writable location and creates proper .gitignore entries to prevent accidental commits.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cacheDir | No | Optional custom directory for cache storage. If not provided, uses intelligent location selection. |
Implementation Reference
- src/tools/persistence/enable.ts:62-129 (handler)The primary handler function that implements the persistence-enable tool logic. It checks if already enabled, calls persistenceManager.enable(), and returns formatted JSON response with status and privacy info.export async function persistenceEnableTool(args: any): Promise<ToolResult> { try { const { cacheDir } = args as PersistenceEnableArgs; if (persistenceManager.isEnabled()) { return { content: [ { type: 'text' as const, text: JSON.stringify( { success: false, message: 'Persistence is already enabled', currentStatus: await persistenceManager.getStatus(), }, null, 2 ), }, ], }; } const result = await persistenceManager.enable(cacheDir); if (result.success) { const status = await persistenceManager.getStatus(true); return { content: [ { type: 'text' as const, text: JSON.stringify( { success: true, message: result.message, cacheDirectory: result.cacheDir, status, privacyNotice: 'Only usage patterns, build preferences, and performance metrics are stored. No source code, credentials, or personal information is persisted.', nextSteps: [ 'State will now persist across server restarts', 'Use "persistence-status" to monitor storage usage', 'Use "persistence-disable" to turn off persistence', ], }, null, 2 ), }, ], }; } else { throw new McpError( ErrorCode.InternalError, `Failed to enable persistence: ${result.message}` ); } } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError( ErrorCode.InternalError, `Failed to enable persistence: ${error instanceof Error ? error.message : String(error)}` ); } }
- src/tools/persistence/enable.ts:5-7 (schema)Type definition for input arguments to the persistenceEnableTool handler.interface PersistenceEnableArgs { cacheDir?: string; }
- src/utils/persistence.ts:31-70 (helper)Core PersistenceManager.enable() method that performs the actual file system operations to enable persistence: selects storage location, creates directories, marker files, gitignore, and version file.async enable( userCacheDir?: string ): Promise<{ success: boolean; cacheDir: string; message?: string }> { try { const selectedDir = await this.determineStorageLocation(userCacheDir); // Ensure directory exists and is writable if (!(await this.ensureDirectoryWritable(selectedDir))) { return { success: false, cacheDir: selectedDir, message: 'Directory is not writable', }; } this.cacheDir = selectedDir; this.enabled = true; // Create directory structure await this.createDirectoryStructure(); // Create .gitignore if needed await this.ensureGitignore(); // Create version file await this.writeVersionFile(); return { success: true, cacheDir: selectedDir, message: 'Persistence enabled successfully', }; } catch (error) { return { success: false, cacheDir: userCacheDir || 'unknown', message: `Failed to enable persistence: ${error instanceof Error ? error.message : String(error)}`, }; } }
- src/tools/persistence/index.ts:64-73 (registration)Routing logic in consolidated 'persistence' tool that dispatches 'enable' operation to persistenceEnableTool.case 'enable': if (!args.cacheDir) { throw new McpError(ErrorCode.InvalidRequest, 'cacheDir is required for enable operation'); } return persistenceEnableTool({ cacheDir: args.cacheDir }); case 'disable': return persistenceDisableTool({ clearData: args.clearData ?? false }); case 'status': return persistenceStatusTool({ includeStorageInfo: args.includeStorageInfo ?? true }); default:
- src/registry/cache.ts:49-75 (registration)MCP server registration of the consolidated 'persistence' tool, which routes 'enable' to the persistence-enable implementation. Note: 'persistence-enable' appears in docs for backwards compatibility but is not separately registered.server.registerTool( 'persistence', { description: getDescription(PERSISTENCE_DOCS, PERSISTENCE_DOCS_MINI), inputSchema: { operation: z.enum(['enable', 'disable', 'status']), cacheDir: z.string().optional(), clearData: z.boolean().default(false), includeStorageInfo: z.boolean().default(true), }, ...DEFER_LOADING_CONFIG, }, async args => { try { await validateXcodeInstallation(); // eslint-disable-next-line @typescript-eslint/no-explicit-any return (await persistenceTool(args)) as any; } catch (error) { if (error instanceof McpError) throw error; throw new McpError( ErrorCode.InternalError, `Tool execution failed: ${error instanceof Error ? error.message : String(error)}` ); } } ); }