OSINT (Open Source Intelligence) reconnaissance MCP server with tools for BSSID lookup, username tracking, IP scanning, TCP port listening, phishing detection, and image metadata extraction
This OSINT MCP server exhibits pervasive definition quality issues. All 6 tools have minimal, generic descriptions (10-20 chars) that fail to explain WHEN to use them or WHAT they return. Tool names use inconsistent verb_noun patterns ('run_*' prefix is redundant with MCP context). Input schemas ARE visible and mostly complete with types, but lack depth: parameter descriptions are minimal (1-3 words), no enums where applicable (IP address, port ranges), and no output schemas are documented. Error handling is present but generic ('Failed to...', exception strings). The server lacks composition guidance, e.g., how username_tracker results chain to other tools, or why both run_ip_scanner and run_tcp_port_listener exist. Critical security concern: tools accept user-controlled input (IP addresses, URLs, usernames) without validation, sanitization, or rate limiting guidance, increasing injection risk. No permission gates, audit trails, or scope declarations.
Descriptions far too short (10-20 chars, baseline 194 chars avg). 'Run the Wigle BSSID lookup tool.' does not explain WHAT is returned, WHEN to call it instead of alternatives, or how to interpret results. LLMs cannot determine when to select this tool.
Output schemas not documented. No indication what fields wigle_bssid_lookup() returns (SSID, location, city, road, last_seen), forcing LLMs to guess or fail to chain results. Pattern:response-shaper requires documented output structure.
Parameter descriptions missing or minimal (1-3 words). 'bssid', 'username', 'ip_address', 'port', 'host', 'buffer_size', 'url', 'image' lack context on format, valid ranges, examples, and constraints. LLMs cannot infer parameter semantics.
Recommendations
Expand all 6 tool descriptions to 100-200 chars. Include: what it does, when to use it vs alternatives, what it returns, and any prerequisites. Example: 'Lookup Wi-Fi network info by BSSID (MAC address). Returns SSID, GPS location, last seen time, and city. Use after discovering a BSSID to gather geolocation context. Requires Wigle API credentials.'
Document output schemas for all tools. For run_wigle_lookup: return {ssid: string, latitude: float, longitude: float, city: string, road: string, last_updated: ISO8601}. Allows LLMs to chain results and extract specific fields.
Add descriptions to all parameters. Example: 'bssid: MAC address in format XX:XX:XX:XX:XX:XX (48-bit hex)' or 'start_port: Starting port number (1-65535, inclusive). Must be <= end_port.' 100+ chars per param description.
Add constraints and enums. For run_ip_scanner: start_port and end_port both 1-65535, max scan range 1000 ports. For run_tcp_port_listener: port 1-65535, host must be valid IPv4 or hostname, buffer_size 512-65536.
Rename tools to drop 'run_' prefix and use clearer verb_noun. Suggested: lookup_bssid_wigle, track_username_cross_platform, scan_open_ports, listen_tcp_port, detect_phishing_url, extract_image_exif.
Add permission gates and scope declarations. Each tool should list required scopes: run_ip_scanner requires 'read:network:target' (indicates network reconnaissance). run_phishing_detector requires 'read:http'. Include audit trail: log timestamp, caller, tool, params, result.
Implement input validation. run_ip_scanner: validate IP is valid IPv4/IPv6, ports are integers 1-65535, range ≤1000 ports. run_phishing_detector: validate URL is valid http/https. Return clear error: 'Invalid IP address: 999.999.999.999, expected dotted-quad IPv4.'
Redundant 'run_' prefix on all tool names. MCP context already indicates these are callable tools. Names like 'lookup_bssid', 'track_username', 'scan_ports' are clearer and follow verb_noun convention. Current names obscure intent.
No enum constraints. 'start_port' and 'end_port' in run_ip_scanner lack range documentation (1-65535?). 'buffer_size' has no bounds. LLMs may pass invalid values (port 100000, buffer_size 1GB). Pattern:constrained-input requires enum/range.
No permission gates or audit trails. run_ip_scanner and run_tcp_port_listener perform network reconnaissance that may be restricted. No scope declarations (read:network, write:network), no logging of who called what. Violates pattern:scope-declaration and pattern:audit-trail.
No input validation or sanitization. User-controlled inputs (IP address, URL, username, bssid) passed directly to external APIs and network operations without checks for injection, malformed data, or command execution. LLMs can be tricked via prompt injection.
No rate limiting. Agents calling run_ip_scanner in a loop (scanning many IPs or broad port ranges) can overwhelm target systems or incur DoS accusations. No guidance on max ports per scan or max concurrent scans.
run_image_metadata_extractor marked 'under working' in code comment, but exported as a tool. Incomplete tool should not be registered. If incomplete, wrap with a clear error message or remove.
Composition gaps. run_wigle_lookup returns location data but no indication how to pass this to other tools. run_username_tracker returns URLs but no tool to fetch or analyze them. No guidance on multi-tool workflows.
Why both run_ip_scanner and run_tcp_port_listener? Overlap confuses LLM selection. run_ip_scanner scans a range; run_tcp_port_listener listens for inbound. Descriptions don't clarify when each applies. Pattern:tool requires one tool per responsibility.
run_ip_scannerrun_tcp_port_listener
Add rate limiting. run_ip_scanner: max 10 concurrent scans per agent per minute, max 1000 ports per scan. run_wigle_lookup: max 100 requests per minute (API rate limit). Document in description: 'Rate limited to 100 lookups/min. Scans exceeding 1000 ports will be rejected.'
Resolve run_image_metadata_extractor. Either complete and document the output schema (e.g., {filename, created_date, camera_model, gps_location}), or remove it. Do not export incomplete tools.
Clarify run_ip_scanner vs run_tcp_port_listener. Split responsibilities: run_ip_scanner discovers open ports on a target (READ_ONLY, active reconnaissance). run_tcp_port_listener sets up a listening server (READ_WRITE, defensive, requires explicit port binding). Update descriptions to highlight this distinction.
Add error recovery guidance. run_wigle_lookup: 'If BSSID not found, try searching for nearby BSSIDs using run_scan_nearby_networks.' run_username_tracker: 'If no accounts found, consider typos or privacy-restricted profiles.' Guides LLM on next steps.
Document chaining. After run_username_tracker finds accounts, next step is run_phishing_detector on the URLs, or enrichment via other tools. Show the workflow in tool descriptions.