MCP server providing tools to fetch cryptocurrency price data from Binance with caching, symbol resolution, and retry logic
The server implements two read-only tools for cryptocurrency price queries with basic input validation and caching. Both tools have functional descriptions and accept string symbol parameters with flexible resolution (friendly names, symbols, with/without USDT suffix). However, the tools lack proper output schema documentation, error handling guidance, and parameter descriptions are minimal. Input schemas are visible in the code decorator and function signatures but lack formal JSON Schema type annotations in the tool registration. The symbol parameter descriptions reference examples but lack format constraints or validation rules. Error handling is present internally (retries, backoff, timeouts) but not surfaced to the LLM via actionable error messages. The tool names follow verb-noun convention (get_*) which is good, but the second tool name 'get_price_price_change' is redundant/awkward (should be 'get_24hr_ticker_change' or similar for clarity). Cache behavior is mentioned in descriptions but cache-related fields in output ('cached': true/false) are undocumented.
Returns a structured dict with current price for the validated symbol. Caches the response for TTL_PRICE seconds.
Returns Binance 24hr ticker data (structured) for the validated symbol. Caches response for TTL_24HR seconds.
Tool name 'get_price_price_change' is redundant and unclear. 'price_change' implies a delta, but the tool returns full 24hr ticker data. Rename to 'get_24hr_ticker' or 'get_ticker_24h' for clarity.
Output schema is not documented. Both tools return structured dicts with fields like 'symbol', 'price'/'data', and 'cached', but the LLM has no declared schema to understand the response structure. This forces the LLM to infer fields from examples rather than machine-readable definitions.
Symbol parameter lacks format/validation description. The description mentions friendly names and variations but does not formalize the constraint. Should state: 'Cryptocurrency symbol (e.g. BTCUSDT, BTC, bitcoin). Resolves friendly names (bitcoin→BTCUSDT) and autocompletes USDT suffix. Returns error if unresolvable.'
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 45 | <=2025-11-25 | v2 |
| 2026-03-09 | F | 42 | - | v1 |
Error handling is not LLM-friendly. Internal code catches ValueError and HTTPError but does not surface actionable recovery guidance. An LLM receiving 'Could not resolve symbol' has no hint to try search or check a reference.
No input schema type definitions visible in tool registration. The @mcp.tool() decorators lack explicit schema dicts with type, description, enum, or format fields. fastmcp may infer types from function signatures, but this is implicit and not machine-verifiable from the code.
Cache behavior exposed in output but undocumented for LLM. Both tools return a 'cached' field, but LLMs need to know: Does cached=true mean stale data? Should the agent retry without cache? This semantic is critical for trust and correctness.
No rate-limit guidance. The code implements exponential backoff for 429 responses and logs retries, but there's no documentation for the LLM on expected rate limits, retry behavior, or recommended call frequency. Agents may repeatedly hit rate limits without guidance on backoff.