MCP Server for YNAB
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| LOG_LEVEL | No | Logging verbosity, default `INFO`. | |
| YNAB_API_KEY | Yes | YNAB personal access token. Generate one at app.ynab.com/settings/developer. Required. | |
| YNAB_PLAN_ID | No | Default plan ID, making `plan_id` optional on most tools. Optional but recommended. | |
| YNAB_ALLOW_WRITES | No | Register write tools. Unset means read-only. Set to 1 to enable writes. | |
| YNAB_HISTORY_PATH | No | Write history file, default `~/.mcp-server-for-ynab/history.jsonl`. | |
| YNAB_RATE_LIMIT_PER_HOUR | No | Client-side request budget, default `190` of YNAB's 200. | |
| YNAB_RATE_WARN_THRESHOLD | No | Warn when this many requests remain, default `50`. |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| months_rangeA | [READ] Budgeted, activity and balance for every category across a range of months, as one matrix. This is the tool for any month-over-month question: one call instead of one months_get per month, and a quarter of the size, because it returns six fields per category rather than every goal field YNAB tracks. from_month and to_month: 'YYYY-MM', an ISO date, or 'current'. to_month defaults to the current month. Narrow it with category_ids or group_ids (category_ids wins if both are given). fields: which of budgeted, activity and balance each cell carries — all three by default, and dropping the two you are not reading takes roughly two thirds off a forty-category range. include_hidden=true adds hidden categories, including the credit-card payment ones. The response carries as_of: a range is a snapshot, and one cached earlier in a session is not what the plan says now. Re-read it, or use changes_since, before acting on an old one. Amounts are in milliunits (1000 = $1.00). Costs one YNAB request per month in the range (limit 36 months); check overview_request_budget before a long range. |
| category_groups_summary_by_monthA | [READ] Per-group, per-month totals of budgeted, activity and balance. Most 'is this budget healthy' questions live at group level, and a group view is small enough to read whole where a category view is not. from_month and to_month: 'YYYY-MM', an ISO date, or 'current'. to_month defaults to the current month. Hidden categories are included by default here, because excluding them would silently drop the credit-card payment group; pass include_hidden=false to leave them out. Amounts are in milliunits (1000 = $1.00). Costs one YNAB request per month in the range (limit 36 months); check overview_request_budget before a long range. |
| analysis_overspent_historyA | [READ] Every negative month-end category balance across a range, with each overspend flagged as cash or credit and a running total of what was absorbed by Ready to Assign. Cash overspending comes out of the next month's Ready to Assign, which is why a month can look under-funded for a reason invisible inside it; credit overspending stays as a negative balance and becomes debt the payment category has not covered. YNAB does not report which kind an overspend was, so it is inferred from the accounts the category was spent on. from_month and to_month: 'YYYY-MM', an ISO date, or 'current'. Also returns the categories that were overspent in the most months. Costs one YNAB request per month in the range (limit 36 months); check overview_request_budget before a long range. Plus one for the transaction history used to tell cash from credit. |
| analysis_group_parityA | [READ] Compare two category groups month by month: assigned, activity, balance, and the gap between them. Written for plans that split money between two people — paired 'his' and 'hers' or 'partner A' and 'partner B' groups — where the question is whether the two are being funded and spent evenly. Gaps are always group A minus group B. Get group ids from categories_list. from_month and to_month: 'YYYY-MM', an ISO date, or 'current'. Costs one YNAB request per month in the range (limit 36 months); check overview_request_budget before a long range. |
| analysis_copied_forward_monthsA | [READ] Find months whose assignments are an exact copy of the month before. That is the signature of YNAB's 'assign last month's amounts' applied without review, which carries one-off assignments forward as though they were the plan — a one-time $10,000 move repeated silently the next month. Defaults to the last 12 months; pass from_month and to_month to widen or shift it. The month before the range is read too, so the first month has something to be compared against. Costs one YNAB request per month in the range (limit 36 months); check overview_request_budget before a long range. |
| analysis_credit_fundingA | [READ] For every credit card and line of credit: what it owes, what its payment category holds, and the difference. Two problems live here and nowhere else in YNAB's interface — debt with no money set aside for it, and money stranded in the payment category of a closed account, which the budget counts as spoken for but cannot spend. Also reports payment categories that went negative in recent months, which is how overspending on a card turns into uncovered debt. months: how many recent months of payment-category history to include (default 6, one request each; 0 to skip). Accounts and payment categories are matched by name, because YNAB provides no identifier linking them; anything unmatched is reported rather than dropped. |
| analysis_flow_traceA | [READ] Follow one category's money through a range of months: assigned in, moved in, moved out, spent, refunded, and the balance left at the end of each month. This is 'where did the holiday money go', which needs three different YNAB resources to answer because assigning, moving between categories, and spending are three different records. from_month and to_month: 'YYYY-MM', an ISO date, or 'current'. Costs one YNAB request per month in the range (limit 36 months); check overview_request_budget before a long range. Plus two for the money movements and transactions. |
| overview_balance_identityA | [READ] Check that the plan adds up: category balances plus Ready to Assign should equal the on-budget account balances plus credit-card debt. It holds whether or not the budget is healthy, so a mismatch means the data is inconsistent — a stale read, a missing category, an account the plan is not counting — rather than that the budgeting is wrong. Run it first in a review: if it ties, the rest of the numbers can be trusted. Costs three requests. |
| changes_sinceA | [READ] What changed in the plan since a given server_knowledge value: categories, months, and transactions, compactly. Use it after the user edits their budget in the app instead of re-reading everything. Call it with no arguments first to get a baseline server_knowledge, then pass that value back on each later call. Every response returns the value to use next time. This is the cheap way to keep a long session honest: re-reading a range you already have costs one request per month, and this costs three no matter how much moved. Deleted records are omitted, and delta sync reports that a record changed, not how — the values shown are current ones. Costs three requests. |
| analysis_unassigned_transfersA | [READ] Transfers between two on-budget accounts, month by month, against what was assigned in the category groups they were meant to fund. A transfer between on-budget accounts moves no category money — both accounts are already inside the budget — so a standing 'move $1,500 to the joint account' changes no category balance, while looking in the register exactly like it did. Seven months of that went unnoticed on the plan this was written for. group_ids: the groups those transfers were meant to fund. Pass them and the months where money moved and nothing was assigned come back flagged; leave them out and you get the transfers alone. Get group ids from categories_list. account_ids narrows it to transfers touching those accounts. from_month and to_month: 'YYYY-MM', an ISO date, or 'current'. Costs two requests, plus one per month when group_ids is given. |
| analysis_assignment_patternsA | [READ] Categories whose monthly assignment equals a fixed base plus the money that arrived in the category that month. This is the interest double-count: a savings category earns interest, the interest is categorised into it, and the assignment is then written as 'the usual $1,500 plus the $12.40 of interest' — funding it twice. Each month is individually plausible, which is why nobody notices; sixteen months of it came to about $841 on the plan this was written for. Narrow it with group_ids or category_ids. from_month and to_month: 'YYYY-MM', an ISO date, or 'current'. total_if_unintended is what the pattern would have double-funded. It is a signal, not a verdict: a category deliberately funded to cover its own activity produces the same shape, so the matching months are reported for checking. Costs one YNAB request per month in the range (limit 36 months); check overview_request_budget before a long range. Plus one for the inflows. |
| pingA | [READ] Is this server up? Answers from the process alone: no YNAB request, no token check, no budget read. This exists for the agent that has been rate limited and scheduled itself to come back — the way to find out whether the server is still reachable must not be a call that spends the quota it is waiting on, or that fails for a second, unrelated reason. Returns the server version, whether write tools are registered, and the request budget. |
| overview_request_budgetA | [READ] How many API requests remain in the current rolling hour, in full. Every other tool already returns requests_used_this_hour and requests_remaining on its response, so call this one only for the rest: the limit, the window, and when an exhausted budget reopens. YNAB allows 200 per token per hour and this server budgets slightly below that. The quota belongs to the access token and is shared with your own YNAB apps, so the figure here is what this server spent, not necessarily what YNAB has left. This tool costs no API requests. |
| overview_available_toolsA | [READ] List all available tools grouped by family, with classification and summary. Start here to understand what the server can do before running other tools. Also returns conventions worth knowing before the first call: how amounts are expressed, which reads cost a request per month, and what hidden categories are. |
| overview_budget_snapshotA | [READ] Single-call budget health snapshot. Returns current month income, spending, to-be-budgeted, age of money, account counts, and overspent categories. Good first call for any budget session. Also reports two things nothing else in YNAB surfaces: unfunded_card_debt, what the credit cards owe beyond what their payment categories hold, and trapped_funds, money assigned to the payment category of a closed or missing account. Costs three requests. |
| overview_month_healthA | [READ] Summarize a budget month. Returns income, budgeted, activity, to-be-budgeted, overspent categories, and underfunded goals. Defaults to current month. Also reports the previous month's overspending, by group: it is settled before this month is budgeted, so a month can have less to assign than its income suggests for a reason nothing inside the month shows. Only cash overspending comes out of Ready to Assign — analysis_overspent_history separates that from overspending charged to a card. month: ISO date string for first day of month (e.g. '2024-01-01'). Costs two requests. |
| overview_cash_positionB | [READ] Summarize account balances. Returns on-budget total, off-budget total, net worth, and per-account detail. Cleared vs uncleared breakdown included for on-budget accounts. |
| triage_summaryA | [READ] Combined triage summary: count of uncategorized and unapproved transactions. Use this to quickly assess whether the budget needs attention before diving deeper. uncategorized_count excludes what can never take a category — transactions on off-budget tracking accounts, and transfers between two on-budget accounts — so it is work, not noise. uncategorized_raw_count is what YNAB's own filter would have said. |
| triage_uncategorizedA | [READ] Transactions that genuinely need a category, most-recent first. Each entry includes payee, amount, account, and memo. Two kinds of transaction are excluded by default because they can never take a category: anything on an off-budget tracking account, and transfers between two on-budget accounts. On a real plan that turned a queue of 533 into the 14 that were actually work. count is the number needing attention; raw_count is what YNAB's filter returned before filtering, and excluded says what went. Set include_tracking_accounts or include_transfers to true to see them anyway. limit and offset page the result; count and raw_count always describe the whole queue. |
| triage_unapprovedA | [READ] List all unapproved transactions, most-recent first. Imported transactions from bank connections typically start as unapproved. limit and offset page the result; count always describes the whole queue. |
| triage_unmatched_manualA | [READ] Hand-entered transactions on bank-linked accounts that never cleared. On an account YNAB imports from, a manual entry is a promise that a real transaction is coming. One still uncleared weeks later means the bank never matched it: a duplicate of something already imported, a payment that did not go through, or a typo. Their net amount is how far YNAB stands from the bank for these entries alone — on the plan this was written for, ten of them on one checking account summed to $9,469. account_id narrows it to one account. older_than_days is how long an entry must have sat (default 30). since_date bounds how far back to read (default 18 months). |
| triage_pending_importsA | [READ] Card authorisations YNAB imported that never became real charges. A merchant's hold — a fuel pump, a hotel, a rideshare — arrives through direct import as a transaction with an import_id starting 'YNAB:P:'. When the real charge posts, usually at a different amount, it comes in as its own transaction and the hold is left behind: uncleared, permanent, and counted in the card's balance. Four of them were inflating one card by about $79 on the plan this was written for. triage_unmatched_manual cannot find these — it looks for entries with no import_id, and these have one. account_id narrows it to one account. older_than_days is how long a hold must have sat (default 7). since_date bounds how far back to read (default 6 months). Check each against the statement before deleting: a hold whose charge did post appears twice, and only the hold should go. Costs two requests. |
| triage_reconciliationA | [READ] Accounts ordered least-trustworthy first: never reconciled, then longest since. Each row carries cleared and uncleared balances, the bank-link state, and warnings — including a cash account whose cleared balance is negative, which means the bank shows an overdraft or the account holds transactions it should not. Reconciliation staleness is what decides whether the rest of a plan's numbers can be trusted, and no other tool reports it. stale_after_days: how long counts as stale (default 45). Costs one request. |
| bookkeeping_categorization_suggestionsA | [READ] Suggest categories for uncategorized transactions using payee history. Confidence: high (>=80% of past transactions), medium (>=50%), or low (<50%). Does NOT write — use transactions_update to apply suggestions. |
| bookkeeping_memo_annotation_suggestionsA | [READ] Find transactions missing memos that probably need them. Flags large transactions (>= $50) and splits without memos. since_date: ISO date to limit history (e.g. '2024-01-01'). |
| bookkeeping_transaction_historyA | [READ] Retrieve recent transactions with optional filters and totals. Filter by one of: payee_id, category_id, or account_id. since_date: ISO date to limit history (e.g. '2024-01-01'). Returns inflow, outflow, and net totals in addition to the transaction list. |
| analysis_overspent_categoriesB | [READ] Categories with negative balances for a given month. Sorted by most-overspent first. Includes budgeted, activity, and balance. month: ISO date string for first day of month (e.g. '2024-01-01'). Defaults to current month. |
| analysis_target_funding_gapsA | [READ] Categories with unmet funding goals for a given month. Shows how much more needs to be budgeted to meet each goal target. month: ISO date string for first day of month (e.g. '2024-01-01'). Defaults to current month. |
| analysis_upcoming_scheduled_risksA | [READ] Scheduled outflows due within lookahead_days that may exceed category balances. Flags each transaction as is_risk=true when the category balance is insufficient. lookahead_days: how many days ahead to scan (default 30, max recommended 90). |
| analysis_recurring_chargesA | [READ] Find repeating charges (subscriptions, memberships, regular bills) and estimate what each costs per year. months: how far back to look, default 12. Charges are grouped by YNAB payee id, not by payee name, so no fuzzy name matching is involved: YNAB already resolves a merchant to one payee regardless of how the bank spelled it. Only outflows count; transfers between your own accounts are excluded. A series needs at least 3 charges on a recognisable cadence (weekly through yearly) to be reported. Each result carries occurrences — treat a series seen 3 times as a weaker signal than one seen 12 times — plus amount_changed and days_since_last, which surface price rises and charges that may have lapsed. Amounts are in milliunits (1000 = $1.00). |
| history_listA | [READ] List writes this server has made, newest first. Each entry says whether it can be reverted and how. Use this before history_revert or history_revert_to to choose an entry. Entries are recorded even when writes are later disabled, so history survives a restart. |
| history_showA | [READ] Show one history entry in full, including the before and after state. The before state is what a revert would restore. |
| accounts_listA | [READ] List all accounts for a plan. Balances are in milliunits (1000 = $1.00). last_reconciled_at is read-only everywhere in this API: marking transactions reconciled does not move it, and no tool here can set it. Only reconciling in the YNAB app does, so an account cleaned up through this server will still show its old reconciliation date. Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call. |
| accounts_getA | [READ] Get a single account by ID. Balance is in milliunits (1000 = $1.00). last_reconciled_at is read-only: no route in the YNAB API sets it, so it stays where the YNAB app last left it however many transactions this server marks reconciled. |
| categories_listA | [READ] List all categories grouped by category group. Amounts (budgeted, activity, balance) are in milliunits (1000 = $1.00) and are for the current month. compact=true returns only id, group, name, budgeted, activity and balance per category — about a quarter of the size, and enough to find an id or read the shape of a plan. include_hidden=true adds hidden categories, which is where YNAB keeps the credit-card payment categories; deleted categories are never returned. Note: category group listing is embedded here — YNAB returns categories already grouped. Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call. |
| categories_getB | [READ] Get a single category by ID. Amounts are in milliunits (1000 = $1.00). |
| categories_get_for_monthA | [READ] Get a category's budgeted, activity, and balance for a specific month. month: ISO date string for the first day of the month (e.g. '2024-01-01'). Amounts are in milliunits (1000 = $1.00). |
| money_movements_listA | [READ] List all money movements for a plan. A money movement is budgeted funds moved between categories within a month — it is not a transaction and has no payee or account. A null from_category_id or to_category_id means Ready to Assign. Amounts are in milliunits (1000 = $1.00). Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call. |
| money_movements_list_by_monthA | [READ] List money movements (budgeted funds moved between categories) for a specific month. month: ISO date string for the first day of the month (e.g. '2024-01-01'). A null from_category_id or to_category_id means Ready to Assign. Amounts are in milliunits (1000 = $1.00). |
| money_movement_groups_listA | [READ] List money movement groups for a plan. A group ties together the movements made in a single action; it carries no amount of its own. Join movements to a group on money_movement_group_id. Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call. |
| money_movement_groups_list_by_monthB | [READ] List money movement groups for a specific month. A group ties together the movements made in a single action; it carries no amount of its own. month: ISO date string for the first day of the month (e.g. '2024-01-01'). |
| months_listA | [READ] List budget months with summary data (income, budgeted, activity, to_be_budgeted). Amounts are in milliunits (1000 = $1.00). Months in which nothing happened — no income and no activity — are left out by default, the way YNAB's own month picker leaves them out. YNAB keeps records for months before a plan really began, sometimes carrying a stray assignment and a large negative to_be_budgeted, and a review that starts from the first month in this list starts a year before the budget did. omitted_month_count says how many went; include_empty=true returns them. Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call. |
| months_getA | [READ] Get one month's categories with their budgeted, activity, and balance. month: ISO date for the first day of the month ('2024-01-01'), 'YYYY-MM', or 'current'. compact=true returns only id, group, name, budgeted, activity and balance per category — about a quarter of the size, and enough for any month-over-month review. Use the full form only when you need goal fields or notes. include_hidden=true adds hidden categories, which is where YNAB keeps the credit-card payment categories; deleted categories are never returned. To compare several months, use months_range instead (up to 36 months in one call). Amounts are in milliunits (1000 = $1.00). |
| payees_listA | [READ] List all payees for a plan. Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call. |
| payees_getC | [READ] Get a single payee by ID. |
| payee_locations_listB | [READ] List all payee locations (geographic lat/lon data from bank imports). Low priority: rarely useful for AI budget workflows. |
| payee_locations_getB | [READ] Get a single payee location by ID (geographic lat/lon data). Low priority: rarely useful for AI budget workflows. |
| payee_locations_list_for_payeeA | [READ] List all locations for a specific payee (geographic lat/lon data). Low priority: rarely useful for AI budget workflows. |
| plans_listB | [READ] List all YNAB plans (budgets) available to the authenticated user. |
| plans_getA | [READ] Get a single plan with full account, category, and month data. Pass last_knowledge_of_server for delta sync — only changed data is returned. The response includes server_knowledge for use in the next delta request. |
| plans_get_settingsA | [READ] Get plan settings including currency format and date format. Note: this endpoint is intentionally narrow — it returns formatting preferences only, not budget data. |
| scheduled_transactions_listA | [READ] List all scheduled transactions for a plan. Includes date_next (next occurrence) for each. Amounts are in milliunits (1000 = $1.00). Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call. |
| scheduled_transactions_getA | [READ] Get a single scheduled transaction by ID. Amount is in milliunits (1000 = $1.00). |
| transactions_listA | [READ] List transactions for a plan. since_date: ISO date string (e.g. '2024-01-01') — only transactions on or after this date. type: 'uncategorized' or 'unapproved' for filtered lists. Amounts are in milliunits (1000 = $1.00). Includes subtransactions for split transactions. Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call.Returns a paginated envelope with items, count, has_more, and next_offset. limit defaults to 100 and cannot exceed 500. Filters applied before paging: cleared ('cleared', 'uncleared', 'reconciled'), approved (true/false), manual_only=true for transactions with no import_id (entered by hand), min_amount to keep only transactions whose absolute amount is at least that many milliunits. fields: name the columns you need and each item is projected down to them, which is where the size of a long list actually goes — fields=['id,date,amount,cleared,import_id,payee_name,memo'] is a fraction of the full row. id is always included, and an unknown name is refused with the list of valid ones. Fields that are null or empty are omitted from each item. A missing category_id therefore means the transaction is uncategorized, and a missing subtransactions list means it is not a split. |
| transactions_list_by_accountA | [READ] List transactions for a specific account. Amounts are in milliunits. A transfer to another on-budget account moves no category money — both accounts are already inside the budget — so a transfer in this list changed no category balance and no assignment. Check assignments separately, or use analysis_unassigned_transfers. Supports delta sync: pass last_knowledge_of_server — the server_knowledge value any earlier response returned — and YNAB sends only what changed since, which is how a long session stays current without re-reading everything. changes_since does the same across categories, months and transactions in one call.Returns a paginated envelope with items, count, has_more, and next_offset. limit defaults to 100 and cannot exceed 500. Filters applied before paging: cleared ('cleared', 'uncleared', 'reconciled'), approved (true/false), manual_only=true for transactions with no import_id (entered by hand), min_amount to keep only transactions whose absolute amount is at least that many milliunits. fields: name the columns you need and each item is projected down to them, which is where the size of a long list actually goes — fields=['id,date,amount,cleared,import_id,payee_name,memo'] is a fraction of the full row. id is always included, and an unknown name is refused with the list of valid ones. Fields that are null or empty are omitted from each item. A missing category_id therefore means the transaction is uncategorized, and a missing subtransactions list means it is not a split. |
| transactions_list_by_categoryA | [READ] List transactions for a specific category. Amounts in milliunits. Returns a paginated envelope with items, count, has_more, and next_offset. limit defaults to 100 and cannot exceed 500. Filters applied before paging: cleared ('cleared', 'uncleared', 'reconciled'), approved (true/false), manual_only=true for transactions with no import_id (entered by hand), min_amount to keep only transactions whose absolute amount is at least that many milliunits. fields: name the columns you need and each item is projected down to them, which is where the size of a long list actually goes — fields=['id,date,amount,cleared,import_id,payee_name,memo'] is a fraction of the full row. id is always included, and an unknown name is refused with the list of valid ones. Fields that are null or empty are omitted from each item. A missing category_id therefore means the transaction is uncategorized, and a missing subtransactions list means it is not a split. |
| transactions_list_by_payeeA | [READ] List transactions for a specific payee. Amounts in milliunits. Returns a paginated envelope with items, count, has_more, and next_offset. limit defaults to 100 and cannot exceed 500. Filters applied before paging: cleared ('cleared', 'uncleared', 'reconciled'), approved (true/false), manual_only=true for transactions with no import_id (entered by hand), min_amount to keep only transactions whose absolute amount is at least that many milliunits. fields: name the columns you need and each item is projected down to them, which is where the size of a long list actually goes — fields=['id,date,amount,cleared,import_id,payee_name,memo'] is a fraction of the full row. id is always included, and an unknown name is refused with the list of valid ones. Fields that are null or empty are omitted from each item. A missing category_id therefore means the transaction is uncategorized, and a missing subtransactions list means it is not a split. |
| transactions_list_by_monthA | [READ] List transactions for a specific month. month: ISO date string for the first day of the month (e.g. '2024-01-01'). Amounts in milliunits. Returns a paginated envelope with items, count, has_more, and next_offset. limit defaults to 100 and cannot exceed 500. Filters applied before paging: cleared ('cleared', 'uncleared', 'reconciled'), approved (true/false), manual_only=true for transactions with no import_id (entered by hand), min_amount to keep only transactions whose absolute amount is at least that many milliunits. fields: name the columns you need and each item is projected down to them, which is where the size of a long list actually goes — fields=['id,date,amount,cleared,import_id,payee_name,memo'] is a fraction of the full row. id is always included, and an unknown name is refused with the list of valid ones. Fields that are null or empty are omitted from each item. A missing category_id therefore means the transaction is uncategorized, and a missing subtransactions list means it is not a split. |
| transactions_getA | [READ] Get a single transaction by ID. Includes subtransactions for split transactions. Check transfer_account_id to identify transfer transactions. Amount is in milliunits (1000 = $1.00). |
| user_getA | [READ] Get the authenticated YNAB user. Returns the user ID. |
| reconcile_previewA | [READ] Does this account agree with its statement, and if not, what is in the way. This is what YNAB's reconcile screen does, and nothing else here answers it: the cleared balance as of a date, the statement balance you give it, the difference between them, and the four queues that explain a difference — transactions cleared but not yet reconciled, uncleared ones old enough to be suspect, hand-entered ones the bank never matched, and card authorisations that never posted. statement_balance: the closing balance from the statement, in milliunits (1000 = $1.00), negative for a credit card you owe money on. as_of_date: the statement's closing date (ISO, defaults to today). The cleared balance is computed as of that date, which is why it can differ from YNAB's own current figure. Costs two requests, and changes nothing — reconcile_apply is the write. |
| transactions_match_statementA | [READ] Pair the rows of a bank export with an account's register, and name what is left over on each side. rows: the statement lines, as objects with date (ISO), amount, and optionally description. amounts_in: 'milliunits' (default, 1000 = $1.00) or 'dollars' if you are passing the CSV's own figures. Either way the sign is YNAB's: negative for money out. An export that writes debits as positive numbers must be negated first, or every row comes back unmatched. date_tolerance_days: how far a posting date may sit from YNAB's date and still match (default 3, which covers a weekend). Matching is on exact amount, one-to-one, closest date first — nothing fuzzy, because a wrong match hides the transaction you were looking for. Returns matched pairs, unmatched_on_statement (the bank saw it and YNAB has no record), and unmatched_in_ynab (the reverse — where duplicates, never-posted card authorisations and bounced payments show up), each labelled with what it looks like. Costs two requests. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| monthly_review | Walk this month's budget: health, overspending, and what needs attention. |
| weekly_triage | Clear the uncategorized and unapproved queues for the week. |
| categorize_and_approve | Categorize uncategorized transactions, then approve what is ready. |
| subscription_audit | Find recurring charges and what they cost per year. |
| cash_position | Summarize balances across every account. |
| undo_last_changes | Show what this server changed, and reverse it if asked. |
| budget_audit | Review a range of months: integrity, overspending, card funding, and drift. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
| YNAB method | The budgeting method, and what its terms actually mean. |
| Write safety | What to confirm, what to verify, and what cannot be undone. |
| Credit accounts | Payment categories, unfunded debt, and why repayments routed through a brokerage go wrong. |
| Tool selection | How the raw and enriched tool families differ, and where to start. |
TDQS
Scored across 62 tools
Several tools have overlapping purposes, such as overview_budget_snapshot vs overview_month_health for month summaries and analysis_overspent_history vs analysis_overspent_categories for overspending. The extensive descriptions and cross-references help, but an agent still faces many similar analytical tools that could cause misselection.
Tool names use consistent snake_case with family prefixes (analysis_, overview_, triage_, bookkeeping_) and resource_list/get patterns. Minor outliers like ping and changes_since are negligible, making the naming mostly predictable across the set.
With 62 tools, the server is far above the typical 3–15 range and exceeds the 25+ threshold that signals too many. While many tools serve distinct niche analyses, the sheer volume increases selection complexity and cognitive load for an agent.
The surface is entirely read-only; there are no create, update, or delete tools, yet descriptions reference write tools like transactions_update and reconcile_apply that are absent. This leaves core budget management workflows incomplete and creates dead ends for an agent.