MCP server for expense tracking with SQLite backend. Provides tools for managing expense categories and expenses with search, filtering, and analytics capabilities.
18 tools with complete schemas and descriptions, but quality is uneven. Most tools have adequate naming (verb_noun pattern) and descriptions (50-200 chars), but parameter descriptions are sparse or missing context. Output schemas are not documented. Error handling is minimal, most tools return bare dicts without recovery guidance. No tool annotations (readOnlyHint/destructiveHint). Date/category parsing is sophisticated but undocumented in tool descriptions, forcing LLMs to guess at accepted formats. Composition is sound (single responsibility per tool), but chaining metadata (e.g., category_id in expense responses) is inconsistent.
Create a new expense category. Fails if the name already exists.
Record a new expense. date : 'today', 'yesterday', or a date like 2026-07-15 / 15-Jul. description : short free text, e.g. 'Lunch'. amount : amount in US dollars. category_id : id from list_categories / find_category.
Return today's date in ISO format (YYYY-MM-DD).
Delete a category. Refuses if expenses are still linked to it.
Delete an expense by id.
List expenses between two dates (inclusive). Accepts 'today', 'yesterday', dates like 2026-07-15, or relative dates like '30 days ago'.
No output schemas documented. Tools return dicts but LLMs cannot see field names, types, or structure. Downstream tool chaining is error-prone.
Date/category parsing accepts multiple formats ('today', 'yesterday', '2026-07-15', '15-Jul', '30 days ago') but tool descriptions do not document these. LLMs must guess or fail.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). LLMs cannot distinguish safe reads from destructive writes without reading descriptions.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | D | 57 | <=2025-11-25 | v2 |
List all expenses in a given category (case-insensitive name match).
Find a category by name (case-insensitive exact match first, then LIKE match).
Get the name of a category from its id.
Get a single expense by id.
List every expense category with its id and name.
List expenses, newest first, with optional limit.
Sum of expenses for a given month. Accepts 'this month', 'last month', 'July', 'July 2026', '2026-07', or None (defaults to current month).
Rename the category with the given id.
Search expenses by description text (case-insensitive substring match).
Sum of all expenses across all categories.
Sum of all expenses in a given category.
Update an existing expense. Only the fields you pass are changed.
Error handling is minimal. Tools return bare {'ok': False, 'error': '...'} dicts without recovery guidance. LLMs cannot determine if errors are retryable or user-fixable.
Parameter descriptions lack format/constraint details. 'amount' is 'number' but no min/max. 'category_id' is 'integer' but no guidance on valid range or how to discover valid IDs.