UNPKG

safe-commander-mcp

Version:

A secure MCP server for executing whitelisted development commands with comprehensive security controls and resource limits

243 lines (242 loc) 8.8 kB
"use strict"; /** * Command categorization and description module * SAFETY-FIRST: This module must handle unknown commands gracefully and never crash */ Object.defineProperty(exports, "__esModule", { value: true }); exports.categorizeCommands = categorizeCommands; exports.getCommandDescriptions = getCommandDescriptions; exports.getCommandInfo = getCommandInfo; exports.validateCommandCategories = validateCommandCategories; exports.getCommandSummary = getCommandSummary; /** * SAFETY-FIRST: Command to category mapping * If a command is not in this mapping, it will fallback to 'other' category */ const COMMAND_CATEGORIES = { // Package Management npm: 'packageManagement', yarn: 'packageManagement', pnpm: 'packageManagement', // Version Control git: 'versionControl', gh: 'versionControl', // File Operations ls: 'fileOperations', cat: 'fileOperations', pwd: 'fileOperations', find: 'fileOperations', grep: 'fileOperations', head: 'fileOperations', tail: 'fileOperations', // Runtime node: 'runtime', python: 'runtime', python3: 'runtime', // Frameworks nest: 'frameworks', next: 'frameworks', vue: 'frameworks', nuxt: 'frameworks', // Containerization docker: 'containerization', 'docker-compose': 'containerization', // Networking curl: 'networking', wget: 'networking', // Build Tools make: 'buildTools', cmake: 'buildTools', tsc: 'buildTools', webpack: 'buildTools', // Testing jest: 'testing', mocha: 'testing', vitest: 'testing' }; /** * SAFETY-FIRST: Command descriptions * If a description is not defined, a fallback will be provided */ const COMMAND_DESCRIPTIONS = { // Package Management npm: "Node.js package manager - install dependencies, run scripts, manage packages", yarn: "Fast, reliable package manager - alternative to npm with better performance", pnpm: "Efficient package manager - uses hard links to save disk space", // Version Control git: "Version control system - track changes, manage branches, collaborate on code", gh: "GitHub CLI - interact with GitHub repositories from command line", // File Operations ls: "List directory contents with detailed file information and permissions", cat: "Display file contents in terminal - view text files quickly", pwd: "Print current working directory path - show where you are", find: "Search for files and directories based on various criteria", grep: "Search text patterns within files - powerful text searching tool", head: "Display first lines of files - preview file beginnings", tail: "Display last lines of files - monitor file endings and logs", // Runtime node: "Execute Node.js JavaScript files and scripts - run JS applications", python: "Execute Python scripts and applications - run Python code", python3: "Execute Python 3 scripts and applications - modern Python runtime", // Frameworks nest: "NestJS framework CLI - create and manage NestJS applications", next: "Next.js framework CLI - create and manage React applications", vue: "Vue.js framework CLI - create and manage Vue applications", nuxt: "Nuxt.js framework CLI - create and manage Vue/Nuxt applications", // Containerization docker: "Container platform - build, run, and manage containers", 'docker-compose': "Multi-container Docker applications - orchestrate container services", // Networking curl: "Transfer data to/from servers - make HTTP requests and download files", wget: "Download files from web - retrieve files via HTTP/HTTPS/FTP", // Build Tools make: "Build automation tool - compile and build projects using Makefiles", cmake: "Cross-platform build system - generate build files for various platforms", tsc: "TypeScript compiler - compile TypeScript to JavaScript", webpack: "Module bundler - bundle JavaScript modules for web applications", // Testing jest: "JavaScript testing framework - unit and integration testing", mocha: "JavaScript test framework - flexible testing with various assertion libraries", vitest: "Fast unit testing framework - Vite-powered testing tool" }; /** * CRITICAL: Safely categorize commands with fallback handling * Unknown commands are placed in 'other' category to prevent crashes * * @param commands - Array of command names to categorize * @returns CommandCategory object with commands organized by category */ function categorizeCommands(commands) { const categories = { packageManagement: [], versionControl: [], fileOperations: [], runtime: [], frameworks: [], containerization: [], networking: [], buildTools: [], testing: [], other: [] }; for (const command of commands) { const category = COMMAND_CATEGORIES[command]; if (category && categories[category]) { categories[category].push(command); } else { // SAFETY: Unknown commands go to 'other' - NEVER crash categories.other.push(command); } } return categories; } /** * CRITICAL: Safely get command descriptions with fallback handling * Missing descriptions get a helpful fallback message * * @param commands - Array of command names * @returns Record of command to description mappings */ function getCommandDescriptions(commands) { const descriptions = {}; for (const command of commands) { descriptions[command] = COMMAND_DESCRIPTIONS[command] || `${command} - Command available but description not defined`; } return descriptions; } /** * Get detailed information about a specific command * * @param command - Command name to get info for * @returns CommandInfo object or null if command not recognized */ function getCommandInfo(command) { const category = COMMAND_CATEGORIES[command]; const description = COMMAND_DESCRIPTIONS[command]; if (!category && !description) { return null; } return { command, category: category || 'other', description: description || `${command} - Command available but description not defined`, commonUsage: getCommonUsage(command) }; } /** * CRITICAL: Validate command mappings to help identify missing configurations * This function helps developers find commands that need categorization/descriptions * * @param commands - Array of commands to validate * @returns ValidationResult with known/unknown commands and missing info */ function validateCommandCategories(commands) { const known = []; const unknown = []; const missingDescriptions = []; const missingCategories = []; for (const command of commands) { const hasCategory = command in COMMAND_CATEGORIES; const hasDescription = command in COMMAND_DESCRIPTIONS; if (hasCategory && hasDescription) { known.push(command); } else { unknown.push(command); if (!hasCategory) { missingCategories.push(command); } if (!hasDescription) { missingDescriptions.push(command); } } } return { known, unknown, valid: unknown.length === 0, missingDescriptions, missingCategories }; } /** * Get common usage examples for a command * * @param command - Command name * @returns Array of common usage examples */ function getCommonUsage(command) { const usageExamples = { npm: ["npm install", "npm run build", "npm test", "npm start"], git: ["git status", "git add .", "git commit -m", "git push"], ls: ["ls -la", "ls -l", "ls *.js"], cat: ["cat package.json", "cat README.md"], node: ["node index.js", "node --version"], docker: ["docker ps", "docker build", "docker run"] }; return usageExamples[command] || [`${command} --help`]; } /** * Get a summary of available commands by category * * @param commands - Array of commands to summarize * @returns Object with category counts and totals */ function getCommandSummary(commands) { const categories = categorizeCommands(commands); const categoryCounts = {}; for (const [category, cmds] of Object.entries(categories)) { categoryCounts[category] = cmds.length; } const topCategories = Object.entries(categoryCounts) .map(([category, count]) => ({ category: category, count })) .filter(({ count }) => count > 0) .sort((a, b) => b.count - a.count); return { totalCommands: commands.length, categoryCounts, topCategories }; }