Help us improve
Share bugs, ideas, or general feedback.
From cashflow
Triggered by "tidy up", "clean up transactions", "categorize uncategorized", "organize my transactions"
npx claudepluginhub davepoon/buildwithclaude --plugin cashflowHow this skill is triggered — by the user, by Claude, or both
Slash command
/cashflow:tidyThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Incrementally clean up uncategorized and miscategorized transactions. Designed to run many times — each run makes a small dent (~10 items per phase).
Categorizes uncategorized bank transactions, matches payments to invoices, verifies bookkeeping entries for freelance or SME accounts via Norman Finance APIs. Use for reconciling accounts or expense categorization.
Auto-categorizes uncategorized financial transactions using vendor/description pattern matching. Applies existing rules, groups unmatched by similarity, suggests categories, and offers spreadsheet formula alternatives.
Categorizes financial transactions by matching raw descriptions against configurable taxonomies and rules, with LLM fallback. Emits merchant, category path, recurring flag, and confidence score. Use for bank, credit-card, or brokerage transaction classification.
Share bugs, ideas, or general feedback.
Incrementally clean up uncategorized and miscategorized transactions. Designed to run many times — each run makes a small dent (~10 items per phase).
Only the cashflow MCP tools are required. Every other data source (email, browser) is opportunistic — attempt each, use what's available, skip gracefully if unavailable.
When you can't identify a merchant from the description alone, try these in order. Stop as soon as one works.
General knowledge — start here, it's free:
Web searches (if available) — cheap, no subagent needed: 2. Web search the cleaned/display name (e.g. "Tock Inc") 3. Web search the raw description — processor codes, location info, or abbreviations often reveal more 4. Web search any phone numbers or domain names embedded in the raw description — highly specific identifiers
Email searches (if available) — search in the main agent, read in a subagent: 5. Email search the exact dollar amount including cents (e.g. "$47.23", not "$47") with a date range near the transaction date. Receipts almost always include the exact amount. 6. Email search the cleaned merchant name with a date range near the transaction date
If a promising email result comes back, use a subagent (Agent tool) to read the full message and extract just: merchant name, what was purchased, amount. Order confirmation emails are extremely verbose — never read them in the main context.
Last resort: 7. Ask the user — show the transaction details and ask what it is
This skill is designed to run repeatedly. On subsequent runs:
admin { "entity": "rule", "action": "list" } and compare party names). Focus on parties without rule coverage.Use the period from $ARGUMENTS (e.g. "this month", "last 30 days"), or last_90d as default.
Start with the highest-value uncategorized transactions — they have the most impact on accuracy.
Fetch top 10 uncategorized expenses by amount:
query { "detail": true, "is_uncategorized": true, "type": "expense", "period": "<period>", "limit": 10, "sort": "-amount" }
Research each transaction using the merchant research steps above. For each, determine:
Present findings as a batch. Show a table with: description, amount, date, proposed party name, proposed category, and confidence level. Ask: "Any corrections before I apply these?"
Apply fixes:
admin { "entity": "rule", "action": "preview", "conditions": { "description_pattern": "<pattern>" }, "actions": { "category_name": "<category>", "party_name": "<party>" } }
Show match count, then create if confirmed. After creating rules, apply them retroactively:
annotate { "action": "apply_rules", "rule_ids": ["<new-rule-id-1>", "<new-rule-id-2>"] }
start/end to scope to the tidy period)
annotate { "action": "categorize", "filter": { "search": "<pattern>", "start": "<period-start>", "end": "<period-end>" }, "category_name": "<category>" }
annotate { "action": "set_party", "filter": { "search": "<pattern>", "start": "<period-start>", "end": "<period-end>" }, "party_name": "<party>" }
Review the most populated expense categories for miscategorized or messy transactions.
Fetch top 10 expense categories by amount:
query { "by": ["category"], "type": "expense", "period": "<period>", "top": 10 }
For each category, fetch top parties:
query { "by": ["party"], "type": "expense", "category": "<category_name>", "period": "<period>", "top": 10 }
Scan for issues in each category:
Present findings as a batch. Show what you found: which parties look miscategorized, which names need cleanup, which are unidentifiable. Ask: "Any corrections before I apply these?"
Apply fixes:
set_party to fix the canonical nameUse the built-in cluster detection to consolidate duplicate merchant names.
Fetch top 10 clusters:
query { "clusters": true, "top": 10 }
Clusters group variant spellings/truncations of the same merchant. Focus on clusters where variants are clearly the same merchant — skip clusters where variants are different businesses.
For each actionable cluster:
Present findings as a batch. For each cluster show: proposed canonical name, variant names, count, suggested category. Ask: "Any corrections before I apply these?"
Preview and create rules for confirmed clusters:
admin { "entity": "rule", "action": "preview", "conditions": { "description_pattern": "<pattern>" }, "actions": { "category_name": "<category>", "party_name": "<canonical_name>" } }
Show match count, then create if confirmed. After creating rules, apply them retroactively:
annotate { "action": "apply_rules", "rule_ids": ["<new-rule-id-1>", "<new-rule-id-2>"] }
Summarize what was done: transactions categorized, rules created, party names cleaned up, clusters consolidated.
Report remaining work:
query { "detail": true, "is_uncategorized": true, "period": "<period>", "limit": 1 }
Report the remaining uncategorized count from the response metadata. If there's more to do, suggest running /tidy again.
Stick to the facts. Present findings and suggestions without judgement — no commentary on spending habits. Just clear, plain-language observations and actionable options.