An MCP server for managing and tracking expenses with SQLite database backend
ExpenseTracker presents a STDIO-only server with basic but incomplete tool definitions. All three tools (add_expense, list_expenses, summarize) have names that start with action verbs and are appropriately structured. However, several critical gaps significantly impact quality: (1) Output schemas are completely undocumented, the code returns dicts/lists but the tool descriptions never specify what fields clients should expect; (2) Parameter descriptions are minimal (10-15 chars on average) and lack format/constraint guidance, 'Date of the expense' tells an LLM nothing about required format (YYYY-MM-DD? ISO 8601?); (3) No error handling guidance, tools return raw SQLite errors or dict status without actionable recovery steps; (4) Missing idempotency guidance for the write operation (add_expense); (5) No documentation of data loss risks or confirmation patterns. The server is functionally complete for its domain but falls well short of production quality standards. Average per-tool score: 52.
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.
Output schemas completely undocumented. Code shows add_expense returns {status, id}, list_expenses returns array of {id, date, amount, category, subcategory, note}, and summarize returns array of {category, total_amount}. LLMs cannot plan downstream tool calls or extract correct fields without documented return types.
Date parameter format undefined. 'Date of the expense' lacks any specification of accepted format (YYYY-MM-DD? ISO 8601? Epoch?). SQLite BETWEEN query suggests string comparison, implying YYYY-MM-DD, but LLMs cannot infer this. This invites format mismatch errors.
No error handling guidance. If date format is invalid, the tool will throw a SQLite error. No recovery hint tells the LLM what to do (retry with corrected format? ask user?). Responses should be 'Invalid date format: expected YYYY-MM-DD' with clear guidance.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 39 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 42 | - | v1 |
add_expense lacks idempotency guidance and confirmation pattern. It modifies state (INSERT) with no mention of retry behavior or undo capability. If an agent retries on a transient error, a duplicate expense is created. For financial data, this is a critical issue.
Parameter descriptions are too brief (10-15 chars). 'Amount of the expense' and 'Category of the expense' fail the 20-char minimum. They provide no constraint info (amount range? negative allowed? category enum?). Should be: 'Amount in USD, positive number (required). E.g. 25.50 for a $25.50 expense. Negative values rejected.'
list_expenses and summarize accept open date ranges with no bounds checking. An agent could pass start_date='1900-01-01' and end_date='2099-12-31', triggering a massive full-table scan and timeout. The tool should document reasonable limits and validate inputs.
list_expenses and summarize have no pagination. If there are 10,000 expenses, both tools return all rows, bloating the context window and risking timeout. The rubric requires page/offset + limit parameters and a total count.
No field mapping guidance. If the LLM wants to filter list_expenses by category, it has no tool, it must call list_expenses for the entire range and parse the response manually. A 'filter_expenses' tool or category parameter on list_expenses would improve composability.