A personal finance management application with transaction tracking, budget management, category rules, and WhatsApp integration. Includes bank scraping capabilities and anomaly detection.
Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
Nudlers is a Next.js financial management MCP server with 27 tools spanning accounts, transactions, budgets, cards, and authentication. While tool names follow verb-noun conventions (listAccounts, createOrUpdateBudget, deleteCardVendor), the implementation has significant quality gaps: (1) Parameter schemas are minimally defined, most parameters lack type constraints and enums despite dealing with sensitive financial data. For example, getAnomalies accepts a 'status' string but provides no enum constraint for valid values (open, acknowledged, dismissed, normal) despite documenting them in the description. (2) Parameter descriptions are present but sparse, typically 1-2 sentences with minimal context about format, range, or dependencies. (3) Output schemas are completely undocumented, no visible schema definitions for any tool's return structure, forcing LLMs to guess what fields are returned and making composition risky. (4) Error handling lacks recovery guidance, no documented error codes, retryable status indicators, or self-correction hints. (5) High-risk operations (deleteAllTransactions, clearAllPasskeys) lack confirmation patterns or dry-run support. The average tool scores 48/100, pulled down by missing output schemas (not visible in provided code) and minimal error handling guidance.
Tools (27)
addManualTransactionwrite50/100
Add a manually entered transaction (expense or income)
clearAllPasskeysdestructive50/100
Delete all registered passkeys (requires vault to be unlocked)
createCategorizationRulewrite50/100
Create a categorization rule to automatically assign categories based on transaction name patterns
createCategoryMappingwrite50/100
Create a category mapping to transform one category name to another
createCredentialwrite50/100
Store encrypted credentials for a financial vendor
createOrUpdateBudgetwrite50/100
Create or update a budget limit for a transaction category
createOrUpdateCardVendorwrite50/100
Create or update a card vendor mapping and nickname for a card's last 4 digits
Output schemas completely undocumented. No visible return type definitions for any of the 27 tools. LLMs cannot determine what fields are returned, breaking tool chaining and forcing unnecessary lookup calls.
CRITICAL: Document output schemas for all 27 tools. Define return type with all fields, types, and descriptions. Example: listAccounts should return {accounts: [{id: string, name: string, balance: number, currency: string, type: 'card'|'bank', hidden: boolean}], total: integer}. Use JSON Schema or inline descriptions.
CRITICAL: Add enum constraints to all constrained parameters. For getAnomalies, change status from {type: 'string'} to {type: 'string', enum: ['open', 'acknowledged', 'dismissed', 'normal']}. For getTransactions, add enums for transactionType ('all'|'bank'|'credit_card'), sortBy, sortOrder.
HIGH: Add structured error handling documentation. Define error codes like 'INVALID_STATUS', 'ACCOUNT_NOT_FOUND', 'BUDGET_LIMIT_EXCEEDED' with recovery hints. Example: getAnomalies might return {error: 'INVALID_STATUS', message: 'Status must be one of: open, acknowledged, dismissed, normal', retryable: true}
HIGH: Implement confirmation patterns for destructive operations. deleteAllTransactions and clearAllPasskeys should support a 'dry_run' parameter or require a separate 'confirm_delete' parameter with a confirmation token. Provide recovery info: 'This action is irreversible. Consider exporting data first.'
HIGH: Refactor 'createOrUpdateBudget' and 'createOrUpdateCardVendor' into separate create/update tools. Simplifies naming, reduces ambiguity, and lets agents understand which operation is happening. E.g., createBudget and updateBudget.
HIGH: Enhance parameter descriptions with format, range, and dependencies. Example: For addManualTransaction, change 'date' from 'Transaction date in YYYY-MM-DD format' to 'Transaction date in ISO 8601 format (YYYY-MM-DD, e.g. 2024-01-15). Must be within last 5 years. Cannot be in future.' Add dependency: 'Either provide date OR billingCycle, not both.'
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Score history
Overall score trend
↑ 50 points across a rubric change (v1 → v2)
50/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
D
50
<=2025-11-25
v2
2026-03-09
F
0
-
v1
deleteCardVendor
destructive50/100
Delete a card vendor mapping
deleteCategorizationRuledestructive50/100
Delete a categorization rule by ID
deleteCategoryMappingdestructive50/100
Delete a category mapping by ID
evaluateAnomalieswrite50/100
Manually trigger anomaly detection evaluation and return summary results
getAnomaliesread only50/100
List financial anomalies detected in transactions with severity levels and status filtering
getScrapeEventsread only50/100
Get historical scrape events with status, duration, and error messages
getSettingsread only50/100
Get application settings and configuration values
getTransactionsread only50/100
List transactions with unified filtering by date range, billing cycle, category, vendor, and search query
listAccountsread only50/100
Get all financial accounts (cards and linked bank accounts) with their balances and metadata
listBudgetsread only50/100
Get all budget limits set per transaction category
listCardOwnershipsread only50/100
Get card ownership records linking cards to credentials and bank accounts
listCardsread only50/100
Get all unique credit/debit cards with transaction counts and bank account linking information
listCategoriesread only50/100
Get all transaction categories with optional transaction counts
listCategorizationRulesread only50/100
Get all transaction name pattern rules for automatic categorization
listCategoryMappingsread only50/100
Get all category mappings that transform source categories to target categories
listCredentialsread only50/100
Get all stored credentials for financial vendors without returning sensitive data
listPasskeysread only50/100
Get all registered passkeys for passwordless authentication
Parameter schemas lack type constraints and enums. For example, getAnomalies documents 'status' can be open, acknowledged, dismissed, or normal, but the schema defines it as a bare string with no enum. createCategorizationRule's 'name_pattern' lacks format/length documentation. This invites LLM hallucination and invalid API calls.
Destructive operations lack confirmation or dry-run patterns. deleteAllTransactions and clearAllPasskeys have no confirmation step, dry-run option, or recovery guidance. An agent mistake leads to permanent data loss with no undo path.
Error handling provides no recovery guidance. No documented error codes, retryable indicators, or self-correction hints. An LLM facing an error has no path forward, cannot distinguish 'retry this' from 'ask the user' from 'unrecoverable'.
Parameter descriptions are minimal and lack actionable constraints. Most describe WHAT the parameter is but not FORMAT, RANGE, or DEPENDENCIES. Example: 'Additional notes' for addManualTransaction's 'notes' param, no character limit, format, or relationship to 'memo' documented.
createCredential parameter 'password' is documented as encrypted but still appears in the tool schema. Even though marked 'never returned to client', storing passwords as parameters risks logging and audit trail exposure. Should use server-side secret injection instead.
List tools (listAccounts, listCards, listCategories, getTransactions) lack documented pagination parameters. Without limit/offset constraints and total counts, LLMs cannot handle large result sets safely, may retrieve thousands of records and blow context window.
Tool names ambiguity: 'createOrUpdateBudget' violates single-responsibility principle. Also, tools like 'listCategories' and 'listCategoryMappings' are similar names that could confuse LLM selection logic, no clear distinction between list categories vs. list category mappings vs. list categorization rules.
Tools dealing with financial data (accounts, transactions, credentials) provide minimal guidance on sensitive data handling and access control. No documented permission scopes, audit trails, or data masking hints in tool descriptions.
HIGH: Remove sensitive parameters from tool definitions. For createCredential, move password, id_number, and card6_digits to server-side environment variables or vault. Accept only vendor and username from the LLM; retrieve secrets from secure storage. Add tool description: 'Sensitive credentials are stored encrypted server-side and never exposed.'
MEDIUM: Document pagination for all list tools. Add parameters: limit (1-100, default 20), offset (default 0). Return response structure: {items: [...], total: integer, limit: integer, offset: integer, has_more: boolean}. Example for listAccounts: 'Returns paginated list of up to 20 accounts. Use offset to retrieve next page.'
MEDIUM: Add permission scope hints to tool descriptions. Example for listCredentials: 'Requires read:credentials permission. Does not return passwords or sensitive fields.' For deleteAllTransactions: 'Requires admin:transactions permission. Irreversible operation, consider export before deletion.'
MEDIUM: Clarify tool overlaps and composition. Document when to use listCategories vs. listCategoryMappings vs. listCategorizationRules. Example: 'Use listCategories to see available transaction categories. Use listCategoryMappings to see source→target transformations. Use listCategorizationRules to see regex patterns that auto-assign categories.'
MEDIUM: Add rich error examples to descriptions. For createCategorizationRule, add: 'If name_pattern is invalid regex, returns error with the invalid pattern highlighted and suggestions for fixing it. E.g., pattern '[invalid' fails; try '[a-z]' instead.'
MEDIUM: Document default behavior for optional parameters. Example for getTransactions: 'If neither startDate nor billingCycle is provided, defaults to current month. If both are provided, startDate takes precedence.'
MEDIUM: Add idempotency hints. For updateCategorizationRule and updateSettings, confirm these are safe to retry. For addManualTransaction, specify: 'Idempotent: calling with same data twice creates one transaction, not two. Uses transaction hash or client-provided idempotency_key.'
LOW: Unify parameter naming style. Some tools use snake_case (card_vendor, last4_digits, target_category) while others use camelCase (category, vendor, budget_limit). Standardize to snake_case for consistency.
LOW: Add examples or non-example clarifications. Instead of 'Card vendor name (required)', use 'Card vendor name, e.g. Visa, Mastercard, Amex. Do NOT include 'The' or descriptors.' to prevent LLM hallucination of invalid vendor names.