MCP server for network scanning and reconnaissance using Nmap
NmapTools exhibits fundamental structural deficiencies across naming, parameter documentation, output schemas, and error handling. While all 14 tools have descriptions and visible implementations, most descriptions are minimal (averaging ~60 chars, well below the 194-char baseline for A+ tools). Parameter documentation is sparse: optional parameters lack descriptions entirely (e.g., 'ports' in basic_port_scan is described as 'Optional port range...' but no guidance on format constraints), and critical parameters like 'mode' in stealth_scan lack enum constraints. Output schemas are entirely undocumented, the source code shows subprocess.run() returning stdout/stderr as plain text strings with no structure, pagination, or field documentation. Error handling is absent: tools return raw subprocess output or stderr with no recovery guidance. Input validation is missing: custom_scan accepts arbitrary command options (command injection risk), and stealth_scan has a minimal inline check but no structured error response. Tool naming follows verb_noun convention (basic_port_scan, detect_services) but several names are overly generic ('custom_scan' could be more specific; 'aggressive_scan' vs 'vulnerability_scan' are functionally unclear in distinction). No tools declare permissions, support idempotency, or offer confirmation workflows for destructive operations. The server provides one resource (nmap://welcome) offering a menu, which is helpful for discovery but does not substitute for structured parameter documentation.
Perform a full aggressive scan (OS, services, scripts, traceroute).
Scan open ports on a target. Ports can be provided as range (e.g., "20-80") or list (e.g., "22,80").
Run a custom Nmap command (user-defined options).
Attempt to detect the target's operating system.
Detect services running on the target.
Attempt to identify firewall or packet filtering.
Count number of live hosts in a subnet.
Missing output schemas: All tools return raw text (subprocess stdout/stderr) with no documented structure, field types, or pagination. LLMs cannot reason about results or extract values for downstream tool chaining.
Undocumented parameter constraints: 'ports' in basic_port_scan accepts 'range (e.g. 20-80) or list (e.g. 22,80)' but provides no enum, pattern, or format specification. 'mode' in stealth_scan has inline validation but no schema-level enum constraint. 'script' in run_nse_script is free-form with no documented valid NSE script names or discovery mechanism.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 39 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 37 | - | v1 |
Choose an Nmap feature by number.
Perform ping sweep on a subnet to find live hosts.
Run a specific Nmap Scripting Engine (NSE) script.
Run Nmap scan and save output to a file.
Run a stealth scan: Null (sN), FIN (sF), Xmas (sX).
Perform a traceroute to the target.
Run vulnerability scan scripts on the target.
Missing parameter descriptions: Optional parameter 'ports' in basic_port_scan is named but has no description of its type or expected format in the description field itself. 'options' in custom_scan is described as 'Custom Nmap command options' but does not explain how to format them (space-separated flags? quoted strings?) or what limitations apply.
No error handling or recovery guidance: Tools return raw subprocess errors (e.g., 'Nmap not found') or output with no actionable guidance. 'Invalid mode' in stealth_scan is the only inline validation; other tools provide no feedback on failed commands, invalid targets, or permission issues.
Command injection risk: custom_scan and scan_to_file accept arbitrary command options (custom_scan passes 'options.split()' directly to subprocess; scan_to_file does the same). Malicious or mistyped input could execute unintended nmap flags or shell metacharacters. No input sanitization or allowlist.
Ambiguous tool naming: 'aggressive_scan' (using -A flag) and 'vulnerability_scan' (using --script vuln) both perform multi-faceted scans with overlapping intent. LLMs must reason about the distinction; names do not make it clear when to use each. Similarly, 'custom_scan' is too generic and could subsume many other tools.
No tool annotations or permission declarations: Tools lack readOnlyHint, destructiveHint, or idempotentHint annotations. No declared permissions (e.g., 'network:read', 'file:write'). Agents cannot determine safe retry strategies or permission requirements.
No confirmation workflow for destructive/network-invasive operations: scan_to_file writes to disk; stealth_scan, aggressive_scan, and firewall_detection perform network operations that could trigger alarms or consume resources. No dry-run, preview, or confirmation step offered.
Minimal description lengths: Most tool descriptions average 45 - 60 characters, falling well below the 194-char A+ baseline and the 10 - 1024 char target range. Descriptions like 'Detect services running on the target.' lack context on when to call this vs. other detection tools, what the output contains, or prerequisites.
No pagination or result limiting: Live host count, aggressive scans, and vulnerability scans can return very large result sets (hundreds of hosts, thousands of script findings). No pagination, limit parameter, or documented max result count. Large results waste tokens and degrade LLM reasoning.