MCP server for Snagr, a self-hosted price tracker. Exposes tools for managing watches, items, listings, jobs, and vision-based authenticity checking through the FastMCP framework.
Four tools with complete input schemas and descriptions, but quality varies significantly. All tools have descriptions (10-200 chars range) and typed parameters with descriptions. However, descriptions lack LLM-optimized guidance on WHEN to use each tool vs alternatives, and error handling is minimal. Output schemas are not documented. Parameter descriptions are functional but sparse (avg ~60 chars vs baseline 72). No tool annotations (readOnlyHint/destructiveHint/idempotentHint) despite all being WRITE operations. Naming is clear and verb-forward (save_*, log_*, check_*), but composition could be tighter, save_listing and log_listing_check are near-duplicates with different outcomes.
Fetch, embed, persist, and score a candidate listing's photos against the item's gold library. Persistence never depends on the listing being saved — rejected listings are where fake reference candidates come from.
Record that a listing was checked but rejected (not saved). Reasons include 'authenticity', 'criteria', 'duplicate', or other rejection causes.
Save a listing that matches the user's selected criteria to the database and return its listing_id. It is saved under the watch, item and site this search is for — those are already known here, so you never pass them.
Record a price check for a listing and return the check_id. The price is validated for plausibility before it can become a target-hit push. At the moment it confirms a price, code reads the page it is on and learns where that price lives, so later rechecks need no model at all.
No tool annotations (destructiveHint, idempotentHint) despite all tools being WRITE operations. LLMs cannot infer retry safety or side-effect scope.
Output schemas not documented. Callers cannot plan downstream tool chains or extract required fields (e.g., listing_id from save_listing).
save_listing and log_listing_check are near-duplicates: both accept URL and reason, but one saves and one rejects. Descriptions do not clarify when to use each.
Parameter descriptions lack actionable constraints. E.g., match_score is '0-100' in description but no min/max in schema; status enum values not listed in description.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
No error handling guidance. Tools do not document what happens on invalid input (e.g., URL on wrong domain, invalid price format, unknown watch_id).