Skip to main content
Glama

vulcan-file-ops

command-validation.ts3.43 kB
import os from "os"; /** * Dangerous command patterns that should trigger approval */ const DANGEROUS_PATTERNS = [ // Destructive operations /\brm\b.*-rf?\b/i, /\bdel\b.*\/s\b/i, /\bformat\b/i, /\bmkfs\b/i, // System modifications /\bsudo\b/i, /\bsu\b/i, /\bchmod\b.*777/i, // Package operations /\b(apt|yum|dnf|brew)\s+(install|remove|purge)/i, /\bnpm\s+(install|uninstall)\s+-g/i, /\bpip\s+install/i, // Network operations /\bcurl\b.*\|\s*(bash|sh)/i, /\bwget\b.*\|\s*(bash|sh)/i, // Process operations /\bkill\s+-9/i, /\bkillall/i, ]; /** * Command substitution patterns (security risk) */ const COMMAND_SUBSTITUTION_PATTERNS = [ /\$\([^)]*\)/, // $(command) /`[^`]*`/, // `command` /<\([^)]*\)/, // <(command) />\([^)]*\)/, // >(command) ]; /** * Extract root command from shell command string * Examples: * "ls -la" -> "ls" * "npm install && npm start" -> ["npm", "npm"] * "sudo apt install" -> ["sudo", "apt"] */ export function extractRootCommands(command: string): string[] { const roots: string[] = []; // Split by common shell operators const segments = command .split(/[;&|]/) .map((s) => s.trim()) .filter(Boolean); for (const segment of segments) { // Remove leading/trailing whitespace and extract first word const firstWord = segment.trim().split(/\s+/)[0]; if (firstWord && !roots.includes(firstWord)) { roots.push(firstWord); } } return roots; } /** * Check if command contains dangerous patterns */ export function isDangerousCommand(command: string): boolean { return DANGEROUS_PATTERNS.some((pattern) => pattern.test(command)); } /** * Check if command contains command substitution */ export function hasCommandSubstitution(command: string): boolean { return COMMAND_SUBSTITUTION_PATTERNS.some((pattern) => pattern.test(command)); } /** * Validate command against security policies */ export function validateCommand( command: string, allowCommandSubstitution: boolean = false ): { allowed: boolean; reason?: string } { if (!command || !command.trim()) { return { allowed: false, reason: "Command cannot be empty" }; } // Check for command substitution if (!allowCommandSubstitution && hasCommandSubstitution(command)) { return { allowed: false, reason: "Command substitution using $(), ``, <(), or >() is not allowed for security reasons", }; } // Extract root commands for approval checking const roots = extractRootCommands(command); if (roots.length === 0) { return { allowed: false, reason: "Could not identify command root for security validation", }; } return { allowed: true }; } /** * Check if command is in approved list */ export function isCommandApproved( command: string, approvedCommands: Set<string> ): boolean { const roots = extractRootCommands(command); return roots.every((root) => approvedCommands.has(root)); } /** * Get platform-specific shell configuration */ export function getShellConfig(): { shell: string; args: string[]; platform: string; } { const platform = os.platform(); if (platform === "win32") { return { shell: "powershell.exe", args: ["-NoProfile", "-NonInteractive", "-Command"], platform: "Windows", }; } else { return { shell: "bash", args: ["-c"], platform: "Unix/Mac", }; } }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/n0zer0d4y/vulcan-file-ops'

If you have feedback or need assistance with the MCP directory API, please join our Discord server