MCP server for pole dance moves search, Spotify integration, and web scraping with LangGraph orchestration
This server exhibits significant quality gaps across naming, descriptions, schemas, and error handling. Of 6 tools, only 2 have adequate descriptions; parameter descriptions are largely missing or generic; schemas lack proper type constraints; and error handling is absent. The codebase shows incomplete parameter typing (e.g., scrape_url and search_tracks_by_user_input missing type hints), inconsistent tool naming patterns, and no output schema documentation. Two tools (scrape_url, fetch_url) appear to wrap external MCP servers but do so without clear separation of concerns or idempotency guarantees. The semantic_search and find_similar_moves tools operate on ChromaDB but return raw stringified responses rather than structured results. Spotify integration exposes API details without input validation. Overall, this server reads as a prototype rather than production-ready tooling.
Fetch content from a URL using mcp_server_fetch. This is a wrapper around the fetch tool from mcp_server_fetch.
Find list of simiar moves given a user input of move and return by default 3 similar moves though the num is userdefined -> Optional[List[str]]
Check login, health check
Scrape content from a URL using the mcp_server_fetch tool
Search spotify using query and limit of results
Get moves from user query.
Output schemas completely absent for all 6 tools. Tools return raw API responses (str(response), response.json()) or implicit None without documenting the structure, fields, or types. LLMs cannot plan downstream operations or extract data reliably.
Parameter type hints missing or incomplete in function signatures. scrape_url(url: str) is typed in source but tool registration does not enforce schema. search_tracks_by_user_input(query, limit=3) has NO type hints in source code. This violates JSON Schema requirements and forces schema inference, which is unreliable.
Tool descriptions are too short or generic. 'Get moves from user query' (18 chars), 'Check login, health check' (24 chars), 'Scrape content from a URL using the mcp_server_fetch tool' (56 chars). Descriptions under 50 chars lack sufficient context for LLM tool selection. Baseline: 194 chars for good tools.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 46 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 37 | - | v1 |
Tool naming ambiguities and poor verb choices. 'login' does not convey 'check auth status'; LLM will attempt authentication. 'scrape_url' vs 'fetch_url' serve similar purposes (both wrap mcp_server_fetch) but names don't distinguish clearly. No verb differentiation guides LLM to correct tool.
Duplicate tools violate single-responsibility. scrape_url and fetch_url both wrap mcp_server_fetch with nearly identical logic. Maintaining two tools wastes LLM reasoning cycles and invites confusion about which to call. Merge into one canonical tool or document clear separation.
Error handling is absent or generic. scrape_url fails silently if fetch_mcp_client.get_tools() returns empty list (returns 'Error...' string but this is not structured). search_tracks_by_user_input has no error handling for API failures. No guidance to LLM on recovery (e.g., 'try with shorter query', 'check network'). Pattern: recovery-guide requires actionable error messages.
Parameter descriptions are missing or vague. find_similar_moves 'num' param description is 'Number of similar moves to return' (terse but present). search_tracks_by_user_input 'limit' has no constraint documentation (valid range, max value). No enum constraints for any enum-like params (e.g., search type). Baseline: 100% of A+ tools have param descriptions.
Credentials and API details exposed in function logic without server-side isolation. Spotify access token obtained via get_valid_access_token() in search_tracks_by_user_input. No evidence of secret injection or environment variable use. If token is stored insecurely or exposed in logs, authentication is compromised.
Response filtering absent. Tools return raw API responses (response.json() from Spotify, str(response) from ChromaDB). These likely include metadata, internal IDs, and fields irrelevant to chat. Returning 500+ char responses wastes tokens and increases hallucination risk. Pattern: strip-api-responses requires extracting only user-relevant fields.
No input validation or constraints. find_similar_moves accepts any string for 'move' param (no enum, no validation). search_tracks_by_user_input accepts unbounded 'limit' (no max constraint documented). Agents can pass invalid values (limit=10000, move='xyz123!@#') without early rejection and actionable error messages.