MCP server for tracking and analyzing subscription spending, with tools to list subscriptions, find unused services, forecast spend, detect duplicates, and manage subscription status.
wallet-watch-mcp demonstrates solid tool design with clear naming, comprehensive descriptions, and proper input schemas. All 8 tools follow verb_noun conventions (list_, get_, find_, snooze_or_downgrade, forecast_). Descriptions are well-crafted (100-250 chars), explaining WHAT the tool does and WHEN to use it. Parameters have types and descriptions. However, output schemas are not formally documented, responses are inferred from code. Error handling returns structured error objects but lacks recovery guidance (e.g., 'try X instead'). No tool annotations (readOnlyHint/destructiveHint) despite clear risk profiles. Missing pagination support on list_subscriptions despite potentially large result sets.
Flag overlapping subscriptions that may be redundant. Use this to answer "am I paying for the same thing twice?" Groups active subscriptions by category and flags any category with two or more, since those are likely overlaps (e.g. Spotify + Apple Music). Returns: {"duplicates": [ {"category": str, "services": [...], "monthlyCost": float} ]}, or an error object.
Find subscriptions unused in the last N days — the "am I wasting money" tool. Use this to surface likely cancel candidates the user is paying for but hasn't used recently. Includes the potential monthly savings.
Project upcoming subscription spend month-by-month for the next N months. Use this to answer "what will my subscription bills look like over the next few months?" Annual subscriptions are charged in full in their renewal month, so this surfaces lumpy months a monthly average would hide. Args: months: How many months ahead to forecast. Defaults to 6. Returns: {"byMonth": {"YYYY-MM": float}, "total": float, "currency": str}, or an error object.
List subscriptions whose price went up recently. Use this to answer "did any of my subscriptions get more expensive?" Only increases are returned, most recent first. Args: since_days: How far back to look, in days. Defaults to 90. Returns: {"count": int, "totalMonthlyIncrease": float, "increases": [...]}, or an error object.
Output schemas not formally documented. Responses are inferred from code (e.g., list_subscriptions returns {count, subscriptions}, get_spend_summary returns {monthlyTotal, currency, byCategory}). LLMs cannot plan downstream tool calls without explicit schema documentation.
Error responses lack recovery guidance. _error() returns {error: true, message: str} but does not suggest next steps. E.g., 'Invalid action' should say 'Use one of: snooze, resume, downgrade'.
No tool annotations (readOnlyHint/destructiveHint/idempotentHint). snooze_or_downgrade is clearly destructive (WRITE risk), but this is not declared in the tool definition. LLMs cannot reason about side effects or retry safety.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 64 | 2026-07-28+ | v2 |
Summarize total monthly spend with a per-category breakdown. Use this to answer "how much am I spending per month, and on what?"
List subscriptions renewing within the next N days, most urgent first. Use this to answer "what's about to charge me?" Results are sorted so the soonest renewal comes first.
List all tracked subscriptions, optionally filtered by category. Use this to see every subscription the user is paying for. `category` filters to one group, e.g. "streaming", "software", "fitness".
Pause, resume, or downgrade a subscription — the "I don't want to fully cancel" tool. Use this when the user wants to keep a subscription but reduce or pause its cost rather than cancel outright. Args: id: The subscription's ID. action: One of "snooze", "resume", or "downgrade". tier: Required when action is "downgrade" — the new plan tier, e.g. "STANDARD". Returns: The updated subscription, or an error object.
list_subscriptions lacks pagination. If a user has hundreds of subscriptions, the response could exceed context limits. No limit parameter or cursor support.
snooze_or_downgrade name uses 'and' (snooze_or_downgrade), suggesting multiple responsibilities. While the tool is well-designed, consider renaming to update_subscription_status or split into update_subscription_pause and update_subscription_plan for clarity.