A security-focused web crawler MCP server that fetches URLs from websites using headless Chrome and analyzes them for security vulnerabilities.
Three tools with basic descriptions but significant structural gaps. echo_hello is trivial (no real parameters). fetch_urls and analyze_security have descriptions but lack output schema documentation, parameter validation constraints, and error recovery guidance. No tool declares what it returns or how to handle failures. Parameters lack enums, ranges, or format constraints. No mention of timeouts, retries, or rate limits despite calling external services (headless Chrome, web crawling). Descriptions are adequate length (100-150 chars) but lack actionable error guidance and dependency hints. No tool annotations (readOnlyHint, idempotentHint). Code shows exception handling but responses are generic ('An error occurred...') without recovery paths.
Analyze a website for security vulnerabilities. Args: url: The starting URL to analyze max_urls: Maximum number of URLs to analyze (default: 5) Returns: Detailed security analysis report
Echo 'hello' in the shell. Returns: A greeting message from the MCP server.
Fetch URLs from a website using headless Chrome. Args: url: The starting URL to crawl max_urls: Maximum number of URLs to crawl (default: 10) Returns: JSON string with all discovered URLs
No output schema documented for fetch_urls or analyze_security. LLMs cannot infer what fields to expect (e.g., does fetch_urls return {urls: [], count: int} or {success: bool, all_urls: []}?). Code shows format_security_report() but return type is opaque.
Parameters lack constraints. max_urls accepts any integer with no bounds (min/max). No enum for security analysis types. No regex or length limits. LLMs will pass absurd values (max_urls=999999) that break crawlers or timeout.
Error responses are generic ('An error occurred while fetching URLs: {str(e)}'). No recovery guidance. LLM cannot distinguish retryable (timeout) from fatal (invalid URL) errors. No suggestion of alternative tools or next steps.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | F | 45 | <=2025-11-25 | v2 |
No tool annotations. fetch_urls and analyze_security are read-only but lack readOnlyHint. No idempotentHint declared, yet crawling the same URL twice may yield different results (dynamic content). LLM cannot reason about retry safety.
Composition issue: fetch_urls and analyze_security both crawl URLs but with different max_urls defaults (10 vs 5). No clear guidance on when to use each. analyze_security likely calls fetch_urls internally but this is not documented, forcing LLM to guess.