A search-and-fetch toolkit for AI agents — MCP server and standalone Agent Skills powered by DuckDuckGo, trafilatura, and Jina Reader
Web-forager has 4 tools with mostly complete schemas but significant description gaps. Three tools (duckduckgo_search, duckduckgo_news_search, web_fetch) are defined in tests/evals/fixture_server.py with basic parameter schemas and tool annotations present. One tool (search) is referenced in src/web_forager/cli.py but its actual implementation is not visible in the provided source. Descriptions exist but are minimal (10-50 chars), below the baseline of 194 chars. Parameters lack descriptions for critical fields (e.g., safesearch values 'on'/'moderate'/'off' are not explained). All tools are read-only, which is appropriate for the domain. Error handling and recovery guidance are absent. No output schemas are documented. Tool composition is reasonable (search, news search, fetch are separate concerns), but parameter naming could be more explicit (e.g., 'safesearch' should explain the exact allowed values).
Search DuckDuckGo for recent news articles.
Search the web using DuckDuckGo.
Search DuckDuckGo for the given query.
Fetch a URL and convert it to markdown or JSON.
Tool 'search' definition not visible in source code; only referenced in cli.py. Actual schema, full implementation, and error handling cannot be verified.
Parameter descriptions are missing or insufficient. 'safesearch' parameter lists example values ('on', 'moderate', 'off') in the description but does not state that these are the ONLY valid options. Should use enum constraint in schema or explicitly state: 'Must be one of: on, moderate, off'.
Tool descriptions are too brief (10-50 chars). Baseline is 194 chars. Current descriptions lack context on when to use each tool vs. alternatives (e.g., when to call duckduckgo_search vs. duckduckgo_news_search). LLMs need explicit guidance for tool selection.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 47 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 57 | - | v1 |
No output schema documentation. Tools return structured objects (list of dicts with title/url/snippet/date for search; string for web_fetch) but no schema is provided to the LLM. Agents cannot plan downstream calls or extract specific fields without guessing.
No error handling guidance. If a search fails (provider unavailable, network error) or URL is unreachable, the tool raises RuntimeError with generic message. No recovery hints provided to the LLM (e.g., 'Retry with a simpler query' or 'Try a different URL').
Parameter 'output_format' accepts 'json' or 'text' but the description does not explain the difference or guide when to use each. LLM may not know that 'text' is more suitable for direct inclusion in prompts.
Parameter 'allow_jina' in web_fetch is unexplained. Description states it allows 'fallback for eligible public URLs' but does not clarify what Jina is, why it exists, or when to set it False. Domain jargon without explanation.
Parameter 'max_length' in web_fetch has type integer but no range constraints documented. An LLM could pass 0, negative, or unbounded large values. Should specify minimum (e.g., 100) and maximum (e.g., 100000).