An MCP server for tracking and managing expenses with SQLite database storage
ExpenseTracker is a minimal STDIO-only MCP server with 2 tools. While the tools are registered via FastMCP decorators and have basic input schemas visible, the implementation has significant quality gaps: (1) Tool descriptions are missing entirely, neither add_expense nor list_expenses have descriptions in the decorator calls, preventing LLMs from understanding when or why to select them; (2) Parameter descriptions exist in the schema JSON but are minimal (e.g., 'The date of the expense' is only 26 chars, below the 50-200 char LLM-optimized range); (3) No output schema documentation, responses are returned as plain dicts with no structured documentation of fields; (4) No error handling or recovery guidance, if date parsing fails or DB operations error, the LLM receives no actionable feedback; (5) No input validation, the date parameter accepts any string with no format specification; (6) Security: SQL injection risk is mitigated by parameterized queries (good), but no rate limiting or permission gating; (7) The add_expense tool is a WRITE operation with no confirmation/dry-run pattern, increasing risk of accidental expense creation.
Missing tool descriptions, neither add_expense nor list_expenses have description fields in the @mcp.tool() decorators. LLMs cannot determine when to select these tools without explicit descriptions.
No output schema documentation. Tools return plain dicts (e.g., {'status': 'ok', 'id': cur.lastrowid} for add_expense and a list of dicts for list_expenses) with no formal schema declaration or description of return fields. LLMs cannot confidently parse or chain these responses.
No input validation or error handling. The 'date' parameter accepts any string with no format constraint (ISO 8601 not enforced). Invalid inputs (non-numeric amount, invalid dates) will cause unhandled SQLite errors with no recovery guidance for the LLM.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | F | 37 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 33 | - | v1 |
No pagination support on list_expenses. If the expenses table grows large (100+ entries), the entire list is returned, wasting tokens and potentially hitting context window limits. No limit parameter or cursor-based pagination.
Destructive write operation (add_expense) lacks confirmation/dry-run pattern. Agents can accidentally create duplicate or incorrect expenses with no recovery mechanism.
Parameter descriptions are minimal (26 - 28 chars), well below the 50 - 200 char LLM-optimized range. E.g., 'The date of the expense' provides no format specification or examples. 'The expense amount' does not specify units, decimal places, or range constraints.
No rate limiting or permission gating. An agent could call add_expense in a loop and generate hundreds of duplicate entries. No access control verifies authorization.