This server exposes a single tool 'exec' that accepts arbitrary binary commands and executes them via os:cmd(). The implementation is extremely minimal and unsafe. The tool has a one-line description ('Execute a command and return its output') that fails to convey critical safety implications or use cases. The input schema shows a 'Command' parameter of type 'binary' with minimal description ('The command to execute'). There is no output schema documentation, no error handling guidance, no idempotency guarantees, and no security warnings. The tool is inherently destructive and dangerous, it allows arbitrary command execution with no input validation, sanitization, or permission gates. This is a critical security risk in any production environment.
Tool name 'exec' is too generic and does not follow verb_noun convention. Does not clearly convey that this executes arbitrary shell commands with severe security implications.
Tool description is only 34 characters and lacks critical context: does not explain WHEN to use it, what permissions are required, or that it is DESTRUCTIVE and UNSAFE. No mention of command format, return value structure, or error conditions. Below the 50+ character baseline for production tools.
Input parameter 'Command' has minimal description ('The command to execute') that does not document format, constraints, or safety warnings. No enum values, regex patterns, or examples of valid/invalid inputs provided.
No output schema is documented. LLMs cannot know what fields to expect in the response. Is output a string? Object with stdout/stderr? Exit code?
exec
Recommendations
Rename tool from 'exec' to a more specific verb_noun pattern such as 'run_shell_command' or 'execute_system_command' to clarify intent.
Expand description to 150 - 250 characters explaining: (1) what it does (execute shell commands), (2) WHEN to use it (only with trusted input), (3) that it is DESTRUCTIVE and requires explicit user confirmation, (4) what it returns (command output or exit status), (5) prerequisites and limitations.
Add comprehensive parameter description for 'Command' including: allowed format (bash/sh syntax), maximum length, character restrictions (no semicolons, pipes, redirects without explicit approval), and examples of valid vs. invalid commands.
Document output schema explicitly: define fields for stdout (string), stderr (string), exit_code (integer), and execution_time_ms (integer). Specify what empty output means.
Implement input validation and sanitization: reject commands containing dangerous patterns (rm, dd, mkfs, >, |, ;, &, $(), backticks). Maintain a whitelist of allowed command prefixes for safe operations.
Add confirmation step before executing destructive commands: implement a dry_run parameter or require explicit user approval via MRTR (Multi Round-Trip Requests with result 'input_required') for any command that modifies the filesystem or process state.
Implement comprehensive error handling: catch os:cmd() errors, return structured error responses with the command that failed, the exit code, stderr output, and actionable recovery guidance. Map common exit codes to user-friendly messages.
No error handling strategy. Tool uses os:cmd() which swallows exit codes and does not distinguish success from failure. LLM has no way to detect command failures or retry intelligently.
CRITICAL SECURITY: No input validation, sanitization, or command injection prevention. Arbitrary binary input is passed directly to os:cmd(). This enables shell injection attacks and allows agents to execute destructive commands (rm -rf /, kill -9, etc.) without safeguards. Tool is marked DESTRUCTIVE but has zero permission gates or confirmation flows.
No audit trail, logging, or user attribution. Destructive operations are unlogged and non-repudiable. Violates compliance and incident response requirements.
Tool lacks idempotence guarantees. Repeated calls with the same command will execute multiple times, risking duplicate side effects (file deletions, permission changes, data corruption).
No timeout, resource limits, or runaway prevention. A command like 'sleep 999999' or infinite loop will hang the entire MCP server indefinitely.
exec
Add permission gate: before executing any command, verify the calling agent has an 'exec' permission scope. Return 403 Forbidden if insufficient privileges.
Implement audit logging: log all command executions with timestamp, caller identity, command text (sanitized), exit code, and result. Send logs to stderr or OpenTelemetry for compliance traceability.
Add timeout enforcement: set a maximum execution time (e.g., 30 seconds). Return a timeout error if the command exceeds the limit, preventing runaway processes from blocking the server.
Implement rate limiting: allow a maximum number of exec calls per minute per agent to prevent runaway retry loops from overwhelming system resources.
Add tool annotations: mark as destructiveHint=true and readOnlyHint=false to signal to clients that this tool modifies system state and should not be called without explicit user consent.
Consider splitting into safer variants: 'run_read_command' (ls, cat, grep, read-only) vs. 'run_write_command' (requires confirmation). This allows fine-grained permission control.
If this tool is intended only for testing/development, add clear documentation restricting its deployment to non-production environments only. Do not expose in production agents.