An MCP server built with FastAPI that provides OAuth 2.0 protected web search capabilities using Tavily API
Single tool (web_search) with basic implementation. Tool has a description and a simple input schema, but lacks critical details expected in production tools. The description is present but generic (54 chars), and the parameter description is minimal. Output schema is not documented. Error handling returns a generic dict with an 'error' key but provides no recovery guidance. The tool follows basic naming conventions (verb_noun), but lacks the richness needed for reliable agent planning. No output structure is defined, forcing LLMs to infer what fields are returned. The implementation is functional but falls short of production-grade tool definition quality.
Use this tool to search the web for information.
Tool description is generic and lacks context for when to use it. '54 chars: Use this tool to search the web for information.' does not explain prerequisites, what it returns, or when to prefer it over other tools. Should be 100-200 chars explaining search result structure and availability.
Parameter description is minimal. 'The search query.' (18 chars) does not explain format constraints, length limits, or expected content type. Should include guidance like 'A natural-language query (max 200 chars). Supports keywords, phrases, and Boolean operators (AND, OR, NOT).'
Output schema is not documented. The function returns List[Dict] but the structure and field names are opaque to the LLM. Without documented fields (e.g., title, url, snippet, score), LLMs cannot reliably extract or chain results. Tavily returns standard fields but the tool does not declare them.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 52 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 51 | - | v1 |
Error handling returns raw exception message in a dict {'error': str(e)} with no recovery guidance. An LLM seeing {'error': 'Invalid API key'} cannot self-correct. Should return actionable errors like 'Search failed: API key invalid. Contact admin.' or 'Search unavailable temporarily. Retry in 30s.' with explicit next steps.
No pagination or result limit documented. The function does not accept limit/offset parameters and will return all Tavily results, which could be many. For large result sets, LLM context is wasted and reasoning degrades. Baselines expect pagination (limit default 20, max 50) with a total count.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) declared. The web_search tool is read-only and idempotent, but the server does not communicate this via toolAnnotations in the schema. Modern clients rely on these hints to optimize agent planning.
No rate limiting, timeout, or concurrency guidance. Tavily API calls could fail due to rate limits or timeouts, but the tool provides no mitigation. Should document per-minute rate limits and include exponential backoff guidance in error messages.