Single tool 'execute_command' has a concerning security posture and lacks critical implementation details. The tool name is adequately verb-prefixed but the description, while present, lacks critical safety guidance. Input schema exists and is properly typed, but parameter descriptions are minimal. No output schema is documented. The tool accepts destructive/dangerous commands with no input validation, confirmation, or rate limiting. Error handling is present but generic. This server exemplifies a common anti-pattern: exposing raw command execution without safeguards.
Tools (1)
execute_commanddestructivesource verified48/100
Executes a command based on the prompt content according to the operating system being used. `command` must include a string that is a valid command with arguments for the operating system.
No input validation or command sanitization. LLM can pass arbitrary shell commands (rm -rf /, curl malicious-url, exfiltrate data) with no constraints. Critical security vulnerability.
No confirmation/dry-run step for destructive operations. Tool description does not warn that commands are irreversible. Agents will execute delete/reformat commands without user approval.
Parameter 'command' description is minimal (47 chars). Does not specify: format/constraints, examples of valid vs invalid commands, os-specific syntax differences, timeout behavior, or shell environment. LLM has no guidance on safe command construction.
No output schema documented. Tool returns plain text via exec(). LLMs cannot predict structure (stdout only? stderr merged? exit code?). Stderr is rejected as error, but description does not clarify this behavior.
Recommendations
Add comprehensive parameter description: 'A shell command string valid for this OS (Linux/macOS: bash-compatible, Windows: cmd.exe). Must not contain pipes, redirects, or shell metacharacters (;, &, |, $, `, etc.). Timeout: 30 seconds. Max output: 1MB. Examples: "ls -la /tmp", "whoami", "date". Do NOT pass user-provided text directly; validate/escape first.' This matches baseline param annotation length (~72 chars) while providing actionable constraints.
Implement command allowlist validation: reject commands not in a configured whitelist (e.g., only permit 'ls', 'cat', 'date', 'whoami'; deny 'rm', 'dd', 'curl'). Reject commands containing shell metacharacters (;, |, &, backticks, $(), redirects). Return: 'Command rejected: contains forbidden character ";" or is not whitelisted. Allowed: [list].'
Add explicit confirmation step for destructive operations. Update tool description: 'CAUTION: Executes commands with full system privileges. Destructive commands (rm, dd, mkfs, reformat, etc.) are IRREVERSIBLE. For destructive commands, request user confirmation before execution.' Consider a separate 'confirm_command_execution' tool or parameter.
Document output schema in tool description and code: 'Returns object with fields: { "stdout": string (max 1MB), "stderr": string (merged into stdout on success; separate on error), "exitCode": number (0=success, non-zero=error), "command_echo": string (echoed command for audit), "executionTime_ms": number }'. Return structured JSON, not plain text.
Add timeout parameter with default and range: 'timeout_seconds: number (1-300, default 30). Maximum wall-clock time to wait for command completion. Returns timeout error if exceeded.' Implement via AbortSignal or child_process.execFile with timeout option.
No rate limiting or timeout enforcement visible in code. exec() has default 0ms timeout (unbounded). Runaway agents can spawn unlimited subprocesses, exhausting system resources.
Tool description mentions 'according to the operating system being used' but provides no platform-specific guidance (Windows vs Linux syntax differs). LLM cannot adapt commands reliably.
Error handling returns error messages as plain text in 'text' content block (no structured error type/code). LLM cannot distinguish retryable vs fatal errors. No recovery guidance provided.
Tool uses shell exec() which invokes /bin/sh. Shell metacharacters in LLM-provided input risk command injection (e.g., 'ls; rm -rf /'). No shell escaping visible.
execute_command
Add rate limiting: implement per-minute call limits (e.g., max 10 calls/min per agent) using a simple in-memory counter or token bucket. Return 429 error: 'Rate limit exceeded: max 10 commands/minute. Next retry available in X seconds.'
Replace exec() with execFile() and an explicit shell argument array to avoid shell injection. Example: `execFile('/bin/bash', ['-c', command], {timeout: 30000, maxBuffer: 1e6})` with proper quoting/escaping of command argument.
Structure error responses with type/code and recovery guidance. Instead of throwing raw error strings, return: `{ "type": "CommandError", "code": "TIMEOUT|PERMISSION_DENIED|INVALID_COMMAND", "message": "...", "suggestion": "Retry with a shorter timeout or check file permissions." }`. Let LLM distinguish retryable errors.
Add audit logging: log timestamp, username/caller_id, command (sanitized), exit code, and output length to stderr or a logging sink. Essential for compliance and incident response.
Document OS-specific behavior: 'On Windows, commands run via cmd.exe (cmd /c). On Linux/macOS, via bash (bash -c). Paths use OS separators (/ on Unix, \ on Windows). Environment variables and PATH lookup differ by OS.'
Consider offering safer alternatives: split into read-only tools (list_files, read_file, get_disk_usage) and restricted write tools (create_file, append_file) that validate paths against a sandbox directory. This reduces blast radius of LLM mistakes.