Fragrance & perfume MCP server and API client: query fragrances, notes, accords, brands, perfumers, reviews, and charts from Noteboxd.
Noteboxd MCP demonstrates strong definition quality with 17 well-structured tools, all featuring proper verb-noun naming (search, get_, list_), complete input schemas with Zod validation, and consistent descriptions. All tools are READ_ONLY with proper annotations. However, output schemas are not explicitly documented in the code, and some parameter descriptions lack actionable constraints (e.g., format specifications). Tool descriptions are generally adequate (50-150 chars) but could be more prescriptive about when to use each tool vs. similar alternatives. No security issues detected (read-only operations only). Composition is sound, each tool has a single responsibility, and fragrance lookup chains are well-designed (search → get_fragrance → enrich_fragrance). The batch_get_fragrances and enrich_fragrance tools show good awareness of agent efficiency patterns.
Fetch up to 50 fragrances by id in a single call.
Compare two fragrances: shared and distinct notes, accords, families, and scores, plus a written synthesis of their character. Takes fragrance ids.
Fetch a fragrance with its notes, accords, recent reviews, and similar fragrances in one call.
Get a brand profile and its top fragrances by slug.
Get a chart leaderboard by slug, for example 'top-rated' or 'top-rated-brand-chanel'.
Get the full profile for one fragrance by id or slug (for example 'tom-ford/oud-wood'): notes, accords, perfumer, and community score.
Output schemas not documented. While input schemas are complete with Zod types and descriptions, the response structure for each tool is not specified in code comments or documentation. LLMs cannot predict which fields each tool returns, forcing exploratory calls and reducing composition confidence.
Error handling lacks recovery guidance. The fail() function in src/tools.ts returns API errors and generic Error messages, but does not suggest next steps or categorize errors as retryable, user-fixable, or fatal. When search_fragrances fails due to invalid slug, the agent receives an HTTP error code without context.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 65 | 2026-07-28+ | v2 |
Get paginated community reviews for a fragrance (id or slug).
Get a note profile and its top fragrances by slug.
Get a perfumer profile and their creations by slug.
Get a short summary of a fragrance's community reviews (id or slug).
Find fragrances with a similar accord profile to a given fragrance (id or slug).
Aggregate wearing counts for a fragrance (id or slug) over the last day, 7 days, and 30 days.
Get a brand's full catalogue by slug, ordered by community score, with pagination.
List available chart rankings. Use get_chart with a slug for the full leaderboard.
Search across fragrances, brands, notes, perfumers, and collections in one call. Good for quick lookups. Use search_fragrances for filtered fragrance queries.
Filter fragrances with cursor pagination. Requires at least one filter (q, brand, note, family, or price_range). Use search for open keyword lookups.
Trending search queries and the most-worn fragrances right now.
Some parameter descriptions lack format constraints. Parameters like 'slug' in get_chart, get_brand, get_note, get_perfumer accept string input but do not specify format rules (e.g., lowercase, no spaces, kebab-case). LLMs may pass 'Tom Ford' instead of 'tom-ford', causing failed lookups.
Tool descriptions inconsistently guide selection between similar tools. 'search' vs 'search_fragrances' both search fragrances but with different constraints. The descriptions state 'Use search_fragrances for filtered fragrance queries' but do not clearly explain when to prefer search (open keyword) vs search_fragrances (at least one filter required).
Pagination parameters inconsistent across tools. get_fragrance_reviews and list_brand_fragrances use page/limit, while search_fragrances uses cursor/limit. No tool explicitly documents the total count or whether pagination is exhaustive. Agents cannot determine when to stop iterating.