A book recommendation MCP server with GitHub OAuth authentication that stores user reading preferences and provides personalized book recommendations
The server defines 4 tools with basic schemas and descriptions. All tools have descriptions and registered input schemas using Zod, which is positive. However, schemas are minimal (most tools have 1-2 parameters), descriptions are brief and lack actionable context for LLM selection, and there is no documented output schema. Parameter descriptions contain example values (a documented anti-pattern) rather than formal constraints. Error handling is present but provides generic responses without recovery guidance. The tool set is well-named (verb_noun pattern) and addresses a coherent domain (book preferences), but lacks depth in design patterns like idempotence, pagination, and chaining. Tool output is unstructured text rather than typed JSON, forcing LLMs to parse freeform responses.
Add a book you have read
Add an author you enjoy reading
Add a book genre you enjoy reading
View your reading history and preferences
Output schemas are not documented. Tools return text content with no typed structure (genre, author, book objects lack formal field definitions). LLMs must parse freeform markdown, wasting tokens and risking hallucination.
Parameter descriptions contain example values (e.g., 'e.g., science fiction, mystery, romance') rather than formal constraints or enums. This anti-pattern causes LLMs to reuse examples literally rather than adapting to context.
Tool descriptions lack actionable context. 'View your reading history and preferences' does not explain WHEN to call it vs. other tools, what fields are returned, or how results support downstream planning.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 0 | - | v1 |
No pagination or result limits documented. getProfile returns booksRead and dislikedBooks arrays without documented max sizes or pagination support. Large collections could exhaust context.
Error handling is generic. Additive tools return duplicate detection, but other error paths (e.g., invalid genre format, storage failures) return catch-all messages without recovery guidance or classification (retryable vs. user-fixable).
No idempotence guarantees documented. addGenre checks for duplicates, but addBookRead does not, agents retrying failed calls could create duplicate book entries.
Tool set lacks composition helpers. No search_genres, search_authors, or list_available_genres tool, agents must guess valid values, risking duplicates and invalid data.