MCP server for malware triage and binary analysis using detect-it-easy, YARA, capa, FLOSS, and UPX tools
TriageMCP is a malware analysis tool suite with 10 well-defined tools for PE binary inspection. However, it has significant definition quality gaps that prevent it from reaching production readiness. All 10 tools are explicitly registered via @mcp.tool() decorator with names, descriptions, and input schemas visible in triage.py. Descriptions range from 20-80 characters, meeting minimum bars but lacking LLM-optimization depth. Input schemas are consistently minimal, every tool accepts only file_path (string) with a description, and most lack constraint documentation (ranges, formats, validation rules). Output schemas are completely undocumented: tools return dicts (hashes, metadata, IAT/EAT, sections, etc.) but no schema definitions are provided, forcing LLMs to infer structure. Error handling is absent, tools will raise unhandled exceptions (FileNotFoundError, ValueError, pefile exceptions) with no recovery guidance or user-fixable hints. Tool naming follows a weak verb_noun pattern (get_*, run_*) which is acceptable but not optimized, names like 'run_detect-it-easy' and 'run_yara-scan' are domain-specific and clear enough. Composition is strong: each tool does one thing, chaining is possible (list_directory → analyze individual files), and operations are read-only with no irreversible side effects. Parameter descriptions exist but are sparse, list_directory mentions '~ for home directory' (good) but tools like get_hashes only say 'Full or relative path to the file to analyze' with no guidance on what happens if the file is not a PE, is corrupted, or does not exist. No parameters are typed as enums or constrained beyond the generic 'string' type, and no defaults are offered for optional parameters (all require file_path). This is a competent domain-specific tool set, but it lacks the polish and defensive detail required for robust agent integration.
List the Export Address Table (EAT) of a PE
List the Import Address Table (IAT) of a PE
Calculate file hashes for a PE
Gets metadata information of the PE, such as timestamps, compilers, original filename or architecture.
Get information about the PE's sections, including their names, sizes, properties and entropy.
If the user asks for analysis of multiple files in a directory, this can be used to list the contents of a directory on the local filesystem.
Runs capa on the binary to get info about its capabilities.
Output schemas completely undocumented. Tools return Python dicts with varying structures (hashes returns {md5, sha256, sha512}, get_IAT returns {dll_name: [{address, name}]}, get_pe_metadata returns 20+ fields) but no formal schema is provided. LLMs cannot plan downstream operations or validate completeness without knowing expected fields.
No error handling or recovery guidance. Tools will raise uncaught exceptions (FileNotFoundError for missing files, pefile.PEFormatError for corrupted binaries, subprocess errors for external tools). No descriptions explain failure modes or what the LLM should do next (e.g., 'Try verifying the file exists with list_directory').
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 35 | - | v1 |
Runs detect it easy to identify the type and characteristics of binary
Runs floss on the binary to get plaintext strings and automatically deobfuscate any obfuscated strings.
Runs a yara scan with all rules in YARA_RULE_PATH on the PE.
Parameter descriptions lack constraint documentation. file_path is described as 'Full or relative path to the file to analyze' with no guidance on: accepted file types (PE binaries only?), size limits, encoding requirements, or what happens if non-PE files are passed. External tool paths (FLOSS_EXE_PATH, CAPA_EXE_PATH, YARA_RULE_PATH) are hardcoded to Windows paths, creating portability issues not documented in parameters.
Tool naming uses hyphens (run_detect-it-easy, run_yara-scan) which are non-standard for Python and MCP conventions. While technically valid, this deviates from verb_noun patterns and may confuse LLM parsing. Should be run_detect_it_easy, run_yara_scan, etc.
Descriptions too brief and missing WHEN-to-use guidance. Examples: 'Calculate file hashes for a PE' (35 chars) does not explain when to prefer get_hashes over other analysis tools, or that it returns three hash types. 'List the Import Address Table (IAT) of a PE' (48 chars) does not explain what an IAT reveals about binary behavior or how it informs triage decisions.
No dependency hints or suggested call sequences. For example, list_directory should document 'Call this first to enumerate files before analyzing with get_hashes, get_pe_metadata, etc.' Tools like run_yara-scan and run_capa-scan lack guidance on prerequisites (e.g., YARA rules must be in YARA_RULE_PATH; capa.exe must be installed and available).