Hack The Box CLI with MCP server support for accessing the Hack The Box platform via tools
HTB-CLI has 10 tools with complete input schemas and descriptions. Naming follows verb_noun convention (get_, list_, search_, submit_). Descriptions are present (avg ~120 chars) but lack actionable context for LLM selection, they state WHAT but not WHEN or WHY. Parameters are typed and described, but lack enums for constrained values (e.g., 'os', 'difficulty', 'category' accept free-form strings instead of enums). Output schemas are not documented, LLMs cannot predict response structure. Error handling returns generic strings without recovery guidance. No tool annotations (readOnlyHint/destructiveHint) despite clear risk distinctions (READ_ONLY vs WRITE). Composition is sound, each tool has one responsibility and output IDs chain to downstream tools.
Show the currently active/spawned machine, if any.
Get detailed information about a specific challenge by slug name.
Get detailed information about a specific machine by name or ID.
Get the current authenticated user's profile info including rank, owns, and points.
List challenges on Hack The Box. Optionally filter by category. Returns name, difficulty, category, solves, and own status.
List machines on Hack The Box. Optionally filter by OS and difficulty. Returns name, OS, difficulty, rating, state, and own status.
No output schemas documented. LLMs cannot predict response structure or plan downstream tool calls. list_machines returns JSON with 'machines', 'page', 'total_pages', 'total' but this is invisible to the agent.
Constrained parameters use free-form strings instead of enums. 'os' accepts any string (should be enum: linux|windows|freebsd|etc), 'difficulty' accepts any string (should be enum: easy|medium|hard|insane), 'category' accepts any string. LLMs hallucinate invalid values.
No tool annotations despite clear risk distinctions. 'submit_challenge_flag' and 'start_challenge' are WRITE operations (destructive/state-changing) but lack destructiveHint annotation. 'get_*' and 'list_*' tools lack readOnlyHint. Agents cannot distinguish safe from risky operations.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 54 | <=2025-11-25 | v2 |
List all seasons and show which is currently active.
Search across machines, challenges, and users on Hack The Box.
Start a challenge container instance. Returns the instance ID.
Submit a flag for a challenge. Returns whether the flag was correct.
Error handling returns generic strings (e.g., '.map_err(|e| e.to_string())'). No recovery guidance. If 'submit_challenge_flag' fails, the LLM gets a raw error with no hint about what to try next. Should return structured errors with actionable recovery steps.
Descriptions lack LLM-optimized context. 'search' description is only 'Search across machines, challenges, and users on Hack The Box.', does not explain WHEN to use it vs list_machines/list_challenges, what fields are returned, or how results are ranked. Descriptions should be 50-200 chars with WHAT/WHEN/WHY.