A cross-platform MCP server exposing a command library for authorized security testing, CTFs, and education.
PentQuiver exposes 5 read-only tools with clear verb-noun naming (search_commands, list_sources, get_command, get_arguments, resolve_command). All tools have descriptions (10 - 100 chars, within baseline 34 - 392 range). Input schemas are visible and properly typed. However, parameter descriptions are minimal or absent (e.g., 'values' in resolve_command lacks guidance on format/constraints), and output schemas are not documented. Error handling converts exceptions to ValueError but provides minimal recovery guidance. No tool annotations (readOnlyHint, idempotentHint) despite all being read-only. Composition is sound, tools chain logically (search → get → resolve). Overall: functional but lacks LLM-optimization depth.
List the placeholder arguments (name + default) of a command.
Get a single command by its id (e.g. 'nmap/nmap-aggressive-scan').
List the cheat-sheet sources (tools) available.
Fill a command's placeholders with the given values and return the string.
Fuzzy-search the cheat-sheet library. Empty query lists everything.
Output schemas not documented. LLMs cannot infer what fields search_commands, get_command, get_arguments, and resolve_command return. This forces LLMs to guess field names for downstream chaining.
Parameter 'values' in resolve_command lacks description. LLMs cannot determine expected format (flat dict? nested? what value types?). Description should state: 'Dictionary mapping placeholder names to string values. E.g. {"target": "192.168.1.1", "port": "22"}'.
No tool annotations despite all tools being read-only and idempotent. Adding readOnlyHint=true and idempotentHint=true to all tools enables agents to optimize retry logic and caching.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 56 | 2026-07-28+ | v2 |
Error handling converts CommandNotFound to ValueError but provides no recovery guidance. When get_command fails with 'unknown command id: nmap/typo', LLM has no hint to call search_commands. Error should suggest: 'Command not found. Try search_commands(query="nmap") to find available commands.'
Parameter descriptions for 'query' and 'limit' in search_commands are present but minimal. 'query' should clarify: 'Fuzzy search term (e.g. "nmap", "scan"). Empty string lists all commands. Matches against command name, description, and tags.' 'limit' should state range: '1 - 1000, default 25.'