← WebMCP Directory

Tool tree

pineapplesour.github.io

Finance & CryptoTools verified
Website
Drop a bank or card statement into the tab. Nothing uploads. A WebMCP agent analyses it in place, and you watch every tool call it makes.
Explore capabilities
    get_overviewAnswer

    Start here. Returns what is loaded (files, row count, date range, accounts, currencies), the money totals, how much of the data is still uncategorised, any budgets, what the person is currently looking at on screen, and the page's egress meter showing how many bytes have left the browser.

    View tool JSON
    {
      "name": "get_overview",
      "kind": "answer",
      "impl": "imperative",
      "description": "Start here. Returns what is loaded (files, row count, date range, accounts, currencies), the money totals, how much of the data is still uncategorised, any budgets, what the person is currently looking at on screen, and the page's egress meter showing how many bytes have left the browser.",
      "inputSchema": {
        "type": "object",
        "properties": {}
      },
      "page": "/tallyroom/"
    }
    query_transactionsAnswer

    Return individual transactions matching a filter, newest first by default, together with the totals for the whole matching set. Use this when you need to look at specific rows. The row list is capped (default 50, maximum 500) but the totals always cover every match, so prefer summarize_spending when you only need a number.

    View tool JSON
    {
      "name": "query_transactions",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return individual transactions matching a filter, newest first by default, together with the totals for the whole matching set. Use this when you need to look at specific rows. The row list is capped (default 50, maximum 500) but the totals always cover every match, so prefer summarize_spending when you only need a number.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Only include transactions on or after this date (YYYY-MM-DD)."
          },
          "to": {
            "type": "string",
            "description": "Only include transactions on or before this date (YYYY-MM-DD)."
          },
          "category": {
            "type": "string",
            "description": "Restrict to one category. Use 'Uncategorised' for rows with no category yet."
          },
          "account": {
            "type": "string",
            "description": "Restrict to accounts whose name contains this text."
          },
          "merchant": {
            "type": "string",
            "description": "Restrict to a merchant. Matching is fuzzy, so 'starbucks' catches every branch and spelling."
          },
          "search": {
            "type": "string",
            "description": "Free-text match against the transaction description."
          },
          "flow": {
            "type": "string",
            "enum": [
              "all",
              "spend",
              "income"
            ],
            "description": "Which side of the ledger to include. Defaults to all."
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum absolute amount."
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum absolute amount."
          },
          "sort": {
            "type": "string",
            "enum": [
              "date-desc",
              "date-asc",
              "amount-desc",
              "amount-asc"
            ],
            "description": "Row ordering. Defaults to date-desc."
          },
          "limit": {
            "type": "number",
            "description": "How many rows to return, 1-500. Defaults to 50."
          }
        }
      },
      "page": "/tallyroom/"
    }
    summarize_spendingAnswer

    Group the transactions and total each group - by category, merchant, month, account or day. This is the cheap way to answer almost any 'how much' question; it reads every matching row but returns only the groups.

    View tool JSON
    {
      "name": "summarize_spending",
      "kind": "answer",
      "impl": "imperative",
      "description": "Group the transactions and total each group - by category, merchant, month, account or day. This is the cheap way to answer almost any 'how much' question; it reads every matching row but returns only the groups.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Only include transactions on or after this date (YYYY-MM-DD)."
          },
          "to": {
            "type": "string",
            "description": "Only include transactions on or before this date (YYYY-MM-DD)."
          },
          "category": {
            "type": "string",
            "description": "Restrict to one category. Use 'Uncategorised' for rows with no category yet."
          },
          "account": {
            "type": "string",
            "description": "Restrict to accounts whose name contains this text."
          },
          "merchant": {
            "type": "string",
            "description": "Restrict to a merchant. Matching is fuzzy, so 'starbucks' catches every branch and spelling."
          },
          "search": {
            "type": "string",
            "description": "Free-text match against the transaction description."
          },
          "flow": {
            "type": "string",
            "enum": [
              "all",
              "spend",
              "income"
            ],
            "description": "Which side of the ledger to include. Defaults to all."
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum absolute amount."
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum absolute amount."
          },
          "groupBy": {
            "type": "string",
            "enum": [
              "category",
              "merchant",
              "month",
              "account",
              "day"
            ],
            "description": "What to group by. Defaults to category."
          },
          "top": {
            "type": "number",
            "description": "Keep only the largest N groups and fold the rest into 'Other'."
          }
        }
      },
      "page": "/tallyroom/"
    }
    get_trendAnswer

    Return a month-by-month series, optionally for one category or merchant, so you can talk about whether something is going up or down rather than just its total.

    View tool JSON
    {
      "name": "get_trend",
      "kind": "answer",
      "impl": "imperative",
      "description": "Return a month-by-month series, optionally for one category or merchant, so you can talk about whether something is going up or down rather than just its total.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Only include transactions on or after this date (YYYY-MM-DD)."
          },
          "to": {
            "type": "string",
            "description": "Only include transactions on or before this date (YYYY-MM-DD)."
          },
          "category": {
            "type": "string",
            "description": "Restrict to one category. Use 'Uncategorised' for rows with no category yet."
          },
          "account": {
            "type": "string",
            "description": "Restrict to accounts whose name contains this text."
          },
          "merchant": {
            "type": "string",
            "description": "Restrict to a merchant. Matching is fuzzy, so 'starbucks' catches every branch and spelling."
          },
          "search": {
            "type": "string",
            "description": "Free-text match against the transaction description."
          },
          "flow": {
            "type": "string",
            "enum": [
              "all",
              "spend",
              "income"
            ],
            "description": "Which side of the ledger to include. Defaults to all."
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum absolute amount."
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum absolute amount."
          },
          "groupBy": {
            "type": "string",
            "enum": [
              "category",
              "merchant",
              "account"
            ],
            "description": "Which dimension `value` refers to. Defaults to category."
          },
          "value": {
            "type": "string",
            "description": "The single category, merchant or account to chart. Omit for everything."
          }
        }
      },
      "page": "/tallyroom/"
    }
    list_merchantsAnswer

    Group the raw description strings into merchants, collapsing branch names, card reference numbers and spelling variants. Ask for onlyUncategorised to get exactly the work that still needs deciding: a few dozen clusters instead of a thousand rows. This is the right input to propose_categories.

    View tool JSON
    {
      "name": "list_merchants",
      "kind": "answer",
      "impl": "imperative",
      "description": "Group the raw description strings into merchants, collapsing branch names, card reference numbers and spelling variants. Ask for onlyUncategorised to get exactly the work that still needs deciding: a few dozen clusters instead of a thousand rows. This is the right input to propose_categories.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Only include transactions on or after this date (YYYY-MM-DD)."
          },
          "to": {
            "type": "string",
            "description": "Only include transactions on or before this date (YYYY-MM-DD)."
          },
          "category": {
            "type": "string",
            "description": "Restrict to one category. Use 'Uncategorised' for rows with no category yet."
          },
          "account": {
            "type": "string",
            "description": "Restrict to accounts whose name contains this text."
          },
          "merchant": {
            "type": "string",
            "description": "Restrict to a merchant. Matching is fuzzy, so 'starbucks' catches every branch and spelling."
          },
          "search": {
            "type": "string",
            "description": "Free-text match against the transaction description."
          },
          "flow": {
            "type": "string",
            "enum": [
              "all",
              "spend",
              "income"
            ],
            "description": "Which side of the ledger to include. Defaults to all."
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum absolute amount."
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum absolute amount."
          },
          "onlyUncategorised": {
            "type": "boolean",
            "description": "Only clusters that have no category yet. Defaults to false."
          },
          "limit": {
            "type": "number",
            "description": "How many clusters to return, largest spend first. Defaults to 60."
          }
        }
      },
      "page": "/tallyroom/"
    }
    find_recurringAnswer

    Detect charges that repeat on a schedule - subscriptions, rent, memberships - by clustering merchants and testing the gaps between charges for weekly, monthly, quarterly or yearly regularity. Reports the typical amount, the annualised cost, and any price change between the early and recent charges, which is how a quiet price rise gets caught.

    View tool JSON
    {
      "name": "find_recurring",
      "kind": "answer",
      "impl": "imperative",
      "description": "Detect charges that repeat on a schedule - subscriptions, rent, memberships - by clustering merchants and testing the gaps between charges for weekly, monthly, quarterly or yearly regularity. Reports the typical amount, the annualised cost, and any price change between the early and recent charges, which is how a quiet price rise gets caught.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "minOccurrences": {
            "type": "number",
            "description": "How many charges before something counts as recurring. Defaults to 3."
          }
        }
      },
      "page": "/tallyroom/"
    }
    find_anomaliesAnswer

    Flag transactions worth a second look: charges far outside the normal range for that same merchant (scored against the median and MAD, so one big charge cannot hide another), the same amount billed twice within two days, and unusually large one-off payments at merchants with no history.

    View tool JSON
    {
      "name": "find_anomalies",
      "kind": "answer",
      "impl": "imperative",
      "description": "Flag transactions worth a second look: charges far outside the normal range for that same merchant (scored against the median and MAD, so one big charge cannot hide another), the same amount billed twice within two days, and unusually large one-off payments at merchants with no history.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Only include transactions on or after this date (YYYY-MM-DD)."
          },
          "to": {
            "type": "string",
            "description": "Only include transactions on or before this date (YYYY-MM-DD)."
          },
          "category": {
            "type": "string",
            "description": "Restrict to one category. Use 'Uncategorised' for rows with no category yet."
          },
          "account": {
            "type": "string",
            "description": "Restrict to accounts whose name contains this text."
          },
          "merchant": {
            "type": "string",
            "description": "Restrict to a merchant. Matching is fuzzy, so 'starbucks' catches every branch and spelling."
          },
          "search": {
            "type": "string",
            "description": "Free-text match against the transaction description."
          },
          "flow": {
            "type": "string",
            "enum": [
              "all",
              "spend",
              "income"
            ],
            "description": "Which side of the ledger to include. Defaults to all."
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum absolute amount."
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum absolute amount."
          },
          "sensitivity": {
            "type": "number",
            "description": "Robust z-score threshold for outliers. Lower finds more. Defaults to 3.5."
          }
        }
      },
      "page": "/tallyroom/"
    }
    check_budgetsAnswer

    Compare each category's monthly budget against what was actually spent, month by month, and report which months went over. Returns nothing useful until budgets exist - use set_budget first.

    View tool JSON
    {
      "name": "check_budgets",
      "kind": "answer",
      "impl": "imperative",
      "description": "Compare each category's monthly budget against what was actually spent, month by month, and report which months went over. Returns nothing useful until budgets exist - use set_budget first.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "description": "Restrict to one month (YYYY-MM). Omit for every month."
          }
        }
      },
      "page": "/tallyroom/"
    }
    load_sample_dataAction

    Load the synthetic twelve-month statement that ships with this app, so the tools have something to work on. Entirely invented data - no real person's finances. Use this when nothing is loaded and you want to demonstrate the app.

    View tool JSON
    {
      "name": "load_sample_data",
      "kind": "act",
      "impl": "imperative",
      "description": "Load the synthetic twelve-month statement that ships with this app, so the tools have something to work on. Entirely invented data - no real person's finances. Use this when nothing is loaded and you want to demonstrate the app.",
      "inputSchema": {
        "type": "object",
        "properties": {}
      },
      "page": "/tallyroom/"
    }
    focus_viewAction

    Drive the page the person is looking at: filter the table, change the sort or the chart grouping, highlight specific transactions, and leave a short message above the table explaining what you did. Use this constantly - it is what makes the conversation and the screen agree with each other. It only changes the view, never the data.

    View tool JSON
    {
      "name": "focus_view",
      "kind": "act",
      "impl": "imperative",
      "description": "Drive the page the person is looking at: filter the table, change the sort or the chart grouping, highlight specific transactions, and leave a short message above the table explaining what you did. Use this constantly - it is what makes the conversation and the screen agree with each other. It only changes the view, never the data.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "from": {
            "type": "string",
            "description": "Only include transactions on or after this date (YYYY-MM-DD)."
          },
          "to": {
            "type": "string",
            "description": "Only include transactions on or before this date (YYYY-MM-DD)."
          },
          "category": {
            "type": "string",
            "description": "Restrict to one category. Use 'Uncategorised' for rows with no category yet."
          },
          "account": {
            "type": "string",
            "description": "Restrict to accounts whose name contains this text."
          },
          "merchant": {
            "type": "string",
            "description": "Restrict to a merchant. Matching is fuzzy, so 'starbucks' catches every branch and spelling."
          },
          "search": {
            "type": "string",
            "description": "Free-text match against the transaction description."
          },
          "flow": {
            "type": "string",
            "enum": [
              "all",
              "spend",
              "income"
            ],
            "description": "Which side of the ledger to include. Defaults to all."
          },
          "minAmount": {
            "type": "number",
            "description": "Minimum absolute amount."
          },
          "maxAmount": {
            "type": "number",
            "description": "Maximum absolute amount."
          },
          "sort": {
            "type": "string",
            "enum": [
              "date-desc",
              "date-asc",
              "amount-desc",
              "amount-asc"
            ],
            "description": "How to order the table."
          },
          "groupBy": {
            "type": "string",
            "enum": [
              "category",
              "merchant",
              "month",
              "account"
            ],
            "description": "What the chart groups by."
          },
          "highlightIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Transaction ids to mark in the table."
          },
          "message": {
            "type": "string",
            "description": "A short line shown above the table, e.g. 'These are the three charges I think are duplicates.'"
          },
          "reset": {
            "type": "boolean",
            "description": "Clear every filter first."
          }
        }
      },
      "page": "/tallyroom/"
    }
    propose_categoriesAction

    Propose rules that assign a category to every transaction matching a merchant. This does NOT change anything on its own: the rules are staged, the page shows the person exactly how many rows each rule would touch, and they approve or discard. Two extra tools - apply_staged_changes and discard_staged_changes - appear while something is staged. Build the rule list from list_merchants, and prefer one rule per merchant cluster using its `key`.

    View tool JSON
    {
      "name": "propose_categories",
      "kind": "act",
      "impl": "imperative",
      "description": "Propose rules that assign a category to every transaction matching a merchant. This does NOT change anything on its own: the rules are staged, the page shows the person exactly how many rows each rule would touch, and they approve or discard. Two extra tools - apply_staged_changes and discard_staged_changes - appear while something is staged. Build the rule list from list_merchants, and prefer one rule per merchant cluster using its `key`.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "rules": {
            "type": "array",
            "description": "The rules to stage.",
            "items": {
              "type": "object",
              "properties": {
                "merchantKey": {
                  "type": "string",
                  "description": "A merchant `key` from list_merchants. Matches that cluster exactly. Preferred."
                },
                "contains": {
                  "type": "string",
                  "description": "Alternative to merchantKey: match any description containing this text."
                },
                "category": {
                  "type": "string",
                  "description": "The category to assign, e.g. Groceries, Dining, Transport, Subscriptions."
                },
                "note": {
                  "type": "string",
                  "description": "Optional one-line reason, shown to the person in the review panel."
                }
              },
              "required": [
                "category"
              ]
            }
          },
          "summary": {
            "type": "string",
            "description": "One line describing the batch, shown at the top of the review panel."
          }
        },
        "required": [
          "rules"
        ]
      },
      "page": "/tallyroom/"
    }
    set_transaction_categoryAction

    Set the category on a small, explicit list of transaction ids. Use this for one-off corrections; for anything that should apply to a whole merchant, use propose_categories so the person can see the blast radius first. A manual category always wins over a rule.

    View tool JSON
    {
      "name": "set_transaction_category",
      "kind": "act",
      "impl": "imperative",
      "description": "Set the category on a small, explicit list of transaction ids. Use this for one-off corrections; for anything that should apply to a whole merchant, use propose_categories so the person can see the blast radius first. A manual category always wins over a rule.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "ids": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Transaction ids, from query_transactions. At most 50."
          },
          "category": {
            "type": "string",
            "description": "The category to assign."
          }
        },
        "required": [
          "ids",
          "category"
        ]
      },
      "page": "/tallyroom/"
    }
    set_budgetAction

    Set a monthly budget for one category, or clear it by omitting the amount. Budgets show up as a line on the chart and feed check_budgets.

    View tool JSON
    {
      "name": "set_budget",
      "kind": "act",
      "impl": "imperative",
      "description": "Set a monthly budget for one category, or clear it by omitting the amount. Budgets show up as a line on the chart and feed check_budgets.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "category": {
            "type": "string",
            "description": "The category to budget."
          },
          "monthlyAmount": {
            "type": "number",
            "description": "Monthly limit. Omit to clear the budget."
          }
        },
        "required": [
          "category"
        ]
      },
      "page": "/tallyroom/"
    }
    annotate_transactionAction

    Attach a short note to one transaction, and optionally flag it so it stands out in the table. Useful for marking something the person should follow up on, like a duplicate charge to dispute.

    View tool JSON
    {
      "name": "annotate_transaction",
      "kind": "act",
      "impl": "imperative",
      "description": "Attach a short note to one transaction, and optionally flag it so it stands out in the table. Useful for marking something the person should follow up on, like a duplicate charge to dispute.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "The transaction id."
          },
          "note": {
            "type": "string",
            "description": "The note to attach."
          },
          "flagged": {
            "type": "boolean",
            "description": "Whether to flag the row."
          }
        },
        "required": [
          "id"
        ]
      },
      "page": "/tallyroom/"
    }
    pin_insightAction

    Put a finding on the board at the top of the page so it survives the conversation: a title, one line of detail, an optional number, and optionally the transaction ids it refers to so the person can click straight through to them. Pin the things worth acting on, not everything you noticed.

    View tool JSON
    {
      "name": "pin_insight",
      "kind": "act",
      "impl": "imperative",
      "description": "Put a finding on the board at the top of the page so it survives the conversation: a title, one line of detail, an optional number, and optionally the transaction ids it refers to so the person can click straight through to them. Pin the things worth acting on, not everything you noticed.",
      "inputSchema": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "description": "Short headline, a few words."
          },
          "detail": {
            "type": "string",
            "description": "One sentence of explanation."
          },
          "amount": {
            "type": "number",
            "description": "The number that matters, if there is one."
          },
          "tone": {
            "type": "string",
            "enum": [
              "neutral",
              "good",
              "warning",
              "critical"
            ],
            "description": "How the card is coloured. Defaults to neutral."
          },
          "transactionIds": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Transactions this refers to, so the card can link to them."
          }
        },
        "required": [
          "title"
        ]
      },
      "page": "/tallyroom/"
    }