WebQuest MCP exposes 5 read-only web search and scraping tools via FastMCP. All tools are explicitly registered with @mcp.tool() decorators and have basic descriptions. However, critical issues severely limit quality: (1) Input parameters are opaque Pydantic request objects (AnyArticleRequest, DuckDuckGoSearchRequest, etc.) with NO visible schema documentation in the MCP server code, the actual field names, types, defaults, and constraints are hidden in the external 'webquest' package, making it impossible for LLMs to understand valid inputs; (2) Output schemas are also undocumented, responses return Pydantic objects but their structure is not declared to MCP clients; (3) Descriptions are generic and lack guidance on when to use each tool or how they differ; (4) No parameter descriptions at all, LLMs see only type names like 'AnyArticleRequest' with no hint of what fields to pass; (5) No error handling guidance, rate limits, or recovery patterns; (6) Transport is STDIO-only, hard-capping protocol readiness. The server delegates all logic to an external 'webquest' library, providing no control over schema documentation or error responses.
Tools (5)
any_articleread onlysource verified35/100
Get the content of an article given its URL.
duckduckgo_searchread onlysource verified35/100
Search the web using DuckDuckGo given a query.
google_news_searchread onlysource verified35/100
Search for news articles using Google News given a query.
youtube_searchread onlysource verified35/100
Search for YouTube videos, channels, posts, and shorts given a query.
youtube_transcriptread onlysource verified35/100
Get the transcript of a YouTube video given its ID.
Input schemas are completely opaque. Tools accept Pydantic request objects (AnyArticleRequest, DuckDuckGoSearchRequest, etc.) but the MCP server code provides NO JSON Schema definition of these objects' fields, types, defaults, or constraints. LLMs cannot see what parameters to pass or what values are valid. This violates the core 'tool' pattern which requires documented input schemas.
Output schemas are undocumented. All tools return Pydantic response objects (AnyArticleResponse, DuckDuckGoSearchResponse, etc.) but the MCP server provides no documentation of the response structure. LLMs cannot plan downstream calls or extract specific fields.
CRITICAL: Document input schemas inline. For each tool, create a JSON Schema that describes the request object's fields. Example for 'duckduckgo_search': define the DuckDuckGoSearchRequest as {type: 'object', properties: {query: {type: 'string', description: 'Search query (required)'}, max_results: {type: 'integer', min: 1, max: 100, description: 'Max results to return (default 20)'}}, required: ['query']}. Use FastMCP's schema generation or Pydantic integration to expose these schemas to MCP clients.
CRITICAL: Document output schemas. For each tool, add a docstring or annotation describing the response structure. Example: '@mcp.tool() async def duckduckgo_search(...) -> DuckDuckGoSearchResponse:\n """Search the web using DuckDuckGo. Returns: {results: [{title, url, snippet}], total: int}"""'
HIGH: Enhance tool descriptions to be LLM-optimized (50-200 chars, action-oriented). Replace generic descriptions with context-aware ones. Example: 'any_article: Fetch and parse the full text content of a web article from a URL. Use this when you need article body text, not just a search result snippet. Returns: title, content, publish_date, authors.' This signals WHAT the tool does, WHEN to use it (vs search results), and WHAT it returns.
HIGH: Add parameter descriptions for the 'request' parameter. Document what fields the request object expects. Example for duckduckgo_search: 'request: DuckDuckGoSearchRequest with fields: query (required, string), max_results (int, 1-100, default 20), region (string, e.g. 'us-en').' This is CRITICAL because without this, LLMs cannot call the tool correctly.
Score history
Overall score trend
↓ 3 points across a rubric change (v1 → v2)
35/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
F
35
2026-07-28+
v2
2026-03-09
F
38
-
v1
No parameter descriptions. Each tool's single parameter is named 'request' with a type hint pointing to an external Pydantic class. There is no description explaining what fields the request object should contain, what they control, or how to structure them. Pattern: tool-description requires every parameter to have a description.
Generic tool descriptions lack actionable guidance. Descriptions like 'Get the content of an article given its URL' and 'Search the web using DuckDuckGo given a query' do not explain WHEN to use each tool, how they differ, what prerequisites are needed, or what to expect in the response.
No error handling or recovery guidance. Tools delegate to external 'webquest' library but provide no documentation of failure modes, rate limits, timeout behavior, or what the LLM should do if a call fails (retry, ask user, use alternative tool). Pattern: recovery-guide requires error responses to guide the LLM's next step.
No pagination documentation. Search tools (duckduckgo_search, google_news_search, youtube_search) likely return multiple results but there is no indication of whether results are paginated, how to request additional pages, what the default/max limit is, or whether a total count is returned. Pattern: paginated-result requires large-result tools to document pagination.
External dependency opacity. All tool logic is delegated to the 'webquest' library. The MCP server has no control over schema documentation, validation, or error messages. If webquest changes its API or response format, this server cannot adapt without modifying external code.
HIGH: Document error handling and retry logic. Add to each tool's docstring: 'Errors: Returns 429 if rate limit exceeded (wait 60s, retry idempotent); returns 404 if URL not found (no retry); returns 500 on network failure (safe to retry).' This guides the LLM's recovery strategy.
MEDIUM: Add pagination guidance to search tools. Document: 'Results are paginated. max_results controls per-page limit (1-100, default 20). Response includes: results (array), total (int, total count), next_page (int or null if last page). Call again with page parameter to fetch next page.' This prevents context overflow and teaches LLMs how to iterate.
MEDIUM: Wrap webquest library with MCP-native schema validation. Instead of passing raw Pydantic objects, validate and document the fields in the MCP server layer. This decouples MCP's interface from webquest's API and gives you control over schema documentation.
LOW: Add tool annotations. Use FastMCP's @mcp.tool(hints=[...]) to mark tools as read-only: '@mcp.tool(hints=['readOnlyHint'])', indicating these are safe to call without confirmation.
LOW: Consider adding a 'discovery' tool or prompt that lists available search types and when to use each. E.g., 'duckduckgo_search for general web results, google_news_search for recent news, youtube_search for videos.' This helps LLMs select the right tool.
LOW: Migrate from STDIO to HTTP or SSE for remote accessibility. STDIO limits clients to local/containerized deployments. HTTP or Streamable HTTP enables hosted MCP clients (e.g., Claude's Agent API, multi-turn orchestrators).