An MCP server that allows executing terminal commands with security restrictions
The server defines a single tool 'run_command' with a minimal description and incomplete schema. The tool name lacks a verb prefix (should be 'execute_command' or 'run_shell_command'), the description is only 55 characters (below the 194-char baseline for production tools), and critically, the input schema visible in the code shows only a 'command' parameter with type 'string' and description. The return type is not documented in the tool definition, the LLM cannot infer what fields (stdout, stderr, returncode) to expect. The tool implements basic denylist-based command filtering rather than allowlist, which is a weak security posture. The docstring references output fields in prose ('Returns: A dictionary containing stdout, stderr, and return code') but this is not formalized in the schema for LLM consumption. The second tool 'mcpreadme' (a resource, not a tool) is hardcoded to a specific user's Desktop path, showing poor generalization.
Run a terminal command and return the output
Tool name does not start with action verb. 'run_command' should be 'execute_command', 'execute_shell_command', or 'run_shell_command' to match LLM convention.
Tool description is only 55 characters, below the 194-char baseline. Lacks context on WHEN to use, WHAT edge cases apply, and any security caveats. Missing information: What shell is used? Does the agent have permission to execute arbitrary commands? Are there timeout limits?
Return type schema is not documented in the tool definition. The code shows the tool returns a dict with 'stdout', 'stderr', and 'returncode', but this is not formalized in the MCP schema. LLMs cannot plan downstream operations without knowing the response structure.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 29 | 2026-07-28+ | v2 |
Input parameter 'command' lacks validation constraints and error guidance. No mention of: max length, allowed characters, timeout behavior, shell context (bash vs sh vs zsh). The denylist filtering is weak, a determined attacker can bypass simple string matching (e.g. 'r m -rf' with spaces, or 'sudo /bin/rm').
Error handling is incomplete. The code returns strings ('Error: Command timed out after 30 seconds') and dicts inconsistently. No recovery guidance, if the agent sees a timeout, it does not know whether to retry, shorten the command, or ask the user. Missing error classification (retryable vs fatal).
Irreversible operations (rm, del, format, etc.) are blocked, but the error response does not suggest alternatives or next steps. When the agent receives 'Error: Command "rm" is not allowed', it has no guidance on what to do instead, should it ask the user, skip the operation, or call a different tool?
No permission gating or audit trail. Any caller can execute arbitrary (non-blacklisted) shell commands. No logging of who invoked the tool, what command, when, or what the result was. This is a compliance and security risk.
The 'mcpreadme' resource is hardcoded to a user's Desktop path ('Path.home() / "Desktop" / "ML" / "mcpreadme.md"'). This is non-portable and fails on different machines or users. Not relevant to tool evaluation but shows poor design.