An MCP server for managing expense tracking with SQLite database backend, supporting adding expenses, listing expenses by date range, and summarizing expenses by category.
Server implements 3 well-structured tools with async/await patterns and proper error handling. All tools have schemas with type definitions and descriptions. However, schemas lack output documentation, parameter descriptions are minimal (below ideal 72-char baseline), and tools lack idempotency/confirmation patterns for destructive operations. Tool naming is clear (add_expense, list_expenses, summarize) and action-oriented. The server uses FastMCP and aiosqlite for async database access, showing modern implementation practices. Main gaps: no output schema documentation, no tool annotations (readOnlyHint/destructiveHint), limited error guidance, and missing validation constraints (e.g., date format, amount range).
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 are not documented. LLMs cannot determine response structure without seeing what fields to expect.
Parameter descriptions lack format, range, and constraint specifications. 'Date of the expense entry' does not specify ISO 8601 format; 'Amount of the expense' does not state numeric range or decimal precision.
Destructive operation (add_expense) lacks confirmation or dry-run pattern. No idempotent marker in tool annotation. Agents cannot safely retry on ambiguous failures without risking duplicate expenses.
Error handling returns generic error messages without actionable recovery guidance. E.g., 'Database error: ...' gives LLM no indication of whether to retry, ask the user, or fail gracefully.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | B | 74 | 2026-07-28+ | v2 |
| 2026-03-09 | F | 44 | - | v1 |
Tool descriptions are 68-75 characters, below the 194-char production baseline and too brief to include dependency hints or selection criteria. LLMs cannot reliably choose between similar tools (e.g., list_expenses vs summarize) without richer context.
No pagination support in list_expenses. Tool does not accept limit/offset or return total_count, risking context window overflow if expense list grows large.
Tool annotations missing. add_expense should declare destructiveHint=true; list_expenses and summarize should declare readOnlyHint=true. This helps LLMs make safer decisions about tool ordering and parallelization.
Database path stored in temp directory by default (tempfile.gettempdir()). On cloud deployments with ephemeral filesystems, data will be lost on restart. Documentation warns users but does not prevent accidental data loss.