A blazing-fast MCP server for multi-engine web search, written in Rust
ferris-search provides 7 read-only tools with basic descriptions and partial schemas. Tool names follow verb_noun convention (web_search, fetch_*) which is good. However, descriptions are inconsistent in depth, some are 1-2 sentences while others lack actionable context. Input schemas are visible in the code but lack explicit type constraints (enums, ranges, patterns). Output schemas are not documented. Error handling returns plain strings without recovery guidance. No tool annotations (readOnlyHint, idempotentHint) despite all tools being read-only. Parameter descriptions exist but are minimal (e.g., 'Optional array of search engine names' lacks format/constraint details). The server lacks pagination support for multi-result tools, risking context window exhaustion.
Fetch full article content from a CSDN (csdn.net) post URL.
Fetch the README content from a GitHub repository URL.
Fetch full article content from a Juejin (juejin.cn) post URL.
Fetch full article content from a linux.do topic URL.
Fetch and extract text content from any public web URL.
Fetch full article content from a Zhihu (zhihu.com) URL.
Search the web using one or more engines. engines parameter accepts an array: ["bing", "duckduckgo", ...]. Supported: bing, duckduckgo, brave, baidu, csdn, juejin, exa, firecrawl, zhihu, linuxdo, jina, tavily, github (repo search), github_code (code search).
Output schemas not documented. Tools return plain strings; LLMs cannot parse structured results or chain downstream calls. fetch_web_content returns 'Title: ... URL: ... Content: ...' as unstructured text instead of {title, url, content, truncated} object.
Input parameter constraints missing. 'engines' array accepts arbitrary strings; no enum constraint prevents hallucinated engine names. 'limit' accepts 1-50 but this is enforced in code (clamp), not declared in schema. LLMs cannot validate inputs before calling.
Error responses lack recovery guidance. 'Search failed: <error>' and 'Failed to fetch URL: <error>' tell LLM nothing about retry eligibility or next steps. No categorization of retryable vs fatal errors.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 52 | <=2025-11-25 | v2 |
No pagination support. web_search returns all results up to limit; no next_cursor or offset. Multi-engine fan-out concatenates results without pagination, risking context window exhaustion on large result sets.
Tool annotations missing. All 7 tools are read-only but lack readOnlyHint annotation. This prevents clients from optimizing caching, retry logic, or UI presentation for safe operations.