# Task ID: 98 **Title:** Implement Persistent File Cache for Stages **Status:** done **Dependencies:** 73 ✓ **Priority:** high **Description:** Extend CacheProvider with file-based persistence in ~/.mcpctl/cache/proxymodel/ for cross-session caching. **Details:** Create `src/mcplocal/src/proxymodel/file-cache.ts`: ```typescript import { mkdir, readFile, writeFile, readdir, stat, unlink } from 'fs/promises'; import { join } from 'path'; import { createHash } from 'crypto'; import type { CacheProvider } from './types'; const CACHE_DIR = join(process.env.HOME ?? '', '.mcpctl', 'cache', 'proxymodel'); export class FileCacheProvider implements CacheProvider { private memCache = new Map(); private maxSizeBytes: number; constructor(options: { maxSizeBytes?: number } = {}) { this.maxSizeBytes = options.maxSizeBytes ?? 100 * 1024 * 1024; // 100MB default } hash(content: string): string { return createHash('sha256').update(content).digest('hex').slice(0, 16); } private keyToPath(key: string): string { const safeKey = key.replace(/[^a-zA-Z0-9-_]/g, '_'); return join(CACHE_DIR, safeKey); } async get(key: string): Promise { // Check memory first if (this.memCache.has(key)) return this.memCache.get(key)!; // Check file try { const content = await readFile(this.keyToPath(key), 'utf-8'); this.memCache.set(key, content); // Warm memory cache return content; } catch { return null; } } async set(key: string, value: string): Promise { await mkdir(CACHE_DIR, { recursive: true }); this.memCache.set(key, value); await writeFile(this.keyToPath(key), value); await this.enforceMaxSize(); } async getOrCompute(key: string, compute: () => Promise): Promise { const cached = await this.get(key); if (cached !== null) return cached; const value = await compute(); await this.set(key, value); return value; } private async enforceMaxSize(): Promise { // LRU eviction based on file mtime when cache exceeds maxSizeBytes } } ``` **Test Strategy:** Unit tests: file-based persistence survives process restart, memory cache is warmed on file read, LRU eviction works when size exceeded, concurrent access is safe. Integration test with real filesystem.