A local MCP server for managing and tracking expenses with SQLite database storage
ExpenseTracker has 3 tools with adequate but not production-grade definitions. All tools have descriptions (10-50 chars, below the 194-char average), full input schemas with types, and clear READ/WRITE semantics. However, descriptions lack depth, they state WHAT but not WHEN, WHY, or common failure modes. Parameter descriptions are present but minimal (8-30 chars, well below the 72-char average). No output schema documentation. No error handling guidance. No parameter enums despite category/subcategory accepting freeform strings (inviting invalid values). Date parameters lack format specification (ISO 8601 assumed but not stated). The add_expense tool description does not explicitly state it modifies state, violating the command-tool pattern. list_expenses and summarize accept date ranges but lack pagination/limit parameters despite potentially returning large result sets. No per-tool output schema documented for response structure. The server follows verb_noun naming correctly but lacks sophistication in parameter validation and LLM guidance.
Add a new expense entry to the database.
List expense entries within an inclusive date range.
Summarize expenses by category within an inclusive date range.
Minimal parameter descriptions (8 - 30 chars, averaging 18 vs. 72-char baseline). Parameters like 'date', 'amount', 'category' lack format, range, or validation hints. LLMs cannot infer that 'date' expects ISO 8601 or that 'amount' must be positive.
Tool descriptions too brief (10 - 50 chars vs. 194-char average). Lack WHEN to call, prerequisites, and state mutation hints. 'Add a new expense entry' does not signal WRITE side effect or irreversibility; LLMs may not realize retry risk.
No output schema documented. Callers do not know the structure of list_expenses (returns array of objects with id, date, amount, category, subcategory, note) or summarize (category, total_amount). LLMs must infer output shape, risking field name mismatches in downstream calls.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 48 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 35 | - | v1 |
No enumeration on category/subcategory parameters. Both accept freeform strings, inviting hallucinated or typo'd categories. A CATEGORIES_PATH file exists (visible in code) but is not exposed as a schema constraint or discovery mechanism.
No date format specification. Parameters 'date', 'start_date', 'end_date' are untyped strings without ISO 8601 or other format hints. LLMs frequently misformat dates (YYYY-MM-DD vs MM/DD/YYYY vs others), causing silent query failures.
list_expenses and summarize lack pagination or result limits. SQLite queries return all matching rows. A large date range could return thousands of rows, exhausting context and degrading LLM reasoning. No offset/limit params or cursor-based pagination.
No error handling guidance. Code silently fails on invalid dates or database errors. LLM receives raw exceptions (e.g. SQLite constraint errors) with no actionable recovery hint. add_expense should validate amount > 0; list_expenses should validate date range logic.
add_expense does not document that it modifies state (INSERT). Description should explicitly say 'Creates a permanent expense record' so LLMs understand retry risk and idempotency concerns.
Parameter 'amount' has no range or type validation hint. Schema shows type 'number' but no minimum (must be > 0) or maximum. LLMs could pass negative, zero, or absurdly large amounts.
No confirmation pattern for add_expense (irreversible operation). If an LLM misunderstands context and creates 50 duplicate entries, the tool returns success each time. Consider a dry-run or confirmation step.