MCP server for installing libraries across multiple programming languages (Python, C, C++, Rust, JavaScript)
install-x exhibits significant quality gaps across all definition dimensions. Tool naming is weak (verb_noun convention not applied, names are single words rather than action_noun pairs). Both tools lack parameter descriptions entirely, the rubric mandates that 100% of A+ tool params have descriptions, and this server has 0%. Output schemas are undocumented (no return type specification visible). Error handling exists but provides minimal recovery guidance. The server attempts to do too much in each tool (is_supported does language auto-detection AND package manager queries; install attempts Python, npm, and Rust installations in sequence), violating single-responsibility principles. Code review notes that install() calls subprocess.run with external command execution (bash script, npm, cargo), creating injection risks without visible input sanitization.
Install a library in the current directory.
Check if a library is supported for installation.
Tool names lack action verbs. 'is_supported' is passive (predicate); should be 'check_library_support' or 'verify_library_support'. 'install' is generic; should be 'install_library' to clarify the object. Single-word tool names force LLMs to read descriptions to understand intent.
The schema shows {"library_name": {"type": "string", "description": "The name of the library to check support for"}} in is_supported, but install() has identical structure with no description visible for library_name. Rubric mandates 100% of A+ params have descriptions. Both tools fail this.
Output schema completely undocumented. install() returns nested dicts with 'success', 'message', 'details' (with per-language sub-results), but no formal return type schema is declared. LLMs cannot plan downstream calls without knowing what fields to expect. is_supported returns boolean implicitly.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 46 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 26 | - | v1 |
Single tool with multiple responsibilities. install() attempts to detect and install Python packages (pip), npm packages, and Rust crates (cargo) in sequence based on auto-detection. This violates single-responsibility: agent cannot control which package manager to use; auto-detection may succeed in unexpected language; cascading installations waste tokens. Should split into install_python_package(), install_npm_package(), install_rust_crate().
Command injection vulnerability. _install_python_package() runs 'bash {INSTALL_DIR}/{package_name}.sh {package_version}' with library_name derived directly from user input. No validation on library_name format; if user passes 'foo; rm -rf /', bash script name is injectable. Similarly, npm install and cargo add accept package_name without visible sanitization against special chars.
Error handling provides no recovery guidance. Error dict returns generic 'success: false' + 'message', but does not categorize errors as retryable, user-fixable, or fatal. When installation fails, LLM has no signal whether to retry, ask user to install manually, or abandon. Example from code: 'Library "X" is not supported' is a user-fixable error but not labeled as such.
is_supported performs expensive network calls (pip search, npm view, cargo search) with 10-second timeouts. These calls are blocking and happen inline for every parameter validation. If LLM calls is_supported with 50 library names in a batch context, server makes 50+ network calls sequentially, risking timeout and poor user experience. No caching, no batch API.
Destructive tool (install) lacks dry-run or confirmation step. install() modifies local environment (creates package.json, Cargo.toml, installs packages) with no way for agent to preview changes or confirm. Rubric pattern:confirmation-request mandates confirmation for irreversible operations; agents make mistakes.