A web search server providing web search capabilities via the Model Context Protocol (MCP) with support for multiple search engines, content extraction, and deep reading.
This server has serious definition quality gaps across nearly all tools. While tool names follow verb_noun conventions (websearch_basic, fetch_page_content, take_screenshot), the parameter schemas are incomplete and descriptions lack depth. Most critically, output schemas are entirely undocumented, LLMs cannot understand what these tools return, making composition and error recovery impossible. Parameter descriptions exist but are minimal (avg ~40 chars, below the 72-char baseline). No error handling guidance is provided. The server defines 8 tools but only 3 have reasonably complete schemas; the remainder lack documented output types, constraints, or usage guidance.
Perform an exhaustive all-web research on a topic. Searches multiple engines, selects diverse authoritative sources, and performs deep reading on each. Returns a structured, cross-referenced research report.
deep_read_pageread onlysource verified65/100
Deep read a webpage by extracting main content and intelligently crawling related sub-pages. Returns structured markdown with main content and linked page summaries. Useful for comprehensive page analysis.
fetch_page_contentread onlysource verified65/100
Directly fetch and extract the main content from a specific URL using Readability and Markdown conversion
Output schemas completely undocumented. All 8 tools return mcp.CallToolResult with TextContent, but no documentation of response structure, fields, or format. LLMs cannot plan downstream tool calls or extract structured data.
Parameter descriptions lack actionable constraints. 'max_results' lacks min/max bounds (tools use 0 as 'unset' and default differently, 10, 5, 10, 5, etc.). 'query' has no guidance on length, language, or malformed input handling. LLMs cannot validate inputs.
Document output schema for every tool. Define the response structure in the tool description or as a structured JSON example. For websearch tools: specify that results are markdown with fields Title, URL, Snippet/Content. For take_screenshot: specify return format (base64 PNG? URL?). For deep_read_page: return structured object with {main_content: string, sub_pages: [{url, summary}], extraction_timestamp}.
Add bounds and enums to all parameters. For max_results, specify min=1, max=50 (or whatever the actual limit is) and default=10. For 'engines' in websearch_multi_engine, document valid values: ['google', 'bing', 'ddg', 'perplexity'] and default=['google']. For 'full_page' and 'extract_content' booleans, clarify what true/false mean in terms of content volume or cost.
Expand parameter descriptions to 60+ characters. Use pattern: 'Parameter name (type, constraints). What it controls. Example: value X produces result Y. Default: Z if omitted.' Example: 'max_results (integer, 1 - 50, default 10). Maximum search results to return. Higher values increase latency but improve coverage. Leave blank for default.'
Add error handling guidance. For websearch_ai_summary, instead of returning 'aggregation not supported', return 'Aggregation unavailable (internal searcher type mismatch). Try websearch_multi_engine instead, which supports custom engines.' For URL-based tools (fetch_page_content, take_screenshot), document HTTP errors: '404 Not Found: page does not exist. 403 Forbidden: page blocks automated access. Try a different URL.'
Score history
Overall score trend
↑ 16 points across a rubric change (v1 → v2)
56/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
D
56
2026-07-28+
v2
2026-03-09
F
40
-
v1
read onlysource verified67/100
Comprehensive search across multiple engines with content extraction
Web search with intelligent content extraction from result pages
No error handling documentation. Tools return raw errors (e.g. 'aggregation not supported' for websearch_ai_summary if searcher is wrong type). LLMs receive no guidance on retryability, alternatives, or recovery actions.
Tool composition broken by missing chaining IDs in responses. For example, deep_read_page returns markdown content but no metadata about which URL was processed, how many sub-pages were crawled, or extraction timestamps. Agents cannot correlate results to requests.
Ambiguous 'engines' parameter in websearch_multi_engine. Description says 'search engines to use' but does not enumerate valid values (e.g. 'google', 'bing', 'ddg'?), default behavior if omitted, or fallback if an engine is unavailable. Invites hallucinated engine names.
Parameter descriptions under baseline. Average length ~40 chars vs 72-char baseline. Examples: 'whether to extract full page content' (46 chars) lacks guidance on what constitutes 'content'; 'maximum number of results to return' (37 chars) omits bounds or defaults.
Include metadata in responses. deep_read_page should return {content: string, processed_url: string, sub_pages_crawled: number, cross_domain_followed: boolean}. comprehensive_research should return {report: string, sources_analyzed: number, extraction_timestamps: [ISO8601]}. This enables agents to track progress and correlate results.
Document parameter dependencies. For deep_read_page, clarify: 'If cross_domain=true, max_links limit applies across all domains; if false, limit applies to same-domain only. Setting both parameters to their defaults respects robots.txt for same-domain crawling.' For websearch_with_content, explain: 'extract_content=true fetches full page text (~1-2s per result); false uses cached snippets (~100ms). Choose based on latency tolerance.'
Add fetch_page_content parameter validation. Document: 'URL must start with http:// or https://. Relative URLs are rejected. Localhost and 127.0.0.1 are not supported (security). Maximum URL length: 2048 chars. Invalid URLs return: Invalid URL format: [reason]. Must be absolute HTTP(S) URL.'
Clarify take_screenshot output format. Specify: 'Returns base64-encoded PNG image embedded in response. full_page=true captures all scrollable content (may be very large; max 5000px height); full_page=false captures viewport only (~800x600px default). Returns error if page fails to load within 10s timeout.'
Define websearch_with_content truncation behavior. Document: 'Content longer than 1500 characters is truncated with '...' suffix. To retrieve full content, use fetch_page_content with the returned URL. This keeps response size manageable for token budgets.'
Add rate-limit and retry guidance. Document: 'Search tools may return 429 Too Many Requests if rate-limited (>10 requests/sec from same IP). Retry after 60 seconds with exponential backoff. Each tool independently enforces limits. Batch queries into max 5 concurrent requests.'
Describe when to use each websearch tool. In descriptions, add routing guidance: 'Use websearch_basic for quick answers (low latency). Use websearch_with_content when you need extracted page text (moderate latency). Use websearch_multi_engine when you need diverse sources (higher latency, better coverage). Use websearch_ai_summary when preparing aggregated data for LLM analysis (returns pre-formatted markdown ready for summarization).'
Document comprehensive_research constraints and process. Clarify: 'max_sources (default 3, max 8) controls how many distinct websites are analyzed. Process: 1. Search topic across engines, 2. Rank results by authority (domain age, traffic), 3. Deep-read top N, 4. Cross-reference findings. Total execution time: ~30-120 seconds depending on max_sources. Returns structured markdown report with citations.'
Specify idempotency guarantees. Document: 'All tools are read-only and fully idempotent. Multiple calls with identical parameters return identical results (cached for 1 hour). Safe to retry without side effects.' This guides agent retry logic.
Add example parameter patterns. For websearch_basic: 'Example: query="Python async tutorial 2024", max_results=5 returns top 5 results from last 6 months.' For take_screenshot: 'Example: url="https://example.com", full_page=true returns complete scrollable page as PNG.' Examples should be in tool description or separate docs, NOT in parameter descriptions (LLMs copy literal examples).