Track, list, update, and summarize personal expenses backed by Neon PostgreSQL. Supports multiple users with complete data isolation using user_id or API keys.
Server has 6 well-named tools with complete input schemas and descriptions. Naming follows verb_noun convention (add_expense, list_expenses, etc.). All tools have docstrings and parameter descriptions. However, descriptions contain example values (e.g., 'e.g. 12.50', 'e.g. "Food"') which LLMs tend to reuse literally. Output schemas are not formally documented, responses are inferred from code. Error handling is basic (ValueError exceptions) without recovery guidance. No tool annotations (readOnlyHint, destructiveHint) despite clear risk levels. Parameter validation exists but error messages could be more actionable.
Add a new expense record for a specific user. amount: positive number, e.g. 12.50 category: short label, e.g. "Food", "Transport", "Rent" description: optional note expense_date: optional date in YYYY-MM-DD format (defaults to today) user_id: optional user identifier (e.g. "alice", "bob", "[email protected]") to keep data separate api_key: optional API key (et_...) to scope to a specific user
Permanently delete an expense for a specific user. expense_id: UUID of the expense to delete user_id: optional user identifier who owns this expense
Summarize spending with totals and per-category breakdown for a specific user. period: one of "week", "month", "year", "all" (default "month") user_id: optional user identifier (e.g. "alice", "bob") to summarize only that person's spending
List all distinct expense categories recorded so far by a specific user. user_id: optional user identifier
List expenses for a specific user, sorted by date descending. category: optional category filter, e.g. "Food" start_date / end_date: optional YYYY-MM-DD range filters (inclusive) limit: maximum number of rows to return (default 50) user_id: optional user identifier (e.g. "alice", "bob") to view only that person's expenses api_key: optional API key (et_...) to scope to a specific user
Example values embedded in descriptions (e.g., 'e.g. 12.50', 'e.g. "Food"'). LLMs reuse examples literally instead of adapting to context.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite clear risk levels (WRITE, DESTRUCTIVE, READ_ONLY). Agents cannot infer safety properties.
Output schemas not formally documented. Responses inferred from code (e.g., {status, expense}, {user_id, count, expenses}). LLMs cannot plan downstream calls without explicit schema.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | <=2025-11-25 | v2 |
Update one or more fields of an existing expense for a specific user. expense_id: UUID of the expense to update user_id: optional user identifier who owns this expense Only provide the fields you want to change.
Error messages lack recovery guidance. ValueError('Expense not found...') tells agent nothing about next steps. Should suggest 'Try list_expenses() to find valid IDs.'
API key exposed as tool parameter. Credentials should use server-side injection via environment variables, not passed in every call. Risks leaking secrets into logs.