# Task ID: 79 **Title:** Implement Stage Registry and Dynamic Loader **Status:** done **Dependencies:** 71 ✓, 75 ✓, 76 ✓, 77 ✓ **Priority:** high **Description:** Create the stage registry that resolves stage names to handlers, loading from ~/.mcpctl/stages/ for custom stages and falling back to built-ins. **Details:** Create `src/mcplocal/src/proxymodel/stage-registry.ts`: ```typescript import { readdir, stat } from 'fs/promises'; import { join } from 'path'; import type { StageHandler } from './types'; const STAGES_DIR = join(process.env.HOME ?? '', '.mcpctl', 'stages'); const builtInStages: Map = new Map(); const customStages: Map = new Map(); // Register built-ins at module load import passthrough from './stages/passthrough'; import paginate from './stages/paginate'; import sectionSplit from './stages/section-split'; import summarizeTree from './stages/summarize-tree'; builtInStages.set('passthrough', passthrough); builtInStages.set('paginate', paginate); builtInStages.set('section-split', sectionSplit); builtInStages.set('summarize-tree', summarizeTree); export async function loadCustomStages(): Promise { customStages.clear(); try { const files = await readdir(STAGES_DIR); for (const file of files.filter(f => f.endsWith('.ts') || f.endsWith('.js'))) { const name = file.replace(/\.(ts|js)$/, ''); const module = await import(join(STAGES_DIR, file)); customStages.set(name, module.default); } } catch { /* directory doesn't exist */ } } export function getStage(name: string): StageHandler | null { return customStages.get(name) ?? builtInStages.get(name) ?? null; } export function listStages(): { name: string; source: 'built-in' | 'local' }[] { const result: { name: string; source: 'built-in' | 'local' }[] = []; for (const name of builtInStages.keys()) { result.push({ name, source: customStages.has(name) ? 'local' : 'built-in' }); } for (const name of customStages.keys()) { if (!builtInStages.has(name)) result.push({ name, source: 'local' }); } return result; } ``` **Test Strategy:** Unit tests: built-in stages are registered, getStage() returns correct handler, custom stages override built-ins, listStages() shows correct sources, missing stages return null. Integration test with actual stage files in temp directory.