UNPKG

knip-mcp-server

Version:

MCP server for knip.dev integration to help AI agents identify and clean up unused code

150 lines 6.59 kB
import { KnipFixIssuesInputSchema } from '../types/index.js'; export function createKnipFixIssuesTool(knipClient, config) { return { name: 'knip_fix_issues', description: 'Automatically fix common knip issues like unused imports and files', inputSchema: { type: 'object', properties: { projectPath: { type: 'string', description: 'Path to the project to fix (defaults to current directory)', }, issueTypes: { type: 'array', items: { type: 'string', enum: ['files', 'imports', 'exports', 'dependencies'], }, default: ['imports'], description: 'Types of issues to fix automatically', }, dryRun: { type: 'boolean', default: true, description: 'Run in dry-run mode (no files are modified)', }, createBackup: { type: 'boolean', default: true, description: 'Create backups before making changes', }, interactive: { type: 'boolean', default: false, description: 'Ask for confirmation before each fix (not supported in MCP)', }, maxFiles: { type: 'number', default: 25, description: 'Maximum number of files to process in one operation', }, }, }, execute: async (args) => { try { const input = KnipFixIssuesInputSchema.parse(args); const results = { success: true, dryRun: input.dryRun, fixed: { files: [], imports: [], exports: [], dependencies: [], }, errors: [], }; // Get analysis results const analysis = await knipClient.scan(); // Fix unused imports if (input.issueTypes?.includes('imports')) { const unusedImports = analysis.imports || {}; const filesToProcess = Object.keys(unusedImports).slice(0, input.maxFiles || 25); for (const filePath of filesToProcess) { try { const result = await knipClient.removeUnusedImports(filePath, { dryRun: input.dryRun, createBackup: input.createBackup, }); if (result.success) { results.fixed.imports.push({ filePath, removedImports: result.removed_imports, backedUp: result.backed_up, }); } else { results.errors.push({ type: 'import', filePath, error: result.error, }); } } catch (error) { results.errors.push({ type: 'import', filePath, error: error instanceof Error ? error.message : String(error), }); } } } // Fix unused files if (input.issueTypes?.includes('files') && config.enableSafeMode !== false) { const unusedFiles = (analysis.files || []).slice(0, input.maxFiles || 25); try { const result = await knipClient.removeUnusedFiles(unusedFiles, { dryRun: input.dryRun, createBackup: input.createBackup, }); results.fixed.files = result.removed; if (result.errors.length > 0) { results.errors.push(...result.errors.map((e) => ({ type: 'file', filePath: e.file, error: e.error, }))); } } catch (error) { results.errors.push({ type: 'file', error: error instanceof Error ? error.message : String(error), }); } } // Note: exports and dependencies fixes would require more sophisticated tooling if (input.issueTypes?.includes('exports')) { results.fixed.exports = []; results.errors.push({ type: 'export', error: 'Automatic export removal not yet implemented - requires AST analysis', }); } if (input.issueTypes?.includes('dependencies')) { results.fixed.dependencies = []; results.errors.push({ type: 'dependency', error: 'Automatic dependency removal not yet implemented - requires package.json modification', }); } // Calculate summary results.summary = { totalFixed: Object.values(results.fixed).reduce((sum, items) => sum + items.length, 0), totalErrors: results.errors.length, issueTypes: input.issueTypes, }; return results; } catch (error) { return { success: false, error: error instanceof Error ? error.message : String(error), }; } }, }; } //# sourceMappingURL=knip-fix-issues.js.map