An MCP server for launching and monitoring asynchronous network penetration testing scans using Nmap, with support for multiple scanning profiles and containerized execution.
The server implements 2 tools for asynchronous Nmap scanning with reasonable descriptions and partial schemas. Naming follows verb_noun convention (start_nmap_job, get_nmap_status). Descriptions are detailed (200+ chars each) and explain purpose, parameters, returns, and notes. However, schema quality varies: start_nmap_job has complete input schema with types and descriptions; get_nmap_status lacks a formal schema in the provided code (parameter documented in docstring only). Output schemas are undocumented, responses are inferred from docstring examples. Parameter validation lacks constraint documentation (no enums for profile, no bounds on target format). Error handling is minimal, no recovery guidance, no validation errors returned, no permission checks. The composition is reasonable (two focused, chainable tools), but lacks idempotency guarantees and doesn't address edge cases like invalid job_id or malformed targets. Security concerns: no input sanitization visible for command injection risks (nmap arguments are shell-executed), no audit logging, no rate limiting.
Retrieve the current status or result of a running Nmap scan job. This tool checks whether an asynchronous Nmap scan (started using `start_nmap_job`) has completed. If the scan is still in progress, it reports "running"; if the scan has finished, it returns the result. Parameters: - job_id (str): The unique job identifier returned by `start_nmap_job`. Returns: - dict: - If still running: {"status": "running"} - If completed: {"status": "done", "result": <nmap_scan_output>} Notes: - The scan result contains the full output returned by Nmap. - You can repeatedly call this tool in intervals (e.g., every few seconds) until the status is "done". - Once done, the result can be processed or stored for further analysis.
Start an asynchronous Nmap scan job. This tool launches an Nmap scan in the background using the provided target, profile, and optional extra CLI arguments. It immediately returns a unique job_id that can be used to check the scan status later. Parameters: - request.target (str): The hostname or IP address to scan. (Required) - request.profile (str): The scanning profile name, typically defined in your Nmap profiles resource. (Required) - request.extra_args (Optional[List[str]]): Additional Nmap CLI arguments to append to the scan command. (Optional) Returns: - dict: {"job_id": <unique_id>} The job_id is used to poll the scan status via `get_nmap_status`. Notes: - The scan runs asynchronously in a background executor thread. - This tool does not block or wait for the scan to complete. - Use `get_nmap_status(job_id)` to check when the scan finishes.
get_nmap_status lacks formal input schema, parameter 'job_id' documented only in docstring, no JSON Schema visible in code.
Output schemas undocumented. start_nmap_job and get_nmap_status both return dicts, but structure is inferred from docstrings only. No Pydantic models or JSON Schema for responses visible in code.
Profile parameter accepts any string but valid values defined in nmap_profiles.py are not exposed as enum constraint. LLM cannot discover valid profiles without reading resource or docs.
No input validation or error handling visible. Target string not validated for injection risk; extra_args passed directly to nmap command without sanitization. Nmap execution could be exploited via malicious target or args.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 71 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 45 | - | v1 |
No error responses documented. If job_id not found in JOB_STORE, get_nmap_status returns {"status": "running"}, ambiguous for invalid IDs. LLM cannot distinguish expired job from still-running job.
No idempotency guarantees. Repeated calls to start_nmap_job with same inputs create new jobs with different job_ids. Agents retrying on ambiguous failures will spawn duplicate scans.
No rate limiting, timeout, or resource cleanup visible. Long-running scans could exhaust memory; malicious agents could spawn unbounded jobs.