MCP server and client for web search and page viewing tools - DuckDuckGo search and web scraping
The server has well-structured tool definitions with detailed descriptions that include usage guidance, examples, and best-practice hints. All three tools have explicit input schemas with type definitions and descriptions. However, there are gaps in output schema documentation and some parameter descriptions could be more prescriptive about constraints. The tool names are clear action verbs (web_search, web_page, download_files) but lack the verb_noun consistency preferred in production tools. No security annotations (readOnlyHint/destructiveHint) are present despite download_files being a WRITE operation.
Download one or more files from URLs to a specified directory. **Best for:** Downloading files from URLs to local storage with security and error handling. **Not recommended for:** When you don't have permission to write to the target directory. **Common mistakes:** Not specifying a valid directory path or providing invalid URLs. **Prompt Example:** "Download these files to /tmp/downloads" **Usage Example:** ```json { "name": "download_files", "arguments": { "urls": ["https://example.com/file1.txt", "https://example.com/file2.pdf"], "directory": "/tmp/downloads", "filenames": ["custom1.txt", "custom2.pdf"], "maxRetries": 3, "retryDelay": 1000, "timeout": 30000, "concurrency": 5 } } ``` **Returns:** Download results with file paths, sizes, and success status.
Fetch and extract content from a specific web page URL. **Best for:** Getting full content from a known URL, extracting article text, documentation, or specific page content. **Not recommended for:** When you don't know the exact URL (use web_search first). **Common mistakes:** Using web_page for general web searches instead of specific URLs. **Prompt Example:** "Get the content from https://docs.python.org/3/library/asyncio.html" **Usage Example:** ```json { "name": "web_page", "arguments": { "urls": ["https://docs.python.org/3/library/asyncio.html", "https://example.com"], "maxLength": 30000, "includeLinks": true, "concurrency": 10 } } ``` **Returns:** Page content in markdown format with optional links and metadata.
Search the web using DuckDuckGo for any query. **Best for:** Finding information across the web, researching topics, getting current information. **Not recommended for:** When you already know the exact URL you need (use web_page instead). **Common mistakes:** Using web_search when you have a specific URL to scrape. **Prompt Example:** "Search for latest TypeScript features released" **Usage Example:** ```json { "name": "web_search", "arguments": { "query": "latest TypeScript features", "maxResults": 5, "time": "m" } } ``` **Returns:** Search results with titles, URLs, and descriptions.
Output schemas not formally documented in tool registration. Only web_search has a documented outputSchema in server/index.ts (lines showing z.object with query/results/title/url/snippet/source). web_page and download_files lack outputSchema definitions, forcing LLMs to guess structure of returned data.
Tool annotations missing. download_files is marked Risk:WRITE but has no destructiveHint or writeGuard in the schema. web_search and web_page lack readOnlyHint annotations despite being read-only. This prevents clients from understanding operation safety and idempotency.
Parameter constraints under-specified. 'time' parameter in web_search states 'Time filter (d, w, m, y)' but does not use enum constraint, LLMs may pass invalid values. 'maxLength' in web_page (default 50000) lacks validation guidance. 'concurrency' parameters (web_page, download_files) lack bounds checking (min/max).
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | 2025-06-18+ | v2 |
| 2026-03-09 | D | 59 | - | v1 |
Error handling not documented. Tools return results but descriptions do not explain failure modes (network errors, timeout, invalid URL, permission denied, disk full for downloads). No recovery guidance in descriptions; LLMs will not know when to retry vs. ask user.
download_files lacks safety guardrails. No dry-run option, no confirmation step. An agent could overwrite user files or fill disk. Description should warn about directory validation and file permissions.